diff --git a/dag/gunbc/bare_name_identity_consumer_census.dag b/dag/gunbc/bare_name_identity_consumer_census.dag index 4ba3bca8d06..830ec3044c6 100644 --- a/dag/gunbc/bare_name_identity_consumer_census.dag +++ b/dag/gunbc/bare_name_identity_consumer_census.dag @@ -95,15 +95,35 @@ type BareNameConsumer { // live tree on 2026-08-22; the per-row method and the exact call-site lines are in // docs/probes/bare-name-identity-consumer-census-2026-08-22.md. Rows are NOT ordered by severity -- // ordering a roster by an author's severity judgement is what lets a reader stop reading early. +// FIVE CITATIONS IN THIS ROSTER WERE RE-AIMED BY THE type_reference_decl_file SPLIT (2026-09-02), +// AND NO ROW'S FINDING CHANGED. That change replaced `decl_file: String` with the coproduct +// std.coercion TypeDeclarationProvenance, which deleted the declarations five rows below pointed +// at -- so the declaration index refused them as CITED-DECLARATION-ABSENT. The pointers now name +// the declarations that answer the same question; the retired spellings survive verbatim in the +// `keys_on`, `holder_expression` and `what_is_emitted` prose, because that prose describes source +// as it stood when the row was swept and rewriting it would falsify the observation. +// +// type_reference_decl_file -> v1.std.core type_reference_provenance +// decl_identity_file -> v1.std.core declaration_provenance_of +// decl_file_declares_structurally -> v1.compiler.coercion provenance_declares_structurally +// rust_seed_host_numeric_alias -> v1.compiler.coercion provenance_host_numeric_alias +// lookup_checkpoint -> v1.compiler.coercion type_reference_realization +// +// NO ROW BELOW WAS RE-JUDGED, AND NOTHING HERE CLAIMS A RUNG FOR THIS ROSTER'S SUBJECT. Each row's +// `site`, `keys_on`, `outcome` and `reach` describes a call site the split did not touch, so the +// re-aimed pointers are a citation repair and nothing else. What the split did and did not change +// about the rung of THESE sites is a claim about this roster's subject, which this roster's own +// lane owns; it is recorded in gunbc.type_reference_decl_file_occurrence_census, under the change +// that authored it, rather than asserted here by a lane that does not own this carrier. data bare_name_identity_consumers: List = [ { - site: decl_ref(module_path: "v1.compiler.coercion", decl_name: "lookup_checkpoint"), + site: decl_ref(module_path: "v1.compiler.coercion", decl_name: "type_reference_realization"), fact_sought: "which Rust type this dag type realizes as", keys_on: "the bare dag_name against the extdeps checkpoint table, whenever decl_file is the empty string. A SECOND WAY THE SAME KEY MISSES, added 2026-08-22: the comparison against cp.dag_name is EXACT, so a QUALIFIED spelling cannot match a bare-keyed row at all -- the table is missed rather than mis-answered. crisp-crab-430 completed the leaf reduction that would close it, MEASURED IT, found it changed no emitted output anywhere but its own mirror, and REVERTED it rather than land an inert change inside a result narrative. Recorded here as a measured-inert repair rather than as an open item, because the next person to notice the exact comparison will otherwise re-derive and re-land it", - identity: AvailableUpstreamNotThreaded { nearest_holder: decl_ref(module_path: "v1.compiler.coercion", decl_name: "type_reference_decl_file") }, + identity: AvailableUpstreamNotThreaded { nearest_holder: decl_ref(module_path: "v1.std.core", decl_name: "type_reference_provenance") }, outcome: SilentWrongProviderAnswer { what_is_emitted: "the table's spelling for the name, with the structural-declaration roster never consulted" }, reach: ReachedByMeasuredPopulation { measurement: "v1.compiler.emit emit_literal passes the empty string for every String literal; executed as literal_suffix_production_call_site_never_threads_declaration_identity in v1.tests.claim.checkpoint_identity_keying_witness_test" }, - sibling: SiblingPresentButOrdered { sibling: decl_ref(module_path: "v1.compiler.coercion", decl_name: "decl_file_declares_structurally"), precedence: "the empty-string guard returns false before the roster is reached, so the roster runs only for callers that already threaded identity" }, + sibling: SiblingPresentButOrdered { sibling: decl_ref(module_path: "v1.compiler.coercion", decl_name: "provenance_declares_structurally"), precedence: "the empty-string guard returns false before the roster is reached, so the roster runs only for callers that already threaded identity" }, call_site_count: 10, }, { @@ -140,7 +160,7 @@ data bare_name_identity_consumers: List = [ site: decl_ref(module_path: "v1.compiler.emit_rust", decl_name: "rust_opaque_kernel_alias_carrier"), fact_sought: "which Rust carrier the opaque kernel names Json, Bytes and Symbol realize as", keys_on: "a three-name equality on the bare name, then coerce_primitive_type with decl_file hardcoded to the empty string INSIDE the function", - identity: AvailableAtSite { holder_expression: "type_reference_decl_file(n: n), computed one line earlier in the same arm for rust_seed_host_numeric_alias", adjacent_consulting_call: decl_ref(module_path: "v1.compiler.coercion", decl_name: "rust_seed_host_numeric_alias") }, + identity: AvailableAtSite { holder_expression: "type_reference_decl_file(n: n), computed one line earlier in the same arm for rust_seed_host_numeric_alias", adjacent_consulting_call: decl_ref(module_path: "v1.compiler.coercion", decl_name: "provenance_host_numeric_alias") }, outcome: SilentWrongProviderAnswer { what_is_emitted: "the kernel carrier spelling, for any declaration anywhere in the closure spelled Json, Bytes or Symbol" }, reach: ReachabilityUnmeasured { what_would_settle_it: "a second declaration spelled Json, Bytes or Symbol in an emitted closure; the three are named in checkpoint_table_bypasses_identity_note's seven-name population as NOT separately declared under src/v2, which bears on how likely reach is and does not establish it" }, sibling: SiblingPresentButOrdered { sibling: decl_ref(module_path: "v1.compiler.emit_rust", decl_name: "rust_scalar_checkpoint_grounding_base"), precedence: "at the two type-alias declaration arms the bare eligibility test is the FIRST branch and the identity-keyed grounding call is the ELSE, so the bare arm wins whenever it fires -- and the identity it would have needed is computed in that same else, as decl_identity_file(item: item)" }, @@ -180,7 +200,7 @@ data bare_name_identity_consumers: List = [ site: decl_ref(module_path: "v1.compiler.infer_emit_info", decl_name: "add_emit_item_summary"), fact_sought: "the emit-time summary, declaration item and function item for a declared name", keys_on: "the bare authored declaration name, inserted into three maps folded over EVERY module in the closure", - identity: AvailableAtSite { holder_expression: "decl_identity_file(item: item) -- the declaration node is the fold's own argument", adjacent_consulting_call: decl_ref(module_path: "v1.compiler.coercion", decl_name: "decl_identity_file") }, + identity: AvailableAtSite { holder_expression: "decl_identity_file(item: item) -- the declaration node is the fold's own argument", adjacent_consulting_call: decl_ref(module_path: "v1.std.core", decl_name: "declaration_provenance_of") }, outcome: SilentWrongProviderAnswer { what_is_emitted: "last write wins in module fold order: two modules declaring one spelling collapse to one summary, and every consumer keyed on that map inherits the survivor. A CLAIM OF A SECOND FAILURE MODE WAS ADDED HERE AND IS WITHDRAWN IN THE SAME DAY, recorded rather than deleted because both this carrier and a peer receipt cited it. The claim was that a QUALIFIED construction site misses this bare key outright and the phantom-parameter lookup then emits nothing -- a missing answer rather than a wrong provider. IT IS FALSIFIED BY ITS OWN REPAIR: crisp-crab-430 leaf-reduced that lookup key, the exact move that fixed the shared_types row, and the emitted output did not change by one line (0 phantom lines emitted, 13 E0063, 382 total, all unchanged). A key that is not the defect does not repair when corrected. The operative discriminator is MODULE LOCALITY, not spelling: the lookup consults the MODULE-LOCAL type env, every failing type is exclusively FOREIGN-constructed (8, 1, 5, 2, 3, 3 foreign against 0 same-module), and the one type whose phantom fields do emit is overwhelmingly same-module (Measure, 48 same-module against 31 foreign). So that specimen is a missing answer from a DIFFERENT lookup and is not this map harm. WHAT THIS COSTS THIS CENSUS, stated because the failure is partly mine: the two-arm control this row cited -- 8 bare-spelled sites emitting _phantom 8 of 8 on main against 0 for the same 8 sites spelled qualified -- was run here and the OBSERVATION stands, but it does not isolate what I said it isolated. Main spelling came WITH AN IMPORT; the branch spelling came without one. Spelling and import CO-VARIED across my two arms, so a control I described as one spelling difference was two differences, and I read the one that matched the map I was already looking at" }, reach: ReachedByMeasuredPopulation { measurement: "build_emit_graph_info folds all modules into one map with no collision arm; this is the denominator the variant, shared-type and field-type rows above are computed from" }, sibling: NoSiblingExists { what_would_have_to_be_built: "a summary map keyed on declaration identity rather than spelling -- this is the row DESIGN section 5's construction move points at. QUALIFIED BY A LATER MEASUREMENT, RELAYED NOT RUN HERE: crisp-bat-769 measured the consumer partition over this map and reports that RE-KEYING ALONE REPAIRS ZERO of the twenty-three consumers, because the two columns do not intersect -- several consumers SCAN the whole map rather than looking one entry up, and a scan is not repaired by a key (crisp-crab-430, same finding from the resolver side, and derive_variant_to_enum above is one of them). So this row is still the construction move and is NOT a one-edit fix: an identity key is the necessary carrier, and each scanning consumer separately has to be taught that two entries sharing a spelling is the refusing case. An earlier revision of this field said the key would let several other rows DISSOLVE; that is the shape to aim at and it is not what the measurement found, so it is stated as the target rather than as the consequence. Relayed through deep-ant-102 and not independently verified by this census" }, diff --git a/dag/gunbc/ci/ci_layer_roots.dag b/dag/gunbc/ci/ci_layer_roots.dag index bcc0f572a64..e08b6bc7359 100644 --- a/dag/gunbc/ci/ci_layer_roots.dag +++ b/dag/gunbc/ci/ci_layer_roots.dag @@ -41,6 +41,52 @@ import std.dissolution { DissolutionCondition, unbound_dissolution, dissolution_ data witness_layer_roots: List = ["dag", "src/v2"] +// WITNESS NAMESPACES THE REQUIRED FOLD DOES NOT EXECUTE, DECLARED SO A MACHINE CAN JOIN ON IT. +// +// WHY THIS ROW EXISTS AND WHY IT IS NOT THE COMPLEMENT OF `witness_layer_roots`. The floor's +// changed-witness projection blocks on any decline, which is right for a witness that COULD have +// run and did not. A root the fold structurally cannot reach is a different subject: its +// non-execution is already a declared 4b(2) tracked stall with a named trigger, so blocking it +// surfaces no new silence and instead forbids touching debt the tree has already declared -- +// including by the very program whose trigger is supposed to retire it. +// +// The arm that reads this MUST be fail-closed against THIS ROSTER and never against the absence of +// a match in `witness_layer_roots`. "Not declared executing" and "declared non-executing" are +// different claims: only the second carries the stall, the trigger and the operator ruling. Keying +// an exemption on the first grants it BY ABSENCE, so an unrostered tree, a typo'd path or a future +// src/v3 would go silently non-blocking -- authority substitution that reads as correct at the arm. +// +// THIS ROW SUPERSEDES the prose `witness_fold_src_v1_coverage_gap_note` carried here until +// 2026-09-02, which stated the same fact in a String no mechanism could read. Its irreducible +// rationale -- WHY the one-token `--source-root src/v1` fix was refused -- is preserved below +// because it is a judgement a reader cannot re-derive from the row: admitting src/v1 would also +// admit the 52 non-test .dag modules under it into the ONE shared flat prepared subject the fold +// depends on, and the v1 tree declares its own module population, so the fold's first census would +// be taken against a colliding subject nobody has run. Chasing coverage that way costs more than +// the gap it closes. +// +// IT EVAPORATES ON ITS OWN TRIGGER rather than needing deletion: when the namespace cut lands and +// src/v1 witnesses resolve by containment, the root leaves this roster, the exemption it grants +// disappears with it, and the arm goes dead by construction. It has no independent dissolution +// condition because it has no independent existence. +// THE GRAIN IS THE MODULE NAMESPACE, NOT THE FILESYSTEM ROOT, AND THAT IS FORCED RATHER THAN +// CHOSEN. The population this roster exempts is undiscovered BY DEFINITION -- the fold never +// enumerated the file -- so no file path exists at the arm to compare against a directory. The +// authored module identity is the only fact available there, so declaring a directory would be +// declaring something the consumer cannot read. +// +// It is faithful, measured rather than assumed (2026-09-02): every module named `v1.*` in the tree +// lives under src/v1 (zero outside), so the namespace prefix and the directory pick out the same +// modules. The correspondence is not exact in the other direction -- four fixture modules under +// src/v1 carry other names -- and those are deliberately NOT exempted: a narrower exemption is the +// fail-closed side of an inexact join. +data non_executing_witness_module_prefixes: List = ["v1"] + +// The 4b(2) standing the roster above carries, as a typed trigger rather than a sentence. Named as +// the CAPABILITY: bare cross-module references binding by containment, whose vehicle is the +// namespace cut -- explicitly NOT the floor getting faster and NOT widening the fold's roots. +data non_executing_witness_module_prefixes_restoration: DissolutionCondition = unbound_dissolution(description: "dissolve-on: bare cross-module references bind BY CONTAINMENT rather than by pool-membership coincidence, so src/v1 and src/v2 can share a prepared subject without their twelve last-segment collisions (artifact, coercion, common, compile, complexity, emit, infer, normalize, ownership, parse, resolve, tokenize) silently rebinding. Current vehicle: the namespace cut, gunbc#8282. Satisfied by NEITHER a faster floor NOR adding --source-root src/v1 to the required fold: both leave the collisions standing, which is the condition this roster exists to survive. When it is satisfied, the `v1` prefix leaves non_executing_witness_module_prefixes and the changed-witness exemption keyed on it disappears with the row.") + // The v2 entry roster a v2-emission phase compiles. // // THE COST DECISION THIS ROW RECORDS HAS BEEN RE-TAKEN AND CAME OUT THE OTHER WAY (operator @@ -1177,7 +1223,18 @@ fn bin_wet(entry: String, f: String) -> ScheduleWitnessEntry { data v1_claim_scoped_witness_batch_deleted_note: String = "THE SCOPED WITNESS BATCH IS DELETED (2026-08-15), and with it the only ScopedWitnessBatch instance that ever existed. It ran five file-grain v1 claim entries under a dag plus src/v1 source-root envelope, in a sequential child worker, so the v1 compiler closure could be resolved without widening witness_layer_roots for everything else.\n\nWHY IT COULD NOT SURVIVE AFFECTED-SET SELECTION. It was the last SelectionApplied consumer on the required path, and its 720-second clamp was derived (PR #8259) from a measured 565-second wall on the assumption that unrelated PRs skip it. With selection deleted the two available readings were both wrong: run it every PR and the required floor grows by roughly nine minutes under a clamp basis that no longer describes it, or keep a selection mechanism alive for one batch. Its cost was also never really the witnesses — the same receipt measured about 390 seconds of closure materialization before the first witness line and about 30 seconds of witness evaluation, so it was paying a whole second subject preparation to check thirty rows.\n\nWHAT THIS NARROWS, stated rather than implied: the five entries under src/v1/tests/claim have NO executing consumer. They are not covered by ordinary discovery, whose roots are dag plus src/v2. Their generated stage0 emissions still compile into the seed crate, which is not execution. This is a real loss of coverage over v1 parser and namespace-binding behavior, taken deliberately as part of deleting the floor rather than discovered later, and it is NOT backstopped by any cadence — the cadence lane those rows might have moved to was refused for the same reason the per-PR slot was: a second subject envelope is the defect, not the schedule it runs on.\n\nRESTORATION: one prepared subject spanning dag, src/v1 and src/v2, at which point a separate envelope, a separate worker, a separate clamp and a separate receipt family all stop existing and these rows are ordinary discovery." -data witness_fold_src_v1_coverage_gap_note: String = "DECLARED COVERAGE GAP (operator ruling relayed 2026-08-15, at the re-add #1 boundary). The required witness fold runs `claim_executor --required-ci --source-root dag --source-root src/v2` (the flag was `--required-floor` until the 2026-08-20 consolidation folded parse, regen and the floor into one invocation; the source roots are unchanged, so this gap is unchanged too), so every witness under src/v1 is OUTSIDE it. Measured at declaration: 116 `test fn` declarations across 15 files under src/v1/tests/claim. Their previous consumer was the scoped witness batch deleted above; nothing has replaced it, and no cadence backstops them.\n\nWHY THE ONE-TOKEN FIX WAS REFUSED. Adding --source-root src/v1 would also admit the 52 non-test .dag modules under src/v1 into the ONE shared prepared subject the fold depends on. That subject is a single flat namespace per scope, and the v1 tree declares its own module population; poisoning the fold's first census with collisions to chase coverage costs more than the gap, and a first measurement taken against a subject nobody has run before is not a measurement worth having.\n\nWHY IT IS DECLARED RATHER THAN QUIET. run_required_floor refuses internally when planned, executed and terminal identity counts disagree, precisely so a narrowed roster cannot present as a roster. That wall operates INSIDE the subject; it cannot see a population the subject never admitted. So the same honesty has to be carried here, in prose, at the boundary: the fold runs every witness IN ITS SUBJECT, and its subject is two roots, not three.\n\nPOPULATION LOCATION IS BRANCH-DEPENDENT (relayed 2026-08-15, after this row was authored). The 15 files are present on main and DELETED on integration/v1-cut, where a src/v1/**/*.dag root deletion swept 16 witness .dag files under src/v1/tests/claim — this population — as collateral. So a reader checking main and a reader checking that cut branch will disagree about whether the gap has a subject at all, and the dissolve-on below is only satisfiable on a branch where the files still exist. A per-file disposition proposal (re-home under a surviving subject, or retire with a receipt naming the rejected behavior) is routed elsewhere and is deliberately NOT acted on here; several of the 16 witness LANGUAGE behavior rather than v1-compiler behavior (§4c annotation capture and erasure, the line-continuation operator-table derivation), so a blanket retire would drop evidence for obligations the replacement still claims. This row stays a declared gap until that proposal lands, at which point it either dissolves for real (files re-homed and inside the fold) or converts to a retirement receipt.\n\nDISSOLVE-ON: the boundary decision on these 15 files. The recommendation carried into that decision is RELOCATION into the dag test root rather than widening the root set — one tree, one namespace, consistent with every cut currently consolidating away from src/v1 — with the caveat that three sibling cuts are reshaping src/v1 concurrently and some of these 116 may die with them, so the relocation census is taken at the boundary and not before it." +// `witness_fold_src_v1_coverage_gap_note` STOOD HERE UNTIL 2026-09-02 AND IS RETIRED, NOT LOST. +// It was a String declaring that the required witness fold does not reach src/v1 -- the fact +// `non_executing_witness_module_prefixes` above now owns as data. Leaving both would be one meaning with two +// names, which section 3 forbids, and the String was the half no mechanism could read: a gate arm +// needed this fact and had to be told to stop rather than infer it. The measurement it carried +// (116 `test fn` declarations across 15 files under src/v1/tests/claim, at declaration) is a +// dated observation rather than a live figure and is not re-asserted here; the roster names the +// namespace, and the population is whatever the tree currently holds under it. Its irreducible +// rationale -- why the one-token --source-root fix was refused -- is preserved at the roster. +// The two notes that cite this name in their own prose, v1_dead_witness_tree_triage_receipt and +// v1_claim_scoped_witness_batch_deleted_note, still read correctly: they cite what it SAID, and +// what it said is now declared above. data v1_dead_witness_tree_triage_receipt: String = "DISCHARGES witness_fold_src_v1_coverage_gap_note's routed-elsewhere per-file disposition proposal (dashboard node adhoc-9b80ec49-d63, session zesty-newt-828, 2026-08-18/19). COUNT CORRECTION: that note measured 116 test fn declarations across 15 files at 2026-08-15 declaration time; by the time this triage read the tree the population was 17 files (12 disposed directly in this receipt, plus 5 files — checkpoint_identity_keying_witness_test.dag, occurrence_binding_parser_walk_witness_test.dag, occurrence_identity_debt_receipt_test.dag, pattern_binder_declaration_node_test.dag, v1_match_pattern_identity_test.dag — dispositioned by a concurrent batch and not re-narrated here; ATTRIBUTION, confirmed against git show --stat 11113ac9e9: all 17 files, including these 5, were deleted in that ONE commit, one author (Brian Searls), on this same branch session/zesty-newt-828 — there is no separate sibling dashboard session to attribute for PR purposes, 'concurrent' here means a parallel work stream inside this session, not a different session's contribution; checkpoint_identity_keying_witness_test.dag alone is carved out to stern-fox-619's own PR per the binding scope exclusion, unaffected by this attribution). The 15-vs-17 gap is branch drift between 2026-08-15 and the triage read, not a miscount of either measurement.\n\nDISPOSITION, MIGRATED (relocated to dag/test/claim, rewritten onto compile_dag_rust_emit_check, running under ordinary discovery — source roots dag + src/v2, no v1 import): dag_parse_continuation_operator_witness_test.dag -> dag/test/claim/dag_parse_continuation_operator_witness_test.dag (8 of 9 tests migrated black-box; w_dual_role_exclusion_intersection_is_singleton_minus retired in-file, pure operator-table introspection with no compile-observable surface, its protected family covered black-box by the comparison-family test beside it). required_expr_newline_continuation_test.dag -> dag/test/claim/required_expr_newline_continuation_witness_test.dag (all 8 tests migrated 1:1, 5 parse-clean + 3 refuses-to-compile each paired against a proven-clean sibling). ordinary_frontend_observation_test.dag -> dag/test/claim/frontend_literal_and_compile_witness_test.dag (2 pure interpreter-literal tests moved unchanged, no v1 import ever needed; 2 compile-observation tests converted to compile_dag_rust_emit_check clean/broken-subject pairs). caret_parse_smoke_test.dag -> dag/test/claim/caret_syntax_witness_test.dag (3 black-box compile/emit-substring tests migrated; 7 white-box tokenizer/parser-internals tests retired in-file, no compile-observable equivalent). v1_annotation_target_emission_test.dag -> dag/test/claim/annotation_erasure_emission_witness_test.dag (the D-C property 4 erasure claim plus a non-vacuity control, both via compile_dag_rust_emit_check includes/excludes on emitted Rust text; not a byte-identical replay of the 2026-08-05 host-execution diff receipt, which stands as separate historical evidence).\n\nDISPOSITION, RETIRED (white-box, no compile-observable proxy for the same claim; deleted with this receipt as the record): v1_annotation_binding_test.dag, v1_annotation_capture_test.dag, v1_annotation_round_trip_test.dag, v1_annotation_erasure_test.dag — all four inspect v1-internal occurrence-identity/annotation-graph/span-provenance/node-fingerprint state directly (std.occurrence_identity, v1.compiler.annotation_bind, dag_node_surface_fingerprint) that has no representation in emitted Rust text; per DESIGN §4c, annotation capture/erasure is disjoint from semantic occurrence identity by construction, so these are facts about the FRONTEND's internal bookkeeping, not about a compiled program, and cannot be reduced to a compile_dag_rust_emit_check assertion without inventing a second v1-internal-state-reading surface this triage was not chartered to build. v1_annotation_erasure_test.dag's own erasure claim (prose does not leak into emitted output) is separately and already covered black-box by the migrated annotation_erasure_emission_witness_test.dag above — that file migrates v1_annotation_target_emission_test.dag, a distinct source, not this one; naming this precisely to avoid the false impression that this exact file was migrated rather than retired. v1_complexity_eviction_hazard_test.dag — retired with a live-defect note, not a clean retirement, structured as an explicit DESIGN §4b(3) declared bounded rung-drop rather than left as prose implying it: it documents a real fail-open in v1.compiler.complexity's evict_summary/lookup_summary (a §5 absorbing-fallback shape) that is orthogonal to emitted-Rust text and therefore not compile-observable, and the defect itself remains live and unfixed by this retirement. PREVIOUS RUNG: mechanically preventable — before v1_claim_scoped_witness_batch was deleted (2026-08-15), this file's assertions executed and would have caught a regression in the eviction fail-open shape. TEMPORARY RUNG: mitigatable — the fail-open itself is unrepaired, so this class sits at the floor rung DESIGN §5 names for an absorbing fallback (a typed, located, counted diagnostic is owed but not yet built); this retirement removes only the dead witness, it does not climb or lower the underlying defect's own rung. REASON: the witness's sole execution path (v1_claim_scoped_witness_batch) is gone and RESTORE (widening the required floor to admit src/v1) was measured and ruled out repo-wide in this same triage. RE-MEASURED 2026-08-19 (gunbc#8520, CI run 32219326621): the stall does NOT reproduce -- preparation completes in ~9 minutes and refuses with 532 typed located diagnostics, none of them in src/v1. The ruling stands on a different cause (twelve last-segment module collisions between src/v1 and src/v2 breaking bare cross-module references that resolve only by pool coincidence), and the trigger is namespace-only resolution rather than any floor speedup. The single corrected measurement lives in v1_dead_witness_tree_triage_receipt_remainder; this row cites it rather than restating it. RESTORATION TRIGGER: a v1-compiler-local cargo test (v1 is semantics-frozen with active maintenance per gunbc.v1_maintenance_standing, and a local Rust-side regression test is an admitted maintenance-class change under that standing, unlike widening the required floor's source roots) — or, separately and preferably, root-causing the fail-open itself into a typed refusal per §5, which would obsolete this witness's assertions rather than merely restore them. namespace_reference_derived_closure_production_admissions_witness_test.dag — retired: white-box, matched ReferenceBindingObservation variant shapes directly rather than compile outcomes; its own fixtures were already documented in-file as illustrative-only and not satisfying the namespace-structural-observations closing contract (see below).\n\nOUT OF SCOPE, NOT A WITNESS, LEFT IN PLACE: src/v1/gunbc/namespace_reference_derived_closure_production_observations.dag is a v1 PRODUCTION module (four ReferenceBindingObservation producers for the namespace-reference-derived-closure clauses a-d), not a test file, so it is outside this triage's 17-file population. Its only historical test consumer was the retired namespace_reference_derived_closure_production_admissions_witness_test.dag above, so it currently has zero executing consumers and zero test coverage — but it is not dead code: gunbc.roadmap_authority's namespace_reference_derived_closure_execution_contract (an open WorkItemExecutionContract, enrolled QuarantineProbeExpectRed) names 'the gated node' supplying production observations for clauses a-d as the precondition for that contract to green, and this module's namespace_structural_binding_observations_a_through_d export is the designated future producer for exactly that seam. Retiring it would delete a still-claimed future authority, not dead scaffolding; it is left in place with this receipt recording its coverage gap rather than silently carrying it.\n\nRECEIPT COMPLETENESS: undispositioned files = 0 among the 12 handled directly here; retired files' evidence is deleted with them (no discriminating claim survives that a compile-observable check could re-prove); migrated files' evidence is the new dag/test/claim files enumerated above, executing under ordinary per-PR discovery. witness_fold_src_v1_coverage_gap_note's dissolve-on ('the boundary decision on these 15 files... RELOCATION into the dag test root rather than widening the root set') is satisfied by this receipt for the population it could reach; that note is retained rather than deleted because it is still the correct historical account of why the gap existed and how the fold's subject is bounded, and because the 5-file concurrent-batch population is disposed under a separate session-local record this row does not restate." diff --git a/dag/gunbc/recurring_failure_mode.dag b/dag/gunbc/recurring_failure_mode.dag index e255f40737d..18d6ccb03e6 100644 --- a/dag/gunbc/recurring_failure_mode.dag +++ b/dag/gunbc/recurring_failure_mode.dag @@ -89,11 +89,11 @@ type RecurringFailureMode { data hollow_alias: RecurringFailureMode = RecurringFailureMode { identity: "hollow_alias" as NonEmptyStr, authored: "hollow alias (minimality ≠ grounding)", evidence: [] } -data state_space_conflation: RecurringFailureMode = RecurringFailureMode { identity: "state_space_conflation" as NonEmptyStr, authored: "state-space conflation (an `Option`/`None` meaning >2 things — split into named variants; its most-repeated form here is **not-applicable rendered as malformed** — one reason symbol over \"the input is wrong\" and \"this strategy had nothing to say about it\", which have opposite owners and opposite repairs. Found three times in three stages by one lane (#8801 and #8828 in body lowering, `parse_g0_tokens_remain` in parse), always by reading the producer and never from the message. Recognition rule: if the arm sits downstream of a search, lookup or alternative that returned `Absent`, it is not-applicable and needs its own reason. A SECOND FORM, which does not match that shape and is the same class: **a dichotomy stated over a domain with three states.** Specimen (gunbc#9324): the `floor_resource_sample` comment documented `pswpin` rising with `pgmajfault` as swap and `pgmajfault` rising with `pswpin` flat as mapping churn — two arms over three states, since BOTH FLAT is quiet. Churn is a defect this lane owns and quiet is the absence of one, so the missing arm inverts the verdict. The mechanism of the misread is what the recognition rule keys on: `pgmajfault rises` and `pswpin flat` are two conditions and only their CONJUNCTION is churn, so a reader matching on the cheaper condition alone selects churn for a state that satisfies `pswpin flat` and nothing else — which zero-and-zero does. **Recognition rule for this form: for every arm of a stated dichotomy, enumerate the domain and check that each arm's conditions are required jointly.** What made it invisible rather than merely wrong is that BOTH readers landed on the same arm — 26 intervals so classified by one and 6 by another, neither having compared notes — and agreement reads as confirmation. THAT IS A PROMPT TO RE-DERIVE, NOT A DIAGNOSTIC, and the distinction is load-bearing: convergent readings are equally produced by shared assumptions, a common heuristic, ambiguity in the subject, or one reader having anchored on the other, and n=2 on one specimen cannot separate those from a defect in the rule. What survives is only the weaker direction — agreement between readers of one rule is not independent evidence about that rule, because the shared input is a shared potential defect, so it licenses re-deriving from the domain and never a conclusion about which cause produced it.) **A THIRD FORM, and the one that is hardest to rank because nothing is wrong today: A STATE THAT IS ALREADY LOAD-BEARING AND CARRIED AS AN AD-HOC SPELLING RATHER THAN A CONSTRUCTOR.** Specimen (2026-09-01): the identity key threaded through v1.compiler.coercion has THREE inhabitants -- a real declaring module path, the synthetic that v1.std.core kernel_span mints for kernel nodes, and the empty string meaning unknown -- while every consumer discriminates only empty from non-empty. lookup_checkpoint and type_realization_decision therefore read as a KNOWN declaration and proceed to the spelling-keyed arm; decl_file_declares_structurally compares that synthetic identity against a roster of real paths with contains, which no can ever match, so the structural gate is unreachable for a kernel-resolved reference BY CONSTRUCTION rather than by decision. The key reaches those gates with exactly that value through type_reference_decl_file, from v1.compiler.emit coerce_primitive_type and v1.compiler.emit_rust rust_named_type_base and rust_applied_type_base. **What makes this the third form rather than an instance of the first two is the evidence that the state is REAL: the tree already handles it, three times, by string prefix.** numeric_realization_declaring_modules carries the literal \"2 things — split into named variants; its most-repeated form here is **not-applicable rendered as malformed** — one reason symbol over \"the input is wrong\" and \"this strategy had nothing to say about it\", which have opposite owners and opposite repairs. Found three times in three stages by one lane (#8801 and #8828 in body lowering, `parse_g0_tokens_remain` in parse), always by reading the producer and never from the message. Recognition rule: if the arm sits downstream of a search, lookup or alternative that returned `Absent`, it is not-applicable and needs its own reason. A SECOND FORM, which does not match that shape and is the same class: **a dichotomy stated over a domain with three states.** Specimen (gunbc#9324): the `floor_resource_sample` comment documented `pswpin` rising with `pgmajfault` as swap and `pgmajfault` rising with `pswpin` flat as mapping churn — two arms over three states, since BOTH FLAT is quiet. Churn is a defect this lane owns and quiet is the absence of one, so the missing arm inverts the verdict. The mechanism of the misread is what the recognition rule keys on: `pgmajfault rises` and `pswpin flat` are two conditions and only their CONJUNCTION is churn, so a reader matching on the cheaper condition alone selects churn for a state that satisfies `pswpin flat` and nothing else — which zero-and-zero does. **Recognition rule for this form: for every arm of a stated dichotomy, enumerate the domain and check that each arm's conditions are required jointly.** What made it invisible rather than merely wrong is that BOTH readers landed on the same arm — 26 intervals so classified by one and 6 by another, neither having compared notes — and agreement reads as confirmation. THAT IS A PROMPT TO RE-DERIVE, NOT A DIAGNOSTIC, and the distinction is load-bearing: convergent readings are equally produced by shared assumptions, a common heuristic, ambiguity in the subject, or one reader having anchored on the other, and n=2 on one specimen cannot separate those from a defect in the rule. What survives is only the weaker direction — agreement between readers of one rule is not independent evidence about that rule, because the shared input is a shared potential defect, so it licenses re-deriving from the domain and never a conclusion about which cause produced it.) **A THIRD FORM, and the one that is hardest to rank because nothing is wrong today: A STATE THAT IS ALREADY LOAD-BEARING AND CARRIED AS AN AD-HOC SPELLING RATHER THAN A CONSTRUCTOR.** Specimen (2026-09-01): the identity key threaded through v1.compiler.coercion has THREE inhabitants -- a real declaring module path, the synthetic that v1.std.core kernel_span mints for kernel nodes, and the empty string meaning unknown -- while every consumer discriminates only empty from non-empty. lookup_checkpoint and type_realization_decision therefore read as a KNOWN declaration and proceed to the spelling-keyed arm; decl_file_declares_structurally compares that synthetic identity against a roster of real paths with contains, which no can ever match, so the structural gate is unreachable for a kernel-resolved reference BY CONSTRUCTION rather than by decision. The key reaches those gates with exactly that value through type_reference_decl_file, from v1.compiler.emit coerce_primitive_type and v1.compiler.emit_rust rust_named_type_base and rust_applied_type_base. **What makes this the third form rather than an instance of the first two is the evidence that the state is REAL: the tree already handles it, three times, by string prefix.** numeric_realization_declaring_modules carries the literal \" Quantity \{ subject.value \}`. gunbc accepts it. DISTINGUISHING FACT, and the reason this class must not be read off the target's error code: WHAT rustc says is decided by what else the emitter minted, not by the source defect. Under the NARROW emitter classifier the consumer emits `pub use crate::scope_provider::\{Quantity\};` then `use crate::scope_provider::Quantity::\{Time\};` with no marker binding, and `pub struct NonApplied \{ pub value: Time \}` refuses `error[E0573]: expected type, found variant Time` at `src/scope_consumer.rs:15:16` on `pub value: Time,`, label `not a type`, help `consider importing this struct instead`. Under the BROAD classifier the consumer instead emits `pub use crate::scope_provider::\{Time\};` beside `\{Quantity\}` -- the provider having emitted `pub enum Quantity \{ Time, Memory \}` AND `pub struct Time;` -- so the field declaration COMPILES, and the refusal moves to the function: `error[E0308]: mismatched types` at `src/scope_consumer.rs:20:5` on `subject.value.clone()`, `expected Quantity, found Time`, against `expected Quantity because of return type`. INDEPENDENTLY REPRODUCED AT PARAMETER POSITION on this branch, 2026-09-01 on gunbc baeabbbf80, by a single-file source handed to the compiler: `type StampMode = StampClass | StampOther` with `fn take(stamp: StampClass) -> StampMode \{ stamp \}`. `gunbc compile --target rust` exits 0 with 0 blocking errors, emits `pub fn take(stamp: StampClass) -> StampMode` beside `pub struct StampClass;`, and `cargo check` on the emitted crate refuses `E0308 expected StampMode, found StampClass`. One source defect; E0573, E0308-at-the-parent, and E0308-at-the-body depending on emission. THE MASK IS THE SHARP HALF, and it is fabricated plausible output rather than a lucky green: the broad classifier's marker import made the FIELD-ONLY source compile by substituting a distinct struct for a variant. It never preserved the modelled meaning, and extending the SAME accepted source across its declared parent boundary -- the function returning `Quantity` -- is what exposes it. So the narrow classifier's E0573 is this class becoming VISIBLE, not a regression the narrowing introduced. GENERAL FORM: a green obtained because the emitter manufactured a target-only entity for a source name is not evidence the source is well-typed, and the discriminator is to extend the source past the boundary the manufactured entity does not model. THE ONE .dag-SIDE SIGNAL IS ABOUT THE WRONG QUESTION: on the parameter reproduction the compile printed the ADVISORY `unlisted import use 'StampClass' (referenced but not in any import's name list)`. It fires because the name was not found among types -- the front end reached the exact fact that decides this case and reported it as import hygiene. It is not a partial wall: it is advisory, it names listing rather than type position, and the field specimen above IMPORTS `Time` explicitly, so it does not fire there at all (see `diagnostic_name_mechanism_silent`). RUNG FOUND AT: below the ladder, established by execution at the emission boundary -- the compile accepts and the emitted crate refuses. Section 4b's rung-1 mitigations are absent: nothing at the .dag boundary is typed, located or countable about this construction. CEILING: 4, structurally impossible, and the reason is that constructor identity and type identity are two distinct modelled facts whose membership is decidable from the coproduct declaration -- a variant name is reachable from that declaration as an ARM and never as a type, so the type-position slot has no constructor that admits it. No undecidable predicate is involved, so this is a wall now and not a ratchet. NEXT-RUNG TRIGGER, phrased as the capability that retires the row rather than an artifact that would contribute to one: type-position name resolution that consults the TYPE namespace alone and refuses a name resolving to a constructor with a located diagnostic, sufficient that NO Accepted program contains a variant name in any non-applied type position -- field, parameter or return. Repairing either specimen, narrowing the emitter classifier, or adding a fixture satisfies less than that and does not retire this row. RECOGNITION RULE: when the target compiler names a symbol at a type position, check whether that symbol is declared as an ARM of a coproduct in the source; if it is, the defect is in accepted .dag and the target compiler is the only wall that fired. SCOPE STATED RATHER THAN GENERALISED: executed for a unit arm at a field type and at a parameter type, Rust target only. Record-shaped arms, applied positions such as `List