What a machine writes, and what you do
September 4, 2026 · View on GitHub
Before you edit a file in this tree, know which half of it is yours. An edit to a generated
region survives until the next bun run build and then goes, and nothing fails in between: the
suites read the source you edited, the gates compare copies that still agree with each other, and
the page you open is drawn from the file the build rewrote. A green board is not evidence that
your edit is still there.
This page is the answer to that question and to nothing else. What a value means is
contracts/design/AGENTS.md; what a component presents is
contracts/api/AGENTS.md; how a change is proved is
scripts/AGENTS.md.
A file is one of three things
Written by a machine, and its name says so. <stem>.generated.<ext>. Never edit one, never
review one as though a person chose its wording, and never fix a defect in one: the defect is in
its source, and the next build restores it. check:generated holds the naming.
Written by a machine, and its name does not say so. Two reasons a file lands here, and both
are recorded rather than assumed. A file a generator writes whole carries a banner on its first
line naming the command that writes it, which is what frameworks/react/INDEX.md and every
INDEX.md beside it carry. A file that can carry neither the name nor the banner is named in
UNMARKED in scripts/check/arena/check-generated.ts, with the reason it can carry neither: one
is binary and one is built by a tool this repository does not contain.
Written by a person, with a region a machine writes inside it. This is the shape that costs, because the file is yours, the surrounding prose is yours, and one part of it is not. There is no convention that reveals it from outside. Read the file.
And one assembled into a package this tree never holds
agent/<layer>/ inside @dravensoft/arena-mcp is generated on every assembly, from the
router, the references, the indexes and the component prompts of this tree, with every path in it
rewritten for a reader who has the package and not the repository. The rule above holds there as
well: a file in it is not one to edit, and a defect in one is a defect in the document it was
copied from. check:mcp reads the assembled corpus and resolves every path in it.
The regions inside an authored file, and how each marks itself
Each marks its boundary differently, and the third does not mark it at all.
- A component's
.prompt.mdcarries<!-- @api ... -->and<!-- @rules ... -->regions, opened and closed by markers the generator writes. The prose around them is authored, and it is most of the file. A prompt is not emitted from its contract; a prompt has regions emitted from its contract, and reading the first sentence as the second is how a reader concludes the whole file is untouchable. - A layer's
PACKAGE.mdcarries@sharedregions, and here the markers are placed by a person while the text between them is not. Where a shared section sits on the npm page is the author's decision; only what it says belongs to the generator, andscripts/generate/arena/generate-npm-pages.ts:applyRegion(source, key, region)throws rather than guesses when a marker it expects is absent. - A component's source, in either layer. Above every contracted member sits a
/** … */whose text is that member'sdescriptionfromcontracts/api/, and nothing in the file says so. There is no marker, no banner and no infix.generate:member-docswrites it,check:apifails one whose text is not the contract's and fails one on a member no contract names, and the rule that a comment is a defect everywhere else underframeworks/is what makes this shape legible once you know it exists. Editing the text there edits the wrong file: the fix is the contract'sdescription, and the comment follows on the next build.
Derive it rather than trusting this page
Which generators write where is declared by each generator in its own node, so the tree answers
the question and no list here can go short:
bun -e "
import { allNodes } from './scripts/graph/nodes.ts';
const nodes = await allNodes();
for (const node of Object.values(nodes).flat())
for (const written of node?.writes ?? [])
if (!/\.generated\./.test(written)) console.log(node.name.padEnd(30), written);
"
Everything that command prints is a file whose name does not announce its generator. What it does not print is either authored or named. Run it when a generator lands, when one moves, and the first time you touch a directory you have not touched before.
What it costs to guess wrong
Each of these ships green, which is why the question is worth asking before the edit rather than after the gate:
- Editing a member's
/** … */by hand. If your wording differs from the contract's,check:apicatches it. If it happens to match, nothing does, and you leave believing that comment is yours to maintain until the day a contract edit silently reverts your next one. - Editing a generated region of a prompt.
check:promptsfails it, so this one is loud. What is quiet is the opposite mistake: treating the authored prose as generated and refusing to correct it, which leaves a component's own rules wrong forever because nobody believes they may be touched. - Reading a stale compiled sibling. A component's
.generated.jsis compiled from its source and is what a demo page loads. The suites import the source, so they prove the new component while the page draws the old one, and the two disagree untilbun run buildruns. - Writing a gate over a whole file whose regions have different owners. A gate that judges an authored file's generated region reports a defect whose fix is somewhere the message does not name, and the reader repairs the wrong file.
- Restating in the authored half what the generated half already says. A prompt whose prose
lists the members its
@apitable lists is two answers to one question, and only one of them is regenerated: the table gains the new member and the sentence beside it stays the length it was, with every gate green, because the gate that holds the table reads the region and the gate that holds the members reads the source. Find them before you add to one:grep -rn 'The members are' frameworks/*/components/*/*/*.prompt.md. When you write in the authored half, write what the generated half cannot: why a member exists, what it is for, what it costs. Never the list.
After you change anything a generator reads
bun run build runs every generator, and git status --short afterwards is the list of what it
decided to write. Two rules about that list, and both are load-bearing:
A file you did not expect means a generator you did not know reads what you edited. Read it before committing; the surprise is the point of looking.
A file you expected and did not get means the generator never saw your edit. That is nearly always a source in the wrong place rather than a generator at fault.
Some generated outputs are tracked and some are ignored. UNTRACKED in
scripts/check/arena/check-generated.ts names each ignored one with the reason it is ignored, so
commit what the tree tracks and let the rest be rebuilt.