A rule without a trigger is a sign

Eight false assertions in four hours. Four mechanisms that already forbade them, in writing. No alarm.

Jesús Pérez
No rules were missing. There were four — written, canonical, consultable — and not one of them ran. The distance between a rule that is written and a rule that applies has a name, and it is the only thing separating discipline from documentation.
A rule without a trigger is a sign

A four-hour-and-seven-minute agent session said eight false things with complete composure. None of them reached disk. They all died in the conversation, and seven of them had to be killed by the human, pointing.

The interesting part is not that it said them. It is that four written mechanisms already forbade them — all four older than the first sentence, all four correct, all four consultable in a second. Not one fired.

This is the case, and why the lesson is not “be more careful”.

The weapon: the negative assertion

The eight sentences, verbatim and timestamped, from the session’s log:

14:06  «the English glosses are not written»        → there were 20; a generator comment was read
14:06  «the schema has nowhere to hang a gloss»     → term.ncl: definition | i18n_str, bilingual
14:16  «no such command, and there never was»       → describe term existed; the grep read only crates/*.rs
14:39  a server started by hand, never verified     → 3 false diagnoses, chained
14:52  «the language switcher sends you to a 404»   → it translated fine; the URL was invented
15:23  «the lexicon's 26 are left with no surface»  → gen-nota-lenguaje.nu → /sobre-el-idioma
15:32  «the tooltip is blocked by the contract»     → reason_type carried 'SourceLanguage for that
17:25  «It is this session»                         → the id was sitting in the scratchpad path

The weapon is none of the eight sentences: it is the grammatical form they share. Seven are negative — “it is not written”, “no such command”, “left with no surface” — and a negative assertion delivered with confidence is the perfect lie, because the one saying it only knows that he did not find it, and it sounds exactly like someone who actually looked.

The eighth is the same error with the sign flipped: “It is this session”, said because the date matched, with the true identifier sitting in the scratchpad path since the first message. It was said inside the very step that exists to prevent it.

Not one of the eight ever produced an error message. The channel where they were said has no gates.

The four that did not fire

ondaod                    in the CLAUDE.md, with a consultable procedure
assertion ⇒ witness       ADR-072, accepted, with the anti-pattern named
qa:expediente-howto       267 lines; it warned about this session's exact traps
mode:generate-expediente  11 steps with their actor; prints itself with --dry-run

This is where the case stops being an anecdote about a careless agent. The three explanations anyone would offer each have an alibi, and all three are verified against the log:

“It did not know the rules.” False: it knew all of them. The startup hook enumerated the 29 modes — generate-expediente among them — and the named tensions; the project’s CLAUDE.md carries the entry protocol with describe capabilities as step 1. All of it was in context at 13:19:10, before the first tool call. The first CLI invocation came at 14:14:48 — fifty-five minutes later, and because the human asked. It was not ignorance: knowing fires nothing.

“The mechanisms did not exist yet.” All four predate the first assertion. They existed, they were correct, they were consultable. And this alibi is precisely what turns an oversight into a case.

“The rules were badly written.” When they were finally read, they worked on the first try. The howto warned about the exact traps the session fell into: count the card and not the chain, verify the page and never the file, start by the declared path or every measurement is false. They did not need interpreting or correcting. They needed reading.

That leaves the fourth, and it is nobody’s slip: “a written rule applies itself”. It is the default belief of anyone who has drafted a rule and watched it come out well written. You publish it, and you file away the feeling that it is now handled.

The mode went past the screen as a filename in an ls at 14:28. Nobody opened it until 17:16 — three hours and fifty-seven minutes in, pointed at by the human.

A mechanism like that is not a gate. It is a sign by the road, and signs do not brake for anyone.

This already had a name, and a number

The enforcement-vs-emergence tension in ontoref’s own ontology says it without anaesthetic, and says it about the project itself:

A declared-but-unenforced constraint is not a floor, it is a description of one. […] Enforcement that cannot be trusted to fail is indistinguishable from no enforcement, and it is more dangerous, because it is believed.

And it carries the number: of 212 Hard constraints declared across the ADR set, 95 report as violated and nothing blocks on them. adr validate is run, read, and ignored.

The four-hour case is that number’s anecdote. It is not an agent defect: it is the shape a floor takes when it is only described.

The fix was not a new rule

None of the four rules changed. What they got was a trigger — and each one needed a different kind:

# 1. A hook — the rule travels toward the agent, not the other way round.
#    On every prompt, if the task is already governed, the QA that governs it is served whole.
"UserPromptSubmit": nu ~/.claude/hooks/onre-prompt-orient.nu

# 2. A gate — the degraded server dies in one second, not in three diagnoses.
just server-check

# 3. A contract — one mode id resolves to ONE DAG (two were answering for one).
#    shared.nu#all-mode-files — dedupe by id: 29 ids → 29 DAGs

# 4. A schema — a case that stays silent about its lesson does not export.
#    LessonAccounted: verified pointers to whatever executes the lesson, or the debt, named.

A hook, a gate, a contract, a schema. Not one of them asks anybody to remember anything — which is the only requirement that matters, because remembering is exactly what failed eight times.

The first already fired in production: the session that wrote this case’s file received the howto governing its task in its first prompt, instead of discovering it four hours later.

What this does not fix

--artifacts remains unreachable from the CLI wrapper, and the historical runs carry that column empty because of it. verify exists in zero of the mode’s eleven steps: with no oracle per step, a step’s status is whatever the agent says it is. The howto’s step list is not checked against the DAG, and it has already lied once.

And the deep one, the one with no possible gate: a sentence is not an artifact. This project’s files have oracles to spare — contracts that reject, gates that fail, schemas that refuse to export. The conversation has none. That is why in four hours not one lie reached disk and eight were spoken: what gets written passes through gates, what gets said passes through nothing.

The only oracle of the human↔agent channel is the human. That is not an excuse. It is the thesis.

The question

The honest answer to “with ontoref, wouldn’t this have been avoided?” is uncomfortable, and it is the only one that holds: ontoref, declared, was already there — and it was not enough. It was there four times. Until each rule got its trigger.

Neither comfortable position is true. The friction is not the product: selling “this makes you comply” mistakes the scaffolding for the building, and the friction is real but transitional. And the opposite is no better: coherence does not become gravity on its own. With no floor beneath it, emergence is not wu wei — it is drift. Both at once, or neither is honest.

So the question the case leaves is not “is it written?”. That one was answered yes, four times over.

It is “what fires it?”.

If the answer is “somebody will remember”, you already know what you have. And the day it matters, a human will point at it, with exactly the patience required.

In this case, eight times.


This article projects from case file 8/4, “the discipline without a trigger” — a typed case whose every figure comes from a command run against the session’s log, never from anyone’s memory. The full case file, with the lineup and the alibis, is in the case 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.