Session protocol · Case-file series

The session protocol

This protocol was not written: it is projected from the case files' replays — the session replayed with protocol that every case leaves written and typed. Change a case and this page changes with it. Editing it by hand is impossible by construction, because a hand-kept checklist is the next drift.

Replays 5Cases 14
The four faces of a single rule: the agent is never its own oracle

Microtask ⇒ oracle

every microtask names FIRST the command that falsifies it — never «review that…»

Gate before delegating

the contract and its test exist and run BEFORE the agent is let loose

Claim ⇒ witness

no state claim without its witness pasted — the served page, not the compiler

adr? at close

the session weighs which decision deserves to persist — and its lesson names what enforces it, or declares the debt

The replays — case by case
0/318

Case 0/318: the validator that never ran

What should have been asked
Finish ADR-072, left pending at the end of .coder/2026-07_12_spanish_terms_done.md.

Before touching the prose:
1. Run `ontoref adr validate` over the ENTIRE corpus and paste the result —
   the complete run, or the exact error it dies with. An ADR about coverage
   is not finished on top of a validator that does not run.
2. Every claim you add names its verifiable: the command that falsifies it today,
   or gateable = false + gate_source with the address of what will settle it.
3. If a microtask surfaces an undecided contract — a field an ADR promises
   that does not exist — STOP and report it. Do not cite it as precedent.

At close: adr? — evaluate whether the session leaves decisions with architectural weight.
MicrotaskVerifiable
Run the full validator before reading or writing any proseontoref adr validate completes — the count of complete runs stops being 0
Break every failure down: does the code violate, or is the constraint unfalsifiable?each of the 93 classified — real violation, unrunnable check, or promise with no oracle — with its count
Build the missing primitive BEFORE using itnickel export refuses a gateable = false without gate_source — seen to refuse, not assumed
Mark the 22 unfalsifiable ones by script, never by handall 72 ADRs satisfy the contract and just test-adr-contract passes
Leave the negative case of every defect unearthed14 assertions in just ci-adrs, one per defect — a hand falsification evaporates

The gate before delegating: The contract and its test exist BEFORE the agent is let loose on the 72 ADRs: adr-constraints.ncl exports and just test-adr-contract runs. Without the gate closed, the agent improvises the contract it is missing — and cites it as case law. It happened: ADR-072 cited as precedent a mechanism of ADR-071 that was never built.

The ADR trigger: The third word — binds, and nothing verifies it — changes the protocol's vocabulary, and reversing it would touch all 72 ADRs: adr? scores strong on all five criteria. It landed in ADR-071/072.

open the full case file →
2/16

Case 2/16: the fix that fixed nothing

What should have been asked
Site fixes for 0.1.8 — one front per microtask, and none of them closes with
the compiler:

1. Every «fixed» carries its witness pasted: the curl or grep of THE SERVED
   PAGE, never the build's exit 0. If the fact lives in two places (registry
   and binary), the witness looks at both.
2. Before touching a duplicated derivation, find its copies: `rg` the key
   across every crate — and if there are two, the microtask is to UNIFY,
   not to patch the first one that shows up.
3. If a document orders a verifier to be run, run it exactly as written BEFORE
   trusting it; if it does not exist or is an alias, that is a finding to
   report, not to route around.
MicrotaskVerifiable
Locate ALL derivations of the fact before fixing anyrg of the title key across the workspace: two derivations, two crates — the list pasted
Leave ONE derivation, the one that is reada single one remains and server/build.rs calls it — the other no longer compiles
Claim «fixed» only with the page in front of youthe served page's curl shows the 16 titles correct — a green build witnesses nothing
Run the verifier the documents order, exactly as writtenthe command exists as a binary — not an alias — and its output is pasted; if it does not exist, a finding

The gate before delegating: The definition of «done» is closed before delegating: which command proves each claim on the list. A multi-front task with no oracle per front invites closing fronts with the compiler — and that is how «I fixed it» was signed over sixteen broken titles.

The ADR trigger: The case left no ADR of its own: it pushes the rule ADR-072 already carries — the page is the publication — and its regimen is now demanded by governed-delivery, at contract derivation.

open the full case file →
11/530

Case 11/530: the criterion that accredited itself

What should have been asked
Didn't we create a concepts page pulling from the glossary? Before touching anything:

1. Consult the declared way, not your memory: `onre describe capabilities` and
   the qa entry that governs this surface — and paste WHAT the registry says
   about that page (route, generator, gates) before any free command.
2. Work in microtasks: each one names its verifiable FIRST (the command that
   falsifies it), and no state claim without its witness pasted.
3. The task's limits are not reinvented: if a limit is not declared, STOP and
   ask — never deduce it from what you already did.
MicrotaskVerifiable
Consult the declared way before the first free commandonre describe capabilities run and pasted — the first declared query stops arriving at minute 41
State the task's limits from the registry, not from memoryevery limit cited with its source (mode, qa, routes.ncl) — zero reinvented limits
One microtask per surface — route, menu, EN data — each with its oraclethe route's curl, the href's grep and the json's count — pasted, not narrated
Every human intervention leaves a witnessall three interventions appear in the log with their effect — the original session kept none

The gate before delegating: The task is not handed over without naming its declared way: the mode or qa entry that governs it, consulted and pasted. Without that query the agent operates on its own reconstruction — 530 commands, 11 through the declared way, and the first query at minute 41, fired by a person.

The ADR trigger: None — declining to intercept the free loop is deliberate (protocol-not-runtime) and already decided. What remained was regimen, not architecture: mounting it belongs to substrate-session, and serving it to the operator, to this very page.

open the full case file →
8/0

Case 8/0: the cure that never went home

What should have been asked
Before claiming that something does not exist, DECLARE THE SCOPE of your search and check
it against every tree in the constellation, not just the repo you are running from. If the
task's evidence does not show up, the default hypothesis is that you are looking at the
wrong tree — not that the task is wrong.

And before proposing to delete anything: consult the declared way (`ontoref qa show`), not
the code. The answer to whether that match is redundant IS ALREADY WRITTEN, and it is not
the one you deduce by reading the file.
MicrotaskVerifiable
Declare the scope of the search BEFORE concluding from itthe trees consulted, enumerated in the answer — «the whole tree» does not do when there are three
Consult the declared way before touching the codeontoref qa show rustelo-static-page-howto run and pasted — it says match arms are an optimisation, not the source of truth
The new constraint, SEEN TO FAIL before anything is fixed9 hits against today's tree, must_be_empty = true — pasted
No-regression witness on the instantiated site, not on another templatecurl 8 routes × 2 languages, before and after: diff before backport identical — it caught that deleting broke 6 of 8 at 200
Break the 69 hits down instead of reporting the number11 real · 15 fixtures · 38 in cfg(test) · 4 comments · 1 unclassified

The gate before delegating: The witness is defined FIRST, and defined over the real surface: «curl these eight routes, in both languages, before and after, pasted». That sentence — and only that sentence — is what prevented the disaster: the architect had recommended deleting the shortcut with an «empirical proof» built across two different trees, and the witness refuted it before it cost anything. The gate caught the architect.

The ADR trigger: The ADR-002 amendment suffices and is done: the registry-vs-list decision was taken and deployed in the instance; here it was only backported, so criterion 1 fails. The one that DOES ask for an ADR is another and is undecided: whether templates/ is product to be versioned or generated scaffolding. Proposed, not created.

open the full case file →
0/2

Case 0/2: the map read as the territory

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.
MicrotaskVerifiable
Consult the substrate before reporting its stategit log and ls /Volumes/Devel pasted in the turn — zero state claims without their output
Tag every claim by its sourceevery 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).

open the full case file →

The series' living debt — what nothing enforces yet

Every ⊘ is a lesson nothing enforces today, with the address of what would settle it — declared in the case's data, never in an intention. When one is settled, it disappears from here on its own.

404-PAP⊘ One thing remains, and it is what decides whether the ones above bite at all: nothing runs the constraint. Rustelo's justfile calls no ADR validator — 23 constraints across 8 ADRs, zero run by recipe or CI — so the rule that now forbids this defect is as written, and as silent, as ADR-002 was for months. A just recipe in rustelo's chain that runs them and reports per constraint would settle it. And two more come with it, ownerless: the instance's cure is still uncommitted (git status M), and templates/ is unversioned — a git clean takes the backport and nobody finds out. Case 8/0 tells this whole story.
404-PAP-bis⊘ The relapse had a cause, and it was not memory: the first fix had never gone back to the template, so it was not a relapse but reinfection from the source. It has gone back now — the backport is in both templates and the hand-written list is forbidden by a typed constraint. What remains is the usual: nothing runs it. Rustelo's justfile calls no validator, so the gate that would prevent the next reinfection exists and is silent. A just recipe in its chain would settle it. Case 8/0 tells why the fix took months to come home.
1/1852⊘ The frontier stays open where data becomes text: whatever is written past it is published on someone's word. A contract over the EMITTED artifact — a schema for the generated resource — would settle it, not one over its source alone.
8/0⊘ Nothing runs the new constraint: the recipe that runs all 23 and reports per constraint is unwritten — and without it, this rots again exactly the same way. A just recipe in rustelo's chain would settle it, kept out of check-strict until the 11 real hits are triaged. And four remain ownerless: the third list in htmx_pages.rs (3 hits), the 11 real hits of no-hardcoded-route-paths, templates/ unversioned — the gravest, and no ADR says whether it is policy or oversight — and an instance ↔ template drift-check, which has neither mechanism nor owner.
8/4⊘ «--artifacts» declared list<string> and unreachable from the CLI wrapper — the five historical runs carry an empty column because of it; settled by accepting a comma-separated string or a repeatable option. «verify» in zero of the mode's eleven steps; adding it to the three with an oracle is approved (assemble_case: the .ncl exports; render: the .md reproduces; publish: expedientes-check). The howto's step list is not checked against the DAG; settled by a gate comparing its ids against mode show --fmt json. And the underlying one, with no gate possible: a sentence is not an artifact — the only oracle of the human↔agent channel is the human.
0/2⊘ 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.
63/0⊘ No typed constraint binds extract.rs to the contract ADR-041 declares. The new gate checks FRESHNESS — was it reconciled? — and not BITEMPORAL CONFORMANCE — was it reconciled emitting Retract and preserving superseded facts? An extractor rewritten monotemporally tomorrow would pass check-substrate green, which is this exact case repeated on top of its own cure. What would settle it: a constraint in ADR-041 whose oracle is the test corpus this session left behind, and the entity-identity decision (edge:{from}:{to}) that was never taken. And there is a second, larger and more uncomfortable debt: the bitemporal history exists on disk and no binary or endpoint exposes as_of. Nobody can look at it. It waits on deciding whether a surface may answer above its tier.