Skip to content

v2 compile-obligation census: claimed vs route-covered vs seed-side escape - #10942

Merged
briansrls merged 22 commits into
mainfrom
session/quiet-hawk-479
Sep 11, 2026
Merged

briansrls merged 22 commits into
mainfrom
session/quiet-hawk-479

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

What this is

A census, as data, of the compile-time obligations on its own roster — with the rung each obligation executes on each route, its ceiling, its next trigger, and the column that motivated the ask: what the v1 seed does outside that obligation's reach.

Read-only measurement. No lens, gate, roster or annotation is repaired here.

The numbers

Derived by folding the roster, never transcribed. One instrument re-derives all six:

gunbc run --source-root dag --source-root src/v2 \
  --entry dag/gunbc/v2_compile_obligation_census.dag --function census_counts

(gunbc run refuses a non-ProcessExit return and prints the value in the refusal; read it there.)

claimed=14  executing_natively=0  executing_interpreted=9  seed_escape_open=14
without_a_home=1  inflated_rung=13  claiming_above_ceiling=0  unverified_entry=9

These numbers moved twice while this PR was open, and that is the argument for deriving them. gunbc#10882 made the required-v2-native lane a required job and executing_natively went 0 → 9, inflated_rung 13 → 4. gunbc#11003 then deleted that job on an operator ruling (one full run took over four hours at 14.8 GB, and the workflow's concurrency group never supersedes a running job). The route still exists as an operator-invoked instrument, but lane membership no longer means execution on an acceptance path — so the counts moved back. An authored column would have sat still through both.

The reached-by-route axis was deleted with the lane. It separated two facts that were genuinely different while the required lane ran — a door a route names, and a door a route reaches. gunbc#11003 deleted the lane and with it the distinction, leaving a constructor nothing could build and a permanently-zero column: §4b's decoration. It returns when gunbc.rung_drop v2_native_route_off_the_merge_path retires.

inflated_rung=13 is the census's whole point as data. obligation_rung_is_inflated compares each row's declared claimed_rung against the rung its path arms establish, as a strict inequality — under-claiming is honesty, so only claimed > executed counts. Thirteen of fourteen obligations claim more than any route executes. claiming_above_ceiling=0 is the paired coherence check (a row claiming above its own declared ceiling), authorable at the fixture boundary and proven non-vacuous by a fixture.

Method note: the 11-vs-9 trap

Asking the native lane's prefix predicate alone reported executing_natively=11. The two extra rows were exactly accumulator_copy and mandatory_tag — the ones gunbc.ci_layer_roots witness_exclusion_frontier carves out.

native_route_universe_member is the lane's predicate over a module name; the lane's own header states that the population it applies to is derived by the harness from the floor's discovery producer. So lane membership is the prefix intersected with floor discovery, and an entry an exclusion pattern removes from discovery never reaches the native harness however well its module name matches. Freeze is deliberately not applied — a freeze row is an admission fact about the required floor's execution standing, not about the discovery walk, and where a fact is not established the narrower claim is the honest one (it happens not to matter today: every frozen subject here is also excluded).

Reporting 11 would have been this census's own headline defect, committed in the column it exists to make honest.

The roster is not proven complete, and the module says so. Rows were enumerated by hand from v2.compiler.compile's two enrolled lens rosters, std.primitive_identity's declared traversal facts, and two classes surfaced by measurement. Nothing joins that set to those authorities at identity grain — the enrolled rosters are the contents of two list literals no reader here can walk — so a de-enrolled or newly added lens leaves this roster stale and silent. Every count is denominated in obligations_claimed; reading them as "v2's obligations" would be completeness inflation in the headline of the module that measures it. The closure is a declared frontier.

route coverage is not qualification, and the fold is named for what it proves. obligation_route_coverage_rung reads whether each route executes the obligation's witnesses — not whether the right lens ran, its red went red, its green stayed green. The inflation findings survive that weaker reading because route coverage is an upper bound on any qualified rung, so claimed > coverage implies claimed > qualified; what it costs is false negatives, and that gap is the named trigger (v2.compiler.self_host.compile_obligation_activation, a QualifiedOnPath arm carrying red-and-green receipts).

The two pending premises each have their own fold. unverified_entry and unread_native_verdict are counted separately, off the interpreted and native standings respectively, because they retire on different days and a single number would hide one inside the other. A premise with no fold is a footnote, not a declared debt.

unverified_entry=9 is a declared debt, not a hidden premise. The derivation can ask the freeze roster and the exclusion frontier; it cannot ask whether an entry file still exists. Rather than let "covered by neither roster" widen into executing, that standing is its own arm — ExecutedPendingEntryVerification, carrying the premise as a typed ref — counted separately, bounded to these fourteen rows, and bound to a typed dissolution trigger.

A second entry point, --function census_report, renders one line per obligation — kind, claimed rung, executed rung, both path standings, ceiling, drop-citation count and trigger — for a lane choosing repair work.

Fourteen: the compile door, the 5 always_required_root_lenses, the 3 always_required_lenses, the 3 declared primitive traversal facts whose order leaves determinism open (map_keys/map_values HostUnspecifiedOrder, index_by TraversalOrderUnclassified), the non-primitive order-exposing fold, and realization cost fidelity.

The dispositions are derived, and that is the whole design

Each row authors only what no authority owns: which witnesses exercise the obligation (entry + function — the grain both rosters key on), what makes them red, and what the seed does outside reach. Whether those witnesses execute is asked, on every fold:

  • gunbc.witness_deferral_freeze frozen_path_deferral_covers(entry, function)
  • a string_contains join against gunbc.ci_layer_roots witness_exclusion_frontier, which reproduces the host's rel.contains(pattern) rule rather than approximating it

The first cut hand-authored these, and the derivation caught it being wrong. That cut read witness_discovery_scan_dirs as the discovery filter and reported executing_interpreted = 0. That declaration has exactly one consumer in v1_compiler.cli_run and it is inside a cfg(test) module asserting the authority's own value. The real walk takes every *_test.dag under witness_layer_roots (dag, src/v2) and subtracts the exclusion frontier. Six obligations reported as unreachable are discovered and running. The error was invisible precisely because the disposition was a sentence rather than a question put to the authority that owns it — DESIGN §3, a fork is a correctness concern, not a style one.

What the corrected census still finds

executing_natively = 0, and it is not the zero it looks like. The door is reached: compile_source_root_ingest_with_admission and stage_translate both call validate_then_compile from inside 00_compile.dag with lenses: [], and the root roster fires regardless of caller-supplied lenses. The emitted SourceRootEvalDriver executes the first on the required-v2-native lane. Every admitted subject there refuses upstream at resolve, so no gate is asked. RouteReach carries that as its own axis: reached_by_native_route = 13 and executing_natively = 0 are different facts, and only the second flips when the closure refusals repair.

mandatory_tag is the sharpest row. The roster's only WallNow — its construction_justification names mandatory_tag_compile_gate as a wall standing now. All its gate witnesses, including mandatory_tag_enrolled_in_root_roster_rejects_violating_module (whose entire job is the root-roster enrollment that claim rests on), are frozen path deferrals and under the test/claim/long/ exclusion. DESIGN §4b(1) rung inflation.

accumulator_copy is excluded, not frozen-only — claim/complexity/accumulator_copy_roster_gate and test/claim/long/ both carve it out.

without_a_home = 1. Realization cost fidelity: std.algebra declares CostShape, but nothing declares that a realization must preserve it and nothing compares the two. Measured, diverging both ways — v2.std.algebra list_append is O(n) declared and O(n²) emitted; list_snoc_item is O(n) declared and O(1) emitted. The lens reads the authority, so it convicts the fast realization and is blind to the quadratic one. That is a modeling obligation (§6), not a conformance row, and Home says so with a typed arm rather than a blank field.

Two error classes filed in the ledger

Per DESIGN §4b, both are rows under dag/gunbc/recurring_failure_mode/, not comments:

  • stale_present_tense_coverage_claim_in_the_authority_consulted_first — v2.compiler.compile's own annotation says the de-enrolled lens_module_gate invariant "executes per-PR via v2.test.claim.enforcement.lens_module_gate_witness". False on two independent grounds: that entry is frozen, and test/claim/enforcement/ is an exclusion pattern. Second specimen: excl_bin_wet_reason, corrected on itself 2026-08-19.
  • receipt_subject_is_the_prose_about_the_mechanism — the only native behavioral receipt for v2.compiler.compile has a one-entry case list: required_lens_grain_note, compared against a nine-line seed module whose whole content is that same string. The shim is well built — --inject-fault, real positive control — and nothing in it would move if every gate were deleted.

The witness

Homed in dag/test/claim and it joins live rosters it does not own, in both directions, separating which authority decided — a derivation that lost the freeze lookup would still get the mandatory-tag answer right through the exclusion pattern alone. Four checks, each carrying its positive control in the same function so a constant reader fails. All green by execution.

A row-shape validator was written and deleted rather than shipped. Every field is NonEmptyStr and "" as NonEmptyStr is refused at typecheck, so its RED is unauthorable in the corpus and at the fixture boundary — a decoration under §4b, not a weak wall. The reasoning is recorded beside the rows.

What is not checked

The row set is not identity-joined to the contents of always_required_root_lenses / always_required_lenses — a walk over two list literals no reader available here can do, so a de-enrolled lens would leave a stale row standing. Entry-path existence is not verified: a moved file leaves a stale key both rosters answer "not covered" for, which reads as executing — the derivation's one optimistic direction, stated where it lives. Cited-symbol resolution is uncovered corpus-wide under the existing drop gunbc.rung_drop cited_symbol_census. All three are named as the census's next trigger.


🤖 Generated with Claude Code

https://claude.ai/code/session_01EPF5TTachtTAeAkYWQshXz

Brian Searls and others added 3 commits September 10, 2026 15:22
Every compile-time obligation v2 declares, as data, with the rung it
EXECUTES on each route rather than the rung it claims.

Twelve obligations: the compile door itself, the five always_required_root
lenses, the three always_required subtree lenses, and the three declared
primitive traversal facts whose order leaves determinism open (two
HostUnspecifiedOrder, one TraversalOrderUnclassified).

Executed by folding the roster, not transcribed: 12 claimed, 0 executing
natively, 0 executing on the interpreted per-PR route, 12 with an open
seed-side escape.

Two independent reasons the executing columns are zero. No lens witness is
in a directory gunbc.ci_layer_roots witness_discovery_scan_dirs walks --
several are additionally frozen path deferrals, which means declared
never-executed -- and validate_then_compile has no production caller, so a
roster that fires on every call of it fires never. The two machine_shape
witnesses that ARE inside the scope import std.machine_shape, not
v2.lens.machine_shape.

mandatory_tag is the roster's only WallNow and all twelve of its gate
witnesses are frozen, including the one whose job is the root-roster
enrollment the claim rests on.

Read-only measurement. Two findings are named and left to their owners: the
compile door's own annotation asserts, present tense, that the de-enrolled
lens_module_gate invariant executes per-PR via an entry that is both frozen
and outside the scan dirs; and the only native behavioral receipt for
v2.compiler.compile compares one prose string against a nine-line seed
module containing that same string.

A row-shape validator was written and deleted rather than shipped: every
field is NonEmptyStr, so its RED is unauthorable in the corpus and at the
fixture boundary alike, which makes it a decoration under DESIGN 4b.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EPF5TTachtTAeAkYWQshXz
REVIEW 63152 ASKED FOR THE DERIVATION AND THE DERIVATION CAUGHT A FALSE
HEADLINE. The first cut hand-authored each row's per-PR standing from a
reading of gunbc.ci_layer_roots witness_discovery_scan_dirs. That reading
was wrong: witness_discovery_scan_dirs has exactly one consumer in
v1_compiler.cli_run and it is inside a cfg(test) module asserting the
authority's own value. The walk that discovers witnesses takes every
*_test.dag under witness_layer_roots (dag, src/v2) and subtracts
gunbc.ci_layer_roots witness_exclusion_frontier by substring.

So the corrected count is 9 of 14 executing on the interpreted per-PR route,
not 0. Six obligations reported as unreachable are discovered and running.
The error was invisible precisely because the disposition was a sentence
rather than a question put to the authority that owns it -- DESIGN section 3,
a fork is a correctness concern.

Each row now authors only what no authority owns: which witnesses exercise
the obligation (entry + function, the grain both rosters key on), what makes
them red, and what the seed does outside reach. Whether those witnesses
execute is ASKED on every fold, through
gunbc.witness_deferral_freeze frozen_path_deferral_covers and a
string_contains join against witness_exclusion_frontier that reproduces the
host's rel.contains(pattern) rule rather than approximating it.

The witness is no longer a fold over data the same file authored. It joins
two live rosters it does not own, in both directions, and separates which
authority decided -- a derivation that had lost the freeze lookup would still
get the mandatory-tag answer right through the exclusion pattern alone.

WHAT SURVIVES THE CORRECTION: executing natively is still 0 (no gate is
reached on the native lane; every admitted subject refuses upstream at
resolve). mandatory_tag is still the only WallNow with no executing evidence
anywhere -- both its entries are frozen AND under the test/claim/long/
exclusion. The 00_compile annotation finding survives on a corrected ground:
test/claim/enforcement/ is an exclusion pattern.

Also per review 63152: the two discovered error classes are filed as rows
under dag/gunbc/recurring_failure_mode/ rather than left in a comment, and
the counts gained census_counts as the single named instrument.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EPF5TTachtTAeAkYWQshXz
CI refused at the parse sweep with 62 errors: source annotations sitting
inside declaration bodies, and a closing block with no module item after it.

The hoist is not mechanical relocation. A field-by-field comment moved above
its type reads as a disconnected list that has lost its referent, so the
PathExecution arm notes and the V2CompileObligation field notes are rewritten
as single annotations that NAME the arm or field they describe. The trailing
findings block moves into the module header, where it has a subject.

Verified with the local check rather than by inference: gunbc compile
--output-dir --source-root dag --source-root src/v2 --entry <file> reports
0 blocking errors on all four files, including recurring_failure_mode/roster
which pulls in both new rows. Witness-green is not parse-clean; they are
different checkers.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EPF5TTachtTAeAkYWQshXz
@gunbai-bot

gunbai-bot Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

Addressed all three findings of review 63152, and the first one caught a false headline — thank you for it.

1. Hand-authored disposition forking witness_deferral_freeze / witness_discovery_scan_dirs. Fixed by deriving, and the derivation immediately falsified the census's own central number. Each row now authors only the (entry, function) pairs — the grain both rosters key on — and the per-PR standing is derived on every fold through gunbc.witness_deferral_freeze frozen_path_deferral_covers and a string_contains join against gunbc.ci_layer_roots witness_exclusion_frontier that reproduces the host's rel.contains(pattern) rule rather than approximating it.

What that surfaced: the previous cut read witness_discovery_scan_dirs as the discovery filter. It is not. That declaration has exactly one consumer in v1_compiler.cli_run and it is inside a cfg(test) module asserting the authority's own value; the real walk takes every *_test.dag under witness_layer_roots and subtracts the exclusion frontier. So executing_interpreted is 9 of 14, not 0 — six obligations I reported as unreachable are discovered and running. The finding's own reasoning is why: the fork was invisible because it was a sentence rather than a question put to the authority.

The witness follows: v2_compile_obligation_per_pr_standing_is_derived_from_the_live_rosters_holds asks two real subjects from opposite sides of both rosters and asserts which authority decided each, so a derivation that silently lost the freeze lookup would still get the mandatory-tag answer right through the exclusion pattern and this arm would catch it. That is a join against data this file does not own, not a fold over its own copy.

2. Counts with no consumer. They now have a named single instrument, census_counts, cited in the module and in the PR body, and the derived standing they fold is consumed by the witness above. I have not routed them into a required-run receipt — that would be a second enrollment surface for a fact the witness already executes — so if you read the counts as still dangling, say so and I will state the named later consumer and its trigger explicitly rather than leave it implicit.

3. Error classes in a comment instead of the ledger. Both are now rows under dag/gunbc/recurring_failure_mode/ with receipts, evidence refs and a next trigger, enrolled in the roster: stale_present_tense_coverage_claim_in_the_authority_consulted_first (carrying the prior excl_bin_wet_reason specimen, which is what makes it recurring rather than singular) and receipt_subject_is_the_prose_about_the_mechanism. The census annotation now points at them rather than carrying the facts.

Also fixed on the way through: CI refused the first push with 62 §4c body-grain annotation errors. Hoisted to module-item grain, rewritten so the moved notes name the arm or field they describe rather than reading as a detached list, and verified with gunbc compile --output-dir … --source-root dag --source-root src/v2 --entry <file> at 0 blocking errors on all four files.

— sent from quiet-hawk-479

Review 63166, both findings, both real.

TRIGGERS. Eight next_trigger strings still required witnesses to be "homed
inside witness_discovery_scan_dirs" -- the authority the same module's header
had just discredited. The correction had shipped half: header and derivation
fixed, repair targets not. That is worse than the original error, because a
census whose job is to aim repair work was aiming it at a lever that does
nothing.

Each now names the capability that actually holds its rung down (DESIGN
4b(3)). For the six rows whose witnesses already execute per-PR, that is the
NATIVE path alone -- the emitted lane's subjects must stop refusing at
resolve so the door is entered -- stated with the reason no discovery,
exclusion or freeze change can move them. For accumulator_copy and
mandatory_tag the real walls are the exclusion patterns and the freeze rows,
and the trigger names the cost that put them there rather than the pattern
text, because editing a pattern around a witness that is still unaffordable
swaps one silence for another.

PUB-USE ATTRIBUTION. determinism_obligation's seed_escape still said the
seed's pub-use walk is something this gate would classify NonDeterministic,
while the same module withdrew exactly that diagnosis on
primitive_map_keys_obligation and filed the measured unique_strings site as
outside the gate's denominator. One measured incident, two answers, inside
one module. The claim is withdrawn here too, on the same gunbc#10941
measurement, and the row now says which single row owns the incident.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EPF5TTachtTAeAkYWQshXz
@gunbai-bot

gunbai-bot Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

Both findings of review 63166 are correct and both are fixed in 2b253eb.

1. Eight next_trigger strings still naming witness_discovery_scan_dirs. Guilty, and the diagnosis is sharper than "stale text": the correction shipped half. I fixed the header and the derivation and left the repair targets pointing at the lever I had just shown does nothing — which is worse than the original error, because aiming repair work is what a census is for.

Each trigger now names the capability that actually holds its rung down. For the six rows whose witnesses already execute per-PR (determinism, machine_shape, undecidable_verdict_collapse, fact_density, unit_modeling, lifecycle_carrier) that is the native path alone — the emitted lane's admitted subjects must stop refusing at resolve so compile_source_root_ingest_with_admission actually enters the door — and each says explicitly that no discovery, exclusion or freeze change can move it, since §4b(1) takes the minimum across paths and the interpreted side is already green.

For accumulator_copy and mandatory_tag the real walls are the exclusion patterns and the freeze rows, and I deliberately did not write "delete the pattern" as the trigger. Per §4b(3) the trigger must name the capability: those exclusion rows exist because the walks were priced out of the per-PR fold, so the trigger is the cost becoming affordable — editing a pattern around a witness that is still unaffordable swaps one silence for another, and a trigger naming less than the capability it restores is satisfied while the capability stays dead.

2. Withdrawn pub-use attribution left standing on determinism_obligation. Also guilty, and it is the exact §3 shape — one measured incident with two answers inside one module. The claim is withdrawn on the root determinism row too, on the same gunbc#10941 measurement that withdrew it from primitive_map_keys_obligation, and that row now states which single row owns the incident (determinism_non_primitive_order_exposing_fold) rather than restating it.

Verified with gunbc compile --output-dir … --source-root dag --source-root src/v2 --entry dag/gunbc/v2_compile_obligation_census.dag at 0 blocking errors, and census_counts re-derived on the committed bytes: claimed=14 reached_by_native_route=13 executing_natively=0 executing_interpreted=9 seed_escape_open=14 without_a_home=1.

On the red CI: the floor's single blocker is not from this PR. required-ci: declarations FAIL IMPORT-MEMBER-ABSENT at dag/gunbc/cloudflare/r2_token_mint_run.dag:69:3 — #10923 moved mutation_status_is_commit_ambiguous to extdeps.transports.rest and the importer still names the old home. It is main-tip and #10945 owns the repair; I will merge main in and rerun once that lands.

— sent from quiet-hawk-479

Brian Searls and others added 2 commits September 10, 2026 17:03
Review 63176, three findings, all real. The first is the one that mattered.

THE CENSUS DID NOT COMPUTE THE COMPARISON IT IS NAMED FOR. claimed_rung was
authored on all fourteen rows and read by no fold -- DESIGN 3c's red arm, and
a title the diff did not make true. obligation_rung_is_inflated now compares
the declared claim against the rung the path arms establish, as a STRICT
inequality: under-claiming is honesty, not a defect, and only claimed >
executed counts. Measured on the live roster: inflated_rung=13 of 14.

That number is the census's whole point stated as data rather than as prose,
and it is the first cut where the roster answers the operator's question by
folding rather than by being read.

A second checkable incoherence came with it: a row claiming above its own
declared ceiling has asserted something its own record calls unreachable.
Unlike the emptiness checks this module deleted for being unauthorable
against NonEmptyStr, this RED is writable at the fixture boundary because the
claim and the ceiling are independent fields. It is authored there and the
live count is 0, with the fixture proving the check is not vacuous.

THE WITNESS CAUGHT MY OWN ARM. The inflation test's third case reused the
shared fixture, which hardcodes a StructurallyGuaranteed claim, and asserted
it was not inflated while it executed at MechanicallyPreventable. It returned
false rather than green. The arm is now four rows varying claim and paths
independently, so the predicate cannot be reading only one axis, and the
comment records the miss rather than hiding it.

CITATIONS. related_drops was a List<NonEmptyStr> of bare identities while
every other citation in the module was a DeclarationRef -- the exact shape
this ledger files as unlanded_citation_indistinguishable_at_the_citing_end.
Now List<DeclarationRef> through rung_drop_ref, which is mechanical because
the row files are one declaration per module named for their identity.

DUPLICATION. The same ~300-character next_trigger sentence was pasted on six
rows; a correction would land in five and drift in the sixth. It is one
shared data binding, the move this module already made for
lens_native_execution.

The report projection consumes the remaining authored fields -- kind, claimed
rung, both path standings, ceiling, drop-citation count, trigger -- through
census_report. discriminating_red and positive_control are deliberately not
rendered: they are paragraphs, and a report that inlined them would be the
source with worse formatting.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EPF5TTachtTAeAkYWQshXz
@gunbai-bot

gunbai-bot Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

All three findings of review 63176 are correct and fixed in b34c0d8. The first one was the important one and I want to name what it caught rather than just report it closed.

1. The census did not compute the comparison it is named for. claimed_rung was authored on all fourteen rows and read by no fold. That is §3c's red arm, not its admissible middle, and it means the PR title was a claim the diff did not make true.

obligation_rung_is_inflated now compares the declared claim against the rung the path arms establish, as a strict inequality — under-claiming is honesty and costs nothing, so only claimed > executed counts. On the live roster: inflated_rung=13 of 14, now in census_counts. That is the operator's question answered by a fold instead of by reading prose, and it should have been the first thing the module did.

A second checkable incoherence came with it: obligation_claim_exceeds_its_ceiling, because a row claiming above its own declared ceiling has asserted something its own record calls unreachable. Unlike the emptiness checks this module deleted for being unauthorable against NonEmptyStr, this RED is writable at the fixture boundary — claim and ceiling are independent fields — so it is authored there, and the live count is 0 with a fixture proving the check is not vacuous.

The witness caught my own arm while I was writing it. The inflation test's third case reused the shared fixture, which hardcodes a StructurallyGuaranteed claim, and asserted the row was not inflated while it executed at MechanicallyPreventable. It returned false. The arm is now four rows varying claim and paths independently — a predicate that read only "claim is high" fails the second, one that read only "paths do not execute" fails the third, and one that collapsed to a boolean executes/does-not fails the fourth. The comment records the miss.

2. related_drops as bare strings. Correct, and your citation of this PR's own unlanded_citation_indistinguishable_at_the_citing_end filing is the right stick to beat it with. Now List<DeclarationRef> via rung_drop_ref, which is mechanical because the row files are one declaration per module named for the identity they carry.

3. The six-times-pasted trigger. Also correct, and the module had already made this exact move one field over for lens_native_execution. It is one shared data native_door_entry_trigger that the six rows reference.

On the rest of the record: census_report renders kind, claimed rung, both path standings, ceiling, drop-citation count and trigger, so those fields have an executing consumer. discriminating_red and positive_control are deliberately not rendered — they are paragraphs, and a report that inlined them would be the source with worse formatting; they are read at the row, which is where a lane that has already picked its obligation is looking. If you read that as still dangling, say so and I will fold them rather than argue it.

Verified: 0 blocking errors on both files via gunbc compile --output-dir … --source-root dag --source-root src/v2 --entry <file>; all six witness checks return true; census_counts on the committed merged tree reads claimed=14 reached_by_native_route=13 executing_natively=0 executing_interpreted=9 seed_escape_open=14 without_a_home=1 inflated_rung=13 claiming_above_ceiling=0.

— sent from quiet-hawk-479

Review 63194. guarantee_rung_rank was a nickname: gunbc.guarantee_rung
already declares guarantee_rung_index with byte-identical arms, the census
already imports that module for guarantee_rung_label and the rung
constructors, and gunbc.guarantee_stall already consumes the index. Minting a
second name for the ladder's order is DESIGN 3's recurring violation, and it
is the one this census exists to measure, committed inside the census.

The order is a property of the closed vocabulary, so a second copy could
disagree with the first the day a rung is added -- which is exactly the
failure the index's own annotation says it exists to prevent.

Deleted and repointed; census_counts is unchanged at inflated_rung=13
claiming_above_ceiling=0, which is the receipt that the swap preserved
behavior rather than the assumption that it did.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EPF5TTachtTAeAkYWQshXz
@gunbai-bot

gunbai-bot Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

Correct, and fixed in 5dafb8d. guarantee_rung_index already exists in gunbc.guarantee_rung with byte-identical arms, the census already imports that module for guarantee_rung_label and the rung constructors, and gunbc.guarantee_stall already consumes the index — so guarantee_rung_rank was a nickname with no excuse. Deleted and repointed.

Worth naming what it was: the ladder's order is a property of the closed vocabulary, and the index's own annotation says it exists so "below its ceiling" is decided by a fold rather than by a reader comparing labels. A second copy is free to disagree with the first the day a rung is added. That is §3's recurring violation committed inside the census whose job is to measure exactly this class — the sharpest possible place to get it wrong.

census_counts is unchanged at inflated_rung=13 claiming_above_ceiling=0, which is the receipt that the swap preserved behavior rather than the assumption that it did, and the file is 0 blocking errors.

On CI: the two failures on earlier heads were not this diff. 5aa4bc98 was blocked by a cost-budget overshoot on v2.test.lens_test_migration_debt.test_migration_debt_test.planted_module_without_tests_refuses (724ms against the 500ms per-claim ceiling — a charge, explicitly "a cost debt only, not a defect", and the same witness carries no cost line on the green main run at 077b771c). b34c0d8c died differently, on a runner memory stall: TERMINAL-LEDGER REFUSAL cause=WireAuthorityUnresolved … MemoryStallRefusedPageThrash: 309058 major faults/minute while computing for only 4% of the wall. That is the floor's own infrastructure guard refusing, not a verdict on the corpus. I am watching the run on this head rather than reading either as a result for the change.

— sent from quiet-hawk-479

…ntry

Two corrections, one from plan review and one from review 63201, and both are
about a name or an arm promising more than it computes.

ROUTE COVERAGE IS NOT QUALIFICATION. obligation_executed_rung read whether
each ROUTE executes the obligation's witnesses -- not whether the right lens
ran, its red went red, its green stayed green, on the compiler closure, in the
current generation. discriminating_red and positive_control are prose joined
to nothing and the native standing is authored, because no per-lens native
receipt authority exists to ask. Harmless today at native=0, but the moment a
native standing flips the old name would report MechanicallyPreventable on the
strength of a route running. Renamed to obligation_route_coverage_rung; the
answer did not change, only the claim the name makes about it.

Inflation findings stay sound under the weaker reading, and the module says
why: route coverage is an UPPER BOUND on any qualified rung, so claimed >
coverage implies claimed > qualified. What the weaker reading costs is false
negatives, which is the gap the qualification authority closes -- named as the
trigger: v2.compiler.self_host.compile_obligation_activation, a QualifiedOnPath
arm carrying red-and-green receipts, required before MechanicallyPreventable
is reportable.

THE DERIVATION WIDENED WHERE IT COULD NOT DECIDE. "Not frozen and not
excluded" reported plain ExecutedOnPath, so a moved or deleted entry --
covered by neither roster -- read as covered at exactly the moment the
derivation lost the ability to answer. That is DESIGN 5's failure arm that
widens instead of refusing. It is now the carve-out section 5 does allow:
LOUD (ExecutedPendingEntryVerification, a distinct arm naming the premise,
counted by obligations_executing_on_an_unverified_entry -- unverified_entry=9
beside executing_interpreted=9, two folds so they can diverge), BOUNDED (the
fourteen rows' entries, it cannot grow with the corpus), and TRIGGERED by a
typed bound DissolutionCondition rather than a sentence.

AND THE SENTENCE IT REPLACES WAS THE CLASS THIS PR FILES. The annotation said
the optimism's trigger was "named on the census's own next_trigger below" when
no such declaration existed -- stale_present_tense_coverage_claim_in_the_
authority_consulted_first, committed inside the module that files it. The
repair is the declaration, not a softer sentence.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EPF5TTachtTAeAkYWQshXz
@gunbai-bot

gunbai-bot Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

Both findings of review 63201 are correct and fixed in 7203e1b, along with a rename from plan review that belongs in the same commit because it is the same defect one field over: a name or an arm promising more than it computes.

1. The standing arm widened where it could not decide. Guilty. "Not frozen ∧ not excluded" reported plain ExecutedOnPath, so a moved or deleted entry — covered by neither roster — read as covered at exactly the moment the derivation lost the ability to answer. §5's failure arm that widens instead of refusing.

It is now the carve-out §5 does allow, on all three counts:

  • Loud — ExecutedPendingEntryVerification is a distinct arm carrying the unverified premise as a typed DeclarationRef, never plain ExecutedOnPath, and obligations_executing_on_an_unverified_entry counts it. census_counts now reads … executing_interpreted=9 … unverified_entry=9. Two folds rather than one number, because the day an entry is verified they diverge and a single number could not show it.
  • Bounded — the population is the entries of the fourteen rows in this file. It cannot grow with the corpus.
  • Triggered — entry_existence_verification_trigger, a typed bound_dissolution naming the declaration that will answer it.

A witness arm exercises it in both directions (v2_compile_obligation_unverified_entry_debt_is_counted_holds), so the debt count cannot be a constant.

2. The annotation asserted a trigger that did not exist. Also guilty, and this is the sharper one: the sentence claimed the optimism's trigger was "named on the census's own next_trigger below" when no such declaration was anywhere in the module. That is stale_present_tense_coverage_claim_in_the_authority_consulted_first — the class this same change files in the ledger — committed inside the module that files it. The repair is the declaration existing, not a softer sentence, and the annotation now records that it got this wrong rather than quietly reading correctly.

3. From plan review, same commit: obligation_executed_rung renamed to obligation_route_coverage_rung. It reads whether each route executes the witnesses — not whether the right lens ran, its red went red, its green stayed green, on the compiler closure, in the current generation. Harmless while native execution is 0, but the moment a native standing flips, the old name would have reported MechanicallyPreventable on the strength of a route running. The module also states why the inflation findings survive the weaker reading: route coverage is an upper bound on any qualified rung, so claimed > coverage implies claimed > qualified — the 13 are sound, and what the weaker reading costs is false negatives. That gap is named as the trigger: v2.compiler.self_host.compile_obligation_activation, a QualifiedOnPath arm carrying red-and-green receipts, required before MechanicallyPreventable is reportable.

Verified: 0 blocking errors on both files; all seven witness checks return true; census_counts reads claimed=14 reached_by_native_route=13 executing_natively=0 executing_interpreted=9 seed_escape_open=14 without_a_home=1 inflated_rung=13 claiming_above_ceiling=0 unverified_entry=9.

For the record on CI: the run on 5dafb8d1 was green. The two earlier failures were environmental — a cost-budget overshoot on an unrelated witness, and a runner MemoryStallRefusedPageThrash — not verdicts on this change.

— sent from quiet-hawk-479

…odule

Review 63208 and the floor's own declarations phase, which caught the second
half before I pushed it.

THE DERIVATION ASKED TWO OF THREE SUBTRACTIONS. Per-PR standing is not
discovery minus freeze minus exclusion: the required floor prepares the import
closure of v2.workflow.required_floor required_gate_prefixes, not the corpus,
and a discovered witness whose MODULE is outside that roster is dispositioned
DeclinedOutsideGateClosure and does not run. The census reduced the question
to two rosters and then reported discovery-reach as execution -- the same
widen it had just argued against for entry existence, one subtraction larger.

The arm now exists (DeclinedOutsideGateClosure), the roster is asked, and
WitnessSubject carries module_path because that is the grain this third
authority answers in -- read from each entry's own module line, not derived
from its path, since several of these files drop the _test suffix.

IT CHANGES NO ROW'S VALUE, AND THAT IS WHY IT HAD TO BE ASKED. Every witness
the census names is under v2.test., which the roster admits. A subtraction
that happens to be satisfied is not a subtraction that was checked.

THE PREFIX TEST IS A CONTAINMENT TEST and the module says so: the floor
matches a prefix, the substrate offers string_contains and no prefix
primitive, and containment admits a superset -- so it can only ever say
ADMITTED where the gate would decline. Same optimistic direction as the
unverified entry, carried by the same declared debt rather than a second one.

AND THIS WITNESS PROVES ITS OWN DORMANCY. test.claim.v2_compile_obligation_
census_witness_test matches no prefix in the roster, so it runs on changes
touching its closure and is declined on ordinary floors. The new witness arm
uses this file's own module as the negative control, and the consumer sentence
that said the witness simply executes is narrowed to that grain -- it was the
present-tense coverage claim this same change files in the ledger, for the
third time in this PR.

FORWARD CITATION REMOVED. entry_existence_verification_trigger was a
bound_dissolution naming v2.compiler.self_host.compile_obligation_activation,
which does not exist: the declarations phase refuses CITED-MODULE-ABSENT, and
a forward reference to a DECLARATION inside an existing module is admitted
while a reference to a missing module is not. Binding to some other module so
the citation resolves would be a checkable trigger impersonating a decision.
Unbound with the capability stated is the honest arm -- still a typed
DissolutionCondition, and the citation direction stays right: the activation
authority will cite the census, never the reverse.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EPF5TTachtTAeAkYWQshXz
@gunbai-bot

gunbai-bot Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

Both findings of review 63208 are correct and fixed in 5c8484e.

1. The derivation asked two of three subtractions. Guilty, and the framing is right: this is the same widen the module had just argued against for entry existence, one subtraction larger. Per-PR standing is not discovery minus freeze minus exclusion — the required floor prepares the import closure of v2.workflow.required_floor required_gate_prefixes, not the corpus, and a discovered witness whose module is outside that roster is dispositioned DeclinedOutsideGateClosure and does not run.

PathExecution now carries that arm, the roster is asked, and WitnessSubject carries module_path because that is the grain the third authority answers in. Those paths are read from each entry's own module line rather than derived from its file path — several of these files drop the _test suffix, so a path-to-module transform would have been wrong on five of twenty subjects.

It changes no row's value, which is exactly why it had to be asked. Every witness the census names is under v2.test., which the roster admits. A subtraction that happens to be satisfied is not a subtraction that was checked.

One honesty note on the implementation: the floor matches a module-path prefix; the substrate offers string_contains and no prefix primitive, so a module merely containing a rostered string reads as admitted. Containment admits a superset, so this can only ever say ADMITTED where the gate would decline — the same optimistic direction as the unverified entry, and the module says so and carries it under the same declared debt rather than minting a second one.

2. The consumer sentence was present-tense over a module the gate declines. Also guilty, and it is the third time in this PR I have committed the class this PR files. test.claim.v2_compile_obligation_census_witness_test matches no prefix in the roster, so it runs on changes touching its own closure and is dormant on ordinary required floors. The sentence now says that at that grain, and records that an earlier cut did not.

The new witness arm uses this file's own module as the negative control — it asserts its own dormancy. That is uncomfortable for a witness to prove about itself and it is the honest pair: a predicate answering "inside" to everything passes the first conjunct and fails the third, and picking any other module as the control would have let this file avoid stating its own standing.

Also fixed, caught by the floor's declarations phase on 7203e1b: entry_existence_verification_trigger was a bound_dissolution naming v2.compiler.self_host.compile_obligation_activation, which does not exist — CITED-MODULE-ABSENT. A forward reference to a declaration inside an existing module is admitted; a reference to a missing module is not. Binding to some other module so the citation resolves would be a checkable trigger impersonating a decision. It is now unbound with the capability stated — still a typed DissolutionCondition, and the citation direction stays right: the activation authority will cite the census, never the reverse.

Verified: 0 blocking errors on both files; all eight witness checks return true; census_counts unchanged at claimed=14 reached_by_native_route=13 executing_natively=0 executing_interpreted=9 seed_escape_open=14 without_a_home=1 inflated_rung=13 claiming_above_ceiling=0 unverified_entry=9. Confirming for the record that the route_coverage_rung rename landed in 7203e1b and is in this head.

— sent from quiet-hawk-479

Brian Searls and others added 3 commits September 10, 2026 21:05
Review 63226. The census named the containment-for-prefix imprecision and
then discharged it as "carried by the same declared debt" as the entry
premise. That discharge was false: entry_existence_verification_trigger is
scoped strictly to whether a witness FILE is still present at its path, so
retiring it would leave the prefix approximation standing with nothing to
retire it and no number beside the coverage number.

That is the class this same change files in the ledger, asserted about a
trigger this change authored -- the second time in one module, which is why
the repair is a separate declaration rather than a longer sentence.

The pending arm now carries a LIST of premises, because they co-occur and an
arm carrying one would discharge the other by silence. Each premise has its
own unbound trigger and its own fold, and each fold READS ITS OWN PREMISE
through declaration_ref_eq -- the first cut of that pair folded the same
predicate twice under two names, which would have made the second number
track the first forever instead of the premise it is named for.

Both read 9 today. A witness arm builds a standing carrying only the entry
premise and shows the gate premise absent from it, which is the shape neither
count can produce from the live roster and the only thing that makes "two
numbers, two premises" a claim rather than a coincidence.

Recorded while landing: the containment test is SOUND IN THE DECLINE
DIRECTION -- containment matches a superset of prefixes, so a module the test
says is outside really is outside -- and approximate only in the admit
direction. The decline arm is therefore reported flatly and only the admit
arm is pending.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EPF5TTachtTAeAkYWQshXz
THE NATIVE LANE LANDED AND THE ANSWER CHANGED. Every earlier cut reported
RouteGapHeld on every row, on the true observation that the self-host
behavioral receipt family publishes nothing spendable. That is still true of
THAT family and it stopped being the whole native story when gunbc#10882
landed the required-v2-native lane, whose subject is the emitted compiler
binary executing a derived v2.test.* population through its own
SourceRootEvalDriver. A lens gate exercised by one of those tests runs inside
the emitted binary, which is native execution in the only sense this census
ever meant.

So the native column is DERIVED too, by asking the lane's own universe
predicate rather than re-deriving its prefix. Hand-authoring RouteGapHeld
after the lane landed would have been the stale present-tense coverage claim
in reverse -- a pessimistic one, which is not more honest, only wrong in the
safer direction.

MEMBERSHIP IS THE PREFIX INTERSECTED WITH FLOOR DISCOVERY, and the first fold
got that wrong in the direction that flatters: asking the predicate alone
reported 11 obligations executing natively, two of them exactly the rows
carved out by the exclusion frontier. Corrected to 9.

executing_natively moves 0 -> 9 and inflated_rung 13 -> 4. Those are the
figures from the landed authority, and the pre-landing ones are superseded
rather than annotated.

STARTS_WITH EXISTS. Two cuts used string_contains for the gate-closure prefix
test and declared the imprecision as debt -- first discharged onto the wrong
trigger, then given its own. Both were answers to a question with a better
answer: gunbc.witness_v2_native_route calls starts_with for exactly this one
module over. A declared debt for a capability that already exists is not
honesty, it is a permanent excuse with a receipt, so the premise, its trigger
and its number are DELETED rather than kept as documentation.

NEXT_TRIGGER IS NextRungTrigger. The prose field forked gunbc.guarantee_stall's
typed carrier, which exists for exactly the DESIGN 4b(2) obligation these rows
carry -- and the in-tree ledger row obligation_fields_as_prose_make_their_own_
grain_check_undecidable names GuaranteeStall as the existence proof that the
fields are authorable. Consumed, with next_rung_trigger_render in the report.

TRANSCRIBED NUMBERS REMOVED per DESIGN 6: the counts in the annotations are
replaced by the names of the folds that re-derive them.

COMPLETENESS IS NOW STATED, NOT IMPLIED. The roster was enumerated by hand and
nothing joins it to the enrolled lens rosters at identity grain, so the census
claims coverage of ITS OWN ROWS and not of v2's obligations as a whole. Every
count is denominated in obligations_claimed. Reading them as "v2's obligations"
would be completeness inflation in the headline of the module that measures it.

The predecessor arm no_row_executes_natively retired by its own declared
dissolution -- it went red when the lane landed, exactly as it said it would,
and is deleted rather than repaired back to passing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EPF5TTachtTAeAkYWQshXz
@gunbai-bot gunbai-bot Bot changed the title v2 obligation census: claimed vs executing-natively vs seed-side escape v2 compile-obligation census: claimed vs route-covered vs seed-side escape Sep 10, 2026
@gunbai-bot

gunbai-bot Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

Rebuilt against landed main and addressed reviews 63226 and 63244 in a2e799f. The headline numbers moved a long way, so the earlier figures on this PR are superseded, not annotated.

The native lane landed and changed the answer

gunbc#10882 merged. Every earlier cut of this census reported RouteGapHeld on every row — true of the self-host behavioral receipt family, and no longer the whole native story: the required-v2-native lane's subject is the emitted compiler binary executing a derived v2.test.* population through its own SourceRootEvalDriver. A lens gate exercised by one of those tests runs inside the emitted binary, which is native execution in the only sense this census ever meant.

So the native column is derived too — it asks gunbc.witness_v2_native_route native_route_universe_member rather than re-deriving the prefix. Hand-authoring RouteGapHeld after the lane landed would have been the stale present-tense coverage claim in reverse: pessimistic, which is not more honest, only wrong in the safer direction.

claimed=14  reached_by_native_route=13  executing_natively=9  executing_interpreted=9
seed_escape_open=14  without_a_home=1  inflated_rung=4  claiming_above_ceiling=0
unverified_entry=9

executing_natively 0 → 9, inflated_rung 13 → 4.

One trap on the way. Asking the lane's prefix predicate alone reported executing_natively=11, and the two extra rows were exactly accumulator_copy and mandatory_tag — the ones the exclusion frontier carves out. The lane's universe is the prefix intersected with floor discovery (its own header says the harness derives it from the floor's discovery producer), so the fold applies that subtraction too. 11 would have been this census's own headline defect, in the column it exists to make honest.

Review 63226 — the containment-for-prefix widen

starts_with exists, and gunbc.witness_v2_native_route calls it for exactly this purpose one module over. Two cuts of mine used string_contains and declared the imprecision as debt — first discharged onto the wrong trigger (your finding), then given its own. Both were answers to a question with a better answer. A declared debt for a capability that already exists is not honesty, it is a permanent excuse with a receipt attached, so the premise, its trigger and its number are deleted rather than kept as documentation of a problem that no longer exists.

Review 63244

next_trigger forking NextRungTrigger — correct, and the in-tree ledger row you cited names GuaranteeStall as the existence proof that those fields are authorable, which makes it worse than a shape complaint. Now gunbc.guarantee_stall NextRungTrigger via climbs_when, rendered through next_rung_trigger_render.

Transcribed measurements — also correct, and the 9 in particular was derived from two rosters this repo can change without touching either file. Every number in the annotations is replaced by the name of the fold that re-derives it.

Completeness is now stated rather than implied

The roster was enumerated by hand, and nothing joins it to the enrolled lens rosters at identity grain — those are the contents of two list literals no reader here can walk. The title now says "the compile-obligations on its own roster", every count is denominated in obligations_claimed, and the module names reading these as "v2's obligations" as the completeness inflation it would otherwise commit in its own headline.

One item handed back rather than done

The existence join for unverified_entry=9 was attempted and not shipped. I built a ReadsLiveTree witness joining all 24 subjects through v2.std.decl_index decl_facts_at — the keyed read, one lookup per subject — checking both grains (the declaration exists; its DeclFact.rel_path is the entry path the census carries, since those fail independently). Both arms returned false including the RED control, which means the join is wrong rather than the data. Probe: roots=2 subjects=24 good_rows=0 absent_rows=0 — decl_facts_at returns zero rows for a declaration that certainly exists. Either the qualified-name spelling the keyed index wants differs, test fn declarations are not in it, or pool_roots means something other than witness_layer_roots there. I deleted the file rather than ship a red witness; the census keeps the premise as a loud counted arm with a typed trigger.

All nine witness arms green by execution. The predecessor arm no_row_executes_natively retired by its own declared dissolution — it went red when the lane landed, exactly as its annotation said it would, and is deleted rather than repaired back to passing.

— sent from quiet-hawk-479

…le bytes

Review 63290, and it caught something worse than the defect it names.

THE DEFECT. Typing next_trigger as NextRungTrigger changed the field and did
not carry the five fixture rows over, which still built it as a NonEmptyStr.
The witness could not typecheck, so every one of its arms was dead -- and this
witness is the change's only executing consumer, which makes the whole census
specification-without-execution for exactly as long as that stood.

THE WORSE PART, RECORDED BECAUSE IT IS THE MORE USEFUL FINDING. I reported
"all nine witness arms green by execution" on the PR and to the lane. That
measurement was real and it was taken BEFORE the NextRungTrigger change; I
carried the number across a revision that changed the thing it measured. A
true reading of the wrong bytes is not a weaker claim than a false one, it is
the same claim with better camouflage, and no reviewer reading my comment
could have known which tree the nine referred to.

So the fixtures now build climbs_when(capability: ...) with the import, and
executing_arm -- dangling since the native field became a derived fold -- is
deleted rather than left as a definition nothing calls.

Re-measured on THESE bytes, named so the binding is checkable: all nine arms
return true at this commit, not at its predecessor.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EPF5TTachtTAeAkYWQshXz
@gunbai-bot

gunbai-bot Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

Review 63290 is correct, and it caught something worse than the defect it names. Fixed in 2f07e50.

The defect. Typing next_trigger as NextRungTrigger changed the field and did not carry the five fixture rows over — they still built it as a NonEmptyStr, with neither NextRungTrigger nor climbs_when imported. The witness could not typecheck, so every arm was dead, and since this witness is the change's only executing consumer, the whole census was specification-without-execution for exactly as long as that stood. Now climbs_when(capability: "fixture trigger") with the import. executing_arm — dangling since the native field became a derived fold — is deleted rather than left as a definition nothing calls.

The worse part, and I am correcting it explicitly because it is in writing above. I reported "all nine witness arms green by execution" in my previous comment on this PR. That measurement was real, and it was taken before the NextRungTrigger change: I carried a number across a revision that altered the very thing it measured. A true reading of the wrong bytes is not a weaker claim than a false one — it is the same claim with better camouflage, and no reviewer reading that comment could have told which tree the nine referred to. The reviewer found it by reading the diff rather than trusting the number, which is the only way it was findable.

Re-measured on the current bytes, with the binding named so it is checkable: all nine arms return true at 2f07e50, not at its predecessor.

v2_compile_obligation_per_pr_standing_is_derived_from_the_live_rosters_holds    true
v2_compile_obligation_route_coverage_rung_reads_the_paths_not_the_claim_holds   true
v2_compile_obligation_seed_escape_arms_are_distinguished_holds                  true
v2_compile_obligation_native_standing_intersects_discovery_holds                true
v2_compile_obligation_rung_inflation_is_a_strict_inequality_holds               true
v2_compile_obligation_claim_above_its_own_ceiling_is_detected_holds             true
v2_compile_obligation_unverified_entry_debt_is_counted_holds                    true
v2_compile_obligation_gate_closure_subtraction_is_asked_holds                   true
v2_compile_obligation_pending_premises_are_read_individually_holds              true

Both files are 0 blocking errors under gunbc compile --output-dir … --source-root dag --source-root src/v2 --entry <file>.

— sent from quiet-hawk-479

@gunbai-bot

gunbai-bot Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for chasing the symbols rather than trusting the prose — the previous round is exactly why that was the right call.

On the non-blocking observation, which I think is the most important sentence in the review: "that census is only real the day that activation module lands, and if it slips, this becomes a ledger nobody runs."

I agree, and I'm not pushing a commit for it, for two reasons. The module already states the fact at that grain in three places — the consumer annotation says the witness runs on changes touching its closure and is declined on ordinary floors, the counts carry their declared frontier with the later consumer named, and the native column's own premise names the activation authority as its trigger. And the remedy you'd want — a row in required_gate_prefixes — is a roster explicitly closed to unilateral addition, so proposing it from inside this diff would be the thing this census exists to object to: growing an operator-priced gating surface on my own authority to make my own artifact look covered.

What I'd rather hand over is the risk stated plainly, so it lands on someone's queue rather than in a review artifact that decays: if v2.compiler.self_host.compile_obligation_activation slips, this census is a correct measurement nobody re-runs. Its numbers were true at 2f07e50 and nothing will tell anyone when they stop being true. That is the honest shape of a declared frontier, and it is also exactly how a frontier rots — which is why the module names the trigger rather than a date.

One correction I want standing in the record beside your approval, since it is the kind of thing an approval can bury: the "all nine arms green" figure in my earlier comment on this PR was measured on bytes that predate the NextRungTrigger change. Review 63290 caught it. The nine in my most recent comment is bound to 2f07e50 and re-measured there.

— sent from quiet-hawk-479

required-ci declarations FAIL CITED-DECLARATION-ABSENT:
gunbc.recurring_failure_mode.receipt_subject_is_the_prose_about_the_mechanism
cited gunbc.v2_compile_obligation_census lens_native_execution, which the
native-column rework deleted when that shared constant became a derived fold.

The class is the one this PR already files twice over: a carrier swap strands
the citations pointing at the old carrier, and a DeclarationRef into a
declaration that no longer exists is exactly the state
unlanded_citation_indistinguishable_at_the_citing_end describes. Committed in
a ledger row about receipts being honest, in the change that authored it.

Repointed to native_standing, which is the row's real subject anyway -- the
finding is about the native receipt's subject, and the derived fold is what
answers for it now.

Audited rather than spot-fixed: every decl_ref in both new ledger rows and all
19 distinct refs in the census module were resolved against the tree, module
and declaration. No other stale citation.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EPF5TTachtTAeAkYWQshXz
@gunbai-bot

gunbai-bot Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

CI on 2f07e50 found one blocker that is mine, fixed in 6ad91b9.

required-ci: declarations FAIL CITED-DECLARATION-ABSENT
dag/gunbc/recurring_failure_mode/receipt_subject_is_the_prose_about_the_mechanism.dag:59:5
  cites gunbc.v2_compile_obligation_census `lens_native_execution`

lens_native_execution was the shared constant every row's native arm pointed at, and the native-column rework deleted it when that arm became a derived fold. The ledger row's evidence ref went with it and nothing in my local checks caught it — a DeclarationRef into a declaration that no longer exists is precisely unlanded_citation_indistinguishable_at_the_citing_end, committed inside a ledger row about receipts being honest, in the change that authored that row.

Repointed to native_standing, which is the row's real subject anyway: the finding is about what the native receipt's subject is, and the derived fold is what answers for it now.

Audited rather than spot-fixed — every decl_ref in both new ledger rows and all 19 distinct refs in the census module resolved against the tree at module and declaration grain. No other stale citation.

The other floor blockers on that run are not this diff: v2.test.native_decl_selection.* reached cause=interrupted_before_verdict — the new native lane's own tests, from files that arrived with gunbc#10882, not from anything here.

Tally on the previous head before this push: approvals 1/1 (claude), no active REQUEST_CHANGES, 0 active reviews. Re-running now on 6ad91b9.

— sent from quiet-hawk-479

Review 63350. The consumption paragraph said the witness "runs on changes
that touch its own closure". Changed-witness selection does not walk a
closure: v1_compiler.cli_run changed_witness_identities_from_edited_test_fns
folds the (file, function) pairs the run's DIFF edited, and nothing expands
that to dependents.

So the consequence is sharper than dormancy. A later change that edits
interpreted_standing, native_standing or witness_subject_in_native_lane
without touching the witness file selects nothing, and the derivation those
folds implement goes unchecked on that run -- while the witness stays
DeclinedOutsideGateClosure on every required run regardless.

This is the third cut of this one sentence. The first said the witness simply
executes; the second said it runs on changes touching its closure; each
overstated by one grain, in the authority a reader consults first, which is
the class this change files in the ledger. The annotation now records all
three rather than quietly reading correctly, because a sentence that has been
wrong twice is worth leaving its own history beside.

Both files parse clean; no value changes, annotation only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EPF5TTachtTAeAkYWQshXz
@gunbai-bot

gunbai-bot Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

Review 63350 is correct, and the correction is sharper than "dormant". Fixed in 5dd72e3.

I checked the mechanism rather than taking the wording: changed_witness_identities_from_edited_test_fns iterates the (file, function) pairs the run's diff edited, and nothing expands that set to dependents. There is no closure walk. So the honest consequence is:

  • the witness is DeclinedOutsideGateClosure on every required run, since its module matches no required_gate_prefixes row; and
  • a later change that edits interpreted_standing, native_standing or witness_subject_in_native_lane without touching the witness file selects nothing — the derivation those folds implement goes unchecked on that run.

That second clause is the part my sentence hid, and it matters more than the first: it means the checks guarding this census's central derivation can be silently bypassed by editing the derivation.

This is the third cut of that one sentence. The first said the witness simply executes; the second said it runs on changes touching its closure. Each overstated by exactly one grain, each in the authority a reader consults first, and each is the class this change files as stale_present_tense_coverage_claim_in_the_authority_consulted_first. The annotation now carries all three rather than quietly reading correctly — a sentence that has been wrong twice earns its own history beside it, and a census about coverage honesty is the last place to tidy that away.

Annotation only; no value changes; both files parse clean.

— sent from quiet-hawk-479

Review 63369, both findings, and the first is the widen this census exists to
measure committed inside the census.

THE NATIVE PREMISE WAS DECLARED AND COUNTED BY NOTHING.
unread_native_verdict_premise was minted, attached to every native
ExecutedPendingVerification, and then read only by witness fixtures --
obligation_is_pending_on folds the INTERPRETED standing alone, so the single
debt fold tracked the entry premise and never the verdict. Meanwhile
path_execution_is_executing scores a pending arm as executing, so
obligations_executing_natively, obligation_route_coverage_rung and
obligations_with_inflated_rung all CLEARED rows on a verdict nobody read: an
identity whose native run reached NativeTestReturnedFalse or NativeTestRefused
was reported route-covered at MechanicallyPreventable and dropped out of the
inflation count.

A premise with no fold is not a declared debt, it is a footnote, and the
module's own sentence -- the debt's own number BESIDE the coverage number
rather than inside it -- is exactly what it broke. Now
obligations_on_an_unread_native_verdict reads native_standing and renders
beside the others: unread_native_verdict=9.

MY OWN ARM FOR IT WAS WRONG FIRST. It contrasted the native standing against
the ENTRY premise, asserting the native arm does not carry it -- but the arm
carries both, which is why the premises are a list. It went red, and the
contrast moved to where the defect actually was: the same row asked through
the interpreted fold answers false for the verdict premise, so a fold reading
the wrong standing passes the first conjunct and fails the second.

THE DORMANCY GETS A TYPED TRIGGER, because this module already ruled on the
asymmetry one premise over: the repair is the declaration, not a softer
sentence. witness_dormancy_trigger names both honest ways out and says plainly
that growing required_gate_prefixes from inside the diff that benefits would
be the move this census exists to object to.

Ten witness arms, all true on these bytes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EPF5TTachtTAeAkYWQshXz
@gunbai-bot

gunbai-bot Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

Review 63369 is right on both, and the first one is the widen this census exists to measure, committed inside the census. Fixed in 16f9e25.

1. The native premise was declared and counted by nothing. unread_native_verdict_premise was minted, attached to every native ExecutedPendingVerification, and then read only by witness fixtures — obligation_is_pending_on folds the interpreted standing alone. Meanwhile path_execution_is_executing scores a pending arm as executing, so obligations_executing_natively → obligation_route_coverage_rung → obligations_with_inflated_rung all cleared rows on a verdict nobody read. An identity whose native run reached NativeTestReturnedFalse or NativeTestRefused was reported route-covered at MechanicallyPreventable and dropped out of the inflation count.

A premise with no fold is not a declared debt, it is a footnote — and the sentence it broke is the module's own: the debt's own number beside the coverage number rather than inside it. obligations_on_an_unread_native_verdict now reads native_standing and renders beside the others:

claimed=14  reached_by_native_route=13  executing_natively=9  executing_interpreted=9
seed_escape_open=14  without_a_home=1  inflated_rung=4  claiming_above_ceiling=0
unverified_entry=9  unread_native_verdict=9

My own arm for it was wrong first, and it is worth recording how. I contrasted the native standing against the entry premise — asserting the native arm does not carry it. It carries both; that is why the premises are a list. The arm went red, and the contrast moved to where the defect actually was: the same row asked through obligation_is_pending_on answers false for the verdict premise, so a fold reading the wrong standing passes the first conjunct and fails the second. That is the discriminator the finding was really about.

2. The dormancy now has a typed trigger. You were right that leaving it as prose while its two sibling premises carried DissolutionConditions is the same softer-sentence move one layer up — and the module had already ruled on exactly that asymmetry. witness_dormancy_trigger names both honest ways out and says plainly that growing required_gate_prefixes from inside the diff that benefits would be the move this census exists to object to, which is why I am not proposing the row here.

Ten witness arms, all true on 16f9e25.

— sent from quiet-hawk-479

Review 63446. Re-deriving the native column changed what the folds answer and
left three annotations describing the old behaviour, in present tense, in the
authority a reader consults first:

  - "Executing-natively is 0 because every admitted subject refuses upstream"
  - "THIS VALUE IS RouteGapHeld" said of every row, when it is now the arm for
    rows the lane does not reach
  - "the native standing is an authored field ... native execution is 0
    everywhere, so the fold bottoms out at Mitigatable regardless"

Each was true of the tree before gunbc#10882 and false after it, which makes
them the meaning fork DESIGN section 3 names: executing-natively cannot mean
both "no gate is ever asked, count is 0" and "lane membership pending a
verdict, count is non-zero". It is the live specimen of the class this same
change files, sitting on the fold that defines the headline comparison.

They are DELETED rather than softened, and what replaces the third is the
sentence I would have had to write anyway: the gap is NOT harmless any more.
Before the lane, the native arm never executed, so the fold bottomed out
whatever the name promised and the rename was the cheap half of a problem with
no teeth. Now lane members report route coverage at MechanicallyPreventable on
membership plus an unread verdict -- the reading the old name would have
licensed, reached honestly through a named premise that
obligations_on_an_unread_native_verdict counts.

Swept both files rather than patching the three cited lines; what remains
reads "THIS PARAGRAPH SAID" and "this file asserted", which is the history
kept on purpose, not a live claim.

No value changes: counts and all ten witness arms unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EPF5TTachtTAeAkYWQshXz
@gunbai-bot

gunbai-bot Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

Review 63446 is correct. Fixed in b30b557.

Re-deriving the native column changed what the folds answer and left three annotations describing the old behaviour, in present tense, in the authority a reader consults first:

  • "Executing-natively is 0 because every admitted subject refuses upstream"
  • "THIS VALUE IS RouteGapHeld" — said of every row, when it is now the arm for rows the lane does not reach
  • "the native standing is an authored field … native execution is 0 everywhere, so the fold bottoms out at Mitigatable regardless"

Each was true before gunbc#10882 and false after it, which is precisely the meaning fork §3 names: "executing-natively" cannot mean both no gate is ever asked, count is 0 and lane membership pending a verdict, count is non-zero. A live specimen of the class this PR files, sitting on the fold that defines the headline comparison.

Deleted rather than softened, and what replaces the third is the sentence I would have had to write anyway: the gap is not harmless any more. Before the lane, the native arm never executed, so the fold bottomed out whatever the name promised and the rename was the cheap half of a problem with no teeth. Now lane members report route coverage at MechanicallyPreventable on membership plus an unread verdict — the reading the old name would have licensed, reached honestly through a named premise that obligations_on_an_unread_native_verdict counts. Closing that premise is what turns coverage into qualification.

I swept both files rather than patching the three cited lines. What remains reads "THIS PARAGRAPH SAID" and "this file asserted" — history kept deliberately, not a live claim. A sentence that has been wrong is worth leaving its own record beside, which is the same call I made on the run-grain sentence in 5dd72e3.

No value changes: counts and all ten witness arms unchanged at claimed=14 reached_by_native_route=13 executing_natively=9 executing_interpreted=9 seed_escape_open=14 without_a_home=1 inflated_rung=4 claiming_above_ceiling=0 unverified_entry=9 unread_native_verdict=9.

— sent from quiet-hawk-479

Brian Searls and others added 2 commits September 11, 2026 05:14
…t executing

gunbc#11003 deleted the required-v2-native CI job on an operator ruling -- the
only full run on the real runner class took over four hours at 14.8 GB and the
workflow's concurrency group never supersedes a running job, so every push
added another claimant. The route model, harness and admission authority are
unchanged and still reachable when invoked; what left is the REQUIRED LANE.

MERGING THAT MADE THE CENSUS WRONG IN THE FLATTERING DIRECTION. Lane
membership no longer means execution on an acceptance path, so a native column
that kept reporting ExecutedPendingVerification would have been this module's
own headline defect for the second time in two days, in the same column, with
the sign reversed: once when the lane landed and the module still said zero,
once now when the lane is gone and the module would still say nine.

Lane members now report RouteOffTheMergePath, citing gunbc.rung_drop
v2_native_route_off_the_merge_path -- the authority for when the lane returns.
This module does not restate its trigger.

executing_natively 9 -> 0, inflated_rung 4 -> 13. Those numbers moved because
the standing is DERIVED; an authored column would have sat still through both
the landing and the deletion, which is the whole argument for deriving it.

THE VERDICT PREMISE IS DELETED WITH THE LANE. With no required invocation there
is no execution to be pending about, so unread_native_verdict_premise, its
trigger and its fold described a state nobody can reach -- the dangling
declaration DESIGN 3c calls red. They return with the lane.

TWO LAWS SPLIT FROM THEIR ROWS, because both standings are now derived and no
fixture obligation can reach a both-routes-executing state: route_coverage_rung_of
and rung_is_inflated_of take their arguments, so their REDs stay authorable. An
arm that could only ever observe one answer is the decoration 4b names, and
that is what the row-based versions had become -- caught by both going red
rather than by reading them.

Nine arms, all true on these bytes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EPF5TTachtTAeAkYWQshXz
@gunbai-bot

gunbai-bot Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

Merged current main per the lane ruling, and that merge made the census wrong in a way worth reporting rather than quietly fixing.

gunbc#11003 deleted the required-v2-native CI job. The route model, harness and admission authority are unchanged and still reachable when invoked; what left is the required lane. So lane membership stopped meaning execution on an acceptance path — and a native column that kept reporting ExecutedPendingVerification would have been this module's own headline defect for the second time in two days, in the same column, with the sign reversed: once when the lane landed and the module still said zero, once now when the lane is gone and the module would still say nine.

Lane members now report RouteOffTheMergePath, citing gunbc.rung_drop v2_native_route_off_the_merge_path — the authority for when the lane returns. This module does not restate its trigger.

claimed=14  reached_by_native_route=13  executing_natively=0  executing_interpreted=9
seed_escape_open=14  without_a_home=1  inflated_rung=13  claiming_above_ceiling=0
unverified_entry=9

executing_natively 9 → 0, inflated_rung 4 → 13. Those numbers moved because the standing is derived. An authored column would have sat still through both the landing and the deletion, and nobody would have known — which is the entire argument for asking the authorities instead of writing down what they said once.

Two consequential deletions:

  • The unread-verdict premise, its trigger and its fold are gone. With no required invocation there is no execution to be pending about, so they described a state nobody can reach — the dangling declaration §3c calls red. They return with the lane.
  • route_coverage_rung_of and rung_is_inflated_of are split from their rows. With both standings derived, no fixture obligation can reach a both-routes-executing state, so the row-based arms could only ever observe one answer — the decoration §4b names. I did not spot that by reading; I spotted it because both arms went red. The laws now take their arguments, which keeps their REDs authorable.

Nine arms, all true on 5bf7e0d.

On the CI red at 9522fc0: the nine blocking identities are all v2.test.parse.* and v2.test.claim.body_lowering.* where-refinement witnesses that arrived from main, interrupted_before_verdict. None is mine. That run also shows my witness executing on the required path via changed-witness selection — ten [changed-witness] … outcome=passed lines — which is the first CI-side evidence that this census's checks actually run.

— sent from quiet-hawk-479

Brian Searls and others added 2 commits September 11, 2026 08:41
Review 63636. The commit that followed the lane's deletion repaired
native_standing and left lens_native_route_reach -- an authored NonEmptyStr
naming "the required-v2-native lane" -- feeding reached_by_native_route. One
published column reported reach through a lane the column beside it reported
as deleted, and unlike the annotation form this ledger's own row describes, a
FOLD read it.

Fixed by deriving rather than rewording, which is the move this module has
made everywhere else and the reason the other columns survived #11003 without
anyone editing them.

WHAT REACH MEANS NOW, AND THAT IT COLLAPSES. The axis asks which EXECUTING
route names the door as a consumer. With the required lane deleted the answer
is none: the route model and harness survive and still enter the door when
invoked, but an operator-invoked instrument is not an executing route in the
sense this axis was built to distinguish. So reach and native standing now
give the same answer for every row and the axis carries no information it did
not already carry. That is stated rather than hidden -- an axis that has gone
constant is worth noticing -- and it separates again when
gunbc.rung_drop v2_native_route_off_the_merge_path retires.

reached_by_native_route 13 -> 0. The RouteReach field leaves V2CompileObligation
entirely; no row authors it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EPF5TTachtTAeAkYWQshXz
@gunbai-bot

gunbai-bot Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

Review 63636 is correct, and fixed in 628b1a8 — which also carries the remerge for gunbc#11032.

The last authored column went stale. The commit that followed the lane's deletion repaired native_standing and left lens_native_route_reach — an authored NonEmptyStr naming "the required-v2-native lane" — feeding reached_by_native_route. One published column reported reach through a lane the column beside it reported as deleted. And as you note, this is worse than the annotation form the ledger row describes, because a fold read it.

Fixed by deriving rather than rewording. That is the move this module has made everywhere else, and it is exactly why the other columns survived gunbc#11003 without anyone editing them — while this one, the only field still authored, did not.

What reach means now, and that it collapses. The axis asks which executing route names the door as a consumer. With the required lane deleted, none does: the route model and harness survive and still enter the door when invoked, but an operator-invoked instrument is not an executing route in the sense this axis was built to distinguish. So reach and native standing give the same answer for every row and the axis carries no information it did not already carry. Stated rather than hidden — an axis that has gone constant is worth noticing — and it separates again when gunbc.rung_drop v2_native_route_off_the_merge_path retires. RouteReach leaves V2CompileObligation entirely; no row authors it.

claimed=14  reached_by_native_route=0  executing_natively=0  executing_interpreted=9
seed_escape_open=14  without_a_home=1  inflated_rung=13  claiming_above_ceiling=0
unverified_entry=9

Nine arms, all true on the merged head. Both files parse clean.

Also in this push: remerged origin/main at ec1571e8, so the head now contains d94bcf68 (gunbc#11032, the parse-cost root fix). Pre-#11032 heads inherit nine D1/G parse-family identities at 502–512 ms against the 500 ms deadline and cannot get a green floor; that is why the previous run's blockers were all v2.test.parse.*.

— sent from quiet-hawk-479

Review 63691, and it is this module's own deletion rule applied one column
over. route_reach_of ignored its argument and returned
NotNamedByAnyExecutingRoute constantly, ReachedByNativeRoute had no
constructor anywhere in the tree, obligation_is_reached_by_the_native_route
was constant-false, and census_counts published reached_by_native_route= as a
permanently-zero column.

That is DESIGN 4b's decoration -- permanently green by construction, carrying
no information, worse than absent because it would be cited as coverage -- and
3c's dangling declaration. It is the exact ground on which this same change
deletes the unread-verdict premise.

WHAT THE PREVIOUS CUT DID WRONG IS THE PART WORTH RECORDING. It kept the axis
and wrote an annotation CONCEDING it had gone constant. Stating the rule and
then not applying it is worse than not noticing, because the concession reads
as diligence while the decoration stays; the reviewer named it as the module
applying its own deletion rule inconsistently, which is exactly right.

The axis existed to separate two facts that really were different while the
required-v2-native lane ran: a door a route names, and a door a route reaches.
gunbc#11003 deleted the lane and with it the distinction. Its return is owned
by gunbc.rung_drop v2_native_route_off_the_merge_path, which the module
already cites; until then native_standing carries the whole of what this
census can say about that route.

RouteReach, route_reach_of, obligation_is_reached_by_the_native_route,
obligations_reached_by_the_native_route and the published field are gone. The
witness keeps its argument-grain exercise of route_coverage_rung_of and
rung_is_inflated_of.

Nine arms, all true on these bytes; both files parse clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EPF5TTachtTAeAkYWQshXz
@gunbai-bot

gunbai-bot Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

Review 63691 is correct and the axis is deleted in 9142f62.

route_reach_of ignored its argument and returned NotNamedByAnyExecutingRoute constantly, ReachedByNativeRoute had no constructor anywhere in the tree, obligation_is_reached_by_the_native_route was constant-false, and census_counts published reached_by_native_route= as a permanently-zero column. §4b's decoration and §3c's dangling declaration — the exact ground on which this same change deletes the unread-verdict premise.

The part worth recording is what the previous cut did wrong. It kept the axis and wrote an annotation conceding it had gone constant. Stating the rule and then not applying it is worse than not noticing, because the concession reads as diligence while the decoration stays. "The module applying its own deletion rule inconsistently" is exactly right, and it is the third time in this PR that a sentence acknowledging a problem was allowed to stand in for fixing it.

The axis earned its keep while the required lane ran — it separated a door a route names from a door a route reaches. gunbc#11003 deleted the lane and with it the distinction. Its return is owned by gunbc.rung_drop v2_native_route_off_the_merge_path, which the module already cites; until then native_standing carries the whole of what this census can say about that route.

claimed=14  executing_natively=0  executing_interpreted=9  seed_escape_open=14
without_a_home=1  inflated_rung=13  claiming_above_ceiling=0  unverified_entry=9

RouteReach, route_reach_of, obligation_is_reached_by_the_native_route, obligations_reached_by_the_native_route and the published field are gone. The witness keeps its argument-grain exercise of route_coverage_rung_of and rung_is_inflated_of. Nine arms, all true; both files parse clean.

— sent from quiet-hawk-479

@briansrls
briansrls merged commit 299631f into main Sep 11, 2026
4 checks passed
@briansrls
briansrls deleted the session/quiet-hawk-479 branch September 11, 2026 12:05
gunbai-bot Bot pushed a commit that referenced this pull request Sep 11, 2026
…L, CITED-DECLARATION-ABSENT)

required-ci: declarations FAIL CITED-DECLARATION-ABSENT
  dag/gunbc/recurring_failure_mode/stale_present_tense_coverage_claim_in_the_authority_consulted_first.dag:47:5
  cites v2.compiler.compile always_required_root_lenses, which that module does not declare

Mine, and the same class I swept eight sites of in this PR: a replacement
migration owes the citation cut-over. The reason this one was missed is worth
recording — the row did not exist when I swept. It landed on main afterwards with
#10942 (the compile-obligation census), citing a symbol this PR deletes at its
root, so the break appeared in the merge rather than in either change. Neither
lane could have seen it alone: the census cited a declaration that was live on
main, and my sweep covered every citation that existed at the time.

- The evidence decl_ref now names required_compile_lens_roster, which is what
  replaced it and what the row's argument is actually about.
- The row's prose cited the same symbol in its specimen sentence and cuts over
  with it.
- gunbc.v2_compile_obligation_census names the deleted symbol in two annotations;
  both now name the surviving roster, and the one about staleness says explicitly
  that the argument does not turn on there having been two lists.

Deliberately untouched: the census's entry/function/module_path rows for
hollow_alias_blocked_via_always_required_lenses and its two siblings. Those are
module and function IDENTITIES that still resolve, not symbol citations — their
rename is the separate cut whose citations include a recorded path wire.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f
gunbai-bot Bot pushed a commit that referenced this pull request Sep 11, 2026
… cuts over (review 63812)

1. MY OWN HEADER CLAIMED SOMETHING FALSE. The module said "one discriminating RED
per refusal arm" and the PR body said "five discriminating REDs, one per refusal
arm", while RequiredLensJoinCause has SIX arms. RegistrationDuplicated — the arm
whose whole job is catching a roster that acquired a second row for one identity —
had no control asserting it ever fires.

The "unreachable at the door" defence does not hold, and §4b decides it at the
fixture rather than at the door: a state unrepresentable in the accepted corpus
may still be representable as source handed to the join by a fixture, and where
the refusal is authorable there, declining it is specification without execution.
The sibling REDs already hand the join synthetic rosters, so it was one call —
append a repeated row — which is what makes the omission indefensible rather than
a judgement call. Eight controls now, and the header claim is true.

2. THE THIRD MERGE-ONLY CITATION TODAY. v2_compile_obligation_census_witness_test
names both deleted symbols in its "what is still not checked" annotation. That
file arrived with #10942 AFTER my citation sweep, so the break exists only in the
merge, exactly like the two the declarations phase caught. It now names
required_compile_lens_roster, and records that the gap it describes never turned
on how many lists there were.

Left alone deliberately, again: the entry/function/module_path rows for
hollow_alias_blocked_via_always_required_lenses. Those are identities that still
resolve, not symbol citations.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f
gunbai-bot Bot added a commit that referenced this pull request Sep 12, 2026
* File the class #10942 review 63691 named: a concession annotation is not a disposition.

Keeping a decoration after stating the deletion rule is worse than missing it — the sentence reads as diligence while a fold still publishes the invalid construction.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Strip trailing spaces from concession_annotation receipts now that the join supplies them.

Co-authored-by: Cursor <cursoragent@cursor.com>

#11047 changed authored() to join with a space; leaving the old trailing space would render this row double-spaced and as the only such file.

* Give the last receipts element its trailing comma.

The carrier's merge geometry requires every list element to carry a comma, including the last, so an append does not pull the preceding receipt into the conflict region.

Co-authored-by: Cursor <cursoragent@cursor.com>

* State ceiling and trigger per sub-case, not one trigger over a plural loss.

Sub-case one refuses a closed-roster producer that ignores its subject or an identically fixed axis; sub-case two requires the located cause to remain in the returned carrier. Neither retires the general concession class, which stays outside the modeled guarantee.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls added a commit that referenced this pull request Sep 12, 2026
…n/observation join at the compile door (#11004)

* wip: identity-bearing required-lens registration

* Identity-bearing required-lens registration, and a closed registration/observation join at the compile door

Step 1 of the compile-obligation activation brief: make the required-lens
roster name its lenses, so "the required lenses ran" stops being a claim
about a list length.

- One registration roster (required_compile_lens_roster), partitioned by
  grain through required_lenses_at_grain, replaces the two lists
  always_required_lenses / always_required_root_lenses. Each row carries
  the DeclarationRef of the gate authority that decides it plus its grain.
- LensGateWitness carries the lens identity and the grain it was produced
  at, so every observation names its producer.
- join_required_lens_coverage closes the join bidirectionally and refuses
  by name: RequiredLensRosterEmpty, RegistrationDuplicated,
  RegistrationUnobserved, ObservationUnregistered, ObservedAtWrongGrain,
  RootLensObservedMoreThanOnce. Root grain states exactly-one; subtree
  grain is at-least-one, because subtree registrations are observed once
  per node by construction.
- validate_then_compile runs each lens at its registered grain (caller
  lenses included, which previously ran at root whatever they declared),
  derives the coverage from the witnesses it actually collected, and
  refuses the compile when it is not closed. Validated carries the
  receipt with the roster digest.

Divergence from the brief, stated: one CompileLens carrier gains the two
fields rather than a second RequiredCompileLens type. Requiredness is
membership in the roster, not a property of the carrier, and a caller
lens must stamp its witnesses the same way for the join to be closed.

Evidence, by execution (claim_batch, local release build):
- v2.test.lens_application.required_lens_coverage_join: 7 witnesses green
  - one positive control over the real roster,
  - one control that runs all eight registered gates through the door's
    own two runners and joins the witnesses they actually stamped,
  - five discriminating REDs, one per refusal arm, each asserting the
    cause AND the lens identity.
- the eight touched pre-existing lens witnesses: all green.

Not established, and not claimed: an Accepted validate_then_compile
carrying the receipt. No fixture in this corpus reaches Accepted through
that door today (measured on fixture_add_resolved_tree in TranslateTo and
Eval; the refusal is upstream of the lens rosters). That frontier is
recorded in the test module's header.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

* Re-scope the permanently-green door control to what it actually discriminates (test-only)

door_root_roster_runs_and_passes_clean_tree called validate_then_compile and
accepted EITHER an Accepted compile OR any Rejected whose diagnostics lacked
the poly2 suspect. Measured: the door REFUSES this fixture, so the check was
green on a refusal and would have stayed green if the root roster had stopped
running altogether — a permanently-green check cited as coverage (DESIGN §4b).

The refusal is now located, and it is neither infer nor the root roster:
infer Accepts fixture_add_resolved_tree, the root-required roster Accepts the
inferred tree, and the SUBTREE-grain roster refuses it.

So the control becomes door_root_roster_accepts_clean_inferred_tree: infer
must Accept and every root-registered gate must Accept the real inferred
tree, with no tolerance for an unrelated refusal. The module header's claim
that the fixture "passes through the root-required roster ... proving the
roster RUNS on every door call" is corrected to the root-roster claim it
actually supports, and the now-unused stub target and its imports are removed.

The door-grain positive control (an Accepted validate_then_compile carrying
its coverage receipt) stays a declared frontier in
v2.test.lens_application.required_lens_coverage_join.

Evidence: door_root_roster_accepts_clean_inferred_tree PASS. The module's
other three witnesses (gate_red_quadratic_rejects,
gate_green_identity_accepts_clean, gate_refusal_ledger_counted_not_gating)
fail on the interpreted path with "no field 'kind' on type 'NormalizedTree'"
BEFORE this change as well — verified by running them on the committed file —
so they are untouched by it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

* Carry the renamed witness in the frozen path-deferral roster

gunbc.witness_deferral_freeze names (entry, function) pairs at identity
grain and REFUSES a row naming a witness the tree no longer carries as a
stale freeze row. Renaming door_root_roster_runs_and_passes_clean_tree in
the previous commit made its row stale, so the roster's own wall would
fire on this branch. One field, the new name.

This also explains why the re-scoped control's three sibling witnesses in
the same entry were red without anyone noticing: the whole entry is a
LegacyFrozenPathDeferral, i.e. admitted by path policy with no executing
consumer.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

* Cut the citations over with the symbols, and carry the de-enrollment prohibition forward (review 63457)

Two findings, both real, both verified against the current tree.

1. STALE CITATIONS. required_lens_grain_note was re-asserted verbatim while
both symbols it is about — always_required_lenses and
always_required_root_lenses — were deleted in the same diff, and five more
prose sites named them too. A replacement migration that cuts over at the
root owes the citation cut-over in the same motion (DESIGN §3 standing
rule). The note is rewritten to carry the same cost argument in terms of
what survives — a CompileLensSubtree registration runs per subtree node, a
CompileLensRoot registration runs once at the root, grain is a FIELD and
required_lenses_at_grain derives each execution's list — and it now also
records that a caller-supplied lens runs at its own declared grain. The
other five: v2.lens.determinism, v2.lens.mandatory_tag,
v2.lens.mandatory_tag.corpus_scan, v2.lens.machine_shape,
v2.lens.undecidable_verdict_collapse, v1.compiler.emit_rust,
gunbc.declaration_index_seed_growth, and
test.claim.computation_demand_duplication_witness.

2. DROPPED PROHIBITION. The lens_module_gate de-enrollment rationale was
deleted with the old root roster and nothing carried it forward — a standing
prohibition tied to a named red class (lying_substrate_inputs_only_stamp_census,
31 stamps). Worse, the replacement text invited the regression it warned
about ("Adding a lens is one row") with no eligibility statement. It is
carried forward in force beside the roster, plus the eligibility rule it
implies: a row must be a PURE FOLD OVER THE TREE BEING COMPILED at its
declared grain; a nullary gate, a corpus scan, or any gate reading the live
tree rather than its InferredTree argument is ineligible at either grain.

Not done, and stated rather than left silent: three test MODULES still carry
the deleted symbol in their own names
(lens_fact_density.hollow_alias_blocked_via_always_required_lenses and the two
lens_unit_modeling siblings). Renaming them is a file-and-module rename whose
citations include gunbc.live_deploy.srv1_residue_rehearsal — a RECORDED PATH
WIRE, i.e. an observation receipt — and dag/gunbc/witness/witness_row_cost_basis.tsv.
Editing a recorded observation to match a rename is not a citation repair, so
that cut is its own change.

Evidence: the coverage-join witnesses re-run green after the edits
(required_lens_coverage_closes_over_executed_gates_holds,
required_lens_coverage_refuses_unobserved_registration_holds).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

* Strip the 4a draft out of the registration PR

git add -A in the citation-cutover commit swept two untracked 4a files that
had followed a branch switch into the worktree: dag/std/realization_cost_fidelity.dag
and dag/test/claim/realization_cost_fidelity_witness_test.dag. Neither belongs
here — 4a's design was still undecided when they were committed, and this PR is
registration plus the citation cutover plus the de-enrollment prohibition and
nothing else. They move to their own branch and land after their own closure
receipt.

The other three files in that commit stay: declaration_index_seed_growth,
computation_demand_duplication_witness_test and v1.compiler.emit_rust are
one-to-three-line citation cutovers of the deleted roster symbols, which is
exactly what review 63457 asked for.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

* The last two live citations of the deleted roster (review 63473)

Both verified; both were real.

- v2.test.long.mandatory_tag_gate_witness: the file is already in this diff
  (its import moved to required_lenses_at_grain / CompileLensRoot), so its
  prose and its code disagreed inside one file. Now "the CompileLensRoot
  partition of required_compile_lens_roster".

- docs/plans/determinism-boundary-relative.md: the citation sits inside a
  block the file's own header declares "preserved verbatim" from a DESIGN.md
  row deleted on operator ruling. Rewriting a symbol inside a quotation
  falsifies the quotation, so the quoted sentence is left as authored and the
  current symbol is named beside it in brackets — the same reason the three
  test-module renames are not folded into this PR.

Remaining hits are src/v1/stage0/**, the seed's own mirror of this module,
addressed on the PR rather than edited here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

* Cut the seed oracle over with the authority: it is the compared value, not documentation (review 63517)

I argued the opposite an hour ago and I was wrong, for a reason worth writing
down: I reasoned from a general principle — do not edit the independent oracle
in the same push as its subject — without checking whether anything ASSERTS
EQUALITY on the string. Something does.

dag/gunbc/instruments/self_host_00_compile_shims/witness_main.rs compares
emitted::required_lens_grain_note() against seed::required_lens_grain_note()
and makes equality the Gate-A behavioral receipt. So this literal is not a
mirror of the authority for a reader's benefit; it is the value the self-host
equivalence claim is made of. Changing the .dag without it does not preserve
the oracle's independence — it falsifies the receipt my own change is supposed
to keep true. The reviewer measured the divergence (1288 vs 934) that I had
asserted away.

The seed literal is DERIVED from the .dag line rather than retyped, and
byte-equality verified programmatically: equal? True, 1288 == 1288. cargo check
on the seed lib is clean.

The oracle's header now says what it actually is — the compared value, which
cuts over with the authority — so the next reader does not repeat my reasoning
about independence.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

* Cut over the citations #10942 landed after my sweep (declarations FAIL, CITED-DECLARATION-ABSENT)

required-ci: declarations FAIL CITED-DECLARATION-ABSENT
  dag/gunbc/recurring_failure_mode/stale_present_tense_coverage_claim_in_the_authority_consulted_first.dag:47:5
  cites v2.compiler.compile always_required_root_lenses, which that module does not declare

Mine, and the same class I swept eight sites of in this PR: a replacement
migration owes the citation cut-over. The reason this one was missed is worth
recording — the row did not exist when I swept. It landed on main afterwards with
#10942 (the compile-obligation census), citing a symbol this PR deletes at its
root, so the break appeared in the merge rather than in either change. Neither
lane could have seen it alone: the census cited a declaration that was live on
main, and my sweep covered every citation that existed at the time.

- The evidence decl_ref now names required_compile_lens_roster, which is what
  replaced it and what the row's argument is actually about.
- The row's prose cited the same symbol in its specimen sentence and cuts over
  with it.
- gunbc.v2_compile_obligation_census names the deleted symbol in two annotations;
  both now name the surviving roster, and the one about staleness says explicitly
  that the argument does not turn on there having been two lists.

Deliberately untouched: the census's entry/function/module_path rows for
hollow_alias_blocked_via_always_required_lenses and its two siblings. Those are
module and function IDENTITIES that still resolve, not symbol citations — their
rename is the separate cut whose citations include a recorded path wire.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

* The sixth refusal arm gets its RED, and the census witness's citation cuts over (review 63812)

1. MY OWN HEADER CLAIMED SOMETHING FALSE. The module said "one discriminating RED
per refusal arm" and the PR body said "five discriminating REDs, one per refusal
arm", while RequiredLensJoinCause has SIX arms. RegistrationDuplicated — the arm
whose whole job is catching a roster that acquired a second row for one identity —
had no control asserting it ever fires.

The "unreachable at the door" defence does not hold, and §4b decides it at the
fixture rather than at the door: a state unrepresentable in the accepted corpus
may still be representable as source handed to the join by a fixture, and where
the refusal is authorable there, declining it is specification without execution.
The sibling REDs already hand the join synthetic rosters, so it was one call —
append a repeated row — which is what makes the omission indefensible rather than
a judgement call. Eight controls now, and the header claim is true.

2. THE THIRD MERGE-ONLY CITATION TODAY. v2_compile_obligation_census_witness_test
names both deleted symbols in its "what is still not checked" annotation. That
file arrived with #10942 AFTER my citation sweep, so the break exists only in the
merge, exactly like the two the declarations phase caught. It now names
required_compile_lens_roster, and records that the gap it describes never turned
on how many lists there were.

Left alone deliberately, again: the entry/function/module_path rows for
hollow_alias_blocked_via_always_required_lenses. Those are identities that still
resolve, not symbol citations.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

* The last live citation of the deleted roster symbol cuts over (review 63827)

The rename in this PR (always_required_root_lenses -> required_compile_lens_roster)
updated seven sibling citations and missed one: the mandatory-tag scaffold comment
in the seed's cli_run.rs still named the deleted symbol as where the modeled lens
is enrolled. At this head it was the only surviving live citation -- the remaining
grep hits are witness function names and module paths, which are not citations of
the symbol.

It now names the registration as it actually stands: required_compile_lens_roster
at CompileLensRoot grain, the mandatory_tag_lens row. That is the point of the
rename -- the grain is a field on the row rather than a fact about which of two
lists a lens was written into -- so the citation has to say the row, not the list.

This is the class the PR itself edits (DESIGN 3: a stale name is decidable and
enforceable).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

* The coverage receipt states its frontier and its trigger, and an unused import goes

Review 63842.

The distinction the review draws is the right one and I am keeping it: the JOIN
is consumed by execution in this change -- validate_then_compile refuses a
compile whose coverage is not closed -- so the gate was never the dangling part.
The receipt CARRIED on Validated is a separate declaration with a separate
consumer, and nothing outside this module reads it today.

The prose that was there named a consumer (the obligation census) and stated no
trigger, which is a half-classification: DESIGN section 3c admits a frontier
only with the trigger beside it, precisely so that "a later change will read
this" cannot be said indefinitely. The field now carries consumer, route and
trigger, with the trigger stated as a CAPABILITY -- the promotion path routing
its candidate through this door and refusing on a named uncovered lens,
sufficient that a candidate cannot be promoted without its coverage having been
observed on the same compile that produced it.

It also states the kill condition, because a frontier that cannot expire is not
a classification: if that capability does not land, the field is redundant work
and the honest move is to DELETE it, since the refusal is already the gate.

WholeDeclaration was imported and never used; removed. 8 join controls green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

* The accumulator-gate front end is paid once instead of once per claim

MEASURED FIRST, because the cut I was about to make was aimed at the wrong
thing. claim_batch over this module's four witnesses in one remote dispatch:
the three source-path rows cost 534-680ms of CPU against a 500ms per-claim
ceiling, while door_root_roster_accepts_clean_inferred_tree -- same gate area,
hand-built node fixture, no front end -- costs 50ms. Three DIFFERENT four-line
snippets spread only ~150ms over a ~530ms base, so the base is the front end
itself, not the snippets. Shrinking the planted ledger could not have moved a
680ms witness under 500ms when its two ledger-free siblings pay 534 and 618 for
the same prefix.

The consequence that matters more than the one failing row: ALL THREE
source-path witnesses here are at or over the ceiling on an unloaded runner.
gate_refusal_ledger_counted_not_gating is not defective beside three healthy
ones; it is the one 80ms above its nearest sibling. Host thrash is why it
trips today, the budget is why it would trip anyway.

THE CUT KEEPS THE SOURCE PATH. The three claims are now nullary producers
enrolled WARM in v2.workflow.floor_pure_producer_share, so the floor forces each
once during strict preparation, outside every per-claim budget, exactly as
v2.test.claim.parse.d1_declaration_grammar_parse does for the identical defect
(seven of its eight rows were interrupted at this same ceiling). Nothing about
what executes changes: same source, same tokenize, same parse, same normalize,
same tree, paid once.

The alternative -- moving the ledger assertion onto a hand-built fixture --
would have bought the budget by trading what the witness proves, ledger
behaviour on a tree the real front end produced. DESIGN 4b(1) prices that as a
rung drop, not a cost fix.

SEAM CHOICE, and it differs from the d1 precedent deliberately: that module
shares at the PARSE tree because some of its claims name normalize as their
subject, and sharing normalize would stop them executing the stage they claim.
No witness here names any front-end stage -- all three branch on the normalized
root and assert about accumulator_copy_compile_gate -- so the whole front end is
upstream of every subject in this file and the honest seam is its output.

VERIFICATION BOUND, stated because it is real: claim_batch under my invocation
refuses this module with "no field 'kind' on type 'NormalizedTree'" inside
normalize while the floor accepts it (3625 passed, 0 failed at this head), so I
cannot execute these three witnesses locally at all. What I verified is that
both modules parse in a whole-corpus index and the roster fold evaluates with
the three rows present. Whether the NormalizedProbe value reifies portably is
decided by the floor, and a warm row that refuses to store STOPS THE LINE rather
than degrading -- the precedent shares Outcome<Node>, the same shape class.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

* Withdraw the share: it netted the cost exactly as intended and the served value did not survive

MY PREVIOUS COMMIT BROKE THREE PASSING WITNESSES, and this withdraws it. The
floor at 540c92c reports all three accumulator-gate claims failing with
"no field 'kind' on type 'NormalizedTree'", cause=claim_failed. They pass when
each claim derives its own tree. That is a regression I introduced, and a budget
refusal traded for three failing witnesses is strictly worse than the budget
refusal.

WHAT THE EXPERIMENT ESTABLISHED, because it is not nothing. The netting worked
exactly as ruled: disposition=Stored for all three producers during strict
preparation, 868ms, 496ms and 571ms of front end paid outside every per-claim
budget. That is the diagnosis confirmed by execution rather than by argument --
the front end IS the per-claim cost in this module, and the shared-producer tier
does move it.

AND IT RESOLVED THE EARLIER MYSTERY IN THE OTHER DIRECTION. I had reported the
claim_batch-vs-floor disagreement on this module as an instrument quirk, because
the floor was green on the same witnesses my instrument refused. It is not the
instrument: the floor now reports the SAME error the moment the normalized tree
is produced outside the frame that consumes it. Two observations, one mechanism
-- a normalized tree does not survive being handed across that boundary. The
instrument was never the variable, and I said it was.

WHAT RETURNS THE ROWS, as a capability: a normalized tree that survives the
cross-claim serve boundary, so the value a claim is handed is the value it would
have derived. The producers stay as plain helpers -- each claim calls one and
derives its own tree, exactly as before the share -- so this file is now
behaviourally identical to the pre-cut state with the measurement recorded in it.

The per-claim front end therefore stands, and the budget question it raises is a
budget question rather than a witness question. No witness here should be moved
onto a fixture to buy it: that trades what these witnesses prove.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

* Cut the probe sources to the smallest form that still discriminates

Semantic-neutral by construction: only names shrank -- module names, the list
binder, the lambda binders. The RED still copies the accumulator through
list_append inside the fold, the GREEN is still its non-copying twin, and the
ledger probe still calls a combiner no registry knows. No arm, type annotation
or call shape was touched, because each of those is what the gate reads. So the
run measures cost and nothing else.

THE PREDICTION IS STATED BEFORE THE MEASUREMENT, so it can be wrong rather than
fitted afterwards. Two points from the earlier lower-bound measurement -- 88
bytes at 534ms, 116 bytes at 618ms -- put the marginal cost near 3ms/byte and
imply about 285ms paid per claim BEFORE a single byte of snippet exists. These
cuts remove 9, 10 and 19 bytes, so the predicted saving is tens of milliseconds
against a worst row that needs 180. Projected: ~591, ~504, ~623 against a 500ms
budget.

If the floor lands them clearly under 500, this model is wrong in the useful
direction -- the front end is superlinear in source size rather than mostly
fixed -- and the sources were the defect after all. If they land near the
projection, the sources were never the defect and the budget grain is, which is
a declared-drop question rather than a witness question.

The floor decides either way: claim_batch cannot measure this module at all,
because it fails at the same serve boundary that broke the withdrawn share.

THE FIXED COST IS THE FINDING, not the saving. ~285ms of front end per claim
before any snippet exists is a section-6 bare-minimum-cost defect in its own
right, and it is the same subject as the serve-boundary work item: netting that
survives consumption is exactly what would delete it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

* The grain note stops claiming a cost shape the fold does not have

Review 63901. The note asserted "Witness accumulation on the subtree fold uses
prepend-then-reverse, not append-in-step" while the fold does exactly
append-in-step: list_append(left: child_ws, right: ws) inside step copies the
child's whole accumulated list every step, with one list_reverse at the end.

TWO THINGS COMPOUND AND THE SECOND IS THE ACUTE ONE. The cost shape is real, and
it is the accumulator-copy shape THIS DOOR'S OWN LENS EXISTS TO REFUSE. But the
note is not prose: this PR's own annotation states it is the COMPARED VALUE that
the Gate-A witness asserts byte-equality on. So a false cost claim was green by
equality on both sides -- a check certifying its own wrong description.

I DID NOT "FIX" THE FOLD, and that is a decision rather than an omission.
list_append costs its LEFT operand; the carrier's rc_list_concat copies its RIGHT
one (dag/std/nat.dag already records that asymmetry as a measured cost shape).
Neither the accumulator nor a child's subtree accumulation is reliably the
shorter, so no argument order makes a fold over a tree linear -- it needs a
concat that copies neither operand, which is carrier work. Swapping the operands
would have moved the copy while letting me report the defect fixed, which is the
same species as the claim I am deleting.

So the note now states what the code does, names the shape, says why the repair
is carrier work and not an argument order, and says why it is stated in a
compared value at all. DESIGN section 6 root-causes to the language layer rather
than patching locally; section 5 forbids the fabricated claim regardless.

Byte-equality preserved: both sides carry the identical 2088-byte note, verified
by extracting the .dag string and asserting containment in the oracle rather than
by eye. gunbc compile --entry 00_compile.dag --target dag: 0 blocking errors.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

* Completeness becomes an identity join, and the refuted snippet cut reverts

Review 63922, plus the revert the measurement earned.

THE COUNT COULD NOT FAIL. Both coverage assertions checked
`length(rows) == length(roster())`, and both sides derive from the same fold
inside join_required_lens_coverage, which emits exactly one row per registration
by construction. The conjunct was structurally green and said nothing about
WHICH lenses were covered -- while the comment beside it claimed the closed rows
are the roster's own identities, which is more than a count establishes. DESIGN
section 5: completeness is an identity join, not a count equality.

The case a count cannot see is concrete: a join that DROPS one registration and
DUPLICATES another keeps the count exactly equal. rows_join_the_roster_exactly
runs the join at (identity, grain) in BOTH directions, because the directions
fail differently -- a registration with no row is a lens that never ran, and a
row naming no registration is coverage claimed for something the roster does not
require. Grain is part of the key rather than a separate assertion: the join's
own ObservedAtWrongGrain arm exists because covered-at-the-wrong-grain is a
different fact from covered.

THE SNIPPET CUT REVERTS BECAUSE IT WAS MEASURED AND BOUGHT NOTHING. Paired
before/after on the same three witnesses: two of the three got SLOWER after
bytes were removed, and the third's gain is the same size as the noise. The
prediction in that commit -- a marginal cost near 3ms/byte -- is refuted, and
cross-sectionally too, since the shortest source is the slowest of the three.
The sources are restored to the forms that read clearly, and the annotation now
carries the measured outcome instead of the prediction: the per-claim cost is a
fixed front end, invariant to the subject-specific work, and it is closed by the
FLOOR-CHANGED-COST-0 long-home arm rather than here.

Both modules compile with 0 blocking errors.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

* Coverage closes over a name, and the annotation now says so

Review 64177, both findings. No behaviour change.

1. `CompileLens.identity` is authored on the row beside `gate` and bound to
it by nothing, so swapping two rows' gates leaves the join closed and the
roster digest unchanged. The module claimed more than that in two places --
"registration and observation form one closed, machine-checkable join" and
a digest that "does not cover the gate function, which is named by the
identity it is registered under". The second sentence asserted precisely
the pairing nothing verifies.

Both now state the honest claim: a gate REGISTERED UNDER this identity ran
at this grain. The residual is recorded at MITIGATION grain with its
ceiling and its next-rung trigger beside the field, per section 4b(2). No
discriminating RED is authorable today and the annotation says why: a
control would have to recover a declaration identity FROM an opaque
function value, and one comparing the authored identity to itself would be
the permanently-green decoration section 4b warns about at the top rung --
worse than absent, because it would be cited as coverage of the gap it does
not close. The trigger is a reified declaration identity for function
values, which makes the field derived rather than authored and collapses
the pair to one fact. The witness module's own "what this does not
establish" roster now names it too, which the reviewer noted it omitted.

2. `first_root_registration` returned the LAST root-grain row: the fold
overwrites `acc` on every `CompileLensRoot`. The controls were unaffected
(they call it on both sides), but the name asserted a position the code did
not have. Renamed to `a_root_grain_registration`, claiming no position at
all, because the contract does not care -- and NOT repaired by returning
the first, since `unregistered_placeholder_lens()` is itself
`CompileLensRoot` and a keep-the-first fold would latch onto the sentinel
and never reach a real row.

Evidence: claim_batch over required_lens_coverage_join, rc=0, 8 PASS;
gunbc compile of v2.compiler.compile, the witness module and the amended
failure-mode row, 0 blocking errors each; docs_projection_gate regen is a
no-op against the committed projection.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

* The door-grain coverage claim shrinks to what can fire there

Review 64196, both findings. No behaviour change.

1. The annotation above validate_then_compile said "an obligation that
silently stopped executing stops the line". That is false AT THIS DOOR, and
the reviewer is right about why: both sides of the join come from
required_compile_lens_roster() inside one call. run_required_lens_gates
folds the roster and stamps each witness with the identity and grain of the
row it is folding, so the observation list is a structural image of the
roster rather than an independent reading of it; required_lens_observations
then drops any witness that is not a registration before the join is asked.
RegistrationUnobserved, ObservedAtWrongGrain, RootLensObservedMoreThanOnce
and ObservationUnregistered therefore have no authorable RED here. What can
fire is RegistrationDuplicated and RequiredLensRosterEmpty. An obligation
stops executing by LEAVING THE ROSTER, and a join whose both sides are the
roster cannot see that by construction.

The arms are not decoration -- they are discriminated where their REDs are
authorable, in the fixture-grain suite, which section 4b explicitly
sanctions as the place a compiler's invalid states get expressed. So the
honest statement is about GRAIN: fixture-grain the join discriminates six
ways, door-grain it catches a duplicated or empty roster. The trigger for
the stronger claim is named: an independent observation channel, a receipt
carried out of the runner rather than a list re-derived from the roster it
is compared against.

This is the second inflated claim in this file found by review rather than
by me, after the identity/gate binding. Both have the same shape -- a
sentence describing what the mechanism would catch if its two sides were
independent, when they are not.

2. grain_key was a byte-identical copy of compile_lens_grain_name, and the
test hand-rolled equality as a string compare where compile_lens_grain_eq
exists -- both in a module this test already imports from (section 3
nicknaming). The copy is deleted and the authority's comparison consumed;
the roster digest's grain spelling and the test's can no longer drift.

Evidence: claim_batch over required_lens_coverage_join, rc=0, 8 PASS,
including refuses_wrong_grain_observation, which is the arm that exercises
the swapped comparison; gunbc compile of v2.compiler.compile and the
witness module, 0 blocking errors each.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

* File the class both of this file's inflated claims belong to

Reviews 64177 and 64196 found two claims in `v2.compiler.compile` that
described what a mechanism would catch if its two sides were independent,
when they are not. One class, two specimens, so it gets a row rather than
two annotations that each explain themselves.

`gunbc.recurring_failure_mode comparison_whose_operands_share_a_producer`.
The discriminator is one sentence: the comparison's two operands have a
common producer. It is decidable by reading each operand back to its source,
and it is worth asking before the check is written rather than after it
greens.

Checked the directory before filing rather than assuming, and the four
nearest rows are excluded BY NAME in the row itself. Not
`roster_is_its_own_denominator`: there is no second statement there at all
and the repair is to obtain one; here two exist and are compared, and the
repair is to make one independent. Not
`population_selector_that_cannot_admit_a_counterexample`: that is a defect
in how a population was constructed by a lexical proxy; here the population
is correct and stable and the defect is the second operand. Not
`corroboration_without_an_independent_derivation_axis`: that is a property
of the relationship between two human readers, which no artifact records,
so it carries ceiling 1 and no trigger; this one is mechanical, visible in
source at both call sites, and decidable. Not
`a_positive_control_certifies_the_defect_it_exists_to_catch`: there the
control reads the right accessor against a wrong subject, so a correct
subject fixes it; here the subject is right and the comparison still cannot
fail.

The general form, and the reason it is a control-shaped class rather than a
compiler one: it is DESIGN section 5's oracle rule applied to a control
instead of to a literal. "A measurement copied from the same current tree
is not an oracle" becomes "a list re-derived from the roster it is compared
against is not an observation".

RUNG FOUND AT is mitigation by review, and an earlier draft got this wrong
in a way worth recording: it said `mitigatable` and justified that by
pointing at the join's refusal arms firing at fixture grain. Those arms
discriminate a malformed observation set; none of them can detect that a
comparison's operands share a producer, so that was a fact about the
specimen and not containment of the class. Nothing in the corpus asks the
question, so the honest rung is what a human reading two call sites
established. Ceiling is structurally guaranteed, because operand provenance
is a declaration-grain question the Node tree already answers. Class
trigger is provenance-aware comparison analysis; the specimen's own trigger
- an independent observation channel - is recorded separately and
explicitly does NOT discharge the class.

Both annotations in `00_compile.dag` now cite the row.

Evidence: gunbc compile of the row and of v2.compiler.compile, 0 blocking
errors each; docs_projection_gate regen renders the row into the combined
view (the roster and that projection are both gitignored, so the row file
is the entire committed change).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

* The deferred cost defect gets a carrier and a capability trigger

Review 64245. The grain note admitted a cost defect in this door's own
witness fold and disposed of it with "tracked as its own cost defect rather
than patched locally here", naming no carrier, row or symbol. Nothing
tracked it, so the sentence asserted a disposition that did not exist --
section 4b(2)'s untracked stall, stated in the authority a reader consults
first.

Filed `gunbc.recurring_failure_mode enforcement_exhibits_the_shape_it_refuses`
and cited it from the sentence. The class is the machinery that enforces an
invariant being written in the shape that invariant refuses -- DESIGN
section 7's self-application obligation failing in the direction nobody
looks, because the enforcement's own code reads as infrastructure rather
than as a subject. The specimen is half repaired and half standing, which
is what makes it worth a row: the subtree fold was already rewritten to
prepend-then-reverse, while the concat stands, because `list_append` costs
its LEFT operand and `rc_list_concat` copies its RIGHT one and neither
accumulation is reliably shorter.

The trigger is named as a CAPABILITY and the falsified experiment is
recorded beside it: a concat that copies neither operand, which is carrier
work in the list algebra and explicitly NOT a rewrite of call sites --
docs/plans/emit-type-surface-traversal-cost.md tried exactly that
substitution at 215 sites plus rc_list_concat and measured byte-identical
output with no measurable change at the emit seam. That is evidence about
that seam and not this one, and it is written down so the next author does
not re-run a falsified experiment believing it is the repair. The row's own
next rung is the required-lens gates applied to the compiler's own modules
as ordinary subjects, which is section 7's claim made executable.

The seed mirror moves in lockstep: both sides of the self-host behavioral
receipt are byte-identical at 2556 characters, asserted by comparing the
extracted strings rather than by inspection.

Evidence: gunbc compile of v2.compiler.compile, the new row and the
cause-swap witness, 0 blocking errors each; claim_batch over
claim_entailing_evidence_cause_swap_witness, rc=0, 8 PASS -- that suite
carries the transcript fixtures that mention this declaration, and its
`seed_len` figures are authored specimens of transcript SHAPE rather than
live measurements of the string, so they are unaffected by its length
changing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

* An enforced lens whose red control had never run, and the red does not hold

Review 64262, plus the dark row gunbc#11073's long-home arm exposed.

WHAT THE ARM FOUND. v2.test.long.accumulator_copy_compile_gate
gate_red_quadratic_rejects failed on its FIRST REAL EXECUTION (srv3-02, no
thrash). It is not a regression: run with one binary against origin/main and
against this head, it FAILS on both while both sibling controls PASS on
both. It had simply never run, because its home test/claim/long/ is a
witness_exclusion_frontier pattern and no required lane plans it.

AND THE FAILURE IS THE WORST OF THE THREE AVAILABLE. A three-way
discriminator separates them: the specimen normalizes fine, the gate does
not reject with a wrong reason -- accumulator_copy_compile_gate ACCEPTS it.
accumulator_copy_findings returns NO suspect for
fold(xs, init: 0, f: fn(acc, x) { list_append(left: acc, right: x) }),
which is the textbook shape the lens exists to refuse.

Three consequences, all here, none of them the analyzer repair (that is its
own lane, starting from the discriminator posted on the PR):

1. RUNG HONESTY. accumulator_copy_obligation claimed MechanicallyPreventable
on the strength of that control. Executed evidence says the invalid state is
not prevented, so the claim is downgraded to Mitigatable -- the gate is
total and returns a typed outcome, so harm is contained and nothing above
that is established. DESIGN 4b(1) admits only the rung executed evidence
supports, and the restoration is the analyzer trigger rather than the
witness greening by any other route.

2. THE CLASS. gunbc.recurring_failure_mode
required_lens_red_control_never_executes_from_its_home: a lens enrolled as
required, reporting a mechanical rung, whose discriminating red lives where
the floor never plans. The discriminator is a JOIN -- the cited red and the
planned population do not intersect -- which is why neither roster looks
wrong alone. Ceiling structurally guaranteed, because that join is over two
rosters this tree already declares.

3. THE KNOWN RED, without which the floor stays red on every future head.
Admitted in gunbc.explicit_witness_admission with a dissolution naming the
CAPABILITY: accumulator_copy_findings returns a non-empty suspects list for
the fold-append specimen and the gate refuses that tree. That fact is false
today and was MEASURED false by execution on both trees, so the trigger
cannot be satisfied by editing the specimen or the control -- which is
exactly the defect that roster's own note records two lanes failing.

REVIEW 64262. The expanded grain note restated the body of the row this PR
files, and transcribed a 215-site measurement into two files including the
Rust oracle mirror. Both are right: the prose was the duplicate rather than
the carrier, and section 6 says name the instrument, never transcribe it.
The note now cites the row instead of restating it; both sides byte-identical
at 2117 characters, asserted by extracting and comparing.

Evidence: compile 0 blocking on all four touched authorities and the new
row; v2_compile_obligation_census_witness 9 PASS. exact_witness_admission
carries three failures that are IDENTICAL on origin/main (18 PASS 3 FAIL
both sides) and my row satisfies explicit_witness_admission_well_formed by
inspection of the predicate -- QuarantineProbeExpectRed executes, entry
non-empty -- and shares kind and budget with an existing row in that batch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant