Decisions
Why this codebase is shaped the way it is — the alternatives that were rejected, and, where there was one, the specific bug that settled the argument.
Thirteen decisions that explain most of the code. Each one names what was rejected and why, because a decision recorded without its alternative is just an assertion.
Most of these were argued out in a doc comment next to the code before they were collected here — that is where the reasoning has always lived, and it stays there. These pages exist so the argument is readable without opening fourteen files, and so the ones that were never written down get written down.
What a record here is worth
The useful ones name a specific failure. A decision justified only by taste is a decision the next person will re-litigate; a decision justified by "this shipped and here is what broke" is one they will leave alone.
Where that evidence exists, it is quoted. Where it does not, the page says so rather than inventing a rationale after the fact — see stack choices, which is four decisions with no recorded reasoning at all.
The thread running through them
Nearly every page below is a variation on one idea, stated in ADR-0001: a convention that only exists in a document is a convention you have not shipped. The ladder — generator, type, database constraint, lint rule, structure check, and only then prose — is what most of the others are an application of.
| # | Decision |
|---|---|
| 0001 | Conventions are executable, and prose is the last resort |
| 0002 | Tenancy is enforced by Postgres, not by remembering a where |
| 0003 | TenantContext is branded, and middleware is not a security boundary |
| 0004 | The action builder is a type-state machine |
| 0005 | The template is vendored, not a dependency |
| 0006 | Managed files carry a marker; the hash lives in the manifest |
| 0007 | Codemods emit text edits, never a reprinted AST |
| 0008 | There is one validation verb |
| 0009 | A calendar date is a date, not a timestamp |
| 0010 | Offset pagination, deliberately |
| 0011 | State management has a single answer |
| 0012 | Integrations are seams, and stay unconfigured until they earn it |
| 0013 | The stack choices, including the four nobody wrote down |