# Design decisions

[Code standards](code-standards.md) are the rules every file follows; this folder is why the system is shaped the way it is.

One file per decision. Each states the decision, the reasoning, the alternatives
rejected, and the consequences — including the bad ones.

## Transport

- [0001 — Git lives at the root namespace, REST lives under `/api`](0001-namespace-split.md)
- [0019 — SSH is a second transport, not a second git](0019-ssh-is-a-second-transport-not-a-second-git.md)
- [0002 — The transport layer takes streams, not `Request`/`Response`](0002-streams-not-http-objects.md)
- [0013 — The request body is captured before anything else can await](0013-raw-body-is-captured-first.md)
- [0014 — A flush-only POST is a probe, not a malformed push](0014-the-pre-push-probe.md)
- [0003 — `git/` is not a REST resource](0003-git-is-not-a-resource.md)

## Storage and durability

- [0004 — Object storage is the source of truth, local disk is a cache](0004-object-storage-is-the-truth.md)
- [0005 — One commit point per push, and it is a compare-and-swap](0005-single-commit-point.md)
- [0006 — Entries carry no sequence number](0006-entries-carry-no-seq.md)
- [0007 — Optimistic concurrency, never locks](0007-optimistic-concurrency.md)
- [0008 — The log is a binary format](0008-binary-log-format.md)
- [0009 — The index holds a ref snapshot, not a diff](0009-index-holds-a-snapshot.md)
- [0010 — Orphaned entries are garbage, never corruption](0010-orphans-are-garbage.md)
- [0012 — Materialization is forward-only replay](0012-forward-only-materialization.md)
- [0015 — Nothing holds a packfile in memory](0015-nothing-holds-a-packfile.md)
- [0020 — Deleting a repository is a tombstone, then a purge](0020-deletion-is-a-tombstone-then-a-purge.md)

## Review

- [0016 — A pull request spans two logs, and lends objects rather than copying them](0016-a-pull-request-spans-two-logs.md)
- [0017 — Issues are rows, not branches](0017-issues-are-rows-not-branches.md)
- [0018 — Timestamps are `timestamptz`, never bare `timestamp`](0018-timestamps-are-timestamptz.md)
- [0021 — Repository access is a role ladder, and an invitation grants nothing](0021-access-is-a-role-ladder.md)
- [0022 — Users and organizations share one namespace](0022-owners-share-one-namespace.md)
- [0023 — Organization access is a base permission, raised per repository](0023-organization-access-is-a-base-permission.md)
- [0024 — Tags live in git, releases live in rows](0024-tags-live-in-git-releases-in-rows.md)
- [0025 — Stored files are billed to the owning account, and the quota is configuration](0025-storage-is-billed-to-the-owning-account.md)
- [0026 — A review is pinned to the head it read, and threads hang off its line comments](0026-a-review-is-pinned-to-the-head-it-read.md)
- [0027 — Squash and rebase carry the head along](0027-squash-and-rebase-carry-the-head-along.md)
- [0028 — Branch writes from the API are ref-only pushes](0028-branch-writes-are-ref-only-pushes.md)
- [0029 — Repository events go through an outbox, and notifications are its first consumer](0029-events-go-through-an-outbox.md)
- [0030 — Columns are snake_case in the database, camelCase in the schema](0030-columns-are-snake-case.md)
- [0031 — Outbound delivery is its own service, and Postgres is its queue](0031-outbound-delivery-is-its-own-service.md)
- [0032 — GitHub imports run outside the API, which owns the retries](0032-github-imports-run-outside-the-api.md)
- [0033 — Pull requests keep `refs/pull/<n>/head` and `/merge` in the base log](0033-pull-requests-keep-refs-in-the-base-log.md)
- [0034 — A push is verified before the log commits it, and the log stores the indexed pack](0034-a-push-is-verified-before-the-log-commits-it.md)
- [0035 — Pushes and forks count against separate quotas, which an account can override](0035-pushes-and-forks-count-against-separate-quotas.md)
- [0036 — Git LFS objects are stored per repository and served through the API](0036-lfs-objects-are-stored-per-repository.md)
- [0037 — Release assets count against a quota of their own](0037-release-assets-count-against-their-own-quota.md)
- [0038 — Attachments are billed to whoever uploads them, and swept once nothing mentions them](0038-attachments-are-billed-to-their-uploader.md)
- [0039 — A pull request's commits are recorded in its timeline as each push lands](0039-pull-request-commits-are-recorded-per-push.md)

## Open

- [0011 — Deferred decisions](0011-deferred.md)
