diff --git a/DESIGN.md b/DESIGN.md index 6042cf58ade..09e0df7a276 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -127,7 +127,7 @@ hollow alias (minimality ≠ grounding) · state-space conflation (an `Option`/` - **§3 residue — ContentHash family grounding — Phase A LANDED (#7480).** `std.content_hash` grounds `ContentHash` as a family coproduct (`Fnv1a64 | Sha256Hash | Sha1Hash`) with where-refined digest carriers; union-level `content_hash_eq`/`combine` deleted; `compare_content_hash` returns `ContentHashCrossFamilyIncomparable` (third state, not Bool collapse). Carrier walls: `OciDescriptor.digest` → `OciContentDigest`; `GateRosterHash` / `v2.std.node.Hash` → `Fnv1a64Structural`; Git tree hashes → `GitObjectId` (Sha1, cited via `extdeps.git.object_store`). `extdeps.crypto.hash` `sha256_digest_content_hash` is the VALIDATING PARTIAL bridge `Digest`→`ContentHash?` (invalid hex refuses via `Absent`, never absorbs a fallback), and `std.content_hash` `as_content_hash_cryptographic` is the TOTAL injection from an already-validated `Sha256Digest` — the distinction matters because only the second is unconditional (corrected 2026-08-01: this row previously called the partial bridge total, and its positive-path witness was named `..._is_total` while a sibling test proved the same function refuses invalid hex); `sha256:` prefix is wire serialization (`serialize_content_hash`), not a discriminant. `Pin.expected_identity` retains the union (subject-generic); `admit_pin_integrity` routes cross-family to `CrossFamilyIdentityIncomparable`. R0 backstop refuses bare union `==`/`!=` on family mismatch (`content_hash_cross_family_eq_v1_seed_bridge_note`; witness `cross_representation_equality_test`). **Remaining Phase B (dissolve-on — this row deletes when landed):** substrate typecheck refuses union-level `ContentHash == ContentHash` so cross-family comparison is structurally unwritable; Phase A closes carrier construction walls + R0 eval only. Authority: `std.content_hash` `content_hash_family_grounding_note`. Witness: `dag/test/claim/content_hash_family_grounded_witness_test.dag`, `where_refinement_enforcement_witness_test.dag` (hex refinement at literal sites). - the remaining deleted-`docs/` references in `.dag` comments — provenance / `bind:` pointers into the bankrupted `docs/` tree (e.g. `docs/planning/*`, `design-*.md`) — fold into the dep-graph reform, not a blind repoint. (The named-corpus ledger marks — `Practice N`, and `INVARIANTS` / `THESIS` / `MODELING` / `RELEASE_TODO` / … citations — were swept: dropped, or re-homed to DESIGN.md §-anchors.) - floor shared-computation memoization — M1 entry-closure memo LANDED (#6999, merge dc2aa25684); post-merge validation (msg_1879f052) shows ~0% batch-wall recovery on capped hosts — fixes are mechanism-correct but discovery loads each entry once/worker; residual ~18min owed to #6848 once-per-entry bare-reference fixpoint + cap-saturation throttle (§1.4). Receipts: [floor-time namespace-walk diagnosis](docs/plans/floor-time-namespace-walk-regression-diagnosis.md) §5. **BANKED:** slice-1 measurement (lane `ci-cost`, subject `entry-graph-union-construction`) merged as #7483 (b5191426479ddec5f9a80b60dc6264ca168b42b6), landed a partition mechanism and one corrected finding, and RETRACTED three claims an earlier draft of this row asserted. What stands: the `[resolve-split]` rows were never quotable as shares because children were summed over every resolve a thread runs while the receipt's parent covered only witness-entry resolves — two denominators, not a nesting — and an exclusive partition over a parent that contains its children now reconciles at 0ns tolerance, refusing (`OverAttributed`/`NestedSpanAttribution`/`NoSpans`) rather than clamping; and the production-selected closures repeat module membership at a 35.9-38.4x duplication factor across narrow/typical/broad subjects (module-count weighted; byte-weighted the same three subjects give 43.0/47.9/49.3, so the count figure is the conservative one and, unlike the count reading, the byte reading rises monotonically with diff breadth). What was RETRACTED, by execution: (a) that `load` is dominated by `referenced_module_paths_in_text`, an unmemoized per-(entry,module) content scan — measured at 4-23ms, ~0% of `load`; (b) that `load` is the dominant cost generally — NOT established either way: it is 67.7-68.1% on a 159-module closure, but on two runs of the SAME 504-module closure it is 38.93% then 49.52%, with typecheck_compute leading the first and `load` the second, so the share ordering flips between repeats of one entry and no share in the partition is a reproducible quantity on this host; (c) that the membership duplication factor multiplies the dominant cost, and the per-source content-hash memo that followed from it. What `load` actually is, measured: ~100% `build_both_closure_edge_index`, a CORPUS-wide edge index that is memoized per `MultiEntryIndex` and costs the same whatever the entry's closure size (51.24s on a 159-module closure vs 50.98s on a 504-module one) though its magnitude is host-noise-dominated (44.96-77.11s across four runs at 2 spans each), so size-independence is the durable claim and the per-index figure is not — so it is fixed per index, not per entry and not per membership. The single-entry `claim_batch` harness pays it twice only because two indices exist on that path (its own, plus `process_shared_index` for machinery). THE BOUND ON ALL OF IT: those shares therefore characterize a fixed-cost-dominated harness, NOT the floor, where one index amortizes across hundreds of entries. The amortization was then MEASURED rather than assumed: on the explicit-entry path (N entries against one shared index), going from 2 spans to 7 grows `load` 1.08x while typecheck_compute grows 2.86x, parse 3.21x and resolve_modules 4.40x, collapsing `load`'s share 67.79% -> 44.97% with no code change — so `load` is paid once per INDEX, not once per entry, and the existing per-index memo already amortizes it. THE REDIRECTION THAT FOLLOWS: a union graph cannot displace a cost that is already paid once, so the program's apparent target is eliminated; the only measured row that scales with BOTH entry count and closure size is typecheck_compute, whose unit of work is module membership — the quantity B measures repeating 38x by count and 48x byte-weighted. Slice 2 CLOSED that candidate as a no-go: three disjoint N<=50 windows and the post-merge representative/reorder receipt found zero repeated typecheck misses and an order-stable distinct-computation set inside one shared typed-cache authority. The durable law remains once-per-content-key; the one-shot ratio instrument was deleted after the merged-SHA provenance receipt. No union construction and no larger-host confirmation run follow from this hypothesis. The separate #7597 successor measures assembly on a new denominator: its exclusive, refusal-based split reproduces symbol-index merge, root symbol-index composition, import-string rewiring, closure symbol-index construction, root variant-base construction, emit-info, pool fill, and services as the priced terms, with the derived other row at 0.32% in both runs. Receipts: [slice 2 closeout](docs/plans/entry-graph-union-slice2-typecheck-attribution.md) and [per-entry assembly decomposition](docs/plans/per-entry-assembly-decomposition-measurement.md). M2: RunnableCompile node gated on v2.std.determinism #5941): [design sketch](docs/plans/floor-shared-compute-memoization.md) -- **five-minute CI gate — central CI program boundary (operator dispatch K, 2026-08-01; sequence revision eager-boar-610, 2026-08-01; contract re-anchored by operator ruling 2026-08-02).** Product contract: every required operation performs the bare minimum computation needed to serve it — no recomputation of any semantic fact whose inputs did not change; wall-clock falls out of the realization/materialization goals rather than defining them. Five minutes is NOT the contract (operator, 2026-08-02: the earlier contract sentence presenting it as such was a mistake) — it is the distress ceiling, 'this is hard / not working well', retained only as the Stage C checkpoint bound; reaching 5:00 does not complete the program while redundant computation remains on a required path. Six sub-lanes plus explicit operator sequence in roadmap authority: (1) #7522 warm-merge net receipt; (2) merge #7599 native bundle slice; (3) bounded production cutover to native execution kind; (4) #7534 materialization substrate (module→entry→bundle hierarchy); (5) union closed → per-entry assembly; (6) this registration. **Native-at-small-scale settled and banked** — #7599 merged 2026-08-02 (merge `1ebff27f1e`; 25/25 witness PASS executed 2026-08-01 at pre-merge head `2f9e780e6`); timing ratio claimed-not-verified per design note. Open question is operational migration rate. **Staged expectations** (not flat wall-clock): Stage A modest admission saving only; Stage B first order-of-magnitude witness reduction after production native cutover; Stage C five-minute gate when all conjunction holds (native majority, materialization hits, no redundant parse/typecheck, pre-index lookup, shared substrate, counted fallback→0). Do not raise CI step cap first — cap lives in `gunbc.ci_spec`. → [five-minute CI gate design](docs/plans/five-minute-ci-gate-design.md) · [witness realization plan](docs/plans/witness-realization-plan.md) · `dag/gunbc/plans/cli_run_hollowing_plan.dag` +- **five-minute CI gate — central CI program boundary (operator dispatch K, 2026-08-01; sequence revision eager-boar-610, 2026-08-01; contract re-anchored by operator ruling 2026-08-02).** Product contract: every required operation performs the bare minimum computation needed to serve it — no recomputation of any semantic fact whose inputs did not change; wall-clock falls out of the realization/materialization goals rather than defining them. Five minutes is NOT the contract (operator, 2026-08-02: the earlier contract sentence presenting it as such was a mistake) — it is the distress ceiling, 'this is hard / not working well', retained only as the Stage C checkpoint bound; reaching 5:00 does not complete the program while redundant computation remains on a required path. Six sub-lanes plus explicit operator sequence in roadmap authority: (1) #7522 warm-merge net receipt; (2) merge #7599 native bundle slice; (3) bounded production cutover to native execution kind; (4) #7534 materialization substrate (module→entry→bundle hierarchy); (5) union closed → per-entry assembly; (6) this registration. **Native-at-small-scale evidence has landed; operational migration rate remains open.** Which change landed it, at which merge commit, at which evaluated head, and under which executing witness are *execution evidence*, carried in one typed receipt (`gunbc.native_witness_transition_receipt` `native_at_small_scale_transition_receipt`) that this document cites rather than restates — a design criterion embedding a SHA or a pass count has to be edited every time the world moves, and a second hand-maintained copy of one advancing status goes stale silently (operator ruling on #7710, 2026-08-02). Timing ratio remains claimed-not-verified per the design note. **Staged expectations** (not flat wall-clock): Stage A modest admission saving only; Stage B first order-of-magnitude witness reduction after production native cutover; Stage C five-minute gate when all conjunction holds (native majority, materialization hits, no redundant parse/typecheck, pre-index lookup, shared substrate, counted fallback→0). Do not raise CI step cap first — cap lives in `gunbc.ci_spec`. → [five-minute CI gate design](docs/plans/five-minute-ci-gate-design.md) · [witness realization plan](docs/plans/witness-realization-plan.md) · `dag/gunbc/plans/cli_run_hollowing_plan.dag` - **#6985 witness-discovery cascade — diagnosis-complete, two confirmed failure classes, both block further stripping.** The initial `pullable()`-never-pulls-arity-zero read was refuted by execution on the `parallelism.dag` restore (DESIGN §5). Two real classes were then confirmed by execution: **Class A** — a re-export-through-partial-strip (qualified-import/re-export mismatch), closed by import-from-definer wave ordering or PR-4 (namespace-resolution-design.md §8). **Class B** — a stripped file's own bare cross-module references resolve only by **pool-membership coincidence**: `resolve_in` finds the target module exactly when some *unrelated* unstripped import elsewhere in the currently-assembled closure has already dragged it into the pool, never from the bare-reference closure itself binding it. A reconciliation probe on an already-stripped `dag/extdeps` file (`bmc/types.dag`) reproduced the identical failure under a narrower closure, confirming this is corpus-wide accidental coverage, not a per-file property — batch-1's ~74 files are green today only because enough unrelated files elsewhere still happen to import the same targets. **This blocks all further `dag/**` import-stripping** until a closure-independent binding fix or a provable-coverage construction check lands. Named side findings, not yet fixed: a LOUDNESS gap (an opaque unlocatable diagnostic for some but not all Class B failure shapes) and an untested zero-arity fn/data-by-value claim. → [import-strip witness-discovery cascade diagnosis](docs/plans/import-strip-witness-discovery-cascade-diagnosis.md) - **v1 whole-corpus run stability — the floor's failure axis is retention, not footprint.** The adaptive governor packs width to the memory envelope by construction, so the honest metric is completion-within-step-budget at width > 1; the root cause was a §6 cost-shape defect in typecheck-env construction (multiplicative inductive-field duplication along the import DAG), not corpus size. M1 construction fixes landed fingerprint-identical (#6528). M2's schedule-derived per-module retention landed in #7129 (bd5afd6bc3e8f3e4bc9ded40bcf3b79cdfee536d) and proved the memory thesis at width 1 (9.24 GB executor RSS / 10.7 GB cgroup peak, zero swap, throttle, or pressure); it did not deliver the lane's width > 1 exit bar. Remaining work is the plural-worker outer ring, exact resident-accounting split/reservations, and the width > 1 fleet receipts; v2-eval-as-realization remains the terminal M3 exit. Decision tree, receipts, non-goals: [v1 run-stability throughline](docs/plans/v1-run-stability-throughline.md) - **emitted crate partition** — derive the Rust crate layout from the module graph (builds on #6677 derived registration; dissolves the hand-drawn 2-crate split in `stage0_crates.dag`). Shared `CompilationUnit` home with the language-consolidation lane; Rust workflow realization here. → [emitted crate partition design](docs/plans/emitted-crate-partition-design.md) diff --git a/dag/gunbc/design_document.dag b/dag/gunbc/design_document.dag index 88e61ebc7d1..854aaac567c 100644 --- a/dag/gunbc/design_document.dag +++ b/dag/gunbc/design_document.dag @@ -162,7 +162,7 @@ fn open_threads_blocks() -> List { li(text: "**§3 residue — ContentHash family grounding — Phase A LANDED (#7480).** `std.content_hash` grounds `ContentHash` as a family coproduct (`Fnv1a64 | Sha256Hash | Sha1Hash`) with where-refined digest carriers; union-level `content_hash_eq`/`combine` deleted; `compare_content_hash` returns `ContentHashCrossFamilyIncomparable` (third state, not Bool collapse). Carrier walls: `OciDescriptor.digest` → `OciContentDigest`; `GateRosterHash` / `v2.std.node.Hash` → `Fnv1a64Structural`; Git tree hashes → `GitObjectId` (Sha1, cited via `extdeps.git.object_store`). `extdeps.crypto.hash` `sha256_digest_content_hash` is the VALIDATING PARTIAL bridge `Digest`→`ContentHash?` (invalid hex refuses via `Absent`, never absorbs a fallback), and `std.content_hash` `as_content_hash_cryptographic` is the TOTAL injection from an already-validated `Sha256Digest` — the distinction matters because only the second is unconditional (corrected 2026-08-01: this row previously called the partial bridge total, and its positive-path witness was named `..._is_total` while a sibling test proved the same function refuses invalid hex); `sha256:` prefix is wire serialization (`serialize_content_hash`), not a discriminant. `Pin.expected_identity` retains the union (subject-generic); `admit_pin_integrity` routes cross-family to `CrossFamilyIdentityIncomparable`. R0 backstop refuses bare union `==`/`!=` on family mismatch (`content_hash_cross_family_eq_v1_seed_bridge_note`; witness `cross_representation_equality_test`). **Remaining Phase B (dissolve-on — this row deletes when landed):** substrate typecheck refuses union-level `ContentHash == ContentHash` so cross-family comparison is structurally unwritable; Phase A closes carrier construction walls + R0 eval only. Authority: `std.content_hash` `content_hash_family_grounding_note`. Witness: `dag/test/claim/content_hash_family_grounded_witness_test.dag`, `where_refinement_enforcement_witness_test.dag` (hex refinement at literal sites)."), li(text: "the remaining deleted-`docs/` references in `.dag` comments — provenance / `bind:` pointers into the bankrupted `docs/` tree (e.g. `docs/planning/*`, `design-*.md`) — fold into the dep-graph reform, not a blind repoint. (The named-corpus ledger marks — `Practice N`, and `INVARIANTS` / `THESIS` / `MODELING` / `RELEASE_TODO` / … citations — were swept: dropped, or re-homed to DESIGN.md §-anchors.)"), li(text: "floor shared-computation memoization — M1 entry-closure memo LANDED (#6999, merge dc2aa25684); post-merge validation (msg_1879f052) shows ~0% batch-wall recovery on capped hosts — fixes are mechanism-correct but discovery loads each entry once/worker; residual ~18min owed to #6848 once-per-entry bare-reference fixpoint + cap-saturation throttle (§1.4). Receipts: [floor-time namespace-walk diagnosis](docs/plans/floor-time-namespace-walk-regression-diagnosis.md) §5. **BANKED:** slice-1 measurement (lane `ci-cost`, subject `entry-graph-union-construction`) merged as #7483 (b5191426479ddec5f9a80b60dc6264ca168b42b6), landed a partition mechanism and one corrected finding, and RETRACTED three claims an earlier draft of this row asserted. What stands: the `[resolve-split]` rows were never quotable as shares because children were summed over every resolve a thread runs while the receipt's parent covered only witness-entry resolves — two denominators, not a nesting — and an exclusive partition over a parent that contains its children now reconciles at 0ns tolerance, refusing (`OverAttributed`/`NestedSpanAttribution`/`NoSpans`) rather than clamping; and the production-selected closures repeat module membership at a 35.9-38.4x duplication factor across narrow/typical/broad subjects (module-count weighted; byte-weighted the same three subjects give 43.0/47.9/49.3, so the count figure is the conservative one and, unlike the count reading, the byte reading rises monotonically with diff breadth). What was RETRACTED, by execution: (a) that `load` is dominated by `referenced_module_paths_in_text`, an unmemoized per-(entry,module) content scan — measured at 4-23ms, ~0% of `load`; (b) that `load` is the dominant cost generally — NOT established either way: it is 67.7-68.1% on a 159-module closure, but on two runs of the SAME 504-module closure it is 38.93% then 49.52%, with typecheck_compute leading the first and `load` the second, so the share ordering flips between repeats of one entry and no share in the partition is a reproducible quantity on this host; (c) that the membership duplication factor multiplies the dominant cost, and the per-source content-hash memo that followed from it. What `load` actually is, measured: ~100% `build_both_closure_edge_index`, a CORPUS-wide edge index that is memoized per `MultiEntryIndex` and costs the same whatever the entry's closure size (51.24s on a 159-module closure vs 50.98s on a 504-module one) though its magnitude is host-noise-dominated (44.96-77.11s across four runs at 2 spans each), so size-independence is the durable claim and the per-index figure is not — so it is fixed per index, not per entry and not per membership. The single-entry `claim_batch` harness pays it twice only because two indices exist on that path (its own, plus `process_shared_index` for machinery). THE BOUND ON ALL OF IT: those shares therefore characterize a fixed-cost-dominated harness, NOT the floor, where one index amortizes across hundreds of entries. The amortization was then MEASURED rather than assumed: on the explicit-entry path (N entries against one shared index), going from 2 spans to 7 grows `load` 1.08x while typecheck_compute grows 2.86x, parse 3.21x and resolve_modules 4.40x, collapsing `load`'s share 67.79% -> 44.97% with no code change — so `load` is paid once per INDEX, not once per entry, and the existing per-index memo already amortizes it. THE REDIRECTION THAT FOLLOWS: a union graph cannot displace a cost that is already paid once, so the program's apparent target is eliminated; the only measured row that scales with BOTH entry count and closure size is typecheck_compute, whose unit of work is module membership — the quantity B measures repeating 38x by count and 48x byte-weighted. Slice 2 CLOSED that candidate as a no-go: three disjoint N<=50 windows and the post-merge representative/reorder receipt found zero repeated typecheck misses and an order-stable distinct-computation set inside one shared typed-cache authority. The durable law remains once-per-content-key; the one-shot ratio instrument was deleted after the merged-SHA provenance receipt. No union construction and no larger-host confirmation run follow from this hypothesis. The separate #7597 successor measures assembly on a new denominator: its exclusive, refusal-based split reproduces symbol-index merge, root symbol-index composition, import-string rewiring, closure symbol-index construction, root variant-base construction, emit-info, pool fill, and services as the priced terms, with the derived other row at 0.32% in both runs. Receipts: [slice 2 closeout](docs/plans/entry-graph-union-slice2-typecheck-attribution.md) and [per-entry assembly decomposition](docs/plans/per-entry-assembly-decomposition-measurement.md). M2: RunnableCompile node gated on v2.std.determinism #5941): [design sketch](docs/plans/floor-shared-compute-memoization.md)"), - li(text: "**five-minute CI gate — central CI program boundary (operator dispatch K, 2026-08-01; sequence revision eager-boar-610, 2026-08-01; contract re-anchored by operator ruling 2026-08-02).** Product contract: every required operation performs the bare minimum computation needed to serve it — no recomputation of any semantic fact whose inputs did not change; wall-clock falls out of the realization/materialization goals rather than defining them. Five minutes is NOT the contract (operator, 2026-08-02: the earlier contract sentence presenting it as such was a mistake) — it is the distress ceiling, 'this is hard / not working well', retained only as the Stage C checkpoint bound; reaching 5:00 does not complete the program while redundant computation remains on a required path. Six sub-lanes plus explicit operator sequence in roadmap authority: (1) #7522 warm-merge net receipt; (2) merge #7599 native bundle slice; (3) bounded production cutover to native execution kind; (4) #7534 materialization substrate (module→entry→bundle hierarchy); (5) union closed → per-entry assembly; (6) this registration. **Native-at-small-scale settled and banked** — #7599 merged 2026-08-02 (merge `1ebff27f1e`; 25/25 witness PASS executed 2026-08-01 at pre-merge head `2f9e780e6`); timing ratio claimed-not-verified per design note. Open question is operational migration rate. **Staged expectations** (not flat wall-clock): Stage A modest admission saving only; Stage B first order-of-magnitude witness reduction after production native cutover; Stage C five-minute gate when all conjunction holds (native majority, materialization hits, no redundant parse/typecheck, pre-index lookup, shared substrate, counted fallback→0). Do not raise CI step cap first — cap lives in `gunbc.ci_spec`. → [five-minute CI gate design](docs/plans/five-minute-ci-gate-design.md) · [witness realization plan](docs/plans/witness-realization-plan.md) · `dag/gunbc/plans/cli_run_hollowing_plan.dag`"), + li(text: "**five-minute CI gate — central CI program boundary (operator dispatch K, 2026-08-01; sequence revision eager-boar-610, 2026-08-01; contract re-anchored by operator ruling 2026-08-02).** Product contract: every required operation performs the bare minimum computation needed to serve it — no recomputation of any semantic fact whose inputs did not change; wall-clock falls out of the realization/materialization goals rather than defining them. Five minutes is NOT the contract (operator, 2026-08-02: the earlier contract sentence presenting it as such was a mistake) — it is the distress ceiling, 'this is hard / not working well', retained only as the Stage C checkpoint bound; reaching 5:00 does not complete the program while redundant computation remains on a required path. Six sub-lanes plus explicit operator sequence in roadmap authority: (1) #7522 warm-merge net receipt; (2) merge #7599 native bundle slice; (3) bounded production cutover to native execution kind; (4) #7534 materialization substrate (module→entry→bundle hierarchy); (5) union closed → per-entry assembly; (6) this registration. **Native-at-small-scale evidence has landed; operational migration rate remains open.** Which change landed it, at which merge commit, at which evaluated head, and under which executing witness are *execution evidence*, carried in one typed receipt (`gunbc.native_witness_transition_receipt` `native_at_small_scale_transition_receipt`) that this document cites rather than restates — a design criterion embedding a SHA or a pass count has to be edited every time the world moves, and a second hand-maintained copy of one advancing status goes stale silently (operator ruling on #7710, 2026-08-02). Timing ratio remains claimed-not-verified per the design note. **Staged expectations** (not flat wall-clock): Stage A modest admission saving only; Stage B first order-of-magnitude witness reduction after production native cutover; Stage C five-minute gate when all conjunction holds (native majority, materialization hits, no redundant parse/typecheck, pre-index lookup, shared substrate, counted fallback→0). Do not raise CI step cap first — cap lives in `gunbc.ci_spec`. → [five-minute CI gate design](docs/plans/five-minute-ci-gate-design.md) · [witness realization plan](docs/plans/witness-realization-plan.md) · `dag/gunbc/plans/cli_run_hollowing_plan.dag`"), li(text: "**#6985 witness-discovery cascade — diagnosis-complete, two confirmed failure classes, both block further stripping.** The initial `pullable()`-never-pulls-arity-zero read was refuted by execution on the `parallelism.dag` restore (DESIGN §5). Two real classes were then confirmed by execution: **Class A** — a re-export-through-partial-strip (qualified-import/re-export mismatch), closed by import-from-definer wave ordering or PR-4 (namespace-resolution-design.md §8). **Class B** — a stripped file's own bare cross-module references resolve only by **pool-membership coincidence**: `resolve_in` finds the target module exactly when some *unrelated* unstripped import elsewhere in the currently-assembled closure has already dragged it into the pool, never from the bare-reference closure itself binding it. A reconciliation probe on an already-stripped `dag/extdeps` file (`bmc/types.dag`) reproduced the identical failure under a narrower closure, confirming this is corpus-wide accidental coverage, not a per-file property — batch-1's ~74 files are green today only because enough unrelated files elsewhere still happen to import the same targets. **This blocks all further `dag/**` import-stripping** until a closure-independent binding fix or a provable-coverage construction check lands. Named side findings, not yet fixed: a LOUDNESS gap (an opaque unlocatable diagnostic for some but not all Class B failure shapes) and an untested zero-arity fn/data-by-value claim. → [import-strip witness-discovery cascade diagnosis](docs/plans/import-strip-witness-discovery-cascade-diagnosis.md)"), li(text: "**v1 whole-corpus run stability — the floor's failure axis is retention, not footprint.** The adaptive governor packs width to the memory envelope by construction, so the honest metric is completion-within-step-budget at width > 1; the root cause was a §6 cost-shape defect in typecheck-env construction (multiplicative inductive-field duplication along the import DAG), not corpus size. M1 construction fixes landed fingerprint-identical (#6528). M2's schedule-derived per-module retention landed in #7129 (bd5afd6bc3e8f3e4bc9ded40bcf3b79cdfee536d) and proved the memory thesis at width 1 (9.24 GB executor RSS / 10.7 GB cgroup peak, zero swap, throttle, or pressure); it did not deliver the lane's width > 1 exit bar. Remaining work is the plural-worker outer ring, exact resident-accounting split/reservations, and the width > 1 fleet receipts; v2-eval-as-realization remains the terminal M3 exit. Decision tree, receipts, non-goals: [v1 run-stability throughline](docs/plans/v1-run-stability-throughline.md)"), li(text: "**emitted crate partition** — derive the Rust crate layout from the module graph (builds on #6677 derived registration; dissolves the hand-drawn 2-crate split in `stage0_crates.dag`). Shared `CompilationUnit` home with the language-consolidation lane; Rust workflow realization here. → [emitted crate partition design](docs/plans/emitted-crate-partition-design.md)"), diff --git a/dag/gunbc/doc_graph_roots.dag b/dag/gunbc/doc_graph_roots.dag index 124350e8328..08bdfd2d80b 100644 --- a/dag/gunbc/doc_graph_roots.dag +++ b/dag/gunbc/doc_graph_roots.dag @@ -95,7 +95,10 @@ data hand_authored_doc_binds: List = [ home: PlanDoc, slug: "five-minute-ci-gate-design", primary_work: DeclarationRef { module_path: "gunbc.roadmap_authority", decl_name: "five_minute_ci_gate_program_note", field: WholeDeclaration }, - additional_works: [DeclarationRef { module_path: "gunbc.roadmap_authority", decl_name: "roadmap_authority_for", field: WholeDeclaration }], + additional_works: [ + DeclarationRef { module_path: "gunbc.roadmap_authority", decl_name: "roadmap_authority_for", field: WholeDeclaration }, + DeclarationRef { module_path: "gunbc.native_witness_transition_receipt", decl_name: "native_at_small_scale_transition_receipt", field: WholeDeclaration }, + ], dissolution: HasTrigger { text: "every sub-lane row is accepted or honestly retired and the program parent five-minute-ci-gate is accepted on fleet receipts showing a representative leaf .dag PR at ≤5 minutes wall with byte-identical verdicts vs a cold recompute control — or the operator recuts the program and this note is superseded by a registered plan row." }, }, HandAuthoredDocBind { diff --git a/dag/gunbc/native_witness_transition_receipt.dag b/dag/gunbc/native_witness_transition_receipt.dag new file mode 100644 index 00000000000..c54331ea634 --- /dev/null +++ b/dag/gunbc/native_witness_transition_receipt.dag @@ -0,0 +1,52 @@ +module gunbc.native_witness_transition_receipt + +import std.decl_ref { DeclarationRef, decl_ref } +import std.types { CommitSha, Int, String } +import gunbc.roadmap_model { RoadmapNodeIdentity } + +data native_witness_transition_receipt_note: String = "ONE HOME FOR A MUTABLE PROGRAM STATUS, SO NO DOCUMENT HAS TO HOLD IT TWICE (operator ruling on gunbc#7710, 2026-08-02). That PR wrote the same changing observation -- native-at-small-scale evidence landed, with its pull request, merge commit, evaluated head and pass count -- independently into gunbc.roadmap_authority five_minute_ci_gate_program_note AND into gunbc.design_document, and therefore into generated DESIGN.md. Two hand-maintained copies of one advancing status is the DESIGN section 3 dual representation: someone updates one, the other silently goes stale, and both read as authoritative. The operator's split is the model here -- the DURABLE DESIGN FACT is two clauses (native-at-small-scale evidence has landed; operational migration rate remains open) and belongs in the design criteria; the pull request, merge commit, evaluated head and executed witness are EXECUTION EVIDENCE and belong in exactly one typed receipt that both documents cite.\n\nWHAT IS DELIBERATELY NOT STORED, and why the exclusion is the point. No pass count. gunbc#7710 recorded 25 of 25 witness receipts; that module declared 31 test functions less than a day later, so a transcribed count is stale before the ink dries and no oracle in this repository could have caught it. The per-member verdicts already have a single authority in std.selected_witness_bundle NativeWitnessBundleExecutionReceipt member_equivalence, produced by the run itself; a hand-typed integer beside it would be a second representation of that list. executed_evidence therefore cites the witness SYMBOL, per the DESIGN section 3 rule that a citation names the module and declaration rather than a position or a snapshot. No rendered status string either: standing is DERIVED below, never stored, so a transcribed standing is unrepresentable rather than lens-caught.\n\nTHIS IS NOT AN ACCEPTANCE AND MUST NOT BE READ AS ONE. gunbc.roadmap_model RoadmapAcceptanceReceipt remains the only fact node_accepted consults, and it requires the node's criteria digest plus executed red-control and delivered handback evidence. This receipt records that ONE piece of evidence landed under a node that is still OPEN -- for the native-selected-witness-bundle node, operational migration rate, fallback counting, artifact identity and fail-closed memory all remain open. A receipt here moves nothing on the roadmap graph.\n\nGENERALIZATION TRIGGER, named rather than pre-built (DESIGN section 6, model just-in-time): partial evidence landing under an open node is not native-witness-specific, but it has exactly one inhabitant today. On the SECOND subject needing this shape, the node identity plus landed change plus evaluated head plus cited evidence generalize into one carrier and this module becomes an instantiation; minting the general shape now would be uninhabited generality." + +type NativeSelectedWitnessTransitionReceipt { + node: RoadmapNodeIdentity + landed_pull_request: Int + landed_merge_commit: CommitSha + evaluated_head: CommitSha + executed_evidence: DeclarationRef +} + +data transition_evidence_standing_note: String = "THE HEAD THE WITNESSES RAN AT IS NOT THE COMMIT THAT LANDED THEM, AND THE DIFFERENCE IS THE WHOLE HONESTY CONTENT. gunbc#7710 carried this distinction in prose -- receipts executed at the pre-merge head, not at the merge -- which is exactly the kind of true sentence that survives only as long as its author is watching. gunbc.roadmap_verification_receipt already states the underlying law for the verification case: head A and head B are different subjects, so evidence gathered at one cannot silently impersonate evidence about the other. Deriving the standing from the two commits the receipt already carries turns that sentence into structure: a reader cannot quote an evidence run as verified-at-the-merged-tree unless the two commits actually agree, because the arm naming both commits is what the fold returns when they do not.\n\nBOTH ARMS ARE ADMISSIBLE EVIDENCE. EvidenceExecutedBeforeLanding is not a refusal and not a defect -- pre-merge execution is the normal shape of a controls-clear-then-merge sequence. It is a NAMED standing, so that the weaker claim cannot be reported as the stronger one." + +type TransitionEvidenceStanding + = EvidenceExecutedAtLandedCommit + | EvidenceExecutedBeforeLanding { + evaluated_head: CommitSha, + landed_merge_commit: CommitSha, + } + +fn transition_evidence_standing( + receipt: NativeSelectedWitnessTransitionReceipt, +) -> TransitionEvidenceStanding { + if receipt.evaluated_head == receipt.landed_merge_commit { + EvidenceExecutedAtLandedCommit + } else { + EvidenceExecutedBeforeLanding { + evaluated_head: receipt.evaluated_head, + landed_merge_commit: receipt.landed_merge_commit, + } + } +} + +data native_at_small_scale_receipt_note: String = "THE ONE INHABITANT. Subject is the durable roadmap node identity rn_2I5K7M9O1Q3R6T8V0W2X4Y7Z9A1C, the native-selected-witness-bundle node, rather than its editable slug -- the same choice gunbc.roadmap_verification_receipt VerificationSubject makes, and it matters here because a slug rename must not orphan the evidence. The landed change is gunbc#7599, merge commit 1ebff27f1e538a06edbaf6a1871bff4c10887b39. The witnesses executed at 2f9e780e6d2130680c4d9fb49739bf0c6cc7c746, the pre-merge branch head, so this receipt's derived standing is EvidenceExecutedBeforeLanding and no consumer may report it as verified at the merged tree. The cited evidence is the cutover-evidence witness in v2.test.execution.native_selected_witness_bundle, which is where the equivalence between native and interpreted execution is actually established; the timing ratio against interpreted and warm-cargo paths remains claimed-not-verified per the design note, and nothing here asserts it." + +fn native_at_small_scale_transition_receipt() -> NativeSelectedWitnessTransitionReceipt { + NativeSelectedWitnessTransitionReceipt { + node: "rn_2I5K7M9O1Q3R6T8V0W2X4Y7Z9A1C" as RoadmapNodeIdentity, + landed_pull_request: 7599, + landed_merge_commit: "1ebff27f1e538a06edbaf6a1871bff4c10887b39", + evaluated_head: "2f9e780e6d2130680c4d9fb49739bf0c6cc7c746", + executed_evidence: decl_ref( + module_path: "v2.test.execution.native_selected_witness_bundle", + decl_name: "native_selected_witness_bundle_cutover_evidence_holds", + ), + } +} diff --git a/dag/gunbc/roadmap_authority.dag b/dag/gunbc/roadmap_authority.dag index 2dfdb8f7af4..925e94a50ee 100644 --- a/dag/gunbc/roadmap_authority.dag +++ b/dag/gunbc/roadmap_authority.dag @@ -78,7 +78,7 @@ fn signed(by: String, works: RedControlEvidence, scope_equivalent: HandbackEvide data namespace_kernel_authority_amendment_note: String = "THE KERNEL BAR AS FIRST WRITTEN DEADLOCKED ITS OWN SUCCESSOR, and this amendment is the fix (operator ruling, 2026-08-01). The recut landed namespace-binding-kernel with a red_control ending 'no second place in the compiler makes that same decision' and a handback demanding 'evidence that nothing else decides the same question'. That bar cannot be met while the bootstrap seed keeps its own hand-written none/one/many mirror inside the v1 adapter, and that mirror cannot be deleted until generic emission carries the canonical carrier with its required bounds. But namespace-reference-derived-closure DEPENDS on the kernel. So on the day the recut merged, the next step was already unstartable for a reason that had nothing to do with what the next step needs: deriving candidate populations does not require the seed mirror to be gone, it requires the canonical decision to EXIST and be callable.\n\nTHE CUT IS AUTHORITY VERSUS RETIREMENT. Owning the canonical decision and removing every rival implementation of it are separate achievements with separate evidence, and fusing them made an acceptance bar that no amount of correct kernel work could satisfy. The kernel now owns being the one canonical authority; namespace-legacy-choice-retirement owns deleting the older mechanisms, and the seed mirror is named there as one of its rows. A new node was deliberately NOT minted: that node already reads 'delete every other way of deciding what a name means' and already inventories every remaining place that decides, so the mirror is a row it should always have carried, and minting a sibling would have been a second home for one concept.\n\nTHE ADAPTER IS NOT THEREBY BLESSED. It remains a declared scaffold with its dissolution trigger on its own carrier, counted and visible; moving WHERE its retirement is tracked does not lower what is owed. What changes is only that a temporary bootstrap realization no longer gates work that does not depend on it.\n\nTWO ACCEPTANCE SENTENCES WERE ALSO WRONG AND ARE CORRECTED HERE. The red_control said 'a malformed name refuses', but this boundary accepts occurrence identities and derives no name spelling at all, so it named a check no implementation executes — it now reads malformed occurrence TRANSPORT. And the bar now states the two refusals that distinguish a malformed supplied population from a real verdict: a candidate handed in the wrong role refuses distinctly from one that is absent, and the same declaration supplied twice refuses as malformed rather than counting as two. Only two DISTINCT declaration identities are ambiguity. Collapsing either of those into an ordinary verdict would let a defective candidate producer read as a legitimate naming answer, which is the state-space conflation this whole lane exists to remove." -data five_minute_ci_gate_program_note: String = "PROGRAM BOUNDARY, NOT A SINGLE PR (operator dispatch K, 2026-08-01; sequence revision eager-boar-610, 2026-08-01; contract re-anchored by operator ruling 2026-08-02). Product contract: every required operation performs the bare minimum computation needed to serve it — no recomputation of any semantic fact whose inputs did not change; wall-clock falls out of the realization/materialization goals rather than defining them. Five minutes is NOT the contract — it is the distress ceiling ('this is hard / not working well'), retained only as the Stage C checkpoint bound. Six sub-lanes plus an explicit operator sequence — (1) finish #7522 warm-merge-admission with net wall receipt; (2) merge #7599 native bundle slice; (3) immediately cut over bounded production witness population to native execution kind (#7599 owner); (4) continue #7534 as materialization substrate under module-grain (hierarchy: module parse/type/interface → resolved entry → native bundle; no default CI savings until ordinary invocations consume it); (5) union CLOSED per #7533 → per-entry-assembly narrow lane; (6) this parent registration. Native-at-small-scale is SETTLED and BANKED — #7599 merged 2026-08-02 (merge 1ebff27f1e; 25/25 witness receipts executed at pre-merge head 2f9e780e6, dispositive at small scale; the banking trigger was #7599 merge, now fired); open question is operational migration rate with equivalence/fallback/identity/memory fail-closed. Staged expectations (not flat 30–35min): Stage A modest admission saving only; Stage B first order-of-magnitude witness reduction after production native cutover; Stage C five-minute gate when all conjunction in docs/plans/five-minute-ci-gate-design.md holds. Dispositions: entry-graph-union CLOSED; retention PARKED (#7581). See docs/plans/five-minute-ci-gate-design.md." +data five_minute_ci_gate_program_note: String = "PROGRAM BOUNDARY, NOT A SINGLE PR (operator dispatch K, 2026-08-01; sequence revision eager-boar-610, 2026-08-01; contract re-anchored by operator ruling 2026-08-02). Product contract: every required operation performs the bare minimum computation needed to serve it — no recomputation of any semantic fact whose inputs did not change; wall-clock falls out of the realization/materialization goals rather than defining them. Five minutes is NOT the contract — it is the distress ceiling ('this is hard / not working well'), retained only as the Stage C checkpoint bound. Six sub-lanes plus an explicit operator sequence — (1) finish #7522 warm-merge-admission with net wall receipt; (2) merge #7599 native bundle slice; (3) immediately cut over bounded production witness population to native execution kind (#7599 owner); (4) continue #7534 as materialization substrate under module-grain (hierarchy: module parse/type/interface → resolved entry → native bundle; no default CI savings until ordinary invocations consume it); (5) union CLOSED per #7533 → per-entry-assembly narrow lane; (6) this parent registration. Native-at-small-scale evidence has LANDED; operational migration rate remains OPEN with equivalence/fallback/identity/memory fail-closed. The landed change, its merge commit, the head the witnesses actually executed at, and the cited executing witness are execution evidence, not design criteria: they live in ONE typed receipt, gunbc.native_witness_transition_receipt native_at_small_scale_transition_receipt, and are restated neither here nor in gunbc.design_document (operator ruling on gunbc#7710, 2026-08-02 — this note and the design document previously carried independent hand-maintained copies of the same advancing status). Staged expectations (not flat 30–35min): Stage A modest admission saving only; Stage B first order-of-magnitude witness reduction after production native cutover; Stage C five-minute gate when all conjunction in docs/plans/five-minute-ci-gate-design.md holds. Dispositions: entry-graph-union CLOSED; retention PARKED (#7581). See docs/plans/five-minute-ci-gate-design.md." data namespace_node_recut_note: String = "THE BROAD NAMESPACE NODE WAS TOO COARSE TO CLOSE HONESTLY, and the recut is the fix (operator ruling, 2026-07-31). namespace-canonical-binding previously combined two separable things in one boundary: working out which declarations a name can see, and calling one decision function on them. A check proving only the none/one/many decision could therefore have marked the whole node accepted while candidate derivation, reference-derived dependency closure, and the production changeover all remained unbuilt — an acceptance hazard, and the exact shape of rung inflation DESIGN 4b forbids, where a carrier named for the top rung occupies the bottom one.\\n\\nThree prerequisites now stand in front of it. namespace-binding-kernel owns the decision alone, on a candidate population SUPPLIED to it. namespace-reference-derived-closure owns structural exposure, authored order, the candidate index, exact reference-to-declaration binding, and the derived dependency edges. namespace-ambiguity-discharge settles the genuinely-many cases from real compilation. namespace-canonical-binding KEEPS ITS DURABLE IDENTITY and is now the final production changeover only, so historical links resolve and no identity is reused.\\n\\nWhy the split falls exactly there: dependency edges are a PROJECTION OF THE BINDING, not a second authored statement. A program that instead authored the missing edges by hand reached 400 of 771 files at roughly one import per CI floor before it was stopped; the unresolved population was evidence that binding and module discovery are coupled at the wrong boundary, not a backlog to grind down.\\n\\nTHE CHANGEOVER AND ITS SUCCESSOR ARE DISJOINT, and an earlier revision of this recut broke that (review 45649). It retitled namespace-canonical-binding as 'switch the whole compiler over' with a boundary reading 'every place that resolves a name', which swallowed namespace-bound-only-consumers underneath it — that node's own boundary is type checking, call lookup, and argument-count checks reading the decided answer. Overlapping boundaries are the §2 redundancy this document exists to remove, and they are worse on a roadmap than in code: completing the parent would already entail most of the child, so either the child can never be honestly accepted or the parent was silently read narrower than it was written. The cut is PRODUCER versus READER. The changeover node owns the sites that WORK OUT what a name refers to, and the deletion of the search-everything fallback behind them. Its successor owns the READERS of that answer and their obligation to stop on unresolved or ambiguous. Neither entails the other, and each can be accepted on its own evidence.\\n\\nONE EDGE WAS DELIBERATELY NOT CHANGED. pderive-source-slot-binding still depends on namespace-canonical-binding, which now means it waits for the whole production changeover. It plausibly needs only occurrence transport plus the binding kernel, but that is unproven: the dependency moves only once the focused P-derive consumer demonstrates it can operate on an exact supplied candidate population. Loosening it on the strength of the argument alone would be asserting a fact nobody has measured." diff --git a/dag/test/claim/native_witness_transition_receipt_witness_test.dag b/dag/test/claim/native_witness_transition_receipt_witness_test.dag new file mode 100644 index 00000000000..d30a1c26464 --- /dev/null +++ b/dag/test/claim/native_witness_transition_receipt_witness_test.dag @@ -0,0 +1,91 @@ +module test.claim.native_witness_transition_receipt_witness + +import std.decl_ref { decl_ref } +import std.types { Bool, Int, String } +import gunbc.roadmap_authority { declared_roadmap_nodes } +import gunbc.roadmap_model { RoadmapNodeIdentity } +import gunbc.native_witness_transition_receipt { + NativeSelectedWitnessTransitionReceipt, + TransitionEvidenceStanding, + EvidenceExecutedAtLandedCommit, + EvidenceExecutedBeforeLanding, + transition_evidence_standing, + native_at_small_scale_transition_receipt, +} + +data native_witness_transition_witness_note: String = "THE TWO STANDING ARMS ARE ASSERTED TOGETHER ON PURPOSE. Either arm alone would pass against a fold that ignored its inputs and returned a constant; asserting both means no constant implementation survives, which is what makes the pair discriminating rather than decorative. The subject join is the second independent question -- a receipt naming a node identity nothing declares is evidence about nobody -- and its RED plants a fabricated identity so the join is proven capable of returning zero. That control is not hypothetical: drafting this receipt first transcribed the node identity as rn_2I5K7M9O1Q3S5T8V0W2X4Y7Z9A1C, one character off the declared rn_2I5K7M9O1Q3R6T8V0W2X4Y7Z9A1C, and the join is what catches that class." + +fn planted_receipt( + identity: String, + merge_commit: String, + evaluated_head: String, +) -> NativeSelectedWitnessTransitionReceipt { + NativeSelectedWitnessTransitionReceipt { + node: identity as RoadmapNodeIdentity, + landed_pull_request: 1, + landed_merge_commit: merge_commit, + evaluated_head: evaluated_head, + executed_evidence: decl_ref( + module_path: "test.claim.native_witness_transition_receipt_witness", + decl_name: "planted_receipt", + ), + } +} + +fn standing_is_before_landing(standing: TransitionEvidenceStanding) -> Bool { + match standing { + EvidenceExecutedBeforeLanding { evaluated_head: _, landed_merge_commit: _ } => true + EvidenceExecutedAtLandedCommit => false + } +} + +fn standing_names_both_commits( + standing: TransitionEvidenceStanding, + expected_head: String, + expected_merge: String, +) -> Bool { + match standing { + EvidenceExecutedBeforeLanding { evaluated_head, landed_merge_commit } => + evaluated_head == expected_head && landed_merge_commit == expected_merge + EvidenceExecutedAtLandedCommit => false + } +} + +fn declared_nodes_carrying_identity(identity: String) -> Int { + declared_roadmap_nodes() + |> filter(n => (n.identity as String) == identity) + |> count +} + +test fn native_at_small_scale_evidence_stands_as_executed_before_landing() -> Bool { + let receipt = native_at_small_scale_transition_receipt() + let standing = transition_evidence_standing(receipt: receipt) + return standing_is_before_landing(standing: standing) + && standing_names_both_commits( + standing: standing, + expected_head: "2f9e780e6d2130680c4d9fb49739bf0c6cc7c746", + expected_merge: "1ebff27f1e538a06edbaf6a1871bff4c10887b39", + ) +} + +test fn evidence_executed_at_the_landed_commit_is_the_other_standing() -> Bool { + let receipt = planted_receipt( + identity: "rn_2I5K7M9O1Q3R6T8V0W2X4Y7Z9A1C", + merge_commit: "1ebff27f1e538a06edbaf6a1871bff4c10887b39", + evaluated_head: "1ebff27f1e538a06edbaf6a1871bff4c10887b39", + ) + return !standing_is_before_landing( + standing: transition_evidence_standing(receipt: receipt), + ) +} + +test fn receipt_subject_joins_exactly_one_declared_roadmap_node() -> Bool { + let receipt = native_at_small_scale_transition_receipt() + return declared_nodes_carrying_identity(identity: receipt.node as String) == 1 +} + +test fn a_fabricated_subject_identity_joins_no_declared_node() -> Bool { + return declared_nodes_carrying_identity( + identity: "rn_2I5K7M9O1Q3S5T8V0W2X4Y7Z9A1C", + ) == 0 +}