From b8e8cce7f0a4e70d1e3f4ff217a36c7b5d8a193c Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Tue, 1 Sep 2026 12:47:47 +0000 Subject: [PATCH] File the disagreement-blind class, the undecided-fraction class, and the upstream cause of the six renderer short-circuits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit THE FINDING BEHIND THE FIRST ROW. The arbiter-repair design commissions a divergence census to adjudicate arm A, and states a calibration control: the diagnostic-producing `DivergesWithExactIdentity` subset must reproduce arm A's 25 sites, joined by source declaration and enclosing declaration, never by line. That control had never run against the typed-graph census landed by #9900. It has now, over the transitive import closure of `src/v2/compiler/01_tokenize.dag`, and it FAILS: - `v2.compiler.tokenize`, the module emitting the file where every arm-A site lives, contributes 76 rows: 74 Agrees, 2 IdentityUnavailable, ZERO DivergesWithExactIdentity. All 26 of its `String`-named rows Agree. - Every divergence row in the closure sits in `v2.std.text`, the DECLARING module, in the opposite direction. Empty intersection with the population the control exists to find. That is not the over-broad walk #9900 predicts — an over-broad walk shows the target population PLUS extras; this shows it NOT AT ALL. The shape of the absence is the diagnosis. The reason is general, and is why it is filed as a class rather than as a census defect: a two-reader DISAGREEMENT census reports AGREEMENT as healthy, so the population where both readers are wrong together is invisible to it by construction. At an arm-A site the short-circuit returns the host spelling before consulting anything and the authority answers from a fallback that returns the REFERENCING module's file, so both answer host and agree. Recognition rule, at the grain that generalises: any two-reader comparison cited as CORRECTNESS coverage — differential oracles, twin fixtures, cross-checks, self-hosted-versus-seed. Ask what a shared error would look like in its output; if the answer is "indistinguishable from health", it is not the correctness evidence. The remedy is a different oracle reaching outside the pair, never a repair of the comparison. SECOND ROW: the same run produced 121 `IdentityUnavailable` rows where the 2026-08-21 front-end-phase run reported zero. Rows that are neither agreements nor divergences are scored as decided by any ratio over the reported total. Both runs are NAMED rather than differenced — they are different instruments at different phases. THIRD CHANGE: `checkpoint_table_bypasses_identity_note` reads as though the spelling its six renderers short-circuit on had one meaning. It does not — a callee parameter type is re-resolved in the CALLER environment, so one declaration denotes the structural carrier in its own module and the kernel scalar at every foreign call site. The appended paragraph records that, and cites #9929 for calm-boar-314's three measurements (qualified spelling silences rather than pins; returns re-resolve on the same axis; one refusal can carry two disagreeing destinations) rather than restating them. No divergence number is published as a measurement of the emitter: the figures above appear only as the control's failure evidence, which is what the design asks for in the failing branch. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Vo22gFeUgs7vAVuhsmWqKk --- DESIGN.md | 2 ++ dag/gunbc/recurring_failure_mode.dag | 14 ++++++++++++++ docs/design-ledgers.md | 2 ++ src/v1/05_emit_rust.dag | 2 +- 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/DESIGN.md b/DESIGN.md index f0d7cc54c5a..f3552474dcb 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -215,6 +215,8 @@ One row per class, each carrying its recognition rule and its receipts, in [docs - `unbacked_execution_claim` - `mitigation_injected_where_judgment_declined` - `merge_region_excludes_shared_tail` +- `disagreement_census_blind_to_agreed_wrong` +- `undecided_fraction_read_as_denominator` ## Building & checks diff --git a/dag/gunbc/recurring_failure_mode.dag b/dag/gunbc/recurring_failure_mode.dag index cdd2e72ba5a..cba82755667 100644 --- a/dag/gunbc/recurring_failure_mode.dag +++ b/dag/gunbc/recurring_failure_mode.dag @@ -149,6 +149,18 @@ data unbacked_execution_claim: RecurringFailureMode = RecurringFailureMode { ide data merge_region_excludes_shared_tail: RecurringFailureMode = RecurringFailureMode { identity: "merge_region_excludes_shared_tail" as NonEmptyStr, authored: "**merge region excludes the shared tail** (a roster carrier whose rows are multi-line blocks ending in an identical suffix makes every two-lane append resolve WRONG BY DEFAULT. The three-way merge factors the shared suffix out of the conflict region, so the region holds two half-blocks above the markers and one tail below them, and the purely additive resolution -- delete the markers, keep both sides, which is the CORRECT resolution when the two appended rows are independent -- leaves the first row's closing lines belonging to the second. Specimen: this carrier, which conflicted on every integration of main across four merge bases in one session (2026-09-01) with a shared tail of `evidence: [],` and `}`; `gunbc.rung_drop` had the same shape with `}` alone. **THE CLASS IS LOUD, AND THAT IS THE HALF A REPORT OF IT WILL GET WRONG.** The first reading was that the severed row survives as a structurally broken declaration under which the natural check -- declared names against rostered names -- still passes, because both lists stay complete. Measured against a gunbc built at d0009ca531 on the resolved shape: it is a PARSE REFUSAL at the module index, `expected expression, found Eq`, because a `data` keyword cannot stand in record-field position. Nothing reaches the checks that reading worried about, so the cost is toil and not silent wrongness -- a load-bearing authority whose every integration lands a conflict whose natural resolution does not compile, hand-repaired each time. **RECOGNITION RULE: for a carrier two lanes append to, ask what suffix the appended units SHARE, because a conflict region never contains it -- whatever semantics live in that suffix are exactly what a resolution can drop.** THE REPAIR IS THE UNIT AND NOT A CHECK: make the appended unit one line, and the shared suffix is a blank separator carrying nothing. A brace-balance or name-join check written here would be the DESIGN section 4b decoration -- permanently green, because the compiler already refuses the only corpus it could fire on.)", evidence: [] } +data disagreement_census_blind_to_agreed_wrong: RecurringFailureMode = RecurringFailureMode { + identity: "disagreement_census_blind_to_agreed_wrong" as NonEmptyStr, + authored: "**a two-reader disagreement census is blind to the case where BOTH readers are wrong together** (an instrument whose subject is DISAGREEMENT between two producers of one answer reports AGREEMENT as healthy, so the population where both answer the same WRONG thing is scored green and is invisible to it by construction. The trap is that such an instrument is commissioned precisely to adjudicate a known-defective population, and it can be structurally incapable of seeing that population while looking perfectly well-formed and producing rows. **SPECIMEN, measured 2026-09-01.** `v1.tests.claim.carrier_realization_census` records, per type-reference occurrence, the legacy short-circuit key and the strict authority answer, and reports where they diverge. Its calibration control -- stated in docs/plans/carrier-realization-arbiter-repair-design.md -- requires the diagnostic-producing `DivergesWithExactIdentity` subset to reproduce arm A 25 sites, joined by source declaration and enclosing declaration, never by line. Run over the transitive import closure of `src/v2/compiler/01_tokenize.dag`, the module that emits the file where every arm-A site lives contributed 76 rows: 74 Agrees, 2 IdentityUnavailable, ZERO divergences, and all 26 of its `String`-named rows Agree. Every divergence row in the closure sat in `v2.std.text`, the DECLARING module, in the opposite direction. Empty intersection with the population the control exists to find. **THE SHAPE OF THE ABSENCE IS THE DIAGNOSIS, and it is what distinguishes this class from an over-broad walk.** `gunbc#9900` predicted the walk might visit occurrences the emitter never renders; that defect shows the target population PLUS extras. This showed the target population NOT AT ALL. Same instrument, same rows, opposite conclusions -- and only the shape separates them. **WHY BOTH READERS AGREE THERE**, read off `v1.compiler.emit_rust` `checkpoint_table_bypasses_identity_note` REACHABILITY CORRECTION rather than executed here: the short-circuit returns the host spelling before consulting any authority, and the authority answers from `type_reference_decl_file`, whose fallback returns the file containing the REFERENCE. Two readers, one wrong answer, perfect agreement. **RECOGNITION RULE: any two-reader comparison cited as CORRECTNESS coverage.** A differential oracle, a twin fixture, a cross-check, a self-hosted-versus-seed comparison, an A/B over two emitters -- each answers `do these two concur`, and none answers `is the answer right`. Ask what a SHARED error would look like in its output; if the answer is `indistinguishable from health`, the instrument cannot be the correctness evidence, whatever else it is good for. **THE REMEDY IS A DIFFERENT ORACLE, NOT A REPAIR OF THIS ONE.** The adjudicating instrument has to reach OUTSIDE the pair of readers for its ground truth -- for this specimen, a census of agreement-at-a-wrong-answer joined against emitted-crate diagnostics. Widening the occurrence set, fixing the walk, or adding a third reader that shares the same defective input do not help, and the first two are what a reader who diagnosed this as an over-broad walk would have spent. **Bounded against `executed_conjunct_discriminates_nothing`**: there a live gated conjunct never meets a population that would falsify it, and one authored fixture retires it; here the instrument meets its population on every run and reports it as healthy, so no fixture over this instrument can retire it. **Bounded against `instrument_output_read_as_subject_content`**: there the instrument answers its own question faithfully and a consumer substitutes the subject; here the instrument answers ITS OWN question faithfully too, and the defect is that its question -- do the readers concur -- was never the question that was asked.)", + evidence: [], +} + +data undecided_fraction_read_as_denominator: RecurringFailureMode = RecurringFailureMode { + identity: "undecided_fraction_read_as_denominator" as NonEmptyStr, + authored: "**a census with an unresolvable fraction of its population reports a denominator it does not have** (an occurrence census that emits a third disposition for `could not determine` is honest at the row grain and misleading at the total grain: rows scored `identity unavailable` are neither agreements nor divergences, so any ratio taken over the reported total silently treats them as decided. **SPECIMEN, unowned and unexplained at filing (2026-09-01).** The `v1.tests.claim.carrier_realization_census` run over the `src/v2/compiler/01_tokenize.dag` closure produced 121 `IdentityUnavailable` rows -- roughly a tenth of its population. The earlier run recorded in docs/plans/carrier-realization-arbiter-repair-design.md, over the same subject module at the FRONT-END phase on 2026-08-21, reported `1142 rows: 1134 Agrees, 8 DivergesWithExactIdentity, 0 IdentityUnavailable`. Zero to a tenth, across a phase change nobody predicted it for. **BOTH RUNS ARE NAMED RATHER THAN THEIR NUMBERS INHERITED**: the earlier is the front-end-phase run the design itself later withdraws as measuring the wrong phase, and the later is the typed-graph census landed by `gunbc#9900`. They are not the same instrument and the pair is recorded to locate the question, not to compute a delta from. **RECOGNITION RULE: an instrument with a `cannot answer` disposition, whose consumers aggregate over the reported total.** Ask what fraction is undecided before reading any ratio, and treat the undecided fraction as a separate finding rather than as noise. **WHY IT IS FILED WITHOUT INVESTIGATION**: identity being unavailable is a different defect from the readers disagreeing, it has no owner, and it was found while running a control for an unrelated question. A row that records it with both runs named is what stops the next reader taking the census denominator at face value.)", + evidence: [], +} + data recurring_failure_mode_roster: List = [ hollow_alias, state_space_conflation, @@ -181,4 +193,6 @@ data recurring_failure_mode_roster: List = [ unbacked_execution_claim, mitigation_injected_where_judgment_declined, merge_region_excludes_shared_tail, + disagreement_census_blind_to_agreed_wrong, + undecided_fraction_read_as_denominator, ] diff --git a/docs/design-ledgers.md b/docs/design-ledgers.md index edc02cf8587..07511ca2958 100644 --- a/docs/design-ledgers.md +++ b/docs/design-ledgers.md @@ -43,6 +43,8 @@ The landing measurement partitions the 31 parser-visible identities into **2 cit - **unbacked execution claim** (prose asserts a live executing relation — this runs on X, X reads these fields, Y already resolves Z — that no authority backs, and a reader forms the premise and plans against it. §4b's CI rung drop names the harm PREMISE CONTAMINATION in its own words; this row is that harm as a general class, since the drop is about one paragraph in the canonical authority and the class is about every carrier. **THE ORIGINS ARE A FIELD OF THIS ONE ROW RATHER THAN SEPARATE ROWS, because the recognition rule is identical across them** — resolve the claim against the authority that owns the relation — **but the REMEDY BRANCHES ON THE ORIGIN, and a remedy applied without reading the origin manufactures new false statements.** Three origins are ATTESTED here and a fourth is conceivable but was NOT found. ORIGIN 1, EXECUTOR DELETED: the claim was true and its executor was removed. Specimen: `gunbc.floor_component_receipt_document` recited that an alert downloads an artifact named `floor-component-receipt` from a run id it is given and reads four named fields; that alert was `falsifier-alert.yml`, deleted 2026-08-15, and a lane read the module, believed the transport live, planned against it, and was corrected by its reviewing authority — the cost is measured, not hypothetical. Second specimen, same origin: `gunbc.ci_failure_class` stated its dissolution trigger as calling `classify_failure_reason` *the way claim_executor already resolves* `gunbc.floor_component_receipt`; `write_floor_component_receipt_at` did exactly that from 2026-07-30 (gunbc#7467) until gunbc#9228 deleted it on 2026-08-25. ORIGIN 2, THE CITED SYMBOL DIED WHILE ITS CONTENT SURVIVED AS AN ANNOTATION, and this one has a corpus-wide producer: `v1_compiler.cli_run` twice cited `floor_component_resource_checkpoint_note` and `floor_component_phase_journal_scaffold_note`, which were real `data …: String` declarations in `gunbc.floor_component_receipt` until the 2026-08-30 prose-bankruptcy sweep (gunbc#9752) converted module-scope commentary rows into §4c annotations corpus-wide. §4c makes an annotation uncitable by construction — `v1_compiler.cli_run` `annotation_erased_scan_text` feeds the semantic passes, so annotation text is not present in the tree the citation harvester walks. **THE CONSEQUENCE IS THE OPPOSITE OF THE ONE THIS ROW FIRST DREW, AND THE CORRECTION IS THE INSTRUCTIVE PART.** The first revision reasoned that the sweep therefore broke every citation of a converted row, making the population the sweep's own diff. Measured by a separate lane (gunbc XL-0-CITE, 2026-09-01) against `v1_compiler.declaration_index`, whose only citation producers are `citation_from_record_literal` and `citation_from_constructor_call`: the typed-citation breakage is **ZERO**, computed both today and as of the sweep commit, on a control that discriminates in both directions. A plain name in annotation prose was never a citation, so the sweep could not break one. What that leaves is a REAL class with an honest ceiling rather than a defect population: these citations bind READERS and no mechanism, so they sit in §4b's *outside the modeled guarantee* column — observed and repaired by reading, never gated — and calling them a dangling-citation population would have been rung inflation about a check that by construction cannot see them. The two `cli_run` sites are genuine instances of the harm and there is no mechanical census that would have found them. ORIGIN 3, WRONG AUTHORITY FOR SOMETHING THAT STILL EXECUTES: `dag/test/claim/instrument_sandbox_witness_test` says its live half `runs on the falsifier lane`; that half sits on `FalsifierSubstrateLongLane`, which `std.witness_admission` `witness_cadence_has_scheduled_route` reports routeless — but it also carries a local recipe, and `OfflineLocalRecipe` HAS a route, so the relation is live and only the named authority is wrong. THE FOURTH, NEVER BACKED AT ALL, IS NOT ATTESTED IN THIS CORPUS and is recorded as unmeasured rather than as a population. **THIS ROW IS NOT THE AUTHORITY ON ANY POPULATION, and saying so is the point:** `gunbc.deleted_cadence_reference_census` already owns the falsifier-cadence instance of origin 1 — twelve sites, a `DeletedCadenceReferenceStanding` vocabulary whose `PremiseInvalidated` arm is exactly this class, and one `GuaranteeRungDrop` filed once for the shared executor rather than per site. A pattern row that restated its population would be a second authority for a fact that already has one, which is the §3 violation this row's own remedy is meant to prevent; so the census is cited here and nothing about its contents is copied. What belongs HERE is only the recognition rule and the remedy arms, which generalize past the falsifier. **THE MECHANICAL TEST for finding one is sharper than asking whether the verb is runs or is enrolled: resolve the claim against the authority that owns the relation, and ask whether the prose implies a live route for something that authority says has none.** The naive runs/enrolled discriminator loses one arm and it is the common one — `Enrolled on falsifier_rehomed_bin_wet_entries (nightly batch 5)` is nominally an enrollment claim, which is TRUE, but `nightly` asserts a cadence that executes and `FalsifierRehomedBinWet` is routeless, so the reader forms the false premise anyway. Three outcomes per line: asserts execution (contaminating), asserts enrollment only (true, leave it), asserts enrollment while implying a live cadence (contaminating). **THE REMEDY HAS THREE ARMS, KEYED TO WHAT THE AUTHORITY SAYS NOW, and picking the wrong one is itself an instance of this class.** Origin 1 → PAST TENSE WITH THE DATE, keeping the reasoning, because the reasoning usually outlives its executor and a reader who finds a dangling claim silently deleted learns nothing. Origin 2 → name the module and the FACT rather than the dead symbol, since §4c left no symbol to cite; past-tensing here would wrongly report the content as gone when only its citability is. Origin 3 → CORRECT IT to the authority that does back it, NOT past tense: past-tensing a live relation records it as dead and is a new contamination in the opposite direction, produced by the remedy itself. Origin 4 → say it was never backed, or delete the assertion while keeping any surviving reasoning; NEVER past tense, because there is no past to record, and `X USED TO resolve Y` asserts an execution that also never happened. **The default against deletion is a default and not an absolute: a sentence whose entire content is a false execution claim has no reasoning to preserve.** **THE SELF-RECEIPT, and it is the most useful thing in this row (2026-09-01):** the first revision of this entry asserted the `ci_failure_class` clause and the two `cli_run` notes as never-true, on the strength of a grep showing they resolve nowhere TODAY. **Both were true when written**, and the row about unbacked claims therefore contained two of them. It was caught by a reviewing authority asking for verification rather than inheritance, not by any check. **RECOGNITION RULE EARNED: `resolves nowhere now` is not `never resolved`, the distinction is decided by history and not by the working tree, and the instrument is `git log --all -S` over the DECLARATION FORM** — which also separates origin 1 from origin 2 by showing WHAT deleted the referent. The neighbouring rule is `positional_citation`'s: a citation left naming a deleted symbol fakes a grep hit, so every arm above records the change rather than quietly removing the name.) - **mitigation injected where the judgment declined** (a downstream stage injects a RUNTIME mitigation at exactly the seam where an upstream judgment returned Undecidable, so a 4b rung-1 fallback comes to occupy the place the wall belongs and the declined seam stops looking empty. **THE LOAD-BEARING HALF IS WHAT THE COINCIDENCE PROVES ABOUT THE DECLINE**: an Undecidable verdict is normally read as benign conservatism — the facts did not settle it, nothing is claimed, no harm asserted — and a mitigation landing on the SAME LINE is the first evidence that a real defect was sitting under that silence. The decline is therefore load-bearing AT THIS SITE, which refutes reading an Undecidable verdict as evidence of ABSENCE. **IT DOES NOT MAKE THE DECLINE CENSUS PREDICTIVE, and this row carries that limit because the author first wrote the stronger claim and then measured it FALSE** on the same board that produced the specimen: 259 of 272 declines sit in modules with ZERO blocking errors, only 6 of 28 decline-bearing modules carry any error at all, and the module holding 42 of the 63 errors carries ZERO declines and 105 ACCEPTS. Declines and defects are ANTI-CORRELATED at module grain, so this specimen is ONE co-location out of 272 and a walk of the decline census would be walking sites that are ~95% empty. The class is about a mitigation landing on a declined seam; it is NOT a claim that declines predict defects. Distinct from `absorbing_fallback`, whose arm WIDENS to a superset and destroys the precise mechanism s signal; here the arm NARROWS to a panic and destroys nothing except the evidence that a judgment was owed. Distinct from `reflection_evidence_structural_proof`, which mistakes an observation for a proof; here nothing is proven or observed — a decision was declined and then papered. Specimen with a receipt, measured 2026-09-01 on gunbc 0e8c49d and unrepaired at authoring: `v2.std.diagnostic outcome_accepted` is `fn outcome_accepted(value: T) -> Outcome` with T FREE; `v2.compiler.07_target_carriers target_fidelity_quotient_optional` declares `-> Outcome>` and calls `outcome_accepted(Present { value: child })`, so T instantiates to `Optional` and THE SOURCE IS CORRECT. The Rust emitter nonetheless rendered `Some(child).expect("fail-closed: an optional value flowed into non-optional parameter 0 of outcome_accepted (empty Optional at runtime)")`. FOUR DEFECTS IN ONE LINE: it fires on a GENERIC formal where `Optional` is a legitimate instantiation rather than a cardinality escape, so the check does not know T is free; it substitutes a runtime panic for a compile-time judgment; the emitted code does NOT typecheck anyway (rustc E0308 expected `Option>` found `Rc`), so the mitigation buys nothing while standing where the wall belongs; and its own panic string calls itself `fail-closed`, which is 4b rung inflation inside a string literal — a diagnostic naming the discipline it violates is worse than a silent one because it will be cited as evidence the discipline holds. The coincidence that makes this a class and not a bug: `v1.compiler.infer declared_type_inhabitance` returned InhabitanceUndecidable{UndecidableOptionalCarrier} at that module s ONLY optional-carrier decline, 07_target_carriers.dag:128:24 parameter `value` — the same line the emitter mitigated. RUNG FOUND AT: 1 (mitigatable) on a seam whose CEILING is 3 (structurally guaranteed), since generic-formal instantiation is decidable from modeled structure. CONSEQUENCE WITH ITS OWN TRIGGER, deliberately NOT folded into this row: wiring the optional-carrier judgment is argued by this specimen but is a separate change, and its trigger is a producer at that seam that can distinguish a FREE type variable from a declared non-optional formal — until that exists the judgment would decline for the same reason it declines today.) - **merge region excludes the shared tail** (a roster carrier whose rows are multi-line blocks ending in an identical suffix makes every two-lane append resolve WRONG BY DEFAULT. The three-way merge factors the shared suffix out of the conflict region, so the region holds two half-blocks above the markers and one tail below them, and the purely additive resolution -- delete the markers, keep both sides, which is the CORRECT resolution when the two appended rows are independent -- leaves the first row's closing lines belonging to the second. Specimen: this carrier, which conflicted on every integration of main across four merge bases in one session (2026-09-01) with a shared tail of `evidence: [],` and `}`; `gunbc.rung_drop` had the same shape with `}` alone. **THE CLASS IS LOUD, AND THAT IS THE HALF A REPORT OF IT WILL GET WRONG.** The first reading was that the severed row survives as a structurally broken declaration under which the natural check -- declared names against rostered names -- still passes, because both lists stay complete. Measured against a gunbc built at d0009ca531 on the resolved shape: it is a PARSE REFUSAL at the module index, `expected expression, found Eq`, because a `data` keyword cannot stand in record-field position. Nothing reaches the checks that reading worried about, so the cost is toil and not silent wrongness -- a load-bearing authority whose every integration lands a conflict whose natural resolution does not compile, hand-repaired each time. **RECOGNITION RULE: for a carrier two lanes append to, ask what suffix the appended units SHARE, because a conflict region never contains it -- whatever semantics live in that suffix are exactly what a resolution can drop.** THE REPAIR IS THE UNIT AND NOT A CHECK: make the appended unit one line, and the shared suffix is a blank separator carrying nothing. A brace-balance or name-join check written here would be the DESIGN section 4b decoration -- permanently green, because the compiler already refuses the only corpus it could fire on.) +- **a two-reader disagreement census is blind to the case where BOTH readers are wrong together** (an instrument whose subject is DISAGREEMENT between two producers of one answer reports AGREEMENT as healthy, so the population where both answer the same WRONG thing is scored green and is invisible to it by construction. The trap is that such an instrument is commissioned precisely to adjudicate a known-defective population, and it can be structurally incapable of seeing that population while looking perfectly well-formed and producing rows. **SPECIMEN, measured 2026-09-01.** `v1.tests.claim.carrier_realization_census` records, per type-reference occurrence, the legacy short-circuit key and the strict authority answer, and reports where they diverge. Its calibration control -- stated in docs/plans/carrier-realization-arbiter-repair-design.md -- requires the diagnostic-producing `DivergesWithExactIdentity` subset to reproduce arm A 25 sites, joined by source declaration and enclosing declaration, never by line. Run over the transitive import closure of `src/v2/compiler/01_tokenize.dag`, the module that emits the file where every arm-A site lives contributed 76 rows: 74 Agrees, 2 IdentityUnavailable, ZERO divergences, and all 26 of its `String`-named rows Agree. Every divergence row in the closure sat in `v2.std.text`, the DECLARING module, in the opposite direction. Empty intersection with the population the control exists to find. **THE SHAPE OF THE ABSENCE IS THE DIAGNOSIS, and it is what distinguishes this class from an over-broad walk.** `gunbc#9900` predicted the walk might visit occurrences the emitter never renders; that defect shows the target population PLUS extras. This showed the target population NOT AT ALL. Same instrument, same rows, opposite conclusions -- and only the shape separates them. **WHY BOTH READERS AGREE THERE**, read off `v1.compiler.emit_rust` `checkpoint_table_bypasses_identity_note` REACHABILITY CORRECTION rather than executed here: the short-circuit returns the host spelling before consulting any authority, and the authority answers from `type_reference_decl_file`, whose fallback returns the file containing the REFERENCE. Two readers, one wrong answer, perfect agreement. **RECOGNITION RULE: any two-reader comparison cited as CORRECTNESS coverage.** A differential oracle, a twin fixture, a cross-check, a self-hosted-versus-seed comparison, an A/B over two emitters -- each answers `do these two concur`, and none answers `is the answer right`. Ask what a SHARED error would look like in its output; if the answer is `indistinguishable from health`, the instrument cannot be the correctness evidence, whatever else it is good for. **THE REMEDY IS A DIFFERENT ORACLE, NOT A REPAIR OF THIS ONE.** The adjudicating instrument has to reach OUTSIDE the pair of readers for its ground truth -- for this specimen, a census of agreement-at-a-wrong-answer joined against emitted-crate diagnostics. Widening the occurrence set, fixing the walk, or adding a third reader that shares the same defective input do not help, and the first two are what a reader who diagnosed this as an over-broad walk would have spent. **Bounded against `executed_conjunct_discriminates_nothing`**: there a live gated conjunct never meets a population that would falsify it, and one authored fixture retires it; here the instrument meets its population on every run and reports it as healthy, so no fixture over this instrument can retire it. **Bounded against `instrument_output_read_as_subject_content`**: there the instrument answers its own question faithfully and a consumer substitutes the subject; here the instrument answers ITS OWN question faithfully too, and the defect is that its question -- do the readers concur -- was never the question that was asked.) +- **a census with an unresolvable fraction of its population reports a denominator it does not have** (an occurrence census that emits a third disposition for `could not determine` is honest at the row grain and misleading at the total grain: rows scored `identity unavailable` are neither agreements nor divergences, so any ratio taken over the reported total silently treats them as decided. **SPECIMEN, unowned and unexplained at filing (2026-09-01).** The `v1.tests.claim.carrier_realization_census` run over the `src/v2/compiler/01_tokenize.dag` closure produced 121 `IdentityUnavailable` rows -- roughly a tenth of its population. The earlier run recorded in docs/plans/carrier-realization-arbiter-repair-design.md, over the same subject module at the FRONT-END phase on 2026-08-21, reported `1142 rows: 1134 Agrees, 8 DivergesWithExactIdentity, 0 IdentityUnavailable`. Zero to a tenth, across a phase change nobody predicted it for. **BOTH RUNS ARE NAMED RATHER THAN THEIR NUMBERS INHERITED**: the earlier is the front-end-phase run the design itself later withdraws as measuring the wrong phase, and the later is the typed-graph census landed by `gunbc#9900`. They are not the same instrument and the pair is recorded to locate the question, not to compute a delta from. **RECOGNITION RULE: an instrument with a `cannot answer` disposition, whose consumers aggregate over the reported total.** Ask what fraction is undecided before reading any ratio, and treat the undecided fraction as a separate finding rather than as noise. **WHY IT IS FILED WITHOUT INVESTIGATION**: identity being unavailable is a different defect from the readers disagreeing, it has no owner, and it was found while running a control for an unrelated question. A row that records it with both runs named is what stops the next reader taking the census denominator at face value.) ## Declared rung drops (§4b(3)) diff --git a/src/v1/05_emit_rust.dag b/src/v1/05_emit_rust.dag index 8ffb8f45b35..24c08ad8711 100644 --- a/src/v1/05_emit_rust.dag +++ b/src/v1/05_emit_rust.dag @@ -562,7 +562,7 @@ fn rust_ground_opaque_kernel_type_name(name: String) -> String { data numeric_realization_relocation_note: String = "RELOCATED to v1.compiler.coercion (smart-ram-730, adhoc-2ea6fb98-a3f, 2026-08-21, review 54335): numeric_realization_identity_note, numeric_realization_roster_extension_note, numeric_realization_declaring_modules, decl_file_realizes_natively and rust_seed_host_numeric_alias moved there in full, completing the relocation checkpoint_table_bypasses_identity_note's structural_declaration_modules_for precedent already established for the negative-form (structural) half of this same two-authority shape -- this was the positive-form (native) half, still sitting in this module and reached back into by v1.compiler.coercion type_realization_decision, an import cycle DESIGN section 3 forbids (emit_rust already imports FROM coercion; coercion calling back into emit_rust closes the cycle). This module now imports only rust_seed_host_numeric_alias back from v1.compiler.coercion, exactly as it already imports lookup_checkpoint from there -- one direction, no cycle; numeric_realization_declaring_modules and decl_file_realizes_natively have no consumer left in this module, since rust_seed_host_numeric_alias was their only caller here and it moved with them. Agreed with swift-moth-294 (msg_502982ac, 2026-08-21) and sequenced behind gunbc#8716 (merged 2026-08-21T06:19:19Z), which is why the move landed now rather than when first proposed." -data checkpoint_table_bypasses_identity_note: String = "CEILING, STATED BECAUSE THE CODE DELIVERS LESS THAN THE DELETION OF RustCorpusRepr SUGGESTS. lookup_checkpoint is keyed on the BARE dag_name and is consulted BEFORE the identity-keyed arm, so any name carrying a checkpoint row in extdeps/languages/rust/types.dag bypasses declaration keying entirely. Nat carries no row and therefore discriminates correctly -- dag/std/nat.dag realizes natively, src/v2/std/nat.dag refuses. Names WITH a row do not. This is not a regression introduced here: the table was already bare-name keyed and the global corpus mode was hiding the question. It is the honest rung. The class is MECHANICALLY PREVENTABLE rather than structurally impossible, and its executing evidence is v1.tests.claim.checkpoint_identity_keying_witness_test, which asserts the CURRENT bypassing answers on purpose so the gap is counted instead of assumed closed. THAT CITATION WAS FALSE WHEN THIS NOTE FIRST LANDED AND IS REPAIRED RATHER THAN SOFTENED. It named the residue block generated by v1.compiler.compiler_tests_rust ct_groupcompletion_checkpoint_fires_under_faithful_corpus_test, which emits into a module declared `#[cfg(test)] mod compiler_tests;` inside the v1-compiler crate -- while the only test step CI runs is `cargo test -p v1-compiler-tests`, a SEPARATE package consuming v1-compiler as an ordinary dependency, so cfg(test) is never set for it and the block is not compiled, let alone executed. Measured rather than reasoned: that step's binary enumerates 30 tests and none is this one, against a positive control confirming the enumeration is non-empty. So a ceiling disclosure cited evidence that had never run -- DESIGN section 4b(1) rung honesty violated in the compiler's own self-description, which is worse than sitting low because an inflated class never ranks for climbing. The assertions were re-authored as an enrolled .dag witness and now execute (seven rows PASS, including the discriminating row where two declarations share the spelling Nat and answer differently); the superseded generated-Rust block is deleted rather than left standing as a second, silent copy. POPULATION (census by vivid-wren-870, who owns the rows): SEVEN of the table's names are also declared under src/v2 -- Int, Float, Bool, Symbol, Unit, String, Hash; Bytes, Secret and Json are not. That is a LOWER BOUND obtained by grepping line-start `type ` declarations under src/v2; it does not find names introduced any other way, and it says NOTHING about how many sites bite in any real closure. Three of the seven are the same shape as Int in that the v2 declaration is a genuinely different STRUCTURE rather than a spelling coincidence -- Int is GroupCompletion, String is FreeMonoid, Bool is a two-variant coproduct. Symbol and Unit are bodyless and may be declared-abstract rather than competing realizations, so their bypass may be harmless. Hash is the one that costs a GUARANTEE rather than merely a representation, and it belongs with the same-shape three rather than apart from them: the row targets v1_rt::Hash, which is `pub type Hash = String` in the seed, against a v2 declaration of Fnv1a64Structural -- a single-field record whose digest field is `String where lower_hex_16`. std.content_hash content_hash_family_constructor_note states the public forgeable record constructors are DELETED and that the where-refinement IS the construction wall, so realizing that type as a bare String alias renders away the carrier the wall is attached to. A name-keyed spelling row can therefore silently drop a §4b construction rung. Established from declarations at both ends (vivid-wren-870, re-read here); NO live site is claimed, because no closure reaching a v2-declared Hash through lookup_checkpoint has been emitted by either of us. NEXT-RUNG TRIGGER -- AND THE OBVIOUS SHAPE IS THE WRONG ONE. An earlier revision of this note named `the checkpoint rows gain a declaring-module column`. vivid-wren-870 refused that shape with an argument this note adopts: a TypeCheckpoint row is cited to the Rust reference and states how RUST spells a type, whereas which dag module declares Int is a gunbc-corpus fact, so a declaring-module column puts corpus data inside an extdeps upstream authority -- a layer inversion, and the same class as a row being asked a question its cited authority cannot answer. The expected terminal shape is TWO authorities rather than one wider one: extdeps keeps Rust type -> spelling, a corpus-side binding says this dag declaration realizes as that Rust type, and lookup_checkpoint keys on the second. That also lets the seven differ from each other, which one column keyed on a single module cannot express. Recorded as a proposal from the rows owner, not as a decision, and unbuilt at the time of writing. When it lands the residue assertions flip to None and the flip is the dissolution signal, not a regression. LANDED FOR HASH (this PR, T7): the second authority is v1.compiler.coercion structural_declaration_modules_for, a corpus-side row roster keyed on the dag_name and enumerating the modules whose declaration of that name is structural rather than native -- \"Hash\" => [\"src/v2/std/node.dag\"] is its one row. lookup_checkpoint (v1.compiler.coercion) now consults it before the bare-name table: when decl_file_declares_structurally holds, lookup_checkpoint refuses (none) rather than answering from the table, and every consumer that already carried a correct identity-arm fallback -- coerce_primitive_type, is_copy, literal_suffix, and the direct callers of lookup_checkpoint itself -- inherits the refusal once decl_file is threaded to the call, which it now is at every production call site across v1.compiler.emit_rust and v1.compiler.emit. table_present_hash_refuses_under_structural_declaration in the witness below is the flip this note predicted; it is no longer residue. LANDED FOR STRING (session merry-lark-67, per smart-ram-730's dispatch): structural_declaration_modules_for gained a second row, \"String\" => [\"src/v2/std/text.dag\", \"dag/std/string_type.dag\"] -- both declare `type String = FreeMonoid`, the structural free-monoid-over-Char carrier, never a host string, so a reference resolving to either module now refuses the bare-name table's `String`/`.to_string()` spelling instead of silently rendering it. residue_table_present_string_bypasses_identity in the legacy oracle (src/v1/tests/claim/checkpoint_identity_keying_witness_test.dag) is retired for the same reason table_present_hash_refuses_under_structural_declaration closed for Hash, and is replaced there by table_present_string_refuses_under_structural_declaration_text / _string_type rather than repaired back to a passing bypass -- the flip is the dissolution signal, not a regression. LANDED FOR BOOL (session merry-lark-67, corpus-wide histogram from smart-ram-730; corrected same session, commit 127ad848070, per review 54257): structural_declaration_modules_for gained a third row, \"Bool\" => [\"src/v2/std/logic.dag\"] -- the initial enrollment mirrored String's two-row shape onto Bool and also listed dag/std/types.dag, but that module is the ordinary corpus-wide native Bool prelude (imported by 300+ dag/test/claim modules with no bit/width/encoding modeling riding on it), directly analogous to dag/std/integer.dag for Int, which sits in the POSITIVE numeric_realization_declaring_modules roster, never the negative structural one. Only src/v2/std/logic.dag's Bool is genuinely structural, carrying BoolWidthFact/BoolEncodingFact/BooleanAlgebra modeling over the two-variant coproduct; a reference resolving to it refuses the bare-name table's `bool`/`false` spelling instead of silently rendering it, while a reference resolving to dag/std/types.dag renders natively as designed. The over-broad row caused required-floor to refuse native bool rendering for 5 unrelated fixtures (e0308_mechanical_trio_test, optional_carrier_signature_test) and caused required-regen to see drift across the self-hosted std_*.rs mirrors; both are the fabricated-plausible-ceiling failure this note elsewhere criticizes, disclosed and repaired here rather than left standing. Bool never had a residue row in the legacy oracle to flip; it lands directly as one CLOSED row, table_present_bool_refuses_under_structural_declaration_logic, alongside table_present_bool_renders_natively_for_the_corpus_prelude confirming dag/std/types.dag's native rendering. KNOWN GAP THIS ROW DOES NOT CLOSE, FOUND WHILE MEASURING IT: emit_typed_item's type-alias arm special-cases `item_text == \"String\"` UNCONDITIONALLY -- rust_string_grounded_type_alias_decl_line emits `pub type String = std::string::String;` at the DECLARATION site regardless of decl_file, never consulting rust_scalar_checkpoint_render_base or this roster at all. So the module that declares `type String = FreeMonoid` keeps emitting itself as a host-String alias even after this row makes every REFERENCE to it refuse the bare-name table; the declaration and its own references can now disagree in the SAME emitted file. THAT KNOWN GAP IS NOW CLOSED, AND THE ROOT WAS NOT WHERE THIS NOTE PUT IT. The gap as recorded: emit_typed_item's type-alias arm special-cased `item_text == \"String\"` UNCONDITIONALLY, emitting `pub type String = std::string::String;` at the DECLARATION site regardless of decl_file and never consulting the identity-keyed authority every REFERENCE already routed through, so one emitted file could disagree with itself. This note framed that as a second bare-name bypass to be deleted. IT WAS NOT. The arm was COMPENSATING, and deleting it alone would have emitted `pub type String = String;` -- self-referential, because the checkpoint's target_type for String is the bare spelling `String` and the declaration site uses target_type as the alias's right-hand side. The real defect was that ONE FIELD CARRIED TWO SPELLING ROLES (the word arity is avoided here on purpose -- in this module it already means type-parameter count, see AliasDeclArityVerdict and rust_checkpoint_scalar_declared_arity_guard_note): one field answering two questions -- what a REFERENCE renders (bare `String`, correct and idiomatic) and what a DECLARATION is GROUNDED IN (`std::string::String`, the spelling no alias can shadow). Whichever spelling one field carried, one consumer was wrong, and the arm was the visible cost of making it try. std.coercion TypeCheckpoint now carries both spellings as separate fields; rust_scalar_checkpoint_reference_base and rust_scalar_checkpoint_grounding_base are two named entry points over one shared identity-keyed body, so every PRODUCTION caller states which question it asks by visibly naming it rather than by passing an argument. That is mechanically preventable, NOT structurally impossible: the shared body stays reachable and carries the discriminator, .dag has no function-privacy concept to hide it behind (the emitted emitter carries 665 pub fn and zero non-pub), and the next-rung trigger is a module-private function boundary in the language. The standing evidence for the narrower claim is that the shared body's only direct callers are the two wrappers; the three reference callers read the reference spelling, the single declaration-RHS caller reads grounding, and the arm is DELETED rather than guarded. WHAT THIS STILL DOES NOT CLOSE, stated so the ceiling is not read as retired: lookup_checkpoint's FIRST arm answers straight from the bare-name table when decl_file is the empty string, consulting no roster at all, so every site reaching emission with UNKNOWN declaration identity still realizes from the table exactly as this note describes. That bypass is live, its population is UNCOUNTED, and no estimate is offered here. It is a separate defect from the two-role split -- the split governs what a row can SAY once identity is known; the bypass governs whether identity is consulted at all -- and it is filed as its own row rather than folded into this one. HOW THIS CLOSURE AND THE REACHABILITY CORRECTION BELOW RELATE, because each narrows the other and reading either alone overstates it: the two-role split is what makes the DECLARATION site able to consult the identity-keyed authority at all, and royal-dove-436's finding is that the REFERENCE site for a String-spelled type never reaches lookup_checkpoint in the first place. So for String specifically the split repairs a position that was answering wrongly, while the position this note elsewhere calls gated is not yet reached -- the declaration half is closed and the reference half is unreachable, which is one authority with two different reasons its consumers do not see it, not one gap. Neither finding weakens the other and neither is the whole story for String; the split is stated here as closing the arm it deletes, never as making every String position identity-keyed. REACHABILITY CORRECTION (royal-dove-436, adhoc-c735d227-60b, 2026-08-21, measured on the 03_ingest closure): TWO CLAIMS ABOVE ARE FALSE FOR STRING AND ARE CORRECTED HERE RATHER THAN SOFTENED -- the LANDED FOR STRING clause's 'a reference resolving to either module now refuses the bare-name table's String/.to_string() spelling instead of silently rendering it', and the KNOWN GAP clause's 'even after this row makes every REFERENCE to it refuse the bare-name table'. The row does not make every reference refuse, because a String-spelled reference in TYPE position never reaches lookup_checkpoint at all. SIX type renderers in this module -- render_rust_type, render_rust_type_without_applied_binding, render_rust_applied_type, render_rust_type_with_applied_binding, render_rust_decl_type and render_rust_fn_sig_type -- each RETURN ON THEIR FIRST LINE (verified: the call is the statement immediately following each fn's own declaration) via is_host_text_carrier_type, rendering the literal \"String\" unconditionally on decl_file, ahead of every checkpoint or roster consultation; and is_host_text_carrier_type accepts the spelling String outright, so no path through those six can reach type_realization_decision's Unrealized-via-structural-gate arm for it. THE ROW IS THEREFORE PRESENT, UNREACHABLE, AND MIS-KEYED FOR THE TEXT CARRIER IN TYPE POSITION -- an unreachable wall rather than a missing one, which is DESIGN section 6's coverage-by-illusion and a section 4b rung this note previously reported as held. THAT SENTENCE READ 'PRESENT, CORRECT, AND UNREACHABLE' UNTIL THIS EDIT, AND IT WAS WRONG IN THE DIRECTION THAT MATTERS. The authority's LOGIC was checked and its KEY was not, and a total function over a wrong key does not fail -- it returns a confidently wrong answer. The key defect is type_reference_decl_file's fallback arm, which cannot distinguish 'this node IS the declaration' from 'this is a reference whose declaration was not recovered here' and in the second case returns the file containing the REFERENCE: the identity key is a LOCATION. THE CONSEQUENCE FOR THE OBVIOUS REPAIR IS THE REASON THIS CORRECTION IS WORTH A REGEN: reading 'correct but unreachable' makes deleting the six short-circuits look SUFFICIENT, and it is not, because what the deletion then reaches is mis-keyed. The deletion is the right EVENTUAL repair and the wrong FIRST move, and the prescribed first step is instead the STATIC decision-divergence census -- how many occurrences the authority answers differently from the short-circuit -- which is computable without emitting, where a deletion produces only the diagnostic-conversion quantity and no record of the divergence that would make it adjudicable. The retraction is restated HERE rather than left in the design document alone because THIS NOTE WAS RELAYED UPWARD AND ITS SUPERSEDED SENTENCE WAS RESTATED AS FACT, which is the DESIGN section 4b(1) rung-honesty failure applied to the compiler's own self-description: a reader who stops at this sentence must not leave with the retracted claim. Authority for every clause above: docs/plans/carrier-realization-arbiter-repair-design.md, whose sections 1 and 2 carry the 52-row arm census and the two refuted repairs. This is a REACHABILITY claim about String's reference-site gate; it does NOT touch the Hash clause above, whose 'NO live site is claimed' is scoped to a v2-declared Hash reaching lookup_checkpoint and is unaffected, and it is a DIFFERENT mechanism from the declaration-site alias line the KNOWN GAP clause otherwise describes. SUPPORTING EVIDENCE, cited as a population rather than as the basis of the claim: 34 live E0308 sites in the 03_ingest closure pair a String-declared field or parameter against a FreeMonoid-realized value, every one of them a type position that rendered the native spelling while the roster says the declaration is structural (docs/probes/t2_t3_realization_route_2026-08-21.md, per-site TSV beside it). ESTABLISHED HOW, because the distinction decides what would falsify this: the reachability claim is decidable from the five renderers' control flow, which is how it was established -- NOT by a discriminating execution, and it says nothing about a sixth renderer that may handle some type position without that preamble. NEXT-RUNG TRIGGER: the short-circuit family is deleted so the existing authority becomes reachable, per docs/plans/carrier-realization-arbiter-repair-design.md, which also counts the decl_file == \"\" residue this module contributes (four sites) that the DECLARED RESIDUE note in v1.compiler.coercion says is uncounted. That design leaves the structural-vs-native direction to its owner and proposes an emit-only blast-radius measurement, not a merge, as the next step -- deliberately, because the over-broad Bool row recorded above is what picking a direction without that measurement already cost once. Int, Float, Symbol remain open -- they have no row in structural_declaration_modules_for -- and are the population the next instance of this class (a name question answered by authored spelling instead of declaration identity) inherits, per the class-level framing this ceiling was folded into. The roster is deliberately a single generic, identity-keyed mechanism with one row rather than a Hash-specific special case, so a future row for Int or String is an addition to this same authority, not a new mechanism. MEASURED CONSEQUENCE AT ARTIFACT GRAIN, added after this note first landed: the bypass is observable in the emitted FILE SET, not only in the emitter's answer. In a two-arm emission of one v2-only closure the file v2_std_integer.rs is present before the cut and ABSENT after it. That module declares exactly one item, the v2-declared structural Int, and its only type-position consumer was a single generated re-export line in std_algebra.rs; with Int reaching the bare-name checkpoint the re-export is no longer generated, nothing references the module, and it is not emitted. Every other hunk in that file is an offset shift from the deleted line -- the Int string literals are unchanged and the i64 count in the file is identical across arms, so nothing became native that was structural. AND THE DROP IS THE MINORITY CASE -- THE WRONG REALIZATION IS EMITTED, NOT AVOIDED. Across eleven emitted closures measured by smart-ibex-716 (corpus a6bceb6903, binaries a6bceb6903 and ad05a2f2d5), the module disappears in only 2; in the other 9 it SURVIVES with its content changed, from pub type Int = GroupCompletion> to pub type Int = i64. So the native realization of the v2-declared Peano-completion type is already present in the emitted artifact. What is absent is only a consumer: the same census found ZERO type-position uses of the v2 Int in any of the eleven -- every qualified occurrence sits on a use line, and the only bare occurrences surviving a use-line exclusion were four string literals inside prose, one of them a parser test fixture. Two false positives were found and discarded on the way to that zero, both by pulling the specimen rather than trusting the count. The residue is therefore NOT a dead re-export being dropped, which was this note's first reading and is corrected here; it is a wrong realization sitting inert with no diagnostic attached, so the day any declaration binds a bare Int in one of those closures it binds i64 silently. THE HAZARD TRIGGER IS THEREFORE A TYPE POSITION APPEARING, not the re-export returning. This is recorded because a module leaving OR silently changing an alias target is the kind of consequence a content-only diff of one closure reads as offset noise: the instruments that name it are a file-set diff and a cross-closure alias-target read, and neither was in this PR's original receipt." +data checkpoint_table_bypasses_identity_note: String = "CEILING, STATED BECAUSE THE CODE DELIVERS LESS THAN THE DELETION OF RustCorpusRepr SUGGESTS. lookup_checkpoint is keyed on the BARE dag_name and is consulted BEFORE the identity-keyed arm, so any name carrying a checkpoint row in extdeps/languages/rust/types.dag bypasses declaration keying entirely. Nat carries no row and therefore discriminates correctly -- dag/std/nat.dag realizes natively, src/v2/std/nat.dag refuses. Names WITH a row do not. This is not a regression introduced here: the table was already bare-name keyed and the global corpus mode was hiding the question. It is the honest rung. The class is MECHANICALLY PREVENTABLE rather than structurally impossible, and its executing evidence is v1.tests.claim.checkpoint_identity_keying_witness_test, which asserts the CURRENT bypassing answers on purpose so the gap is counted instead of assumed closed. THAT CITATION WAS FALSE WHEN THIS NOTE FIRST LANDED AND IS REPAIRED RATHER THAN SOFTENED. It named the residue block generated by v1.compiler.compiler_tests_rust ct_groupcompletion_checkpoint_fires_under_faithful_corpus_test, which emits into a module declared `#[cfg(test)] mod compiler_tests;` inside the v1-compiler crate -- while the only test step CI runs is `cargo test -p v1-compiler-tests`, a SEPARATE package consuming v1-compiler as an ordinary dependency, so cfg(test) is never set for it and the block is not compiled, let alone executed. Measured rather than reasoned: that step's binary enumerates 30 tests and none is this one, against a positive control confirming the enumeration is non-empty. So a ceiling disclosure cited evidence that had never run -- DESIGN section 4b(1) rung honesty violated in the compiler's own self-description, which is worse than sitting low because an inflated class never ranks for climbing. The assertions were re-authored as an enrolled .dag witness and now execute (seven rows PASS, including the discriminating row where two declarations share the spelling Nat and answer differently); the superseded generated-Rust block is deleted rather than left standing as a second, silent copy. POPULATION (census by vivid-wren-870, who owns the rows): SEVEN of the table's names are also declared under src/v2 -- Int, Float, Bool, Symbol, Unit, String, Hash; Bytes, Secret and Json are not. That is a LOWER BOUND obtained by grepping line-start `type ` declarations under src/v2; it does not find names introduced any other way, and it says NOTHING about how many sites bite in any real closure. Three of the seven are the same shape as Int in that the v2 declaration is a genuinely different STRUCTURE rather than a spelling coincidence -- Int is GroupCompletion, String is FreeMonoid, Bool is a two-variant coproduct. Symbol and Unit are bodyless and may be declared-abstract rather than competing realizations, so their bypass may be harmless. Hash is the one that costs a GUARANTEE rather than merely a representation, and it belongs with the same-shape three rather than apart from them: the row targets v1_rt::Hash, which is `pub type Hash = String` in the seed, against a v2 declaration of Fnv1a64Structural -- a single-field record whose digest field is `String where lower_hex_16`. std.content_hash content_hash_family_constructor_note states the public forgeable record constructors are DELETED and that the where-refinement IS the construction wall, so realizing that type as a bare String alias renders away the carrier the wall is attached to. A name-keyed spelling row can therefore silently drop a §4b construction rung. Established from declarations at both ends (vivid-wren-870, re-read here); NO live site is claimed, because no closure reaching a v2-declared Hash through lookup_checkpoint has been emitted by either of us. NEXT-RUNG TRIGGER -- AND THE OBVIOUS SHAPE IS THE WRONG ONE. An earlier revision of this note named `the checkpoint rows gain a declaring-module column`. vivid-wren-870 refused that shape with an argument this note adopts: a TypeCheckpoint row is cited to the Rust reference and states how RUST spells a type, whereas which dag module declares Int is a gunbc-corpus fact, so a declaring-module column puts corpus data inside an extdeps upstream authority -- a layer inversion, and the same class as a row being asked a question its cited authority cannot answer. The expected terminal shape is TWO authorities rather than one wider one: extdeps keeps Rust type -> spelling, a corpus-side binding says this dag declaration realizes as that Rust type, and lookup_checkpoint keys on the second. That also lets the seven differ from each other, which one column keyed on a single module cannot express. Recorded as a proposal from the rows owner, not as a decision, and unbuilt at the time of writing. When it lands the residue assertions flip to None and the flip is the dissolution signal, not a regression. LANDED FOR HASH (this PR, T7): the second authority is v1.compiler.coercion structural_declaration_modules_for, a corpus-side row roster keyed on the dag_name and enumerating the modules whose declaration of that name is structural rather than native -- \"Hash\" => [\"src/v2/std/node.dag\"] is its one row. lookup_checkpoint (v1.compiler.coercion) now consults it before the bare-name table: when decl_file_declares_structurally holds, lookup_checkpoint refuses (none) rather than answering from the table, and every consumer that already carried a correct identity-arm fallback -- coerce_primitive_type, is_copy, literal_suffix, and the direct callers of lookup_checkpoint itself -- inherits the refusal once decl_file is threaded to the call, which it now is at every production call site across v1.compiler.emit_rust and v1.compiler.emit. table_present_hash_refuses_under_structural_declaration in the witness below is the flip this note predicted; it is no longer residue. LANDED FOR STRING (session merry-lark-67, per smart-ram-730's dispatch): structural_declaration_modules_for gained a second row, \"String\" => [\"src/v2/std/text.dag\", \"dag/std/string_type.dag\"] -- both declare `type String = FreeMonoid`, the structural free-monoid-over-Char carrier, never a host string, so a reference resolving to either module now refuses the bare-name table's `String`/`.to_string()` spelling instead of silently rendering it. residue_table_present_string_bypasses_identity in the legacy oracle (src/v1/tests/claim/checkpoint_identity_keying_witness_test.dag) is retired for the same reason table_present_hash_refuses_under_structural_declaration closed for Hash, and is replaced there by table_present_string_refuses_under_structural_declaration_text / _string_type rather than repaired back to a passing bypass -- the flip is the dissolution signal, not a regression. LANDED FOR BOOL (session merry-lark-67, corpus-wide histogram from smart-ram-730; corrected same session, commit 127ad848070, per review 54257): structural_declaration_modules_for gained a third row, \"Bool\" => [\"src/v2/std/logic.dag\"] -- the initial enrollment mirrored String's two-row shape onto Bool and also listed dag/std/types.dag, but that module is the ordinary corpus-wide native Bool prelude (imported by 300+ dag/test/claim modules with no bit/width/encoding modeling riding on it), directly analogous to dag/std/integer.dag for Int, which sits in the POSITIVE numeric_realization_declaring_modules roster, never the negative structural one. Only src/v2/std/logic.dag's Bool is genuinely structural, carrying BoolWidthFact/BoolEncodingFact/BooleanAlgebra modeling over the two-variant coproduct; a reference resolving to it refuses the bare-name table's `bool`/`false` spelling instead of silently rendering it, while a reference resolving to dag/std/types.dag renders natively as designed. The over-broad row caused required-floor to refuse native bool rendering for 5 unrelated fixtures (e0308_mechanical_trio_test, optional_carrier_signature_test) and caused required-regen to see drift across the self-hosted std_*.rs mirrors; both are the fabricated-plausible-ceiling failure this note elsewhere criticizes, disclosed and repaired here rather than left standing. Bool never had a residue row in the legacy oracle to flip; it lands directly as one CLOSED row, table_present_bool_refuses_under_structural_declaration_logic, alongside table_present_bool_renders_natively_for_the_corpus_prelude confirming dag/std/types.dag's native rendering. KNOWN GAP THIS ROW DOES NOT CLOSE, FOUND WHILE MEASURING IT: emit_typed_item's type-alias arm special-cases `item_text == \"String\"` UNCONDITIONALLY -- rust_string_grounded_type_alias_decl_line emits `pub type String = std::string::String;` at the DECLARATION site regardless of decl_file, never consulting rust_scalar_checkpoint_render_base or this roster at all. So the module that declares `type String = FreeMonoid` keeps emitting itself as a host-String alias even after this row makes every REFERENCE to it refuse the bare-name table; the declaration and its own references can now disagree in the SAME emitted file. THAT KNOWN GAP IS NOW CLOSED, AND THE ROOT WAS NOT WHERE THIS NOTE PUT IT. The gap as recorded: emit_typed_item's type-alias arm special-cased `item_text == \"String\"` UNCONDITIONALLY, emitting `pub type String = std::string::String;` at the DECLARATION site regardless of decl_file and never consulting the identity-keyed authority every REFERENCE already routed through, so one emitted file could disagree with itself. This note framed that as a second bare-name bypass to be deleted. IT WAS NOT. The arm was COMPENSATING, and deleting it alone would have emitted `pub type String = String;` -- self-referential, because the checkpoint's target_type for String is the bare spelling `String` and the declaration site uses target_type as the alias's right-hand side. The real defect was that ONE FIELD CARRIED TWO SPELLING ROLES (the word arity is avoided here on purpose -- in this module it already means type-parameter count, see AliasDeclArityVerdict and rust_checkpoint_scalar_declared_arity_guard_note): one field answering two questions -- what a REFERENCE renders (bare `String`, correct and idiomatic) and what a DECLARATION is GROUNDED IN (`std::string::String`, the spelling no alias can shadow). Whichever spelling one field carried, one consumer was wrong, and the arm was the visible cost of making it try. std.coercion TypeCheckpoint now carries both spellings as separate fields; rust_scalar_checkpoint_reference_base and rust_scalar_checkpoint_grounding_base are two named entry points over one shared identity-keyed body, so every PRODUCTION caller states which question it asks by visibly naming it rather than by passing an argument. That is mechanically preventable, NOT structurally impossible: the shared body stays reachable and carries the discriminator, .dag has no function-privacy concept to hide it behind (the emitted emitter carries 665 pub fn and zero non-pub), and the next-rung trigger is a module-private function boundary in the language. The standing evidence for the narrower claim is that the shared body's only direct callers are the two wrappers; the three reference callers read the reference spelling, the single declaration-RHS caller reads grounding, and the arm is DELETED rather than guarded. WHAT THIS STILL DOES NOT CLOSE, stated so the ceiling is not read as retired: lookup_checkpoint's FIRST arm answers straight from the bare-name table when decl_file is the empty string, consulting no roster at all, so every site reaching emission with UNKNOWN declaration identity still realizes from the table exactly as this note describes. That bypass is live, its population is UNCOUNTED, and no estimate is offered here. It is a separate defect from the two-role split -- the split governs what a row can SAY once identity is known; the bypass governs whether identity is consulted at all -- and it is filed as its own row rather than folded into this one. HOW THIS CLOSURE AND THE REACHABILITY CORRECTION BELOW RELATE, because each narrows the other and reading either alone overstates it: the two-role split is what makes the DECLARATION site able to consult the identity-keyed authority at all, and royal-dove-436's finding is that the REFERENCE site for a String-spelled type never reaches lookup_checkpoint in the first place. So for String specifically the split repairs a position that was answering wrongly, while the position this note elsewhere calls gated is not yet reached -- the declaration half is closed and the reference half is unreachable, which is one authority with two different reasons its consumers do not see it, not one gap. Neither finding weakens the other and neither is the whole story for String; the split is stated here as closing the arm it deletes, never as making every String position identity-keyed. REACHABILITY CORRECTION (royal-dove-436, adhoc-c735d227-60b, 2026-08-21, measured on the 03_ingest closure): TWO CLAIMS ABOVE ARE FALSE FOR STRING AND ARE CORRECTED HERE RATHER THAN SOFTENED -- the LANDED FOR STRING clause's 'a reference resolving to either module now refuses the bare-name table's String/.to_string() spelling instead of silently rendering it', and the KNOWN GAP clause's 'even after this row makes every REFERENCE to it refuse the bare-name table'. The row does not make every reference refuse, because a String-spelled reference in TYPE position never reaches lookup_checkpoint at all. SIX type renderers in this module -- render_rust_type, render_rust_type_without_applied_binding, render_rust_applied_type, render_rust_type_with_applied_binding, render_rust_decl_type and render_rust_fn_sig_type -- each RETURN ON THEIR FIRST LINE (verified: the call is the statement immediately following each fn's own declaration) via is_host_text_carrier_type, rendering the literal \"String\" unconditionally on decl_file, ahead of every checkpoint or roster consultation; and is_host_text_carrier_type accepts the spelling String outright, so no path through those six can reach type_realization_decision's Unrealized-via-structural-gate arm for it. THE ROW IS THEREFORE PRESENT, UNREACHABLE, AND MIS-KEYED FOR THE TEXT CARRIER IN TYPE POSITION -- an unreachable wall rather than a missing one, which is DESIGN section 6's coverage-by-illusion and a section 4b rung this note previously reported as held. THAT SENTENCE READ 'PRESENT, CORRECT, AND UNREACHABLE' UNTIL THIS EDIT, AND IT WAS WRONG IN THE DIRECTION THAT MATTERS. The authority's LOGIC was checked and its KEY was not, and a total function over a wrong key does not fail -- it returns a confidently wrong answer. The key defect is type_reference_decl_file's fallback arm, which cannot distinguish 'this node IS the declaration' from 'this is a reference whose declaration was not recovered here' and in the second case returns the file containing the REFERENCE: the identity key is a LOCATION. THE CONSEQUENCE FOR THE OBVIOUS REPAIR IS THE REASON THIS CORRECTION IS WORTH A REGEN: reading 'correct but unreachable' makes deleting the six short-circuits look SUFFICIENT, and it is not, because what the deletion then reaches is mis-keyed. The deletion is the right EVENTUAL repair and the wrong FIRST move, and the prescribed first step is instead the STATIC decision-divergence census -- how many occurrences the authority answers differently from the short-circuit -- which is computable without emitting, where a deletion produces only the diagnostic-conversion quantity and no record of the divergence that would make it adjudicable. The retraction is restated HERE rather than left in the design document alone because THIS NOTE WAS RELAYED UPWARD AND ITS SUPERSEDED SENTENCE WAS RESTATED AS FACT, which is the DESIGN section 4b(1) rung-honesty failure applied to the compiler's own self-description: a reader who stops at this sentence must not leave with the retracted claim. Authority for every clause above: docs/plans/carrier-realization-arbiter-repair-design.md, whose sections 1 and 2 carry the 52-row arm census and the two refuted repairs. This is a REACHABILITY claim about String's reference-site gate; it does NOT touch the Hash clause above, whose 'NO live site is claimed' is scoped to a v2-declared Hash reaching lookup_checkpoint and is unaffected, and it is a DIFFERENT mechanism from the declaration-site alias line the KNOWN GAP clause otherwise describes. SUPPORTING EVIDENCE, cited as a population rather than as the basis of the claim: 34 live E0308 sites in the 03_ingest closure pair a String-declared field or parameter against a FreeMonoid-realized value, every one of them a type position that rendered the native spelling while the roster says the declaration is structural (docs/probes/t2_t3_realization_route_2026-08-21.md, per-site TSV beside it). ESTABLISHED HOW, because the distinction decides what would falsify this: the reachability claim is decidable from the five renderers' control flow, which is how it was established -- NOT by a discriminating execution, and it says nothing about a sixth renderer that may handle some type position without that preamble. NEXT-RUNG TRIGGER: the short-circuit family is deleted so the existing authority becomes reachable, per docs/plans/carrier-realization-arbiter-repair-design.md, which also counts the decl_file == \"\" residue this module contributes (four sites) that the DECLARED RESIDUE note in v1.compiler.coercion says is uncounted. That design leaves the structural-vs-native direction to its owner and proposes an emit-only blast-radius measurement, not a merge, as the next step -- deliberately, because the over-broad Bool row recorded above is what picking a direction without that measurement already cost once. Int, Float, Symbol remain open -- they have no row in structural_declaration_modules_for -- and are the population the next instance of this class (a name question answered by authored spelling instead of declaration identity) inherits, per the class-level framing this ceiling was folded into. The roster is deliberately a single generic, identity-keyed mechanism with one row rather than a Hash-specific special case, so a future row for Int or String is an addition to this same authority, not a new mechanism. MEASURED CONSEQUENCE AT ARTIFACT GRAIN, added after this note first landed: the bypass is observable in the emitted FILE SET, not only in the emitter's answer. In a two-arm emission of one v2-only closure the file v2_std_integer.rs is present before the cut and ABSENT after it. That module declares exactly one item, the v2-declared structural Int, and its only type-position consumer was a single generated re-export line in std_algebra.rs; with Int reaching the bare-name checkpoint the re-export is no longer generated, nothing references the module, and it is not emitted. Every other hunk in that file is an offset shift from the deleted line -- the Int string literals are unchanged and the i64 count in the file is identical across arms, so nothing became native that was structural. AND THE DROP IS THE MINORITY CASE -- THE WRONG REALIZATION IS EMITTED, NOT AVOIDED. Across eleven emitted closures measured by smart-ibex-716 (corpus a6bceb6903, binaries a6bceb6903 and ad05a2f2d5), the module disappears in only 2; in the other 9 it SURVIVES with its content changed, from pub type Int = GroupCompletion> to pub type Int = i64. So the native realization of the v2-declared Peano-completion type is already present in the emitted artifact. What is absent is only a consumer: the same census found ZERO type-position uses of the v2 Int in any of the eleven -- every qualified occurrence sits on a use line, and the only bare occurrences surviving a use-line exclusion were four string literals inside prose, one of them a parser test fixture. Two false positives were found and discarded on the way to that zero, both by pulling the specimen rather than trusting the count. The residue is therefore NOT a dead re-export being dropped, which was this note's first reading and is corrected here; it is a wrong realization sitting inert with no diagnostic attached, so the day any declaration binds a bare Int in one of those closures it binds i64 silently. THE HAZARD TRIGGER IS THEREFORE A TYPE POSITION APPEARING, not the re-export returning. This is recorded because a module leaving OR silently changing an alias target is the kind of consequence a content-only diff of one closure reads as offset noise: the instruments that name it are a file-set diff and a cross-closure alias-target read, and neither was in this PR's original receipt. UPSTREAM OF THE SIX SHORT-CIRCUITS, RECORDED HERE BECAUSE THE REACHABILITY CORRECTION ABOVE READS AS THOUGH THE SPELLING HAD ONE MEANING TO SHORT-CIRCUIT ON (2026-09-01). It does not. A callee parameter type is re-resolved in the CALLER environment, so one declaration denotes two different types depending on which module is asking: measured on a fixture pair, a module declaring `type String = FreeMonoid` and calling its own `fn f(s: String)` refuses with the STRUCTURAL destination, while a foreign module with no import calling `v2.std.text` `string_head` refuses with the KERNEL one -- same declaration, same parameter, nothing between. So `is_host_text_carrier_type` is not merely answering from a spelling instead of an identity; the spelling it answers from is already CALLER-DEPENDENT before the renderer sees it, and deleting the short-circuits would expose an authority keyed on a location whose value is itself scope-relative. Three further facts belong to `calm-boar-314` measurements at gunbc#9929 and are cited rather than restated: the qualified spelling SILENCES the destination rather than pinning it (an `Int` is admitted at a qualified parameter in both scopes, against two different qualification targets); returns re-resolve on the same axis as parameters; and a single refusal can carry TWO disagreeing destinations for one parameter, which arises when two bindings for the spelling are simultaneously live in the resolving scope. None of that changes this note's next-rung trigger, and it is recorded because a reader planning the short-circuit deletion from the paragraph above would be planning against a one-meaning spelling that does not exist." // TWO ENTRY POINTS OVER ONE BODY, because a checkpoint answers two questions and the caller must // state which one it is asking. The shared body below decides WHETHER a checkpoint governs this