Mostly Done.
Contents

10 Make memory durable

The context window is temporary. The codebase has to remember for it. An agent can read a repository quickly and still repeat a mistake you solved six months ago.

Good project memory does not record every event. It preserves the failure classes that would otherwise return.

10.1 Write down scars

The most useful agent instructions read like scar tissue: each rule traces to a shipped bug. Take a text editor built largely by agents. Its instruction file warns that carriage return and line feed behavior matters at grapheme boundaries, that per-glyph backgrounds produce ugly strips, that two recognizers for one grammar will drift, that equivalence tests compare only the fields they name. Each warning explains the trap, not only the preferred helper.

Compare two instructions:

Use the unified matcher.

and:

Use the unified matcher because two recognizers for the same grammar diverged in production.

The second survives refactoring. A future agent may replace the helper, but it knows the system must keep one grammar implementation.

The best scars sit in the code they protect. Picture a comment in an editor’s styling code: the line-prefix loop must advance by the full line range, because the old clamped-location version re-derived the same final line forever once the scan reached the end of the text, hanging the UI with a pinwheel. Four facts in a few lines: the rule, the tempting wrong approach, the shipped symptom, and the location. That is the anatomy of a scar worth keeping.

Other scars worth carrying share the shape:

A scar should be brief enough to read and specific enough to alter behavior.

10.2 Give documents authority

Documentation turns dangerous when several files describe overlapping truths without saying which one wins. A fresh agent will quote the wrong document with perfect confidence.

A useful document map identifies:

Treat the current handoff document as authoritative for the work in flight, and record when it overrides older material. The conflict stays visible instead of silently splitting into two realities.

Keep the map small. Adding a new canonical document should be harder than adding a note to the right existing one.

10.3 Update the whole contract surface

Ship a language feature and your parser is the smallest part of the change. The feature is incomplete until the documentation, the website, the embedded machine-readable specification, the editor grammar, the examples, and the migration behavior agree with it.

Agents and tools consume these surfaces as operational inputs, so this is more than documentation hygiene. A stale embedded specification can teach another agent to emit syntax your parser no longer accepts. An old editor grammar presents removed syntax as valid. A migration page can preserve a semantic model the runtime has abandoned.

Make the update in the same branch as the behavior, while the author still holds the full model in context.

A contract-surface checklist might include:

Not every project has every surface. Every project has more than the code.

10.4 Record rejected ideas when they will recur

Review sometimes proves a concern false, and the refutation is worth keeping when the false premise is attractive. Consider a port of a published typesetting algorithm. A reviewer concludes that a rule was inverted during the port; the algorithm’s published source shows it was not. A short note or test tied to that reference stops the same finding from returning with every new reviewer.

Durability is where this usually fails. Refutations tend to live wherever the review happened, in a scratch file one reboot away from vanishing. Move them into the repository’s committed notes. The raw candidate list from the review will not survive, and it does not need to: the accepted findings and the reasoned rejections are what the next session needs.

Do not archive every rejected comment. Preserve the ones that reveal an ambiguous design, a misleading code shape, or a domain rule that is easy to misremember.

10.5 Let guardrails remember and evolve

Suppose your pre-commit gates on complexity and file size catch real debt and also create repeated friction, because the hook does not understand the code that predates it. The wrong responses are to bypass the gate or to declare the friction a feature. Pay down some of the debt and record that the gate needs to learn the baseline.

That is the right relationship with guardrails. They should be:

10.6 Memory should shorten the next session

The test of project memory is not page count. It is how fast a fresh agent can answer:

Good memory turns old pain into a lower future cost. The bug gets paid for once.

use ← and → to turn pages