Moving the rule is not enough

The reason was in the agent's context and nothing executed it. Moved into the mechanism, it went in as a spelling.

Jesús Pérez
A rule written in CLAUDE.md reaches every session in full, and an agent still cited, in an ADR, a session file that did not exist. The fix moved the rule into the command. Measured afterwards, the command flagged mentions that were not citations, let through citations that did not carry the string, and no hook ran it. What makes a rule hold, and why it matters even more inside an authored work.
Moving the rule is not enough

CLAUDE.md is the instruction file an AI agent receives at the start of every working session on a project. A rule written there reaches its context in full, every time. Nobody has to look it up or remember it: it is there. And yet, in a recent session, an agent amended an ADR — an architecture decision record, the document where a project writes down what it decided and why — belonging to an authoring project. In the warrant field, the one that says what the decision rests on, it put a reference to a file in .coder/: the session tree, where each session’s plans and working notes are kept. The file, on top of that, did not exist.

The reason not to do it was in its context: session files are not product. They are the scaffolding of the work, not what the project publishes or what a decision can rest on. The agent recognised it as soon as it was asked. But by then it had built five calls on that amendment, touched three files nobody had asked for, and closed its report with a bullet saying the reference was invented and should be replaced with the real path.

The operator’s question was the one that matters: what is the point of what gets recorded in CLAUDE.md?

Reading is not executing

CLAUDE.md, the agent’s memory, a hook that injects orientation: all of that is a carrier. It brings context to the agent. It executes nothing. A carrier can hold the perfect rule, written with exactly the right precision, and the rule will still depend on someone applying it at the exact moment it is needed.

This case adds a nuance worth keeping. The rule’s letter said “no links from docs/ to .coder/”. An ADR is not docs/. What did cover the ADR was the reason: session files are not product. The agent had the reason in front of it, and the letter did not name the place it was about to write to. A rule in a carrier depends on interpretation even when it is read correctly.

The harness — the wrapper that runs the model with its context, its tools and its loop — delivers the carrier. ontoref is not a harness: it is what a harness queries. And what a project needs to hold cannot depend on the harness delivering it and the model applying it.

Three places to leave a lesson

After the incident, the lesson could go to three places.

Into the agent’s memory, as one more note. The fastest and the least useful: another carrier, read or not read.

To the harness vendor, as a bug report. The agent drafted it twenty-three seconds after the operator’s question and before answering it, and the tool told it not to announce it. The report was not sent. Not because reporting was a mistake, but because a report improves the harness and, in the project, executes nothing. The decision was a different one: put the rule where it runs.

Into the mechanism. Since ADR-112, adr validate, the command that checks a project’s ADRs, fails when one of them contains a path into .coder/, in any project that runs it. It arrived red, meaning it failed the first time it ran: 23 lines in ontoref’s own ADRs and 1 in the authoring project.

That is the right thing. And it is not enough.

The rule went in as a spelling

The case file that documents it, a report whose numbers come from the session and from commands that were run, then measured what the mechanism refuses. It does not look for citations: it looks for a spelling, a way of writing. Specifically, .coder/ followed by a name character. The dot counts as a name character, so .coder/.claude, which only names the layer, gets flagged just like a citation.

  • Of the 23 flagged lines, 10 cite nothing: they name the layer or treat it as a subject. Four of them are in the two ADRs the validator’s own comment gives as examples of what is not a citation.
  • The ADRs hold 26 warrant entries that rest on a session. The schema, the definition of what shape each field takes, accepts any text as their reference, and most are a session name or a date with a label. The pattern sees 2.
  • In the 3 projects measured, no hook runs it before a commit. A hook is a script that runs by itself every time a change is saved to the history, without anyone having to remember. In ontoref a recipe runs the command, and it has to be called by hand.

The judgement “this cites the session tree” was replaced by a text pattern. And the project already knew. Its glossary marked «garantía» as a word a pattern cannot police, because a pattern cannot tell the ordinary use of the Spanish word from its mistranslation of warrant. And ADR-072 says a check has to measure what it claims to measure, not something that resembles it. That constraint is soft, meaning it warns but does not block. And it showed green in the same run that flagged the ten lines.

Moving a rule from the carrier into the mechanism is necessary. What makes it hold is something else, and it fits in three questions.

Three questions for any rule

Where does it run? If the answer is “in the head of whoever reads it”, it is a carrier. If it is “in a command someone has to remember to run”, it is half a mechanism. It truly runs when it sits in the chain that already runs: the hook, the recipe another recipe calls, the mode step that cannot be skipped.

What does it check: the meaning or a spelling? A text pattern is cheap and almost always close by. But if the rule is about citing, attributing or provenance, what has to be checked is a relation — that the reference resolves to something that exists and is record — not a string. It shows quickly: the pattern flags what it should not and lets through what it should catch.

Has anyone seen it refuse, and accept? A validator that arrives red on the existing documents proves it finds something, not that it finds the right thing. It needs to be seen refusing a real citation and accepting a legitimate mention. Until then, its green says little.

In an authored work it matters more

What an ADR suffers, a work suffers too, with more at stake. In a knowledge-works domain like librosys, where the unit is the work as a coherent whole and dissemination is its expression, an agent writing inside the work faces the same three risks as the case, under other names:

  • Completing by inventing. A slot that admits content gets plausible content: a footnote, a bibliography entry, a figure caption, a date. Plausibility is exactly what lets it pass review.
  • Citing without provenance. A citation promises the reader can go and open the source. A reference to a session log, a private note or a URL nobody archived breaks that promise without a sound.
  • Speaking for the author. In the case it was a line that presented as the author’s ruling words the author never said. In a work it is a paragraph, a sentence in the preface, a correction that changes the meaning.

The gates that domain declares today, meaning the checks a document has to pass to move forward, are about lifecycle and completeness: what stage a document is in, whether it covers its concepts, whether its glossary is complete. None checks where an inserted fact came from or who wrote a sentence. Giving the agent access to the work’s own texts does not settle it either: it does not stop it from writing a citation those texts do not contain.

It is recorded in librosys as an open question, not as a decided mechanism. And the case’s lesson holds in full: if that rule ends up written only in a consuming project’s CLAUDE.md, it will be read and not enforced. And if it ends up in a gate, the gate will have to check provenance, not the shape of a path.

The operator’s question, answered

What is the point of what gets recorded in CLAUDE.md? It is so the agent knows. It is not so the rule holds. For that, the rule has to be where it runs, check what it says, and have been seen refusing what it forbids and accepting what it allows.

In this case the rule has taken the first step halfway: it is in a command, but not in the chain that runs on its own. The other two are filed as open debt in the project’s backlog (bl-115), together with what it would take to close it. It has deliberately not been wired into the hook: with today’s pattern, it would block changes over the ten lines that cite nothing.

This case is one piece. What it means to have a heading that can be checked, and not just brakes, in project governance, in infrastructure and in authoring, is told in “A brake is not a heading”.


This article is projected from case file 2/26, “the rule that was in the context”: a typed case whose numbers come from the session transcript held in custody and from commands run against the corpus, never from anyone’s memory. The line-up with its alibis, and the full bill, are in the case-file series.

Was this useful? Rate it
Got something to add? Tell me what you think, what you'd suggest, or whether we should keep exploring this topic.
· reads

We use cookies to help this site function, understand service usage, and support marketing efforts. Cookie Policy for more info.