The expensive thing about AI-assisted development is not the tokens. It is re-answering questions that were already answered — re-reading a codebase to recover a decision, re-litigating a settled trade-off, or confidently shipping something that then has to be unshipped. Everything below exists to make that class of waste structurally hard.
Some work happens on a workstation with the live application, local database and hardware attached. Some happens in a cloud container with the repo and production database but none of that. Neither can see the other's chat history. If a decision lives only in a conversation, it is already lost — so the repository carries it instead, and there is a standing rule that a call gets written down in the same session it is made.
| File | What it exists to stop | Size |
|---|---|---|
| Architecture map | Re-deriving how the system fits together, and re-litigating release routing. Explicitly outranks the README when they disagree. | 766 lines |
| Feature → file index | The wrong “no, we don’t have that.” A feature can span four surfaces; a single grep that misses one produces a confident false negative. | 1,209 lines |
| Status ledger | Redoing finished work, or re-proposing something already tried and abandoned. Carries done / queued / abandoned and why. | 2,305 lines |
| Dated decision log | Losing the reasoning behind a call. Each entry: the decision, why, and where it took effect. | running |
| Design docs | Reconstructing intent from code. Each opens with the request captured verbatim. | 25 docs |
| Domain cheat-sheet | Re-deriving schema conventions from query plans every single time someone touches the catalog. | — |
52 documents in total, plus an archive for retired plans. The archive matters as much as the index: a superseded plan left in place reads as current and gets re-implemented.
A startup hook prints the open-items table, the document index, and the live version of each component read straight from its manifest. Deliberately prints pointers, not a summary: no model call, no latency, nothing that can go stale or be hallucinated. It is guarded at every read and exits successfully no matter what, because a memory aid that can fail a session is worse than none.
A slash command dispatches a single subagent on the cheapest capable model to answer from the committed docs — in a fixed precedence order, returning every supporting quote with its file and line. It is explicitly instructed to do three things most retrieval does not: flag loudly when two documents disagree, answer “not documented” rather than guess from code, and offer to fix the doc when what it finds is stale.
The split is the point. The thing needed at the start of every session should cost nothing and never lie; the thing needed occasionally can afford a model, but not the expensive one, and must show its sources. A stale index produces exactly the wrong “we don’t have that” answer — which is why the recall path is required to surface disagreement instead of silently picking a winner.
| Audit | What it found | Result |
|---|---|---|
| Cross-branch drift | The branch every client release shipped from had drifted 79,199 lines behind, and carried 35 test files against the other branch’s 90. | 55 suites restored |
| Release-gate replay | Running the full suite against the shipping branch surfaced a pattern-compiler defect that had ridden through ten consecutive releases unseen — because the suite that caught it did not exist on that branch. | P1 caught pre-fleet |
| Silent-join audit | A join that was supposed to bind time-series rows to their parent matched 96 of 3,651. Two independent causes; the query returned rows either way, so nothing ever errored. | 2.6% → full |
| Enabled-but-dead rules | 37 of 109 enabled user rules could never fire — anchored against a line format that does not exist at match time. Being enabled is what made them invisible; they read as coverage. | whole class fixed |
| Single-source evidence | One emote was being counted as a real event. 44% of every stored record of that type was false, and nothing in the pipeline could contradict it, because nothing else was watching. | 2nd source designed |
| Capped-query sweep | A paginated query feeding a set rather than a list produced wrong answers past the cap. The audit generalised the shape and flagged 23 more instances of it. | class documented |
| Retention grain | A telemetry table rolled up to the grain actually queried: 114,444 rows → 1,087, folding 104,846 events. | 31 MB → 4.8 MB |
| Ignore-file inheritance | A file-level promotion process only ever moves the files it is told to. An ignore rule protecting a credential existed on one branch and had never crossed to the other. | closed; never leaked |
The common thread: every one of these looked healthy from the outside. Green tests, enabled features, queries returning rows. They were only findable by asking a question nobody had asked yet, which is exactly the work that is cheap to run and expensive to skip.
Every design doc opens with the original ask, unedited. Paraphrasing loses the constraints, and the constraints are the part that survives contact with reality. A worked example — the first ask specified the goal and every gating condition:
request the cleric that has it available (not on recast cooldown) and has emeralds AND is not coming up on the chain within the cast time plus global cooldown time
Research then established that two of those conditions were unknowable: one depended on a manual inventory export three weeks stale, the other on data only a minority of clients report. A paraphrased version would have hidden that. Instead the follow-up ask absorbed the finding and landed on something buildable:
how about calling out two clerics that have recently healed on the chain as potential casters so that they can call out in voice who is doing it? The design doc’s verdict: “That second message is the design. The rest of this doc explains why.”
That is the pattern worth naming: a well-specified request is not one that gets built as written — it is one that can be revised precisely when a constraint turns out to be false. The counter-example is in the same corpus: a perfectly clear request for arrival estimates that research killed outright, because the data source carries no position information at all. Good ask, impossible answer, settled in one pass because the ask was specific enough to test.
A feature needed the exact string a server emits on a rare event. Documentation, forums and an AI assistant all agreed on two strings. One was real. The other described an outcome the server never emits at all — and a version of it had already been implemented once from a guess, sitting enabled and matching nothing for weeks.
Reading the server’s own source settled it in minutes, and produced three facts no secondary source had: the message uses the name form even for the affected player, it is range-limited so distant clients never receive it, and the failure case is silent by design — meaning “detect the failure” was not a feature that could be built, and would have been chased indefinitely.
Server source, database schema, a live measurement, or a recorded real-world sample. Anything else is a hypothesis to be checked, including a confident answer from a model.
86 test suites, golden-file regression over recorded production input, a dedicated checker for a template that had shipped a blank-page bug twice, and CI on every branch that reaches a user.
None of it is exotic. It is the same discipline any long-lived codebase needs, applied a little earlier than usual — because assistance makes it cheap to produce work and just as cheap to produce the wrong work, and the difference between the two is almost always whether someone bothered to check first.