AGENTS.md and lightweight spec-driven collaboration
Long-running collaboration with coding agents needs durable rules and explicit decisions, but not a specification for every change.
The first session with a coding agent is easy. Explain the goal, inspect the result, correct what is wrong, and continue.
The tenth session is harder.
Some decisions now live in chat history, others in code, and a few only in the user’s memory. A new agent can read the repository without understanding why a reasonable-looking choice was rejected three weeks ago. The same debate returns, terminology drifts, and tests pass for a result that no longer matches the product direction.
The problem is not prompting. It is how a collaboration preserves decisions over time.
I have found two small mechanisms useful for this: a living AGENTS.md and lightweight specifications for changes that deserve them.
Three places for three kinds of knowledge
Collaboration becomes confusing when every piece of context is placed in one giant instruction file.
I prefer to separate three kinds of knowledge:
AGENTS.mdcontains current operating rules. It explains how work should be approached in this repository now.- A Spec contains a decision for a particular change. It records the problem, intended behavior, boundaries, and acceptance criteria.
- The code contains the implementation. It should not need comments that retell the entire design discussion.
Chat remains useful for exploration, disagreement, and rapid feedback. It is not a reliable long-term source of truth. Once a decision becomes reusable across future tasks, it should leave the conversation and enter the correct durable surface.
AGENTS.md is not project history
A useful AGENTS.md is closer to a current field guide than a constitution.
It should answer questions an agent will repeatedly face:
- What is this product trying to become?
- Which architectural and design boundaries are intentional?
- Which commands provide meaningful validation?
- What must never happen without explicit approval?
- Where does each kind of code and content belong?
- Which previous choices should not be casually reintroduced?
It should not accumulate every correction as another dated rule. When a new agreement replaces an old one, the file should replace the old rule as well. Duplicate guidance should be merged; obsolete guidance should be deleted.
The goal is not to preserve the story of the collaboration. The goal is to make the next correct action easier.
Not every request deserves a Spec
“Spec-driven” can easily become a ritual: write a document, ask for approval, implement a tiny change, and spend more effort maintaining the document than changing the product.
That is not rigor. It is uniform process applied to unequal risk.
A copy correction, a spacing adjustment, or a local bug fix usually has a narrow blast radius and an obvious result. The conversation itself can provide enough alignment.
A Spec becomes valuable when a decision changes several surfaces or is expensive to reverse. Examples include:
- redesigning a page or core user journey;
- changing navigation or information architecture;
- introducing internationalization or a new content model;
- adding a stateful interaction or external service;
- changing the technology stack, deployment model, or public contract.
The deciding question is not “Is this task important?” It is:
How much ambiguity, coupling, and rollback cost will this change create if we interpret it differently?
Spec depth should grow with that risk.
A small Spec is usually enough
Most product changes do not need a long requirements document. A useful lightweight Spec can fit into a few sections:
- Problem and goal — what should become better, and for whom?
- Non-goals — which tempting adjacent work is deliberately excluded?
- Behavior or content — what will users observe?
- Impact surface — which pages, contracts, data, or systems change?
- Acceptance criteria — what evidence will tell us the result is correct?
- Validation and release boundary — what can be checked locally, and what still needs human or production confirmation?
The non-goals are particularly important for coding agents. They prevent a reasonable implementation step from expanding into an unrequested redesign, dependency change, migration, or cleanup.
A Spec should reduce the number of decisions made during implementation. If it only restates the request in more words, it is not doing useful work.
Approval is attached to decisions, not documents
The purpose of writing a Spec is not to manufacture permission.
Approval means that the human and the agent agree on the consequential decisions: the direction, scope, tradeoffs, and evidence required. If those decisions change materially during implementation, the Spec should change before the code continues down a different path.
Small discoveries do not require a new approval cycle. A missing type, a better internal name, or an equivalent implementation detail belongs to engineering judgment. A new data source, a different public behavior, or a larger release boundary does not.
This division lets the agent remain autonomous inside the agreed solution while keeping product authority with the human.
Local acceptance and release are different states
One of the most useful boundaries in long-running agent collaboration is the distinction between implementation, validation, acceptance, and release.
A clean sequence looks like this:
- Align on the high-impact decision.
- Implement within the agreed scope.
- Run the relevant technical validation.
- Let the human evaluate the result where judgment is required.
- Release only after explicit authorization.
Tests can prove that a route exists, a type is valid, and a build succeeds. They cannot prove that the writing feels right, the hierarchy communicates the intended identity, or a redesign has the right level of restraint.
Likewise, a human saying “the local version looks good” does not automatically authorize a deployment, domain change, data migration, or external notification. These actions have different consequences and should remain distinct.
This separation is not bureaucracy. It prevents technical completion from silently expanding into external side effects.
The collaboration itself should be maintainable
The same engineering qualities we expect from code also apply to agent instructions.
They should be:
- cohesive, so one rule has one clear home;
- minimal, so important constraints remain visible;
- current, so obsolete decisions do not compete with new ones;
- testable, so validation commands and acceptance criteria produce evidence;
- scoped, so repository rules do not become universal personal preferences;
- safe, so authority boundaries are explicit before a tool changes external state.
An instruction file that grows without deletion eventually becomes another legacy system. Agents will select whichever sentence best supports the action they already planned, and humans will stop reading it.
Maintenance therefore matters more than completeness.
A durable interface between intent and code
Coding agents make implementation dramatically faster, but speed increases the cost of ambiguous direction. More code can be produced before anyone notices that the wrong decision was made.
AGENTS.md and lightweight Specs address different parts of that problem. One preserves the current rules of collaboration; the other makes a consequential change explicit before it spreads through the system.
Neither should attempt to capture everything. Their value comes from preserving the few decisions that future work must not accidentally forget.
The result is not a more obedient agent. It is a collaboration in which both sides can move quickly without repeatedly renegotiating the foundations.


Discussion
Comments
Questions, disagreements, and useful additions are all welcome.