Methodology
Agents need context, not access
Agentic development keeps pushing teams into monorepos, so that an agent can see the service next door. One documentation repository, mounted into every code repository as a git submodule, hands it the same context without the same reach.
The trade a monorepo makes
An agent reads what is on disk. Put four surfaces in one working copy and it finally has the context — and write access to all four.
So when the screen fails because the endpoint returns the wrong shape, changing the endpoint is the shortest path to green. It will take it. Same incentive that gets a failing test edited instead of the code, with a wider radius.
Figure 1
- writes to any of them
- writes to one of them
- cannot reach it at all
I want the context. I do not want the reach.
One repository holds the documents
Every surface keeps its own repository. One more joins them and holds no code: shared-docs — specifications, decisions as numbered ADRs, the task queue, a progress log per surface, changelogs. It is mounted into each code repository as a submodule, at the same path in all of them.
A session — a person and an agent together — writes there. A dispatched agent only reads.
Figure 2
- written by a person and an agent together
- read-only wherever it is mounted
shared-docs/adr/0003.md
names the same file from the API and from the mobile application, so a link written once
resolves everywhere.
The loop
Figure 3
- a person and an agent, together
- detent, on its own
- the agent, alone
The boundary holds mechanically rather than by instruction. acme-api/ is not in the working copy: an instruction not to touch something is a request, and an absent directory is not. The blast radius of a bad run is one repository — which is also the unit you revert, review and grant access to.
The friction: a pointer is a pin
A submodule points at one commit and stays there until somebody moves it. That is right for the thing submodules were built for — vendoring a library — and backwards here: shared-docs is not a dependency of the web client, it is the same product written down, and the whole point of it is that it is current.
Figure 4
So after every write to the documents: git submodule update --remote in each repository, then commit the moved pointer. I did that by hand for months, across four repositories and then seven. Skip it once and an agent builds against Tuesday's specification — correctly, and it passes every check you have.
Doing half of it is worse. The update without the commit leaves the superproject reporting M shared-docs: a dirty tree holding nobody's work, which every check that refuses to run in one now refuses.
What detent automates
detent runs coding agents against a queue of tasks and lets nothing finish until the repository's own checks pass. Four moments in a run belong to the submodules; between them it does not touch them at all.
Figure 5
- lets the commit through
- stops and asks a person
- the run's own steps
neverCommit: then it is not
fetched, not moved and not committed, and the agent is told to leave it alone.
Two of the four I would not have got right by hand. The commit records what was read — the moved pointer goes into the task's own commit, so the history answers "which revision was this built against" instead of somebody's memory. And it is verified before it is recorded — a commit claiming the agent read revision X when it read Y is worse than no record at all, because it looks like one. Written up as ADR 0012.
The trade, line by line
Figure 6
A monorepo
One repository per surface
context
A monorepoevery surface, by reading its code
One repository per surfaceevery surface, by reading its documents
write reach
A monorepoevery surface
One repository per surfacethe one repository the task names
a change across two surfaces
A monorepoone commit
One repository per surfacetwo runs, and a document between them
the interface between two surfaces
A monorepoinferred from source
One repository per surfacean artefact somebody signed off on
what it costs you
A monorepoa bad run can reach anything
One repository per surfaceyou have to write the documents
None of it is free. The context layer is not generated: if it is not written, there is nothing to read and the agent goes back to inferring. And a document is checked by somebody reading it, not by a compiler. I would argue for writing the specification first anyway — it is still work.
Where it has run
- Yuk Markaz 24 — a freight logistics platform: four applications to production in four months, built in parallel over this layer.
- QMed — a platform for private clinics: seven repositories over one API, one documentation layer, thirty-three ADRs.
- detent — the tool, open source.