A Declaration Is Only a Promise
Backfill: this covers 2026-08-28 and was written on 2026-09-07 from the two commits, the spell page as shipped, the warding ledger, the signed manifest snapshot, and the blob store — all still on disk. git log --all --since=2026-08-24 --until=2026-08-31 in datamancy.dev returns exactly two commits, stamped 67 seconds apart that Friday afternoon: 1db0ada, “publish 2026-08-28T21-31-32Z — mint experiri — the executing ward”, 25 files and +1465/−55; and ebf6148, “ledger: experiri warded — 17 rounds, 0 un-dispositioned”, one file and one line. That publish takes the manifest’s resource count 28 → 29, with experiri at 40487 bytes and its serverInfo.commit pointing at af00e81 — the manifest is generated before the publish commit carrying it exists. Those are still the served bytes: the file has one commit in its history, and today’s manifest lists the same hash and size. Two commits reads thin; 1465 lines and a 1200-word table cell are not.
Every spell in the grimoire before this one reads. That is the right instrument for almost every question the book asks — no program tells you whether a name lies, whether a document coheres, whether prose rings true. On August 28 the exception was minted.
The class that has no divergence in it (as shipped, 1db0ada)
Section titled “The class that has no divergence in it (as shipped, 1db0ada)”A reading ward finds a divergence: the spec says X, the code does Y, one is wrong. conferre is built for that shape, which is the shape most audits assume. experiri was minted for the case where there is nothing to disagree with. From the shipped page:
The worked case that earned this spell: a constructor row in a rules engine’s operator table. It was declared in the table; the query fence admitted it; the type-checker typed it; the purity analysis approved it; the naming rule derived its name; the totality gate passed it. Source and spec agreed completely — and both were wrong together, because the table advertised a surface the executor had no implementation arm for. Every reading ward correctly reported harmony.
Six gates green, no implementation arm behind the row. Nothing reads as wrong because nothing is inconsistent — and no reader goes looking for an absence that nothing references. The page names the cost: vigilia — the meta-spell that musters the inward set — converged twice on that subsystem, two consecutive recasts at zero findings, while six such rows sat in it.
The obvious workaround — if reading cannot see it, sample the corpus:
And a corpus cannot stand in for the run. A corpus records what compiled, so it is structurally blind to what cannot be written. Three of those six broken rows appeared nowhere in a 1569-file corpus. That reads like neglect; it was the symptom.
experiri answers with two defining properties. The first is that the ward executes: evidence is a program that ran, never a file that parsed. The second is that it synthesizes its own callers and may not sample the corpus — the corpus holds only what already worked, which is precisely the blind spot. Between them they set the ceiling every other instrument in the book is under: a reading cannot reach an execution defect, and counting, listing and declaring each stop one step short of the run. The epigraph puts it in four clauses: “A reading cannot see an execution defect. A count cannot see a value defect; a list is only a claim; a declaration is only a promise.”
The unit is (declaration × position) — the portable part of 1db0ada
Section titled “The unit is (declaration × position) — the portable part of 1db0ada”The third property is the portable one, and 1db0ada shipped it with a derivation rule attached rather than as an assertion: the unit of the audit is not the declaration, it is the pair.
A position is a distinct site the system’s own admission rules let a declaration appear in, and the page separates two sets that get conflated everywhere. The admissible set is every site the system says yes to — discovered, not chosen. The driven set is the subset a cast drives — chosen, declared by name, and it is the coverage. The derivation rule generalizes to any registry: what does the system’s own admission rule vary over, once the declaration is fixed? An operator table’s positions are the grammar productions that admit an operator; a serializer’s type registry has the write path and the read path. Derive it by asking the system, never by sampling where callers happened to use it — a guessed position set manufactures findings against positions the system never offered.
Why the pair and not the declaration alone: in the worked case one operator was reachable inside a fenced expression and refused as an inline constraint — same operator, same field, same comparison, two different answers. A ward that asks once per declaration must pick one, and either choice is a lie about half the surface.
The serializer row is the cheapest version of the same fact. Every cell is driven twice, to the two answers the surface itself distinguishes — fire and refuse. For a registered Money type, the write cell’s fire-drive encodes Money(3,"GBP") and expects bytes; its refuse-drive encodes Money(3,None), which the registry declares invalid. The read cell is driven separately, on the bytes the write cell produced. Two cells, four drives, and the read cell’s verdict is independent of the write cell’s. A type that constructs and never decodes is one cell green and one cell dead — invisible to every reading ward, because construction and access are declared in different places and neither contradicts the other.
Two synthesis rules decide whether the harness measures the system or itself. The refuse-drive comes from the fire-drive by a single negation of an operand the declaration itself constrains — never of the routing or the rendering that got you there, and arity is explicitly not an operand, because negating the argument count measures your calling convention. And the fire-drive’s expected answer comes from the declaration, never from the artifact the position serves: a driver checking a route’s response against the file that route serves is green by construction.
The direction an executing auditor fails in
Section titled “The direction an executing auditor fails in”The 2026-08-28 page flags this as the most important thing the spell teaches, and it is why the file 1db0ada shipped is 40KB instead of 4KB: the extra bytes are apparatus against one failure direction.
A broken reader finds NOTHING; a broken driver finds a JACKPOT. A filter matching no pattern reports an empty list, and empty reads as clean. But one mis-rendered position reports an entire column of refusals that looks exactly like a discovery — and this ward’s findings are meant to be believed. The failure mode is a false triumph, which is the expensive direction.
Everything structural follows. A calibration is mandatory — two cells whose behaviour is already known, driven to four outcomes, two expected-fire and two expected-refuse, before a single real cell is touched. The mix is not decoration: a driver that renders nothing passes an all-refuse control, and a driver that never applies its constraint passes an all-fire control, so only a mixed control fails in both directions. Nor is a failed calibration a do-over you can hide: once reported it stays a cast-level finding.
A cast without a passing calibration is a rumour with a table.
The subtler machinery is the attribution fork, which exists because “it refused” is two different facts: the question is whether the refusal came from the system under audit or from the harness, and what the refusal names is evidence for that, not the test. The case that breaks the naming heuristic is the ward’s signature finding — a refusal raised by the position’s own machinery, downstream of a call that succeeded. The declaration ran and returned, and the position could not carry the result. It names neither the declaration nor the harness, and filing it as a driver defect erases exactly the asymmetry the ward exists to find. The mirror image is as specific: a cell that fires when it should refuse is re-driven with the operand moved and never the rendering, and if the answer holds, the same negation is re-rendered by a different mechanism before anything is concluded, because a rendering fault can be invariant under every operand.
The census has to add up, and the verdict is gated on it
Section titled “The census has to add up, and the verdict is gated on it”The report format minted on 2026-08-28 is three populations and an arithmetic, and the page says the arithmetic is the point:
CALIBRATION: PASSED (2 cells, 4 drives)COVERAGE: driven fenced-expression, inline-constraint | not driven aggregate-clause (no loader for that production) | untestable — | unadjudicated —CELLS IN GRID: 120 = attempted 118 | exempt 2 (platform-gated 1, driver-limit 1) | never reached 0ATTEMPTED: 118 = drove-and-discriminated 101 | unreachable 12 | inert 5 | driver defects 0FINDINGS: 17 = unreachable 12 (L1) + inert 5 (L2)DECLARATIONS: asymmetric 3 COST: 41s wall-clock, sharded 6 waysVERDICT: the declared surface is NOT fully reachableEach boundary is load-bearing. A runed cell is exempt and deliberately not in attempted — the rune took it out before synthesis, and counting it as attempted would be the false triumph the ward refuses. A driver defect sits inside attempted, because it was tried and did answer, but never in FINDINGS, because a driver defect is not a disposition: that cell has no verdict yet, and the column counts only defects still standing when the report is filed.
The VERDICT: line may claim fully reachable only when every cell was driven and classified and the coverage line’s not driven, untestable and unadjudicated slots are empty, with exempt, never reached and driver defects at zero. The standard the page sets itself: the test is not whether the cast found nothing, but whether every cell answered for itself. And a cast that cannot finish files its stop as a cast-level Level 1 finding — the ward’s diagnosis turned inward, because a findings-free row renders as converged.
Seventeen rounds, and every one of them a subtraction (ebf6148, 14:32)
Section titled “Seventeen rounds, and every one of them a subtraction (ebf6148, 14:32)”The ledger row is the second commit of the week, stamped 2026-08-28T21-32-27Z. Commit times in this post are local (UTC-7); a version string like 2026-08-28T21-31-32Z is the publish stamp, in UTC — which is why 1db0ada reads 14:31 on one clock and 21:31 on the other. Its method cell records what the builder put the new spell through: a full applicable vigilia in docs-kind — nesciens, cohaerere, exigere, circumspicere last — fetched by value from the signed manifest, fresh subagents, 17 combat rounds, and nesciens run with a blind sub-reader that drove a real target every round.
Seventeen is an outlier by roughly three times: every other admission trial in that ledger sits at three rounds (cohaerere, 2026-06-26; partire, 2026-06-27) or six (the grimoire index plus extirpare, 2026-06-30). exigere ran 0/0 across 16 of them, and the row notes the instrument caught its own blind spot three times and repaired before reporting.
None of the three structural outcomes those rounds produced is an addition:
a
misdeliveredverdict was minted and reversed (it contradicted the ward’s own agreement-jointly-wrong identity); the reporting section was cut 161→39 lines; the refusal fork was rewritten from an enumeration into a discriminator after each new surface added an arm.
A verdict the builder minted and then withdrew for contradicting the ward’s own identity. A reporting section he cut by three quarters. An enumeration that kept growing an arm per surface, which he replaced with the attribution rule above. The trial’s product was a smaller spell.
The row that refuses to claim closure
Section titled “The row that refuses to claim closure”Every other row in the ledger converges. The 2026-08-28 row, by its own wording, does not:
Bounded, and stated because it is true: this is the only ward whose readers can execute it, so its test surface does not close — eight target classes produced eight distinct finding sets, and a ninth is expected to find more.
The signed record names exactly one of the eight: a blind reader found reproducible (declaration × position) asymmetries in CPython’s argparse action registry — parsers reachable from add_subparsers, a TypeError from add_argument — independently reproduced. The other seven are not written down in datamancy.dev, so this post does not name them. A row meaning “converged on the surfaces driven” rather than “closed” is a different claim from every other row in the table, and one the ward’s own arithmetic forced the builder to make about the ward he had just minted.
The gate arrives, and two of the builder’s four rows cannot stand
Section titled “The gate arrives, and two of the builder’s four rows cannot stand”1db0ada also created scripts/check-warding-ledger.mjs, 126 lines, whose header names the class against the ledger’s own header:
Nothing enforced that. A row could vouch for a file that had changed a dozen commits ago and the build stayed green — which is the exact failure mode the ledger’s own header says it exists to avoid (“a stamp comment can go false while the build stays green”). The ledger was the last claim in this repo held by vigilance alone.
The class is a proof-of-work record that silently outlives the thing it proved. The ledger already said a row holds only as long as a fresh cast still measures it warded — and nothing checked it. That rule was a convention; this commit makes it a build-time check. It does not close the class, and the repo does not pretend it does: the gate cannot see a spell with no row at all, so that step stays held by discipline.
Three of its design decisions are each a place a gate could have quietly lied.
Struck rows are excluded on purpose. The parser slices the file at the ## Struck rows heading and gates only what is above it, with the reason in the source: a struck row is explicitly not a claim, so gating it would make the honest disposition impossible to record.
A row that fails to parse refuses the whole run. The live data rows are counted independently of the parse, and any mismatch exits 1 — under a comment that is the same sentence experiri uses about itself: “a filter that matches no pattern reports an empty list, and empty reads as clean.” Two artifacts in one commit, written under one idea.
Two git failures are told apart. git exits 1 for “path changed” and 128 for “bad revision”, and a bare catch folds them together and reports a change against a ref git never resolved — what a shallow CI clone produces for every stamped commit. So the script resolves the ref first with git cat-file -e, reports the two conditions separately, and the same commit adds fetch-depth: 0 to the workflow. A gate caught fabricating a diagnosis, repaired to refuse instead of guess.
Going into 1db0ada the ledger held four live rows. Two were moved into a new ## Struck rows section by that same commit — scripts/lib/spells.mjs with scripts/generate-vigilia-skill.mjs, stamped 2026-06-05, and grimoire/SKILL.md with extirpare/SKILL.md, stamped 2026-06-30 — and both were invalidated by the commit that shipped the gate. spells.mjs gained new gates during the landing; the grimoire index gained its Runes section, and the strike note says why that row could not stand: that section shipped three successive false universals before converging. The struck rows are kept verbatim under a <details> block — history preserved, claim withdrawn.
Two rows survived, and the third the ledger holds today is experiri’s own, written 67 seconds later — which is not a tidying habit. scripts/publish.mjs now runs ledger:check inside ship, so the row must cite a commit that does not exist until the publish is made. Two commits is the shape the gate forces.
The fossil the append-only store kept
Section titled “The fossil the append-only store kept”1db0ada added four blobs to blobs/sha256/, which scripts/generate-manifest.mjs documents as immutable and append-only: generate refreshes the latest pointer and the blobs, while the signed snapshot is written later by sign-manifest.mjs. That layout has a consequence nobody designed for.
Three of the four are referenced by the signed manifest: 3d49e26… (experiri/SKILL.md), and the new grimoire and vigilia pages. The fourth, 957c3ac…, is referenced by no manifest in the repository. Checked across every manifests/*/manifest.json plus .well-known/mcp/manifest.json: 122 blobs on disk, 121 referenced, exactly one orphan — that one, added by this commit.
It is a version of grimoire/SKILL.md, differing from the published index in exactly two places. It is missing the “one ward is not a scan” paragraph entirely. And its Runes paragraph asserts a flat universal: a rune is “an inline marker placed in the substrate under audit”, full stop. The shipped index reads “It is placed in the substrate under audit, or, where a ward says so, declared in the cast when that substrate is not yours to edit.”
The universal is false, and what falsifies it is the spell shipping in the same commit. experiri’s rune section requires exactly the case the orphan’s sentence forbids — a rune you cannot place is still a judgment you must record, so when the roster is not yours to edit, the exemption is declared in the cast and counted in exempt. That is load-bearing: casting against a roster you cannot write to must not force exempt to 0, because that turns a deliberate exemption into a finding and lets an incomplete cast satisfy the fully-reachable gate.
So the store holds a paragraph superseded inside its own commit, by that commit’s other file. That the blob is the residue of a publish attempt hashed by generate-manifest and abandoned before signing is an inference — the shape a stopped publish leaves, given that generate writes blobs and sign writes snapshots; no log entry proving a specific aborted run was found. The orphan, its content and its commit are not inferences.
What minting one ward forced everywhere else
Section titled “What minting one ward forced everywhere else”Four other files in 1db0ada answer “why did this change?” the same way: an existing universal was false the moment an executing ward existed.
The grimoire index gained the ### Runes section, because the rune convention had lived only in per-spell pages and the README, and experiri’s rune needed an optional second positional the index had never described. It also gained a safety line ahead of the casting instructions — one ward is not a scan; it executes the surface it audits, so cast it only where you can undo the side effects. Both strings live in the generator, so the index cannot drift.
vigilia gained experiri as a conditional code ward in three places, and its trigger is a conjunction whose second half is new to the watch: a target that declares a callable surface and can be driven in the caster’s own process without irreversible effect. The watch had never had to gate a ward on whether running it is safe.
The README’s rune paragraph was rewritten. It had said runes suppress the finding without denying its presence; it now says whether a spell honours the rune on sight or adjudicates it is that spell’s own rule. experiri adjudicates, so that universal was false the moment the spell shipped. The README also took the “one ward is not a scan” warning directly under the bullet advertising every cast as a mechanical scan — the document selling the practice as read-only, amended by one ward’s arrival.
scripts/lib/spells.mjs gained two build gates, both carrying the same confession in the comment: “They matched by inspection until this line existed.” The first requires a ## The rune section in every non-primer spell, because the index now tells readers a ward’s rune rules live there — and that universal, the comment notes, has shipped false three times. The second requires frontmatter name to equal the directory name, and its reasoning names the mechanism: the two travel down different pipes and meet only at the consumer, so a mismatch ships a signed manifest whose catalog advertises a spell that 404s, and nothing downstream would notice, because each pipe is internally consistent. A signed-but-unfetchable catalog entry is now a red build.
Seventeen rounds subtracted, two of the builder’s own rows struck against the new rule, and the row for the ward itself refuses to claim closure. A declaration is only a promise — the grimoire’s own included.
Likely Contributions to the Field
Section titled “Likely Contributions to the Field”- (declaration × position) as the unit of a reachability audit. Reachability is not a property of the declared thing; it is a property of the pair. A type green on write and dead on read, an operator that fires fenced and refuses inline — one declaration, two answers, and a per-declaration audit must lie about half the surface. The derivation generalizes to any registry through one question: what does the system’s own admission rule vary over, once the declaration is fixed? The admissible set is read out of the system; the driven subset is declared by name, because it is the coverage.
- An executing auditor fails in the opposite direction from a reading one, and the calibration follows from that. A broken reader returns an empty list, which is cheap to mistake for a clean result; the expensive direction is the other one, where a single mis-rendered position refuses an entire column and the harness’s own defect arrives looking exactly like a finding. Hence a mandatory mixed control before any real cell: an all-refuse control passes a driver that renders nothing, an all-fire control passes a driver that never applies its constraint, and only two-fire-plus-two-refuse fails both ways. That is the argument for an execution-based audit needing more apparatus than a reading one, not less.
- A verdict gated on its own coverage arithmetic, with the null result made expensive. Three populations that must add up, a fully-reachable claim admissible only when every unsettled slot is empty, and a cast that cannot finish filing a cast-level finding rather than an empty row — because a findings-free row renders as converged. Silence cannot be read as proof.
- A proof-of-work ledger gated against its own re-prove rule, one step and labeled as one step. The gate excludes struck rows so the honest disposition stays recordable, refuses the run when a row fails to parse rather than reporting the survivors, and separates “path changed” from “revision unresolvable” so a shallow clone cannot make it fabricate a diagnosis. It climbs convention → build check, not to unrepresentable, and the remaining hole is documented rather than implied away.
- An append-only content store turns a superseded claim into physical evidence. One orphan blob among 122 preserves a paragraph the same commit’s other file falsified, in a store whose design forbids deletion. A record that cannot forget differs from one merely versioned: the withdrawn claim survives byte for byte, without anyone having chosen to keep it.