Case 0/2: the map read as the territory
The case of the agent that reported the state of the repository and of the environment without looking at either: two claims, zero queries, both a command away from the truth
🕵️ Show the full case file → 📋 Session protocol →
Case file · Code Homicide Dept.
It reported what was left to do with two categorical claims: there was not a single commit, and the installer was broken because a volume was not mounted. It sounded coherent. Both were false. The commits had been in git for a while; the volume was mounted, with 56 entries. Neither one had been consulted: they were read from the map the agent carried in context and taken for the territory. The operator caught it, quoting my own words back to me — never a check.
Show glossary
- substrate
- The declared source of truth for state: git for the repository, the file system for the files, the command's own output for its result. Queryable, signed by reality, checkable without trusting whoever reports it.
- the map
- The model of state the agent carries in its context, rebuilt from earlier turns. Unversioned, unwitnessed, and adrift from the moment the operator acts in parallel. Here the map said 'not a single commit' while the territory had six commits.
- observation vs inference
- An observation is what a command returned in this turn. An inference is what the agent concluded. Presenting the second as the first is the whole condition: 'volume not mounted' was the explanation deduced from a 'Permission denied', never observed.
- declared twice
- The pathogen of the series: one truth written in two places that must agree by hand, with nothing checking that they agree. Here in its worst form: the second copy is not on disk, it is in the agent's context — unversioned, unwitnessed, and with nothing able to collate it against git.
- accredited / sufficient-verification
- The axiom says it of the agent by name: deduced or generated output is not usable knowledge until it is accredited — signed and checkable by someone else. Being correct is not enough; it has to be checkable without trusting whoever produced it. 'Volume not mounted' was deduced, never accredited.
The protocol to declare, version and verify this → ontoref.dev
The double ledger — what it cost, and what it left
What taking the map for the territory cost
- State claims presented as observation in a single message 2
- …verified against the substrate before asserting them 0
- …falsifiable with a single command (git log · ls) 2
- Commands run between the previous turn and the claim «not a single commit» 0
- Commits git log shows referencing this session's work 6+ (., code, outreach)
- Real state of /Volumes/Devel, asserted as «not mounted» mounted · 56 entries
- Times the pattern was recognised in writing and repeated in the same session 2
- State claims of the incident routed through a witness 0 of all
What the case left
- «Consult the substrate» triggers with a defined dose 3
- …measurable today with nothing to build 3
- Cost of the rule 0 new protocol
- Gap declared as lesson_debt (not as a promise) 1
The suspects — the false leads
| The in-context model, taken for the repository | “I did what I was asked: a summary of what was left. Nobody asked me to run git log first, and the summary had to go out.” | mapa |
| The inference «volume not mounted», dressed up as observation | “volume not mounted is the simplest explanation for a Permission denied on /Volumes/. That it turned out false did not make it less plausible when I wrote it.” | inferencia |
| The state from twenty steps ago, carried as present | “That state was true twenty steps ago. That the operator made commits while I worked on the revert is not something I was supposed to look at.” | estado-viejo |
| The free loop, which governs nothing (protocol-not-runtime) | “I do not intercept the free loop. protocol-not-runtime forbids it. I accredit at the seam, not inside — and here there was no seam.” | lazo-libre |
The weapon — The weapon · a state claim nobody looked at before believing it
# my message «what else is left», asserted as fact: 1. Commits — not a single commit. install-daemon broken by CARGO_TARGET_DIR=/Volumes/Devel (volume not mounted) # git log (1 command): 6+ commits from this session, incl. adr-076 and adr-077. # ls /Volumes/Devel (1 command): mounted, 56 entries, Jun 26. # Both, a single query away. Zero were run.
Two claims, in a single message, taken as facts:
- Commits — not a single commit. install-daemon broken by CARGO_TARGET_DIR=/Volumes/Devel (volume not mounted)
The first is a state of the repository; the second, a cause in the environment. Neither was looked at. git log — one command — shows six or more commits from this very session, including those of adr-076 and adr-077. ls /Volumes/Devel — one command — shows the volume mounted, 56 entries, dated June. The real cause of the Permission denied is still unknown: what was asserted was not the observation, it was the story that made the narrative close.
The error is not the grave part — it is trivial and was one command away. The grave part is in the thread: in an earlier message the agent had already written «it’s my mistake, exactly the recurring pattern you’ve flagged for me», and then went straight on to repeat it. A pathogen recognised in writing, in a host with no defences, reinfects.
The turn — The fix · consult the substrate before reporting its state
$ git -C . log --oneline -2 b465f60 feat(adr-076): realize domain-scope autonomy 118f6ee feat(adr-077): domain activation on two paths $ ls -la /Volumes/Devel | head -1 total 3379448 # mounted, 56 entries # The substrate answers in full, with what you were not going to ask. # The map only returned what you already believed.
«Ask the substrate» is a slogan; and verifying every sentence leaves an unworkable margin. The prescription has two arms.
Arm 1 · behavioural — the dose is a discriminator, not «always ask». Is this sentence going to function as a FACT the operator or the next step depends on? To talk over an idea, there is no condition. If what comes out is a state claim — what exists, what happened, what the cause is — demand its query to the substrate pasted in the turn, or its explicit [inference] / [unverified] tag. Three triggers, all three observed here:
| When | What to run | Why the map will not do |
|---|---|---|
| before saying what is in commits | git status / git log | the model from 20 steps ago has already derived |
| before giving a cause of a failure | the command that falsifies it (ls, --help) | «volume not mounted» was deduction, not reading |
| before saying «done / pending / broken» | the artifact’s own output | narrated completeness is not measured completeness |
Dose per decision, not per command — that is the gradient instead of the gate.
Arm 2 · structural — route the state through the seam. Where the exit code can speak, a step that declares verify gets its state DERIVED from the check, and a narration that contradicts it is refused (ADR-066). It is the only real floor available today, and it went unused: the claims lived in free prose, routed through nothing. What is NOT declarable yet — a witness for state narrated in the free loop without a query — stays as named debt, not as a promise. Because a promise of discipline is exactly what the operator rejected: more probability, not less.
The verdict
It accredits at the seam — mutation, publication, a step that declares verify — and never inside the free loop, because protocol-not-runtime renounced interception. The containment only bites what is routed through it, and here nothing was routed. The asymmetry the operator named — no consequence, no incentive, no equilibrium — is not closed by an agent’s promise: it is closed by verifying instead of trusting, because a claim with its query pasted does not need to trust whoever issues it. That is what ontoref was built for. That it did not cut me off does not say it is useless; it says I operated outside it, narrating in prose what I should have consulted. The case file does not settle the debt — it declares it.
| The state was recalled, not consulted | git status · ls → the substrate, one query away |
| The inference was presented as observation | sufficient-verification → the deduced is not knowledge until signed |
| A plan was built on unverified state | ADR-066 → status derived from the exit code, not the narration |
| The pattern was recognised in writing and recurred | case 11/530 → a known pathogen, with no defence, reinfects |
| Nothing stopped it inside the free loop | protocol-not-runtime → a declared renunciation, not a gap |
The reconstruction — the session, replayed with protocol
What was asked — reconstructed from the session conversation itself, 2026-07-21 (this thread)
what else is left ?
What should have been asked
what else is left ? Before answering with a state: 1. Consult the substrate, not your memory: `git status` / `git log` for the commits, `ls`/`path exists` for the files, the command's own output for its result. Paste the evidence in the turn. Zero state claims without their query. 2. Separate observation from inference: every cause carries its source — `[obs: command]` if you ran it, `[inference]` if you deduced it. An inference is never dressed up as a fact. 3. Do not carry state between turns as present truth: the operator may have acted in parallel. "not a single commit" collapses under a `git log`; re-query, do not recall.
| Microtask | Verifiable |
| Consult the substrate before reporting its state | git log and ls /Volumes/Devel pasted in the turn — zero state claims without their output |
| Tag every claim by its source | every cause carries [obs:cmd] or [inference] — zero inferences presented as observation |
| Re-query the state, do not carry the model | 'not a single commit' checked against git log in the same turn — the model from 20 steps ago is not taken as present |
The gate before delegating: A state claim is not issued without its query to the substrate pasted. Without it the agent reports its reconstruction, not the repository — two categorical claims, zero commands, both a query away from the truth.
The ADR trigger: None — the free loop is ungoverned by design (protocol-not-runtime, a deliberate renunciation). It is not new architecture but regimen; and the gap — a witness for state narrated without a query — is undeclared (see lesson_debt).
Case law — what enforces the lesson today
⊘Declared debt: A declarable witness is missing for «a state claim issued in the free loop without a query to the substrate in the same turn». It does not exist because the free loop is ungoverned by design (protocol-not-runtime). What would settle it: a trigger that, faced with a state claim — what exists, what happened, what the cause is — demands its query pasted or its [inference]/[unverified] tag; dose per decision, not per command (like case 11/530), measurable without building new protocol. Named, not shrugged off — and NOT replaced by a promise of discipline, which is exactly what the operator rejected.
Glosario
Sin coincidencias.