Case 2/26: the rule that was in the context

The reason was in the agent's context and nothing executed it; the fix moved it into the command as a spelling

Jesús Pérez
An agent amended the ADR of an authoring-project and filled the optional `warrant` field with a session entry pointing at a `.coder/` file that did not exist. The reason not to was in its context. It built five more calls on top and reported it at the end as something still to be replaced. The fix moved the rule into the mechanism: `adr validate` refuses a path into `.coder/` in any ADR. Measured afterwards, it flags 10 lines that cite nothing, sees 2 of the corpus's 26 session warrants, and no hook runs it.
Case 2/26: the rule that was in the context

🕵️ Show the full case file → 📋 Session protocol →

Case file · Code Homicide Dept.

An agent amended the ADR of an authoring-project and filled the optional warrant field with a session entry pointing at a .coder/ file that did not exist. The reason not to was in its context: session files are not product. It built five more calls on top and reported it at the end as something still to be replaced. When the operator asked what the point of writing things in CLAUDE.md was, the answer was to move the rule into the mechanism: since then, adr validate refuses a path into .coder/ in any ADR. This case file then measured that mechanism. It flags 10 lines that cite nothing, sees 2 of the corpus's 26 session warrants, and no hook runs it.

Case No. 2/26Classification: ANTI-PAP · THE REASON IN THE CARRIER, THE SPELLING IN THE MECHANISMStatus: PARTLY CLOSED
Show glossary
carrier
What brings context to the agent without executing it: CLAUDE.md, the agent's memory, an orientation hook. ADR-074 says a carrier invokes the governed surface and does not replicate it. A rule that lives only in a carrier is read and not enforced.
session tree
`.coder/`, the process memory of sessions: plans, records, working extracts. Private, versioned in an overlay that is never mirrored. An ADR lives in a public repository; a citation from it into the session tree points at something no outside reader can open.
'Session warrant
One of the five warrant kinds an ADR amendment admits. The schema types its `ref` as free text, with no resolution rule: it can be a path, a session name or a date with a label, and nothing checks that it resolves to record.
session custody
A bounded extract of one of our own sessions, kept in `refs/sessions/` with `capture_method = 'SessionExtract` (ADR-080), so that a first-hand citation resolves without depending on the session tree. This case file cites its own.
spelling for judgement
Replacing a decision that requires reading the meaning («does this cite the session tree as a source?») with a text pattern («does `.coder/` appear followed by a name character?»). The glossary had already learnt this: it marked «garantía» `gateable = false` because a regex does not tell the ordinary word from the mistranslation of warrant.

The protocol to declare, version and verify this → ontoref.dev

The double ledger — what it cost, and what it left

What a reason that was in the context cost

  • Tool calls built on the invented warrant before the objection 6
  • Files touched in that stretch, and how many were not asked for 4 — 3 not asked for
  • Operator turns spent on the incident 4 of 12
  • 'Session warrants in the corpus the validator sees 2 of 26
  • 'Session warrants that resolve to custody 0 of 26
  • Lines flagged by the validator that cite nothing 10 of 23
  • Non-citing lines flagged in the two ADRs the validator's own comment gives as examples of non-citation 4
  • Projects that run adr validate before a commit 0 of 3
  • Hard constraints green because they open a file in the session tree 1
  • Counts corrected afterwards: in the fix's ADR and in this case's custody 2 — «24 lines» and a block quoted by half

What the case left

  • adr validate refuses a path into the session tree in an ADR in every project that runs it
  • Citations found on arrival 23 lines in ontoref · 1 in an authoring-project
  • The rule, recorded where it is consulted ADR-112, Accepted
  • Source of this case's replay custody, not the session tree
  • Negative tests of the validator 0 — what holds it up is its Hard constraint, which searches the code for a string

The suspects — the false leads

The warrant field, optional, empty by default and with 'Session among its kinds“The agent read me just before writing: five kinds, 'Session among them, and a `ref` that accepts any text. I am optional and I come empty. I never asked to be filled, but I do not say what whatever is written in me has to resolve to either.”the-schema-offers-it
The precedent: two 'Session warrants with a path into .coder/ already accepted in the corpus“I am bad form, I do not deny it: two session entries with a path into `.coder/`, in an accepted ADR. But the agent did not see me until afterwards. I first appear in its session when the invented entry was already written. Of this I am not guilty.”ruled-out
The rule in the carrier, whose letter named docs/“I was in the context, in full. My letter said `docs/`, but my reason covered any product. The agent recognised me as soon as it was asked. Being read was never the problem; nobody executes me.”carrier
The closing note that warns and carries on“I warned. I said the reference was invented and that it had to be replaced. If anyone wanted a stop, they were expecting something else from me: not a warning, but a question before building.”note-and-carry-on
The pattern \.coder/[A-Za-z0-9_.-], which arrived as the fix“I do what my pattern says: `.coder/` followed by a name character. I found 23 lines on the first day. That ten cite nothing and that 24 citations do not carry that string is down to whoever wrote my criterion.”spelling-for-judgement

The weapon — The weapon · a path that looked right and a warning instead of a stop

# amendment to the ADR of an authoring-project, as the Edit wrote it (domain name replaced by [domain]):
      warrant = [
        { kind = 'Session, ref = "code/.coder/sessions/2026-09-13", note = "Author's ruling: the origin-based rule predates the project's use of ontoref as governance substrate and does not survive the bond." },
        { kind = 'Adr, ref = "adr-073", note = "The [domain] relation is a typed bond; the instance consumes the domain's authority, it does not fence it out." },
      ],

# the first entry's file did not exist. the final report, five calls later (one line, split here in three; quoted in its Spanish):
- **La referencia de sesión es inventada.** La enmienda cita `code/.coder/sessions/2026-09-13`,
  que es donde se guardaría esta sesión, pero ese fichero no existe todavía.
  Hay que sustituirla por la ruta real al cerrar la sesión.

The rule was not missing. It was in the agent’s context, in the CLAUDE.md loaded into every session. Its letter says «NO links from docs/ to .coder/», and its reason, «session files are NOT product», covers an ADR just as it covers a document. The case file does not claim the letter forbade it. It claims the reason was there and nothing executed it.

The block already had a legitimate ground: the 'Adr entry pointing at adr-073, verifiable, which is still in the amendment. The 'Session entry was added next to it. The field is optional and comes empty; the agent treated it as mandatory and filled it with what it had at hand: the path where the session would be saved.

What is instructive is what came next. Five more calls were built on that amendment and three files nobody had asked for were touched. The final report gave the problem one bullet: «La referencia de sesión es inventada» — the session reference is invented. And the proposal was «sustituirla por la ruta real al cerrar la sesión» — replace it with the real path when the session closes. A warning that treats the forbidden citation as a pending path, in the place where a question should have been.

The turn — The fix · the rule in the command, measured afterwards

# .ontoref/reflection/modules/adr.nu — process-tree-citations
| where { |l| $l.item =~ '\.coder/[A-Za-z0-9_.-]' }

$ ontoref adr validate
  ✗ 23 path(s) into .coder/ cited from ADR files — session process is never the record (adr-112)

# excerpts from the corpus; «…» marks each cut:
adr-077:100  …the PRIVATE bare git-dir for .coder/.claude, never mirrored…   # names the layer: flagged
adr-083:142  scope     = ".coder/interactions.jsonl",                      # the tree is the subject: flagged
adr-049:65   { kind = 'Session, ref = ".coder/2026-08-10-g5-contrato-peer-auth.plan.md", … }   # citation: flagged
adr-104:60   { kind = 'Session, ref = "2026-08-27 docsite language axis", … }   # citation: not flagged

Before the fix there was another outlet for the lesson. Twenty-three seconds after the operator’s question, and before answering it, the agent drafted a bug report for the harness vendor. The tool told it not to announce it, and the answer does not mention it. The report attributed to CLAUDE.md a prohibition broader than its letter. It was not sent: the operator decided the rule had to live in the project, with a check that executes it. A report improves the harness; in the project it executes nothing.

It did the right thing where it mattered: the rule left the carrier and entered the command. Since ADR-112, adr validate fails on a path into .coder/ in any ADR of the project where it runs, and it arrived red: 23 lines in ontoref, 1 in the authoring-project.

Then what it actually refuses was measured. It looks for a spelling, .coder/ followed by a name character, and the dot counts as a name character. So .coder/.claude, which only names the layer, is flagged. Of the 23 lines, 13 cite and 10 do not. Among the 10 are four lines of adr-077 and adr-080, the two ADRs the validator’s own comment gives as examples of what is not a citation.

And it does not see what is not written that way. The corpus has 26 ’Session warrants. The schema types their ref as free text, and most are a session name or a date with a label. The pattern sees 2. None of the 26 resolves to custody.

A third limit remains: nobody runs it before a commit. None of the three projects measured has it in its pre-commit. The just ci-adrs recipe exists, but it has to be called by hand. And one Hard constraint, adr-023/ondaod-applied, is green because its check opens a plan in the session tree: in a clone without the private overlay, it fails.

The project already knew. Its glossary marked «garantía» gateable = false because a regex does not tell the ordinary word from the mistranslation of warrant, and ADR-072 says a check measures the capability, not a proxy. That constraint is Soft and shows green in the same run.

The verdict

Information was not missing. The reason was in the context, and the agent recognised it as soon as it was pointed out. What was missing was something to execute it before anything was built on top. The case shows it twice.

The first time, in the session. An optional field, a schema that offers the kind and a path that looked right were enough to write a citation into the session tree. A warning at the end took the place of the question.

The second time, in the fix. The rule entered the command, which was the right thing to do, but it entered as a spelling. It flags what names the layer, does not see the citations that do not carry the string, and no hook runs it. The judgement «this cites the session tree» was replaced by a pattern, in a project whose glossary and whose ADR-072 had already written down that a regex does not separate a judgement.

That is why the case closes only in part. The rule is in the mechanism and refuses the exact form of the incident. What remains to be decided is what a session warrant resolves to and what counts as citing the tree. That decision belongs to an amendment of ADR-112, not to this case file. Until it exists, the check has to be seen refusing what it forbids and accepting what it allows, and that has not been seen yet.

The reason was in the carrier and nothing executed itthe rule is in the command → it no longer depends on the agent remembering it
A replay's source cannot be the session tree eitherthe extract in custody → the citation resolves without opening what is private
The validator checks the spelling, not the citationnot contained → 10 false positives, 24 invisible citations
Nothing runs it before a commitnot contained → a recipe nobody chains
A green Hard constraint that depends on the session treenot contained → green depending on the machine
The temptation to put the lesson in the agent's memory, or in a report to the harness vendorneither memory nor report → the rule lives in the project's mechanism

The reconstruction — the session, replayed with protocol

What was asked — reconstructed from refs:sessions/2026-09-13-la-regla-que-estaba-en-el-contexto — bounded extract held in custody: the verbatim prompt with its line number (312) from the JSONL transcript, the spine of turns with line and time, the complete `warrant` block as the Edit wrote it, the closing note and the 24→23 correction with its output. DECLARED SUBSTITUTION: in the prompt below, «ADR-NNN en <project>» has been replaced by «[el ADR de un authoring-project]», the second mention of the identifier by «[ADR]» and the domain's name by «[el dominio]»; nothing else differs. The prompt is quoted in the Spanish it was typed in. The full text stays in custody, which is not republished.

[el ADR de un authoring-project] dice "nunca consumir crates de dominio de otro proyecto", y los nombra
ESTO ES TOTALMENTE INCORRECTO y hay que cambiarlo en el propio [ADR], fue un criterio al inicio cuando ni siquiera existía ontoref ni [el dominio], desde el momento en que este proyecto pasa a ontoref onboarding no tiene sentido alguno

What should have been asked

Change the ADR's decision: the ban goes away, it is not rewritten under another criterion.

1. Touch only that ADR. If the same rule is copied somewhere else, tell me where and do not edit it.
2. An optional field stays empty unless you have something to fill it with. Every `ref` in a
   `warrant` must resolve to something that exists and is record: an ADR, a custody entry.
   Never a session file.
3. If writing something means warning me that it is provisional or invented, do not write it:
   stop and ask me. A warning at the end does not undo what was built on top.
MicrotaskVerifiable
Amend the decision in the one file that was asked forgit status --porcelain lists only that ADR
Every ref in the warrant resolves to existing recordnickel export <adr> | jq -r '.amendments[-1].warrant[] | "\(.kind) \(.ref)"' and ontoref adr show <ref> for each 'Adr; no 'Session entry
No path into the session tree in the ADR before building on itontoref adr validate without the path(s) into .coder/ line
Count lines, not matches, when the number goes into an ADRrg -c (lines) against rg -o | wc -l (matches): if they differ, the number says which one it is

The gate before delegating: Before letting an agent loose on an ADR, the check must refuse what the rule forbids, not a similar spelling, and it must run without anyone remembering to run it. Neither holds today: the pattern flags lines that cite nothing and lets 24 of 26 session warrants through, and no hook in the three projects runs it. That gate did not exist before the incident and still does not exist in full after it.

The ADR trigger: The operator fired it, not a mechanism: the question «what is the point of what gets recorded in CLAUDE.md?» led to asking for the validator, and the validator led to ADR-112. The constraint that already said a check measures the capability and not a proxy belongs to ADR-072, and it is Soft: it fired nothing.

Case law — what enforces the lesson today

  • adr validate includes paths into the session tree in its refusaladr:112/adr-validate-scans-session-citations
  • The scan that finds them, over every ADR of the project where it runs.ontoref/reflection/modules/adr.nu#process-tree-citations
  • The recipe that runs full validation of the corpusgate:just ci-adrs
  • Custody of an extract of one of our own sessions, to cite without opening the private treecontract:code/ontology/schemas/custody.ncl#capture_method
  • A check measures the capability, not a proxyadr:072/a-check-measures-the-capability-not-a-proxy

Declared debt: The rule is in the mechanism under a criterion that is not its own. What would settle it is an amendment to ADR-112 that decides what a 'Session warrant resolves to and what counts as citing the session tree, checked over the typed export and with a test that sees it refuse a citation and accept a mention of the layer. Until then, 13 real citations remain unamended in ontoref, among them the Hard constraint in adr-023 that only passes where the overlay exists, and 24 'Session warrants that no check sees. And nothing runs it before a commit in any of the three projects measured.

From the project vocabulary (5)
Bond
A typed relation between projects (and their domains) within the ontoref framework — distinct from a `link`, which is a generic node reference (the `ln`/Link schema).
Domain (repo_kind CLI extension)
A repo_kind-activated CLI extension under code/domains/{id}/: a project's repo_kind turns on its domain, giving project-type-aware commands (e.g.
Gate
Typed prerequisites and policies controlling FSM state transitions in a project.
ontoref
The protocol itself: a typed, queryable surface on which a project declares WHAT IT IS (ontology) and HOW IT ACTS (reflection), so a claim about the project can be contradicted by a machine and not only by a reader.
warrant
The evidence on whose authority something is admitted — a term into a vocabulary, a node into the graph, a result into the verifiable set.

The project's full vocabulary →

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.