· 7 min read

The Standards I Give My Coding Agents

A cross-project memory system for AI coding agents: decisions, feedback, changelog, and a skill layer that knows this isn't a Tailwind project.

An AI coding agent has no memory between sessions unless you build it one, which makes it something like a very fast intern with amnesia: sharp in the moment, and a stranger to itself by morning. Close the terminal and the reasoning behind yesterday's decision is gone, along with the fact that you already tried the obvious approach and it broke something, and the feedback you gave about a pattern you never want to see again. The agent starts from zero every time, which means you start from zero every time too, re-explaining context you already paid for once.

I got tired of that tax and built a system for it: a small set of conventions, shared across every project I run an agent against, that gives the agent somewhere to put what it learns.

The failure mode this is solving

Three specific things kept going wrong, on a loop, before I had this in place.

The agent would ask me a clarifying question mid-task that it could have answered itself by reading the code, or that did not need answering at all because any competent default was fine. Multiply that by every session and it is a constant low-grade interruption, worse than doing the work myself for anything small.

A decision would get made, silently, inside a diff. Six weeks later a different session would undo it, because the reasoning behind the original choice existed nowhere except a commit message nobody reads on a random Tuesday, and the code alone does not explain why it is the way it is rather than the more obvious way.

And feedback I gave in the moment, a correction, a preference, a "no, not like that," would apply to that one session and evaporate. The next agent would make the same mistake, because nothing captured that I had already ruled it out and why.

The philosophy, before the mechanics

Three rules do most of the work, and they are all about where judgment happens relative to interruption.

Decide, don't ask. Pick the option a competent engineer would pick, write the assumption down, keep going. Stop only for something destructive, something involving real money or production, or a genuine fifty-fifty fork with no clearly better option. Everything else is a default, not a question.

Batch, never interrupt. Open questions go into one list at the end of a response, not as a mid-task interruption that breaks flow. If five things were ambiguous, I want to resolve five things once, not get stopped five separate times.

Look backwards first. Before changing existing code, find out why it is the way it is. Search the decision records, then the git history, before assuming the current shape is an accident rather than a choice. Reasoning disappears the moment code gets overwritten by someone who did not know it was there.

Put together, the point is an agent that behaves like a colleague with institutional memory, not one that behaves like a very fast intern who has never seen the codebase before and needs everything re-explained.

The four places memory actually lives

Decisions. One file per non-obvious choice, in a .dev-standards/decisions/ folder, numbered and immutable: a later change supersedes a decision, it never rewrites one. Each record states the options that were actually considered, which one was picked, and why, so a future session can find the reasoning instead of reverse-engineering it from the diff. The first decision record in this system, fittingly, is the one that documents adopting the system itself.

Feedback. A reaction, a correction, a stated preference gets quoted verbatim before it gets interpreted, because the interpretation is where nuance gets lost, and having the original words on record means a later session can re-derive the right lesson even if my first interpretation of my own feedback was slightly off.

Changelog. Every user-visible change gets a one-line fragment in its own file, not a hand-edited shared changelog. The reason is mechanical: multiple sessions or parallel worktrees writing to one file is a guaranteed merge conflict, and a fragment per change sidesteps it entirely. Something assembles the fragments into the real changelog later.

A handoff note, for work that spans more than one session: what is done, what is next, oriented enough that picking the work back up does not require replaying the whole conversation that led here.

The layer that keeps borrowed advice from winning by default

The other half of this system is a set of skills, which are really just packaged instructions for how to approach a category of work: reviewing an interface, writing accessible markup, structuring a layout. Most of the useful ones are written by other people and shared publicly, which is a shortcut worth taking. It is also a trap if you take it uncritically, because those skills encode someone else's stack.

A generic frontend skill will assume Tailwind, CSS modules, oklch() color functions, a particular animation library, because that is what most projects use. None of that is true here. Following that advice literally would mean rewriting working CSS to match conventions this project never adopted, for no reason better than the instructions said so.

The fix is a precedence rule, not a rewrite of the borrowed skills. Borrowed instructions live in one folder, pinned by a content hash so an update is a deliberate, visible act rather than a silent drift. This repo's own corrections live in a separate folder that explicitly outranks the borrowed one, the same way a project's own conventions should outrank generic advice whenever the two disagree. Without a stated precedence, the house style loses by attrition, one plausible-sounding suggestion at a time, because "this is standard practice" is a very persuasive argument even when it is standard practice for a different kind of project.

What it looks like when it is working

The clearest evidence I have that this is worth the overhead came from an afternoon that went badly on purpose.

I was building diagrams for these articles with an agent. The approach changed three times: drawn shapes, then real interface on a scaled canvas, then real interface that sizes itself. Each turn produced a decision record, and each new one superseded the last rather than editing it. By the end there were three records describing the same feature, two of them wrong.

That looks like waste and it is the opposite. The third record could say why the second one failed, in specific terms, because the second one had written down what it was betting on. Without that, the third attempt would have been a fresh guess with no memory of the first two, and the most likely outcome of a fresh guess is the first idea again.

The other half is quoting before interpreting. Every correction went into a feedback record with the exact words first and my reading of them second, and one of those pairs is the reason this system earns its keep: "building mini pc, en asked ai to render my house mogen weg" was read as "remove the images from those two articles", and it meant "unpublish those two articles". Because the sentence was recorded verbatim, the misreading was visible the moment it was questioned, and the fix took a minute. Had I only recorded my interpretation, the record would have confidently preserved the wrong one.

Why this is the same problem as the design side

I have written elsewhere about the judgment layer in AI-generated design output: the layer that decides whether something is right, not just plausible, and that a model cannot supply on its own. This system is the same idea applied one level up, to the process rather than a single output. Instead of checking each result by hand every time, I encoded the judgment once, as a set of standing rules and a place to record exceptions, so the checking happens by default instead of by memory. The agent still needs a human in the loop. It just needs fewer reminders about which human decisions have already been made.