From cf164c72f0cdb3fbb29c15a286bde1eb9a3216e4 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 00:42:05 -0400 Subject: [PATCH 01/52] docs(roadmap): record CharClass phase-1 closure + add Class 5 Gap 3 ledger row (post-#693 escalation) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Director-authored amendment following the 2026-04-24 escalation from PR #693 (sub-child sharp-bear-829 under Surface Manager). Two edits: 1. New "Class 5 Gap 3 — port-carried field values in data bodies" row in the 2026-04-21 post-merge-debt section. The substrate gap was documented in src/v3/DOWNSTREAM_REQUIREMENTS.md:239 but had no ROADMAP ledger row for cross-lane visibility. PR #693's execution surfaced it as the blocker on sub_charclass_in_std_unicode phase-2. 2. Retract the "ready-to-dispatch (no substrate capability gap)" claim on the Character-level row, annotate phase-1 landed via PR #693 (CharClass vocabulary + Rust-mirror structural scanner path), and point phase-2 at the new Class 5 Gap 3 row. Codifies the audit pattern: "this consumption gap has no substrate capability gap" claims must be verified by attempting the retype before the claim lands. Co-Authored-By: Claude Opus 4.7 (1M context) --- ROADMAP.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ROADMAP.md b/ROADMAP.md index 5f7f712997e..bf50de09158 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -311,6 +311,7 @@ Per-row tagging is a scheduled follow-up sweep — **trigger:** post-merge of th ### Post-merge debt (2026-04-21 receipt-closure wave) - **Class 5 Gap 1 — `Bool` inhabits `BooleanAlgebra` grounding not wired**: surfaced during #610's closing. Current `OperatorKind::Logical(_)` dispatch in the three emitters is hardcoded (`if let OperatorKind::Logical(_)` branches bypass the algebra-field resolution that arithmetic operators use). The substrate already models `BooleanAlgebra` with `meet/join/complement` per `dsl/std/algebra.dag:230-236`, and comments there state *"Bool inhabits BooleanAlgebra"* — but the `inhabits` edge isn't structurally landed. Dissolution: wire `Bool inhabits BooleanAlgebra` + extend `resolve_operator_arrow` for `OperatorKind::Logical(_)` + delete the hardcoded emitter branches. Owner: 1e-2b lane (Path A). +- **Class 5 Gap 3 — port-carried field values in `data` bodies (substrate capability gap)**: authoritative enumeration at `src/v3/DOWNSTREAM_REQUIREMENTS.md:239` (gap partially closed at M1(2.8) for literal-only fields via `ValueBody::Structural` / `SurfaceExpr::Record` / `lower_record_to_structural`; remaining open half is port-carried field values — nested records, list literals, declaration references, `Var` references, sum-variant literals). `compile_to_dag` rejects these shapes inside `data` bodies today. **Consumer impact surfaced 2026-04-24** by PR #693 escalation (sub-child `sharp-bear-829` under Surface Manager): blocks `sub_charclass_in_std_unicode` phase-2 — specifically the `tokenize.dag` retype of `StringEscapeSpec.suffix`, `LocalPunctSpec.pattern`, `OperatorSpec.symbol`, `dag_keyword_set` keys, etc. to `Char` / `List` + `CharClass` sum-variant literals. Adjacent future retype-to-structured-carrier lanes (syntax.dag keyword sets, other opaque-string fields) will hit the same wall. Dissolution: extend `compile_to_dag` to parse port-carried field values in data bodies. Alternative design call (out of scope here): shift the authority shape for these configs from `data` bodies to extractor-over-unparsed-source. Owner: unassigned; substrate-capability scope — routes through a self-hosting / substrate-capability lane, not through the consuming lanes. **Audit pattern:** future "this consumption gap has no substrate capability gap" claims should be verified by attempting the retype before the claim lands — the 2026-04-23 authoring of the Character-level row (this file, `:354`) made this claim and was factually wrong; retracted 2026-04-24. - **`emit_rust_module` gap: SurfaceLiteral → LiteralBits rename**: substrate declares `LitInt/LitBool/LitString` in `LiteralBits`; Rust enum is `Int/Bool/String`; no rename facility in `emit_rust_module` causes connective-producing slices (per #612's staging choice notes) to fail on this. Dissolution: add per-variant name mapping in spec or rename-facility in emit. Owner: unassigned; blocks deeper SG-3g slices. - **`emit_rust_module` gap: `render_variant_constructor` fails on external tuple variants**: `src/v3/compiler/src/emit/rust_target.rs:4296` unconditionally emits `Variant { _0: value }` which is wrong for external tuple variants. Dissolution: spec-driven variant-constructor template per source kind. Owner: unassigned; blocks deeper SG-3g slices. - **File-preference rank is a ratified-parallel-authority scaffold**: `Dag::declaration_name_preference_rank` (`src/v3/compiler/src/dag.rs:1985-2015`) and its mirror in `collect_symbols` (`src/v3/compiler/src/lower.rs:1258-1278`) resolve same-named declarations by preferring `src/v3/` over `dsl/`. This is a P2 Boundary Discipline violation — a stable lookup rule that *normalizes* duplicate authority instead of dissolving it. Held as a scaffold rather than deleted because the duplicates carry v3-only substrate content (`v3.std.substrate` imports, `ElementRef` / `PortId` references, partitioned `EffectShape`, diagnostic-assertion surface) that cannot yet live under `dsl/std/` — v2 CI recursively ingests `dsl/` and cannot parse v3 grammar. Dissolution trigger: when every module currently duplicated between `dsl/std/` and `src/v3/std/` (or `src/v3/spec/`) has converged to a single canonical home, delete the rank function + mirror policy and remove the duplicate-authority preference rule entirely. After convergence, `declaration_by_name` must resolve against the single surviving authority or fail closed on multiple matches; no rank-based bridge remains. Convergence checklist: (1) `module std.effects` — `dsl/std/effects.dag` ↔ `src/v3/std/effects.dag` (v3 copy imports `v3.std.substrate`, partitions `EffectShape`, uses `ElementRef`); (2) `module std.verification` — `dsl/std/verification.dag` ↔ `src/v3/std/verification.dag` (surfaces are disjoint today: v2 `AssertKind/TestClaim/TestCase` vs v3 `DiagnosticKind / DiagnosticReference / PortStateExpectation`; convergence requires a design call on which surface wins); (3) embedded `http_path` mirror inside `src/v3/std/effects.dag:118-260` (resolves via either staging `http_path.dag` in v3 or rewiring imports to consume `std.http_path` directly once v3-substrate staging lands). Owner: unblocked by v3.std.substrate staging lane + v3-grammar CI convergence. @@ -350,7 +351,7 @@ Tracked debt not dispatched with the 2026-04-21 lane wave (Lane 1e P3.0, SG-2c-4 - **`extdeps/browser.dag` typed-carrier service-boundary collapse**: `dsl/extdeps/browser.dag:21-32` declares typed carriers (`BrowserConfig`, opaque `BrowserContext` / `Page` / `Element` handles, imports `Url`), but service ops use raw `String`: `Launch.input.headless: String = "false"`, `output.context_id: String`; `Goto.input.url: String`, `wait_until: String`, `output.final_url: String`; selector/query/evaluate outputs all remain `String` (`:42-47,56-60,75-103`). Same class as the LLM service flattening and the GitHub auth model bypass (both tracked separately). P1 Modeling Faithfulness / M8 "dispatch structural, not string extraction". **Dissolution trigger**: when the transport layer (REST/shell/file) can consume typed carriers end-to-end rather than stringly — this requires transport-level capability support that currently forces the String fallback. The Lane H brief (PR #658) pilots the pattern on browser.dag specifically; if that lands cleanly, LLM + GitHub dissolutions can consume the same pattern. Until then, the transport-capability gap is the upstream blocker. Surfaced by 2026-04-22 exploratory analysis. Owner: unassigned (pilot in-flight on Lane H #658); M per service family, contingent on transport capability. -- **Character-level under-consumption in tokenize + syntax authorities (consumption gap, not substrate gap)**: `src/v3/compiler/tokenize.dag` and `dsl/extdeps/languages/dag/syntax.dag` both slice the ASCII/Unicode codepoint space in two parallel non-canonical forms. **Reserved individual codepoints as opaque strings**: `StringEscapeSpec.suffix`, `output_codepoint: Int`, `LocalPunctSpec.pattern`, `string_literal_delimiter`, `line_comment_prefix`, `OperatorSpec.symbol`, `dag_keyword_set` keys — all encode specific codepoints as byte strings. **Reserved codepoint classes as hidden Rust predicates**: `is_ascii_whitespace` / `is_ascii_digit` / `is_ascii_alphabetic` / `is_ascii_alphanumeric` plus a bare `byte == b'_'` `push_str`'d into `regen_tokenize.rs:700,727,750,752`. Not mentioned in `.dag` at all. **The character-level concepts already exist in `dsl/std/`** and are imported cross-tree today (e.g., `src/v3/compiler/regen.dag:3` imports `std.types`): `std.types::Char = Int` (Unicode scalar, U+0000–U+10FFFF), `std.string_type::String = FreeMonoid`, `std.unicode` (`DisplayWidth`, `UnicodeBlock`, block/width classification), `std.encoding` (`ASCII | UTF8 | Latin1 | Text | Binary | Unknown` lattice with `ASCII <: UTF8 <: Text` — literally the ASCII→Unicode causal chain), `std.bit::Byte`. **Framing**: this is a consumption gap — the modeling is done, the tokenizer and syntax authorities just aren't using it. Only one substrate delta is needed. **Dissolution (follow-up lane)**: (1) add `CharClass = Whitespace | Digit | IdentStart | IdentContinue` (or superset) to `std.unicode` as a sibling to `DisplayWidth`, plus classification predicates as data/functions; (2) retype the opaque-string fields in `tokenize.dag` (`suffix: Char`, `output_codepoint: Char`, `pattern: List`, `string_literal_delimiter: Char`, `line_comment_prefix: List`) and the parallel fields in `syntax.dag` (`OperatorSpec.symbol: List`, keyword-set keys as `List`); (3) rewire `regen_tokenize` to read the class-predicate list structurally rather than hardcoding host-stdlib method names. Scaffold note lives in the `tokenize.dag` header. Owner: unassigned; migration-gate: **ready-to-dispatch** (no substrate capability gap). If the `tokenize.dag → std/tokenize.dag` consolidation migration (from the compiler–std consolidation program above) is dispatched first, the rewrite piggybacks on it so the structurally-labeled borrow lands in its final home. +- **Character-level under-consumption in tokenize + syntax authorities (consumption gap, not substrate gap)**: `src/v3/compiler/tokenize.dag` and `dsl/extdeps/languages/dag/syntax.dag` both slice the ASCII/Unicode codepoint space in two parallel non-canonical forms. **Reserved individual codepoints as opaque strings**: `StringEscapeSpec.suffix`, `output_codepoint: Int`, `LocalPunctSpec.pattern`, `string_literal_delimiter`, `line_comment_prefix`, `OperatorSpec.symbol`, `dag_keyword_set` keys — all encode specific codepoints as byte strings. **Reserved codepoint classes as hidden Rust predicates**: `is_ascii_whitespace` / `is_ascii_digit` / `is_ascii_alphabetic` / `is_ascii_alphanumeric` plus a bare `byte == b'_'` `push_str`'d into `regen_tokenize.rs:700,727,750,752`. Not mentioned in `.dag` at all. **The character-level concepts already exist in `dsl/std/`** and are imported cross-tree today (e.g., `src/v3/compiler/regen.dag:3` imports `std.types`): `std.types::Char = Int` (Unicode scalar, U+0000–U+10FFFF), `std.string_type::String = FreeMonoid`, `std.unicode` (`DisplayWidth`, `UnicodeBlock`, block/width classification), `std.encoding` (`ASCII | UTF8 | Latin1 | Text | Binary | Unknown` lattice with `ASCII <: UTF8 <: Text` — literally the ASCII→Unicode causal chain), `std.bit::Byte`. **Framing**: this is a consumption gap — the modeling is done, the tokenizer and syntax authorities just aren't using it. Only one substrate delta is needed. **Dissolution (follow-up lane)**: (1) add `CharClass = Whitespace | Digit | IdentStart | IdentContinue` (or superset) to `std.unicode` as a sibling to `DisplayWidth`, plus classification predicates as data/functions; (2) retype the opaque-string fields in `tokenize.dag` (`suffix: Char`, `output_codepoint: Char`, `pattern: List`, `string_literal_delimiter: Char`, `line_comment_prefix: List`) and the parallel fields in `syntax.dag` (`OperatorSpec.symbol: List`, keyword-set keys as `List`); (3) rewire `regen_tokenize` to read the class-predicate list structurally rather than hardcoding host-stdlib method names. Scaffold note lives in the `tokenize.dag` header. **Status (2026-04-24, post-PR #693):** phase-1 landed — step (1) done (`CharClass` + `char_in_class` in `dsl/std/unicode.dag`, ASCII-aligned); step (3) partially done via a `tokenize_char_class.rs` Rust mirror (gate-locked 0..=127 against Rust ASCII helpers per `sub_charclass_in_std_unicode_gate`), so generated tokenizer carries no `is_ascii_*` calls. Phase-2 (step 2 — the `.dag`-native retype to `Char` / `List` / `CharClass` variants inside `data` bodies) is **blocked on Class 5 Gap 3** (port-carried field values in `data` bodies per `src/v3/DOWNSTREAM_REQUIREMENTS.md:239`); see that row above for the substrate-capability dissolution. **The 2026-04-23 authoring of this row claimed "no substrate capability gap"; retracted — PR #693's execution found the gap.** Owner: phase-1 landed (PR #693); phase-2 unassigned, blocked on Class 5 Gap 3. If the `tokenize.dag → std/tokenize.dag` consolidation migration (from the compiler–std consolidation program above) is dispatched before Class 5 Gap 3 closes, the phase-1 Rust mirror piggybacks on it; the full structural `.dag`-native path lands only when Class 5 Gap 3 closes. ### Post-merge debt (2026-04-23 thesis-doc surface — PR #672) From 6dcceb8a68f25741b2f0fb13304fa9658db77a64 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 00:47:20 -0400 Subject: [PATCH 02/52] =?UTF-8?q?resolve=20merge=20conflict=20on=20ROADMAP?= =?UTF-8?q?.md=20character-level=20row=20=E2=80=94=20keep=20phase-1=20stat?= =?UTF-8?q?us=20edits=20+=20char=5Fin=5Fclass=20interpreter-parity=20sibli?= =?UTF-8?q?ng=20row=20from=20main?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ROADMAP.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 0dbec61e0bd..e3deb800af0 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -351,12 +351,8 @@ Tracked debt not dispatched with the 2026-04-21 lane wave (Lane 1e P3.0, SG-2c-4 - **`extdeps/browser.dag` typed-carrier service-boundary collapse**: `dsl/extdeps/browser.dag:21-32` declares typed carriers (`BrowserConfig`, opaque `BrowserContext` / `Page` / `Element` handles, imports `Url`), but service ops use raw `String`: `Launch.input.headless: String = "false"`, `output.context_id: String`; `Goto.input.url: String`, `wait_until: String`, `output.final_url: String`; selector/query/evaluate outputs all remain `String` (`:42-47,56-60,75-103`). Same class as the LLM service flattening and the GitHub auth model bypass (both tracked separately). P1 Modeling Faithfulness / M8 "dispatch structural, not string extraction". **Dissolution trigger**: when the transport layer (REST/shell/file) can consume typed carriers end-to-end rather than stringly — this requires transport-level capability support that currently forces the String fallback. The Lane H brief (PR #658) pilots the pattern on browser.dag specifically; if that lands cleanly, LLM + GitHub dissolutions can consume the same pattern. Until then, the transport-capability gap is the upstream blocker. Surfaced by 2026-04-22 exploratory analysis. Owner: unassigned (pilot in-flight on Lane H #658); M per service family, contingent on transport capability. -<<<<<<< HEAD -- **Character-level under-consumption in tokenize + syntax authorities (consumption gap, not substrate gap)**: `src/v3/compiler/tokenize.dag` and `dsl/extdeps/languages/dag/syntax.dag` both slice the ASCII/Unicode codepoint space in two parallel non-canonical forms. **Reserved individual codepoints as opaque strings**: `StringEscapeSpec.suffix`, `output_codepoint: Int`, `LocalPunctSpec.pattern`, `string_literal_delimiter`, `line_comment_prefix`, `OperatorSpec.symbol`, `dag_keyword_set` keys — all encode specific codepoints as byte strings. **Reserved codepoint classes as hidden Rust predicates**: `is_ascii_whitespace` / `is_ascii_digit` / `is_ascii_alphabetic` / `is_ascii_alphanumeric` plus a bare `byte == b'_'` `push_str`'d into `regen_tokenize.rs:700,727,750,752`. Not mentioned in `.dag` at all. **The character-level concepts already exist in `dsl/std/`** and are imported cross-tree today (e.g., `src/v3/compiler/regen.dag:3` imports `std.types`): `std.types::Char = Int` (Unicode scalar, U+0000–U+10FFFF), `std.string_type::String = FreeMonoid`, `std.unicode` (`DisplayWidth`, `UnicodeBlock`, block/width classification), `std.encoding` (`ASCII | UTF8 | Latin1 | Text | Binary | Unknown` lattice with `ASCII <: UTF8 <: Text` — literally the ASCII→Unicode causal chain), `std.bit::Byte`. **Framing**: this is a consumption gap — the modeling is done, the tokenizer and syntax authorities just aren't using it. Only one substrate delta is needed. **Dissolution (follow-up lane)**: (1) add `CharClass = Whitespace | Digit | IdentStart | IdentContinue` (or superset) to `std.unicode` as a sibling to `DisplayWidth`, plus classification predicates as data/functions; (2) retype the opaque-string fields in `tokenize.dag` (`suffix: Char`, `output_codepoint: Char`, `pattern: List`, `string_literal_delimiter: Char`, `line_comment_prefix: List`) and the parallel fields in `syntax.dag` (`OperatorSpec.symbol: List`, keyword-set keys as `List`); (3) rewire `regen_tokenize` to read the class-predicate list structurally rather than hardcoding host-stdlib method names. Scaffold note lives in the `tokenize.dag` header. **Status (2026-04-24, post-PR #693):** phase-1 landed — step (1) done (`CharClass` + `char_in_class` in `dsl/std/unicode.dag`, ASCII-aligned); step (3) partially done via a `tokenize_char_class.rs` Rust mirror (gate-locked 0..=127 against Rust ASCII helpers per `sub_charclass_in_std_unicode_gate`), so generated tokenizer carries no `is_ascii_*` calls. Phase-2 (step 2 — the `.dag`-native retype to `Char` / `List` / `CharClass` variants inside `data` bodies) is **blocked on Class 5 Gap 3** (port-carried field values in `data` bodies per `src/v3/DOWNSTREAM_REQUIREMENTS.md:239`); see that row above for the substrate-capability dissolution. **The 2026-04-23 authoring of this row claimed "no substrate capability gap"; retracted — PR #693's execution found the gap.** Owner: phase-1 landed (PR #693); phase-2 unassigned, blocked on Class 5 Gap 3. If the `tokenize.dag → std/tokenize.dag` consolidation migration (from the compiler–std consolidation program above) is dispatched before Class 5 Gap 3 closes, the phase-1 Rust mirror piggybacks on it; the full structural `.dag`-native path lands only when Class 5 Gap 3 closes. -======= -- **Character-level under-consumption in tokenize + syntax authorities (consumption gap, not substrate gap)**: `src/v3/compiler/tokenize.dag` and `dsl/extdeps/languages/dag/syntax.dag` both slice the ASCII/Unicode codepoint space in two parallel non-canonical forms. **Reserved individual codepoints as opaque strings**: `StringEscapeSpec.suffix`, `output_codepoint: Int`, `LocalPunctSpec.pattern`, `string_literal_delimiter`, `line_comment_prefix`, `OperatorSpec.symbol`, `dag_keyword_set` keys — all encode specific codepoints as byte strings. **Reserved codepoint classes as hidden Rust predicates**: `is_ascii_whitespace` / `is_ascii_digit` / `is_ascii_alphabetic` / `is_ascii_alphanumeric` plus a bare `byte == b'_'` `push_str`'d into `regen_tokenize.rs:700,727,750,752`. Not mentioned in `.dag` at all. **The character-level concepts already exist in `dsl/std/`** and are imported cross-tree today (e.g., `src/v3/compiler/regen.dag:3` imports `std.types`): `std.types::Char = Int` (Unicode scalar, U+0000–U+10FFFF), `std.string_type::String = FreeMonoid`, `std.unicode` (`DisplayWidth`, `UnicodeBlock`, block/width classification), `std.encoding` (`ASCII | UTF8 | Latin1 | Text | Binary | Unknown` lattice with `ASCII <: UTF8 <: Text` — literally the ASCII→Unicode causal chain), `std.bit::Byte`. **Framing**: this is a consumption gap — the modeling is done, the tokenizer and syntax authorities just aren't using it. Only one substrate delta is needed. **Dissolution (follow-up lane)**: (1) add `CharClass = Whitespace | Digit | IdentStart | IdentContinue` (or superset) to `std.unicode` as a sibling to `DisplayWidth`, plus classification predicates as data/functions; (2) retype the opaque-string fields in `tokenize.dag` (`suffix: Char`, `output_codepoint: Char`, `pattern: List`, `string_literal_delimiter: Char`, `line_comment_prefix: List`) and the parallel fields in `syntax.dag` (`OperatorSpec.symbol: List`, keyword-set keys as `List`); (3) rewire `regen_tokenize` to read the class-predicate list structurally rather than hardcoding host-stdlib method names. Scaffold note lives in the `tokenize.dag` header. Owner: unassigned; migration-gate: **ready-to-dispatch** (no substrate capability gap). If the `tokenize.dag → std/tokenize.dag` consolidation migration (from the compiler–std consolidation program above) is dispatched first, the rewrite piggybacks on it so the structurally-labeled borrow lands in its final home. +- **Character-level under-consumption in tokenize + syntax authorities (consumption gap, not substrate gap)**: `src/v3/compiler/tokenize.dag` and `dsl/extdeps/languages/dag/syntax.dag` both slice the ASCII/Unicode codepoint space in two parallel non-canonical forms. **Reserved individual codepoints as opaque strings**: `StringEscapeSpec.suffix`, `output_codepoint: Int`, `LocalPunctSpec.pattern`, `string_literal_delimiter`, `line_comment_prefix`, `OperatorSpec.symbol`, `dag_keyword_set` keys — all encode specific codepoints as byte strings. **Reserved codepoint classes as hidden Rust predicates**: `is_ascii_whitespace` / `is_ascii_digit` / `is_ascii_alphabetic` / `is_ascii_alphanumeric` plus a bare `byte == b'_'` `push_str`'d into `regen_tokenize.rs:700,727,750,752`. Not mentioned in `.dag` at all. **The character-level concepts already exist in `dsl/std/`** and are imported cross-tree today (e.g., `src/v3/compiler/regen.dag:3` imports `std.types`): `std.types::Char = Int` (Unicode scalar, U+0000–U+10FFFF), `std.string_type::String = FreeMonoid`, `std.unicode` (`DisplayWidth`, `UnicodeBlock`, block/width classification), `std.encoding` (`ASCII | UTF8 | Latin1 | Text | Binary | Unknown` lattice with `ASCII <: UTF8 <: Text` — literally the ASCII→Unicode causal chain), `std.bit::Byte`. **Framing**: this is a consumption gap — the modeling is done, the tokenizer and syntax authorities just aren't using it. Only one substrate delta is needed. **Dissolution (follow-up lane)**: (1) add `CharClass = Whitespace | Digit | IdentStart | IdentContinue` (or superset) to `std.unicode` as a sibling to `DisplayWidth`, plus classification predicates as data/functions; (2) retype the opaque-string fields in `tokenize.dag` (`suffix: Char`, `output_codepoint: Char`, `pattern: List`, `string_literal_delimiter: Char`, `line_comment_prefix: List`) and the parallel fields in `syntax.dag` (`OperatorSpec.symbol: List`, keyword-set keys as `List`); (3) rewire `regen_tokenize` to read the class-predicate list structurally rather than hardcoding host-stdlib method names. Scaffold note lives in the `tokenize.dag` header. **Status (2026-04-24, post-PR #693):** phase-1 landed — step (1) done (`CharClass` + `char_in_class` in `dsl/std/unicode.dag`, ASCII-aligned); step (3) partially done via a `tokenize_char_class.rs` Rust mirror (gate-locked 0..=127 against Rust ASCII helpers per `sub_charclass_in_std_unicode_gate`), so generated tokenizer carries no `is_ascii_*` calls. Phase-2 (step 2 — the `.dag`-native retype to `Char` / `List` / `CharClass` variants inside `data` bodies) is **blocked on Class 5 Gap 3** (port-carried field values in `data` bodies per `src/v3/DOWNSTREAM_REQUIREMENTS.md:239`); see that row above for the substrate-capability dissolution. **The 2026-04-23 authoring of this row claimed "no substrate capability gap"; retracted — PR #693's execution found the gap.** See the `char_in_class` interpreter-parity follow-up row below for the bridge-finish step (retiring the host-stdlib-only ratchet on `tokenize_char_class.rs`). Owner: phase-1 landed (PR #693); phase-2 unassigned, blocked on Class 5 Gap 3. If the `tokenize.dag → std/tokenize.dag` consolidation migration (from the compiler–std consolidation program above) is dispatched before Class 5 Gap 3 closes, the phase-1 Rust mirror piggybacks on it; the full structural `.dag`-native path lands only when Class 5 Gap 3 closes. - **`char_in_class` interpreter parity (tokenizer bridge finish, PR #693):** `dsl/std/unicode.dag::char_in_class` is canonical; `src/v3/compiler/src/tokenize_char_class.rs` stays hand-synced until M1(2.8) class-5 gap #3 allows structural scanner rows. Today unit tests ratchet against `u8::is_ascii_*` only. **Next step:** once `char_in_class` is evaluable from the v3 compiler test harness, assert code-point parity on `0..=127` against `byte_matches` and retire the host-stdlib-only ratchet / duplicate sync prose. Same migration gate as deleting `tokenize_char_class.rs` when `regen_tokenize` reads classes from lowered `tokenize.dag`. ->>>>>>> origin/main ### Post-merge debt (2026-04-23 thesis-doc surface — PR #672) From 5a9d79710ca1547c569ca48d8dee90c51e98714d Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 00:48:56 -0400 Subject: [PATCH 03/52] docs(roadmap): name retraction mechanism explicitly in Class 5 Gap 3 audit note (PM review) --- ROADMAP.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ROADMAP.md b/ROADMAP.md index e3deb800af0..c43438fc513 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -311,7 +311,7 @@ Per-row tagging is a scheduled follow-up sweep — **trigger:** post-merge of th ### Post-merge debt (2026-04-21 receipt-closure wave) - **Class 5 Gap 1 — `Bool` inhabits `BooleanAlgebra` grounding not wired**: surfaced during #610's closing. Current `OperatorKind::Logical(_)` dispatch in the three emitters is hardcoded (`if let OperatorKind::Logical(_)` branches bypass the algebra-field resolution that arithmetic operators use). The substrate already models `BooleanAlgebra` with `meet/join/complement` per `dsl/std/algebra.dag:230-236`, and comments there state *"Bool inhabits BooleanAlgebra"* — but the `inhabits` edge isn't structurally landed. Dissolution: wire `Bool inhabits BooleanAlgebra` + extend `resolve_operator_arrow` for `OperatorKind::Logical(_)` + delete the hardcoded emitter branches. Owner: 1e-2b lane (Path A). -- **Class 5 Gap 3 — port-carried field values in `data` bodies (substrate capability gap)**: authoritative enumeration at `src/v3/DOWNSTREAM_REQUIREMENTS.md:239` (gap partially closed at M1(2.8) for literal-only fields via `ValueBody::Structural` / `SurfaceExpr::Record` / `lower_record_to_structural`; remaining open half is port-carried field values — nested records, list literals, declaration references, `Var` references, sum-variant literals). `compile_to_dag` rejects these shapes inside `data` bodies today. **Consumer impact surfaced 2026-04-24** by PR #693 escalation (sub-child `sharp-bear-829` under Surface Manager): blocks `sub_charclass_in_std_unicode` phase-2 — specifically the `tokenize.dag` retype of `StringEscapeSpec.suffix`, `LocalPunctSpec.pattern`, `OperatorSpec.symbol`, `dag_keyword_set` keys, etc. to `Char` / `List` + `CharClass` sum-variant literals. Adjacent future retype-to-structured-carrier lanes (syntax.dag keyword sets, other opaque-string fields) will hit the same wall. Dissolution: extend `compile_to_dag` to parse port-carried field values in data bodies. Alternative design call (out of scope here): shift the authority shape for these configs from `data` bodies to extractor-over-unparsed-source. Owner: unassigned; substrate-capability scope — routes through a self-hosting / substrate-capability lane, not through the consuming lanes. **Audit pattern:** future "this consumption gap has no substrate capability gap" claims should be verified by attempting the retype before the claim lands — the 2026-04-23 authoring of the Character-level row (this file, `:354`) made this claim and was factually wrong; retracted 2026-04-24. +- **Class 5 Gap 3 — port-carried field values in `data` bodies (substrate capability gap)**: authoritative enumeration at `src/v3/DOWNSTREAM_REQUIREMENTS.md:239` (gap partially closed at M1(2.8) for literal-only fields via `ValueBody::Structural` / `SurfaceExpr::Record` / `lower_record_to_structural`; remaining open half is port-carried field values — nested records, list literals, declaration references, `Var` references, sum-variant literals). `compile_to_dag` rejects these shapes inside `data` bodies today. **Consumer impact surfaced 2026-04-24** by PR #693 escalation (sub-child `sharp-bear-829` under Surface Manager): blocks `sub_charclass_in_std_unicode` phase-2 — specifically the `tokenize.dag` retype of `StringEscapeSpec.suffix`, `LocalPunctSpec.pattern`, `OperatorSpec.symbol`, `dag_keyword_set` keys, etc. to `Char` / `List` + `CharClass` sum-variant literals. Adjacent future retype-to-structured-carrier lanes (syntax.dag keyword sets, other opaque-string fields) will hit the same wall. Dissolution: extend `compile_to_dag` to parse port-carried field values in data bodies. Alternative design call (out of scope here): shift the authority shape for these configs from `data` bodies to extractor-over-unparsed-source. Owner: unassigned; substrate-capability scope — routes through a self-hosting / substrate-capability lane, not through the consuming lanes. **Audit pattern:** future "this consumption gap has no substrate capability gap" claims should be verified by attempting the retype before the claim lands — the 2026-04-23 authoring of the Character-level row (this file, `:354`) made this claim and was factually wrong; retracted 2026-04-24 by the update to that row in this PR (see the `:354` Status block). - **`emit_rust_module` gap: SurfaceLiteral → LiteralBits rename**: substrate declares `LitInt/LitBool/LitString` in `LiteralBits`; Rust enum is `Int/Bool/String`; no rename facility in `emit_rust_module` causes connective-producing slices (per #612's staging choice notes) to fail on this. Dissolution: add per-variant name mapping in spec or rename-facility in emit. Owner: unassigned; blocks deeper SG-3g slices. - **`emit_rust_module` gap: `render_variant_constructor` fails on external tuple variants**: `src/v3/compiler/src/emit/rust_target.rs:4296` unconditionally emits `Variant { _0: value }` which is wrong for external tuple variants. Dissolution: spec-driven variant-constructor template per source kind. Owner: unassigned; blocks deeper SG-3g slices. - **File-preference rank is a ratified-parallel-authority scaffold**: `Dag::declaration_name_preference_rank` (`src/v3/compiler/src/dag.rs:1985-2015`) and its mirror in `collect_symbols` (`src/v3/compiler/src/lower.rs:1258-1278`) resolve same-named declarations by preferring `src/v3/` over `dsl/`. This is a P2 Boundary Discipline violation — a stable lookup rule that *normalizes* duplicate authority instead of dissolving it. Held as a scaffold rather than deleted because the duplicates carry v3-only substrate content (`v3.std.substrate` imports, `ElementRef` / `PortId` references, partitioned `EffectShape`, diagnostic-assertion surface) that cannot yet live under `dsl/std/` — v2 CI recursively ingests `dsl/` and cannot parse v3 grammar. Dissolution trigger: when every module currently duplicated between `dsl/std/` and `src/v3/std/` (or `src/v3/spec/`) has converged to a single canonical home, delete the rank function + mirror policy and remove the duplicate-authority preference rule entirely. After convergence, `declaration_by_name` must resolve against the single surviving authority or fail closed on multiple matches; no rank-based bridge remains. Convergence checklist: (1) `module std.effects` — `dsl/std/effects.dag` ↔ `src/v3/std/effects.dag` (v3 copy imports `v3.std.substrate`, partitions `EffectShape`, uses `ElementRef`); (2) `module std.verification` — `dsl/std/verification.dag` ↔ `src/v3/std/verification.dag` (surfaces are disjoint today: v2 `AssertKind/TestClaim/TestCase` vs v3 `DiagnosticKind / DiagnosticReference / PortStateExpectation`; convergence requires a design call on which surface wins); (3) embedded `http_path` mirror inside `src/v3/std/effects.dag:118-260` (resolves via either staging `http_path.dag` in v3 or rewiring imports to consume `std.http_path` directly once v3-substrate staging lands). Owner: unblocked by v3.std.substrate staging lane + v3-grammar CI convergence. From 559773ca361c12aec42686518bf69f1e79df1a0f Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 00:50:00 -0400 Subject: [PATCH 04/52] docs(roadmap): reconcile Character-level row title with body (per gpt-5.4 review) Row title still said 'consumption gap, not substrate gap' while the body block retracted that claim and cited Class 5 Gap 3 as a substrate dependency for phase-2. Title now matches body: mixed classification, consumption for steps 1+3, substrate for step 2. --- ROADMAP.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ROADMAP.md b/ROADMAP.md index c43438fc513..2fe5ea36213 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -351,7 +351,7 @@ Tracked debt not dispatched with the 2026-04-21 lane wave (Lane 1e P3.0, SG-2c-4 - **`extdeps/browser.dag` typed-carrier service-boundary collapse**: `dsl/extdeps/browser.dag:21-32` declares typed carriers (`BrowserConfig`, opaque `BrowserContext` / `Page` / `Element` handles, imports `Url`), but service ops use raw `String`: `Launch.input.headless: String = "false"`, `output.context_id: String`; `Goto.input.url: String`, `wait_until: String`, `output.final_url: String`; selector/query/evaluate outputs all remain `String` (`:42-47,56-60,75-103`). Same class as the LLM service flattening and the GitHub auth model bypass (both tracked separately). P1 Modeling Faithfulness / M8 "dispatch structural, not string extraction". **Dissolution trigger**: when the transport layer (REST/shell/file) can consume typed carriers end-to-end rather than stringly — this requires transport-level capability support that currently forces the String fallback. The Lane H brief (PR #658) pilots the pattern on browser.dag specifically; if that lands cleanly, LLM + GitHub dissolutions can consume the same pattern. Until then, the transport-capability gap is the upstream blocker. Surfaced by 2026-04-22 exploratory analysis. Owner: unassigned (pilot in-flight on Lane H #658); M per service family, contingent on transport capability. -- **Character-level under-consumption in tokenize + syntax authorities (consumption gap, not substrate gap)**: `src/v3/compiler/tokenize.dag` and `dsl/extdeps/languages/dag/syntax.dag` both slice the ASCII/Unicode codepoint space in two parallel non-canonical forms. **Reserved individual codepoints as opaque strings**: `StringEscapeSpec.suffix`, `output_codepoint: Int`, `LocalPunctSpec.pattern`, `string_literal_delimiter`, `line_comment_prefix`, `OperatorSpec.symbol`, `dag_keyword_set` keys — all encode specific codepoints as byte strings. **Reserved codepoint classes as hidden Rust predicates**: `is_ascii_whitespace` / `is_ascii_digit` / `is_ascii_alphabetic` / `is_ascii_alphanumeric` plus a bare `byte == b'_'` `push_str`'d into `regen_tokenize.rs:700,727,750,752`. Not mentioned in `.dag` at all. **The character-level concepts already exist in `dsl/std/`** and are imported cross-tree today (e.g., `src/v3/compiler/regen.dag:3` imports `std.types`): `std.types::Char = Int` (Unicode scalar, U+0000–U+10FFFF), `std.string_type::String = FreeMonoid`, `std.unicode` (`DisplayWidth`, `UnicodeBlock`, block/width classification), `std.encoding` (`ASCII | UTF8 | Latin1 | Text | Binary | Unknown` lattice with `ASCII <: UTF8 <: Text` — literally the ASCII→Unicode causal chain), `std.bit::Byte`. **Framing**: this is a consumption gap — the modeling is done, the tokenizer and syntax authorities just aren't using it. Only one substrate delta is needed. **Dissolution (follow-up lane)**: (1) add `CharClass = Whitespace | Digit | IdentStart | IdentContinue` (or superset) to `std.unicode` as a sibling to `DisplayWidth`, plus classification predicates as data/functions; (2) retype the opaque-string fields in `tokenize.dag` (`suffix: Char`, `output_codepoint: Char`, `pattern: List`, `string_literal_delimiter: Char`, `line_comment_prefix: List`) and the parallel fields in `syntax.dag` (`OperatorSpec.symbol: List`, keyword-set keys as `List`); (3) rewire `regen_tokenize` to read the class-predicate list structurally rather than hardcoding host-stdlib method names. Scaffold note lives in the `tokenize.dag` header. **Status (2026-04-24, post-PR #693):** phase-1 landed — step (1) done (`CharClass` + `char_in_class` in `dsl/std/unicode.dag`, ASCII-aligned); step (3) partially done via a `tokenize_char_class.rs` Rust mirror (gate-locked 0..=127 against Rust ASCII helpers per `sub_charclass_in_std_unicode_gate`), so generated tokenizer carries no `is_ascii_*` calls. Phase-2 (step 2 — the `.dag`-native retype to `Char` / `List` / `CharClass` variants inside `data` bodies) is **blocked on Class 5 Gap 3** (port-carried field values in `data` bodies per `src/v3/DOWNSTREAM_REQUIREMENTS.md:239`); see that row above for the substrate-capability dissolution. **The 2026-04-23 authoring of this row claimed "no substrate capability gap"; retracted — PR #693's execution found the gap.** See the `char_in_class` interpreter-parity follow-up row below for the bridge-finish step (retiring the host-stdlib-only ratchet on `tokenize_char_class.rs`). Owner: phase-1 landed (PR #693); phase-2 unassigned, blocked on Class 5 Gap 3. If the `tokenize.dag → std/tokenize.dag` consolidation migration (from the compiler–std consolidation program above) is dispatched before Class 5 Gap 3 closes, the phase-1 Rust mirror piggybacks on it; the full structural `.dag`-native path lands only when Class 5 Gap 3 closes. +- **Character-level under-consumption in tokenize + syntax authorities (mixed: consumption gap for steps 1+3, substrate gap for step 2 — see Status block below)**: `src/v3/compiler/tokenize.dag` and `dsl/extdeps/languages/dag/syntax.dag` both slice the ASCII/Unicode codepoint space in two parallel non-canonical forms. **Reserved individual codepoints as opaque strings**: `StringEscapeSpec.suffix`, `output_codepoint: Int`, `LocalPunctSpec.pattern`, `string_literal_delimiter`, `line_comment_prefix`, `OperatorSpec.symbol`, `dag_keyword_set` keys — all encode specific codepoints as byte strings. **Reserved codepoint classes as hidden Rust predicates**: `is_ascii_whitespace` / `is_ascii_digit` / `is_ascii_alphabetic` / `is_ascii_alphanumeric` plus a bare `byte == b'_'` `push_str`'d into `regen_tokenize.rs:700,727,750,752`. Not mentioned in `.dag` at all. **The character-level concepts already exist in `dsl/std/`** and are imported cross-tree today (e.g., `src/v3/compiler/regen.dag:3` imports `std.types`): `std.types::Char = Int` (Unicode scalar, U+0000–U+10FFFF), `std.string_type::String = FreeMonoid`, `std.unicode` (`DisplayWidth`, `UnicodeBlock`, block/width classification), `std.encoding` (`ASCII | UTF8 | Latin1 | Text | Binary | Unknown` lattice with `ASCII <: UTF8 <: Text` — literally the ASCII→Unicode causal chain), `std.bit::Byte`. **Framing**: this is a consumption gap — the modeling is done, the tokenizer and syntax authorities just aren't using it. Only one substrate delta is needed. **Dissolution (follow-up lane)**: (1) add `CharClass = Whitespace | Digit | IdentStart | IdentContinue` (or superset) to `std.unicode` as a sibling to `DisplayWidth`, plus classification predicates as data/functions; (2) retype the opaque-string fields in `tokenize.dag` (`suffix: Char`, `output_codepoint: Char`, `pattern: List`, `string_literal_delimiter: Char`, `line_comment_prefix: List`) and the parallel fields in `syntax.dag` (`OperatorSpec.symbol: List`, keyword-set keys as `List`); (3) rewire `regen_tokenize` to read the class-predicate list structurally rather than hardcoding host-stdlib method names. Scaffold note lives in the `tokenize.dag` header. **Status (2026-04-24, post-PR #693):** phase-1 landed — step (1) done (`CharClass` + `char_in_class` in `dsl/std/unicode.dag`, ASCII-aligned); step (3) partially done via a `tokenize_char_class.rs` Rust mirror (gate-locked 0..=127 against Rust ASCII helpers per `sub_charclass_in_std_unicode_gate`), so generated tokenizer carries no `is_ascii_*` calls. Phase-2 (step 2 — the `.dag`-native retype to `Char` / `List` / `CharClass` variants inside `data` bodies) is **blocked on Class 5 Gap 3** (port-carried field values in `data` bodies per `src/v3/DOWNSTREAM_REQUIREMENTS.md:239`); see that row above for the substrate-capability dissolution. **The 2026-04-23 authoring of this row claimed "no substrate capability gap"; retracted — PR #693's execution found the gap.** See the `char_in_class` interpreter-parity follow-up row below for the bridge-finish step (retiring the host-stdlib-only ratchet on `tokenize_char_class.rs`). Owner: phase-1 landed (PR #693); phase-2 unassigned, blocked on Class 5 Gap 3. If the `tokenize.dag → std/tokenize.dag` consolidation migration (from the compiler–std consolidation program above) is dispatched before Class 5 Gap 3 closes, the phase-1 Rust mirror piggybacks on it; the full structural `.dag`-native path lands only when Class 5 Gap 3 closes. - **`char_in_class` interpreter parity (tokenizer bridge finish, PR #693):** `dsl/std/unicode.dag::char_in_class` is canonical; `src/v3/compiler/src/tokenize_char_class.rs` stays hand-synced until M1(2.8) class-5 gap #3 allows structural scanner rows. Today unit tests ratchet against `u8::is_ascii_*` only. **Next step:** once `char_in_class` is evaluable from the v3 compiler test harness, assert code-point parity on `0..=127` against `byte_matches` and retire the host-stdlib-only ratchet / duplicate sync prose. Same migration gate as deleting `tokenize_char_class.rs` when `regen_tokenize` reads classes from lowered `tokenize.dag`. ### Post-merge debt (2026-04-23 thesis-doc surface — PR #672) From b7bb38e56fb8a13876781f9d6b7dcf9b365d8425 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 01:42:45 -0400 Subject: [PATCH 05/52] docs(roadmap): correct Class 5 Gap 3 shape description + soften CharClass phase-2 blocker classification (per gpt-5.4 audit) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gpt-5.4's review on 706 @ 71f46afe caught that the row's "remaining gap" description was wrong: field-level shapes (nested records, list literals, declaration refs, Var refs, sum-variant literals) are supported today via FieldValue variants + lower_structural_field_value (dag.rs:328-353, lower.rs:2616+). The actual remaining gap is the top-level ValueBody boundary (non-scalar, non-record top-level bodies). The authority I cited — DOWNSTREAM_REQUIREMENTS.md:239 — is itself stale: it describes the pre-PR-B-unwind shape where FieldValue was LiteralBits-only. PR-B's unwind extended FieldValue to carry Reference / Record / List / Variant, moving the gap to ValueBody. Two fixes: 1. Rewrite the Class 5 Gap 3 row to describe the actual ValueBody boundary, point at code paths (dag.rs, lower.rs) as live authority, flag DOWNSTREAM entry as itself stale, and soften phase-2 CharClass blocker classification to "provisional pending reproduction." 2. Update the Character-level row's phase-2 block to name that the specific shape of the CharClass failure needs concrete reproduction from the escalating sub-child before the blocker is finalized. Recursive audit-pattern instance: the row I wrote to codify "verify live state before claiming substrate gap" itself failed to verify live state. Both incidents (2026-04-23 original row + 2026-04-24 my retraction row) are now cited in the audit-pattern sub-note as examples of the same discipline. Co-Authored-By: Claude Opus 4.7 (1M context) --- ROADMAP.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 2fe5ea36213..89acf40cf6e 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -311,7 +311,7 @@ Per-row tagging is a scheduled follow-up sweep — **trigger:** post-merge of th ### Post-merge debt (2026-04-21 receipt-closure wave) - **Class 5 Gap 1 — `Bool` inhabits `BooleanAlgebra` grounding not wired**: surfaced during #610's closing. Current `OperatorKind::Logical(_)` dispatch in the three emitters is hardcoded (`if let OperatorKind::Logical(_)` branches bypass the algebra-field resolution that arithmetic operators use). The substrate already models `BooleanAlgebra` with `meet/join/complement` per `dsl/std/algebra.dag:230-236`, and comments there state *"Bool inhabits BooleanAlgebra"* — but the `inhabits` edge isn't structurally landed. Dissolution: wire `Bool inhabits BooleanAlgebra` + extend `resolve_operator_arrow` for `OperatorKind::Logical(_)` + delete the hardcoded emitter branches. Owner: 1e-2b lane (Path A). -- **Class 5 Gap 3 — port-carried field values in `data` bodies (substrate capability gap)**: authoritative enumeration at `src/v3/DOWNSTREAM_REQUIREMENTS.md:239` (gap partially closed at M1(2.8) for literal-only fields via `ValueBody::Structural` / `SurfaceExpr::Record` / `lower_record_to_structural`; remaining open half is port-carried field values — nested records, list literals, declaration references, `Var` references, sum-variant literals). `compile_to_dag` rejects these shapes inside `data` bodies today. **Consumer impact surfaced 2026-04-24** by PR #693 escalation (sub-child `sharp-bear-829` under Surface Manager): blocks `sub_charclass_in_std_unicode` phase-2 — specifically the `tokenize.dag` retype of `StringEscapeSpec.suffix`, `LocalPunctSpec.pattern`, `OperatorSpec.symbol`, `dag_keyword_set` keys, etc. to `Char` / `List` + `CharClass` sum-variant literals. Adjacent future retype-to-structured-carrier lanes (syntax.dag keyword sets, other opaque-string fields) will hit the same wall. Dissolution: extend `compile_to_dag` to parse port-carried field values in data bodies. Alternative design call (out of scope here): shift the authority shape for these configs from `data` bodies to extractor-over-unparsed-source. Owner: unassigned; substrate-capability scope — routes through a self-hosting / substrate-capability lane, not through the consuming lanes. **Audit pattern:** future "this consumption gap has no substrate capability gap" claims should be verified by attempting the retype before the claim lands — the 2026-04-23 authoring of the Character-level row (this file, `:354`) made this claim and was factually wrong; retracted 2026-04-24 by the update to that row in this PR (see the `:354` Status block). +- **Class 5 Gap 3 — `data` body shape boundary (substrate capability gap; precise shape requires live-state audit)**: `ValueBody` in `src/v3/compiler/src/dag.rs:259-287` carries three variants — `Unparsed(SourceSpan)`, `Structural { fields: Vec<(String, FieldValue)> }`, `Scalar(LiteralBits)`. **Field-level** shapes inside `Structural` are FULL per `FieldValue` at `src/v3/compiler/src/dag.rs:328-353` (`Literal`, `Reference`, `Record`, `List`, `Variant { constructor, payload }`) — nested records, list literals, declaration references, `Var` references, sum-variant literals all lower today via `lower_structural_field_value` at `src/v3/compiler/src/lower.rs:2616+`. **Remaining gap is at the top-level `ValueBody` boundary**: `data foo: List = [...]`, `data foo: SumType = SomeVariant`, and `data foo: T = other_decl_ref` cannot parse as top-level bodies today — only scalar literals (→ `ValueBody::Scalar`) and record-structural bodies (→ `ValueBody::Structural`) are accepted; anything else falls to `ValueBody::Unparsed`. The comment at `dag.rs:269-287` is explicit: growing `Scalar` to swallow `Reference` / `List` / `Variant` is rejected; extension is via new `ValueBody` variants. **Authority caveat:** `src/v3/DOWNSTREAM_REQUIREMENTS.md:239` describes the *pre-PR-B-unwind* shape (where `FieldValue` was `LiteralBits`-only and "port-carried field values" were the gap); the code has since extended `FieldValue` with the four additional variants, so the DOWNSTREAM entry's "remaining gap" framing is itself stale against the live code. Read `dag.rs` / `lower.rs` for the current boundary. **Consumer impact surfaced 2026-04-24** by PR #693 escalation (sub-child `sharp-bear-829` under Surface Manager): `sub_charclass_in_std_unicode` phase-2 (`tokenize.dag` retype to `Char` / `List` / `CharClass`) failed during execution; the specific shape of the failure (top-level `ValueBody` boundary vs. something narrower) needs concrete reproduction from the escalating sub-child before the dissolution direction is finalized — phase-2 "blocked on Class 5 Gap 3" is a provisional classification pending that reproduction. Dissolution direction: extend `ValueBody` with the additional top-level variants needed by downstream consumers, informed by concrete reproduction. Alternative design call: shift authority shape for config declarations from `data` bodies to extractor-over-unparsed-source. Owner: unassigned; substrate-capability scope — routes through a self-hosting / substrate-capability lane, not through the consuming lanes. **Audit pattern — recursive application.** The 2026-04-23 Character-level row (this file, `:354`) claimed "no substrate capability gap" and was factually wrong; retracted 2026-04-24 by the update to that row in this PR (see the `:354` Status block). The 2026-04-24 initial authoring of *this* row then described the remaining gap incorrectly (claimed field-level shapes were blocked when they were actually supported, citing the stale DOWNSTREAM entry as authority); corrected later the same day after gpt-5.4's independent audit caught the drift. Both incidents instantiate the rule: **claims about substrate capability must be verified against live `ValueBody` / `FieldValue` / `lower_*` code paths before the claim lands — reading a summary authority (ROADMAP row, DOWNSTREAM entry) is necessary but not sufficient, because authority text itself drifts.** - **`emit_rust_module` gap: SurfaceLiteral → LiteralBits rename**: substrate declares `LitInt/LitBool/LitString` in `LiteralBits`; Rust enum is `Int/Bool/String`; no rename facility in `emit_rust_module` causes connective-producing slices (per #612's staging choice notes) to fail on this. Dissolution: add per-variant name mapping in spec or rename-facility in emit. Owner: unassigned; blocks deeper SG-3g slices. - **`emit_rust_module` gap: `render_variant_constructor` fails on external tuple variants**: `src/v3/compiler/src/emit/rust_target.rs:4296` unconditionally emits `Variant { _0: value }` which is wrong for external tuple variants. Dissolution: spec-driven variant-constructor template per source kind. Owner: unassigned; blocks deeper SG-3g slices. - **File-preference rank is a ratified-parallel-authority scaffold**: `Dag::declaration_name_preference_rank` (`src/v3/compiler/src/dag.rs:1985-2015`) and its mirror in `collect_symbols` (`src/v3/compiler/src/lower.rs:1258-1278`) resolve same-named declarations by preferring `src/v3/` over `dsl/`. This is a P2 Boundary Discipline violation — a stable lookup rule that *normalizes* duplicate authority instead of dissolving it. Held as a scaffold rather than deleted because the duplicates carry v3-only substrate content (`v3.std.substrate` imports, `ElementRef` / `PortId` references, partitioned `EffectShape`, diagnostic-assertion surface) that cannot yet live under `dsl/std/` — v2 CI recursively ingests `dsl/` and cannot parse v3 grammar. Dissolution trigger: when every module currently duplicated between `dsl/std/` and `src/v3/std/` (or `src/v3/spec/`) has converged to a single canonical home, delete the rank function + mirror policy and remove the duplicate-authority preference rule entirely. After convergence, `declaration_by_name` must resolve against the single surviving authority or fail closed on multiple matches; no rank-based bridge remains. Convergence checklist: (1) `module std.effects` — `dsl/std/effects.dag` ↔ `src/v3/std/effects.dag` (v3 copy imports `v3.std.substrate`, partitions `EffectShape`, uses `ElementRef`); (2) `module std.verification` — `dsl/std/verification.dag` ↔ `src/v3/std/verification.dag` (surfaces are disjoint today: v2 `AssertKind/TestClaim/TestCase` vs v3 `DiagnosticKind / DiagnosticReference / PortStateExpectation`; convergence requires a design call on which surface wins); (3) embedded `http_path` mirror inside `src/v3/std/effects.dag:118-260` (resolves via either staging `http_path.dag` in v3 or rewiring imports to consume `std.http_path` directly once v3-substrate staging lands). Owner: unblocked by v3.std.substrate staging lane + v3-grammar CI convergence. @@ -351,7 +351,7 @@ Tracked debt not dispatched with the 2026-04-21 lane wave (Lane 1e P3.0, SG-2c-4 - **`extdeps/browser.dag` typed-carrier service-boundary collapse**: `dsl/extdeps/browser.dag:21-32` declares typed carriers (`BrowserConfig`, opaque `BrowserContext` / `Page` / `Element` handles, imports `Url`), but service ops use raw `String`: `Launch.input.headless: String = "false"`, `output.context_id: String`; `Goto.input.url: String`, `wait_until: String`, `output.final_url: String`; selector/query/evaluate outputs all remain `String` (`:42-47,56-60,75-103`). Same class as the LLM service flattening and the GitHub auth model bypass (both tracked separately). P1 Modeling Faithfulness / M8 "dispatch structural, not string extraction". **Dissolution trigger**: when the transport layer (REST/shell/file) can consume typed carriers end-to-end rather than stringly — this requires transport-level capability support that currently forces the String fallback. The Lane H brief (PR #658) pilots the pattern on browser.dag specifically; if that lands cleanly, LLM + GitHub dissolutions can consume the same pattern. Until then, the transport-capability gap is the upstream blocker. Surfaced by 2026-04-22 exploratory analysis. Owner: unassigned (pilot in-flight on Lane H #658); M per service family, contingent on transport capability. -- **Character-level under-consumption in tokenize + syntax authorities (mixed: consumption gap for steps 1+3, substrate gap for step 2 — see Status block below)**: `src/v3/compiler/tokenize.dag` and `dsl/extdeps/languages/dag/syntax.dag` both slice the ASCII/Unicode codepoint space in two parallel non-canonical forms. **Reserved individual codepoints as opaque strings**: `StringEscapeSpec.suffix`, `output_codepoint: Int`, `LocalPunctSpec.pattern`, `string_literal_delimiter`, `line_comment_prefix`, `OperatorSpec.symbol`, `dag_keyword_set` keys — all encode specific codepoints as byte strings. **Reserved codepoint classes as hidden Rust predicates**: `is_ascii_whitespace` / `is_ascii_digit` / `is_ascii_alphabetic` / `is_ascii_alphanumeric` plus a bare `byte == b'_'` `push_str`'d into `regen_tokenize.rs:700,727,750,752`. Not mentioned in `.dag` at all. **The character-level concepts already exist in `dsl/std/`** and are imported cross-tree today (e.g., `src/v3/compiler/regen.dag:3` imports `std.types`): `std.types::Char = Int` (Unicode scalar, U+0000–U+10FFFF), `std.string_type::String = FreeMonoid`, `std.unicode` (`DisplayWidth`, `UnicodeBlock`, block/width classification), `std.encoding` (`ASCII | UTF8 | Latin1 | Text | Binary | Unknown` lattice with `ASCII <: UTF8 <: Text` — literally the ASCII→Unicode causal chain), `std.bit::Byte`. **Framing**: this is a consumption gap — the modeling is done, the tokenizer and syntax authorities just aren't using it. Only one substrate delta is needed. **Dissolution (follow-up lane)**: (1) add `CharClass = Whitespace | Digit | IdentStart | IdentContinue` (or superset) to `std.unicode` as a sibling to `DisplayWidth`, plus classification predicates as data/functions; (2) retype the opaque-string fields in `tokenize.dag` (`suffix: Char`, `output_codepoint: Char`, `pattern: List`, `string_literal_delimiter: Char`, `line_comment_prefix: List`) and the parallel fields in `syntax.dag` (`OperatorSpec.symbol: List`, keyword-set keys as `List`); (3) rewire `regen_tokenize` to read the class-predicate list structurally rather than hardcoding host-stdlib method names. Scaffold note lives in the `tokenize.dag` header. **Status (2026-04-24, post-PR #693):** phase-1 landed — step (1) done (`CharClass` + `char_in_class` in `dsl/std/unicode.dag`, ASCII-aligned); step (3) partially done via a `tokenize_char_class.rs` Rust mirror (gate-locked 0..=127 against Rust ASCII helpers per `sub_charclass_in_std_unicode_gate`), so generated tokenizer carries no `is_ascii_*` calls. Phase-2 (step 2 — the `.dag`-native retype to `Char` / `List` / `CharClass` variants inside `data` bodies) is **blocked on Class 5 Gap 3** (port-carried field values in `data` bodies per `src/v3/DOWNSTREAM_REQUIREMENTS.md:239`); see that row above for the substrate-capability dissolution. **The 2026-04-23 authoring of this row claimed "no substrate capability gap"; retracted — PR #693's execution found the gap.** See the `char_in_class` interpreter-parity follow-up row below for the bridge-finish step (retiring the host-stdlib-only ratchet on `tokenize_char_class.rs`). Owner: phase-1 landed (PR #693); phase-2 unassigned, blocked on Class 5 Gap 3. If the `tokenize.dag → std/tokenize.dag` consolidation migration (from the compiler–std consolidation program above) is dispatched before Class 5 Gap 3 closes, the phase-1 Rust mirror piggybacks on it; the full structural `.dag`-native path lands only when Class 5 Gap 3 closes. +- **Character-level under-consumption in tokenize + syntax authorities (mixed: consumption gap for steps 1+3, substrate gap for step 2 — see Status block below)**: `src/v3/compiler/tokenize.dag` and `dsl/extdeps/languages/dag/syntax.dag` both slice the ASCII/Unicode codepoint space in two parallel non-canonical forms. **Reserved individual codepoints as opaque strings**: `StringEscapeSpec.suffix`, `output_codepoint: Int`, `LocalPunctSpec.pattern`, `string_literal_delimiter`, `line_comment_prefix`, `OperatorSpec.symbol`, `dag_keyword_set` keys — all encode specific codepoints as byte strings. **Reserved codepoint classes as hidden Rust predicates**: `is_ascii_whitespace` / `is_ascii_digit` / `is_ascii_alphabetic` / `is_ascii_alphanumeric` plus a bare `byte == b'_'` `push_str`'d into `regen_tokenize.rs:700,727,750,752`. Not mentioned in `.dag` at all. **The character-level concepts already exist in `dsl/std/`** and are imported cross-tree today (e.g., `src/v3/compiler/regen.dag:3` imports `std.types`): `std.types::Char = Int` (Unicode scalar, U+0000–U+10FFFF), `std.string_type::String = FreeMonoid`, `std.unicode` (`DisplayWidth`, `UnicodeBlock`, block/width classification), `std.encoding` (`ASCII | UTF8 | Latin1 | Text | Binary | Unknown` lattice with `ASCII <: UTF8 <: Text` — literally the ASCII→Unicode causal chain), `std.bit::Byte`. **Framing**: this is a consumption gap — the modeling is done, the tokenizer and syntax authorities just aren't using it. Only one substrate delta is needed. **Dissolution (follow-up lane)**: (1) add `CharClass = Whitespace | Digit | IdentStart | IdentContinue` (or superset) to `std.unicode` as a sibling to `DisplayWidth`, plus classification predicates as data/functions; (2) retype the opaque-string fields in `tokenize.dag` (`suffix: Char`, `output_codepoint: Char`, `pattern: List`, `string_literal_delimiter: Char`, `line_comment_prefix: List`) and the parallel fields in `syntax.dag` (`OperatorSpec.symbol: List`, keyword-set keys as `List`); (3) rewire `regen_tokenize` to read the class-predicate list structurally rather than hardcoding host-stdlib method names. Scaffold note lives in the `tokenize.dag` header. **Status (2026-04-24, post-PR #693):** phase-1 landed — step (1) done (`CharClass` + `char_in_class` in `dsl/std/unicode.dag`, ASCII-aligned); step (3) partially done via a `tokenize_char_class.rs` Rust mirror (gate-locked 0..=127 against Rust ASCII helpers per `sub_charclass_in_std_unicode_gate`), so generated tokenizer carries no `is_ascii_*` calls. Phase-2 (step 2 — the `.dag`-native retype to `Char` / `List` / `CharClass` variants inside `data` bodies) failed at execution time and the sub-child classified the blocker as Class 5 Gap 3; the row above now correctly describes that gap as a top-level `ValueBody` boundary (top-level non-scalar, non-record bodies — field-level shapes inside `Structural` already work). **The specific shape of the CharClass phase-2 failure — whether it hits the top-level `ValueBody` boundary or a narrower limitation — needs concrete reproduction from PR #693's sub-child before the blocker classification is finalized.** See the Class 5 Gap 3 row above for the substrate-capability dissolution direction and authority pointers. **The 2026-04-23 authoring of this row claimed "no substrate capability gap"; retracted — PR #693's execution found the gap.** See the `char_in_class` interpreter-parity follow-up row below for the bridge-finish step (retiring the host-stdlib-only ratchet on `tokenize_char_class.rs`). Owner: phase-1 landed (PR #693); phase-2 unassigned, blocked on Class 5 Gap 3. If the `tokenize.dag → std/tokenize.dag` consolidation migration (from the compiler–std consolidation program above) is dispatched before Class 5 Gap 3 closes, the phase-1 Rust mirror piggybacks on it; the full structural `.dag`-native path lands only when Class 5 Gap 3 closes. - **`char_in_class` interpreter parity (tokenizer bridge finish, PR #693):** `dsl/std/unicode.dag::char_in_class` is canonical; `src/v3/compiler/src/tokenize_char_class.rs` stays hand-synced until M1(2.8) class-5 gap #3 allows structural scanner rows. Today unit tests ratchet against `u8::is_ascii_*` only. **Next step:** once `char_in_class` is evaluable from the v3 compiler test harness, assert code-point parity on `0..=127` against `byte_matches` and retire the host-stdlib-only ratchet / duplicate sync prose. Same migration gate as deleting `tokenize_char_class.rs` when `regen_tokenize` reads classes from lowered `tokenize.dag`. ### Post-merge debt (2026-04-23 thesis-doc surface — PR #672) From af451620ec27ada3f05d8a4a887e52eb4ef7a6e0 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 12:15:07 -0400 Subject: [PATCH 06/52] WIP: gunbc Director --- docs/briefs/r1-selfhosting-manager.md | 8 ++++++ docs/briefs/r1-surface-manager.md | 41 +++++++++++++++++++++++---- docs/briefs/r1-testgen-manager.md | 14 ++++++--- 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/docs/briefs/r1-selfhosting-manager.md b/docs/briefs/r1-selfhosting-manager.md index 83a34292016..d00b57d0253 100644 --- a/docs/briefs/r1-selfhosting-manager.md +++ b/docs/briefs/r1-selfhosting-manager.md @@ -137,6 +137,14 @@ Lane-owner dispatch status (update as sub-deliverables close): Decisions log (append as they happen): +- 2026-04-24: **T-PB-A reduction wave active.** Non-test hand-Rust shims + retired today: lens_idempotency wrapper (#699), lens_parallelism wrapper + (#715), lens_parallelism compatibility alias (#724), lower pass-through + scaffold + `regen_lower.rs` + non-authoritative `lower_generated.rs` + (#729), infer payload span shim (#730), plus T-PB-A-E (#731) and + T-PB-A-F (#732). SG-0 census + SG-6 ratchets shrunk accordingly. Live + floor read from `src/v3/compiler/tests/integration/sg0_census_test.rs`; + the ≤5 irreducible-shim target not yet reached. - 2026-04-24: **T-PB-B-1** — landed `src/v3/compiler/tests/dag/*.dag` (`data` `TestClaim` / `TestSuite` per `std.verification`) + `t_pb_b_1_tests_dag_smoke_test`; Rust tests not deleted; Testgen runner / `pb_*` coordination still open (`docs/briefs/t-pb-b-1.md`). diff --git a/docs/briefs/r1-surface-manager.md b/docs/briefs/r1-surface-manager.md index 81c9200e9fd..cff145573ad 100644 --- a/docs/briefs/r1-surface-manager.md +++ b/docs/briefs/r1-surface-manager.md @@ -134,20 +134,51 @@ Lane-owner dispatch status (update as sub-deliverables close): - [x] `no_profile_sentinel` audit completed (brief: `p0-bug-no-profile-sentinel.md`) **T-Sub:** -- [ ] `sub_match_over_user_sum` gate compiles + passes (Day-1) +- [x] `sub_match_over_user_sum` gate compiles + passes (Day-1) + (PR #702, merged 2026-04-24 — `TestClaim` + suite in + `src/v3/compiler/tests/fixtures/r1_gates.dag` run through + `TestRunner`; #690 prior receipt confirmed structural match) - [ ] `sub_type_alias_where_lowers` gate compiles + passes - (DB-11 alias-RHS path) + (DB-11 parse + lower substrate landed in PR #703, 2026-04-24 — + `SurfaceItem::TypeAlias` carries `refinement`; `.dag` gate still + to be authored once [ext] predicate path is named) - [ ] `sub_charclass_in_std_unicode` gate compiles + passes + (phase-1 tokenizer half landed in PR #693 + ROADMAP row #706, + 2026-04-24 — `CharClass` + `char_in_class` in `std.unicode`, + tokenizer calls `tokenize_char_class::byte_matches`; follow-ups + open: `syntax.dag` / `std.syntax` consumer wiring and structural + `CharClass` consumption from lowered `tokenize.dag` — blocked by + M1(2.8) class-5 gap #3) **T-Emit:** -- [ ] Rust harden — `emit_rust_fixtures_rustc_green` passes +- [x] Rust harden — `emit_rust_fixtures_rustc_green` gate test landed + (PR #694, merged 2026-04-24 — `#[ignore]`d named gate sweeps + 9 program fixtures + 5 reflected-module fixtures through the + batched rustc roundtrip; baseline `rustc_roundtrip_*` tests all + green) - [ ] PR #650 generic-bound fidelity — `emit_generic_bounds_survive` - passes + passes (PR #676 in review — session `vivid-cat-794`) - [ ] Python/Go reconcile — `emit_omni_demo_fixtures_green` passes - across all three targets + across all three targets (cross-target progress 2026-04-24: + `Behavior::Loop` emission for Python + Go in #692; Python + operator-realization parity for `*` / `!=` / int comparisons + in #691; omni gate still pending) Decisions log (append as they happen): +- `2026-04-24` — T-Sub wave landed. `sub_match_over_user_sum` Day-1 gate + closed via #702 (with #690 prior receipt). DB-11 parse+lower substrate + landed via #703 (type-alias RHS `where`); the `.dag` gate itself awaits + the [ext] predicate path. `sub_charclass_in_std_unicode` phase-1 closure + via #693 + ROADMAP row #706 — tokenizer authority + mirror; syntax + consumer wiring and structural `.dag` read remain (blocked on M1(2.8) + class-5 gap #3). +- `2026-04-24` — T-Emit partial progress. `emit_rust_fixtures_rustc_green` + named gate test landed in #694 (ignored baseline sweep; non-ignored + roundtrips green). Python/Go cross-target progress via #691 (Python + operator-realization parity) and #692 (`Behavior::Loop` emission for + Python + Go). `emit_generic_bounds_survive` (#676) still in review; + `emit_omni_demo_fixtures_green` pending. - `2026-04-23` — T-P0 reclassified from dispatchable R1 work to already-landed closure on current ancestry after direct source audit (`dsl/std/render.dag`, `src/v2/tests/src/effects.rs`, diff --git a/docs/briefs/r1-testgen-manager.md b/docs/briefs/r1-testgen-manager.md index 71fe68c5edf..81518d727a6 100644 --- a/docs/briefs/r1-testgen-manager.md +++ b/docs/briefs/r1-testgen-manager.md @@ -145,10 +145,12 @@ Lane-owner dispatch status (update as sub-deliverables close): **T-LensAPI:** - [x] `user_authored_lens_compiles` gate (Day-1) passes (PR #679, merged 2026-04-24) -- [ ] `AlgebraicLaw` predicate (schema extension, shared with - lens_composition_associative) — predicate declared in #678; - runner evaluation not yet wired -- [ ] `lens_composition_associative` gate compiles + evaluates +- [x] `AlgebraicLaw` predicate runner evaluation wired + (PR #728, merged 2026-04-24 — `Associativity` resolves `lens_ref`, + compiles the claim program, and checks the canonical structural + witness) +- [x] `lens_composition_associative` gate compiles + evaluates + (PR #728, merged 2026-04-24 — witness + `r1_gates.dag` suite) - [ ] `lens_output_is_queryable_data` gate compiles + evaluates (PR #717 in review — adds runner seam dispatch for `LensOutputEquals` → NYI(String); gate stays [ ] until runner executes lens functions) @@ -163,6 +165,10 @@ Lane-owner dispatch status (update as sub-deliverables close): Decisions log (append as they happen): +- 2026-04-24: **T-LensAPI `lens_composition_associative` closed** via + PR #728. Runner dispatch of `AlgebraicLaw { law: Associativity }`, + witness DAG, and `r1_gates.dag` suite landed together. Remaining + T-LensAPI work: `lens_output_is_queryable_data` (PR #717 in review). - 2026-04-24: T-PB-B / Testgen **pre–Rust-deletion** coordination checklist consolidated in this brief (Hand-off → Self-hosting); `docs/briefs/t-pb-b-1.md` now points here instead of duplicating From ec4d4c3e8b359b231221e978538acadde88572bc Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 12:19:37 -0400 Subject: [PATCH 07/52] WIP: gunbc Director --- docs/briefs/r1-surface-manager.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/briefs/r1-surface-manager.md b/docs/briefs/r1-surface-manager.md index cff145573ad..5691bf63a0f 100644 --- a/docs/briefs/r1-surface-manager.md +++ b/docs/briefs/r1-surface-manager.md @@ -191,6 +191,12 @@ Open questions for director: Cross-manager notifications queued: -- _(none yet — coordinate with Self-hosting when T-Sub first gate - lands; coordinate with Testgen when T-Emit `emit_omni_demo_fixtures_green` - predicate shape needs defining)_ +- **Self-hosting Manager**: first T-Sub gate landed — `sub_match_over_user_sum` + Day-1 via #702 (merged 2026-04-24). `match` lowering is live for + consumer self-hosting surfaces; T-PB-A match-emit-dependent clusters + (`regen-emits-match`, variant-constructor templates) can now plan + consumption. ⬅ **SEND** +- **Testgen Manager**: T-Emit `emit_omni_demo_fixtures_green` still + pending — predicate shape coordination not yet triggered. Cross- + target progress continues in #691 / #692 but does not change the + predicate shape ask. From 44ba264704c3e6d76b233dd33b971a2c297a7e72 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 18:59:18 -0400 Subject: [PATCH 08/52] WIP: gunbc Director --- docs/briefs/grounding-manager.md | 107 ++++++--- docs/briefs/r1-director-brief.md | 37 +++ docs/briefs/r2-structural-close-manager.md | 259 +++++++++++++++++++++ 3 files changed, 365 insertions(+), 38 deletions(-) create mode 100644 docs/briefs/r2-structural-close-manager.md diff --git a/docs/briefs/grounding-manager.md b/docs/briefs/grounding-manager.md index 288c38525e4..44714827804 100644 --- a/docs/briefs/grounding-manager.md +++ b/docs/briefs/grounding-manager.md @@ -1,27 +1,45 @@ -# Grounding Manager Brief — Post-R1 Grounding Completeness Program +# R2 Grounding Manager Brief + +**Status:** `PROPOSAL` — pending R2 proposal +([`docs/r2-structure.md`](../r2-structure.md), PR #754) merge + +R1 all-gates-green closure. Until then, this brief is the R2 +Grounding Manager's scope-in-preparation; it does not dispatch +work. On R2 promotion, the `PROPOSAL` banner lifts and this brief +becomes the live dispatch authority for the lane. ## Orient before reading +- **R2 structure authority:** [`docs/r2-structure.md`](../r2-structure.md) + (in PROPOSAL mode at PR #754). Names this manager as one of + two R2 standing managers (alongside R2 Structural Close + Manager) and locates the T-Ground lane within the R2 program. + On promotion, the authoritative section becomes + `ROADMAP.md §"Release R2 Program"`. - **Program scope authority:** [`ROADMAP.md`](../../ROADMAP.md) - §"Post-R1 Program — Grounding Completeness" — lane list, - acceptance gates, dependencies. -- **Thesis claim tracked:** `THESIS.md` §"Thesis claims — - complete list" → Tier 1 → "Grounding completeness." This - program is the ROADMAP counterpart of that thesis claim. + §"Post-R1 Program — Grounding Completeness" (`:149`+) — lane + list, acceptance gates, dependencies. Promotes into R2 lane + `T-Ground` on R2 proposal merge; the pre-promotion section + remains the scope reference until then. +- **Thesis claim tracked:** [`THESIS.md`](../../THESIS.md) + §"Thesis claims — complete list" → Tier 1 → "Grounding + completeness." This program is the ROADMAP counterpart of that + thesis claim. - **Architectural authority:** [`docs/single-emitter-design.md`](../single-emitter-design.md) (coercion = emission; algebra-homomorphism-not-lookup; - `TypeCheckpoint` / `InhabitantDecl` dissolve). This - manager operationalizes that architectural design. + `TypeCheckpoint` / `InhabitantDecl` dissolve). This manager + operationalizes that architectural design. - **Work breakdown + worked examples:** the target-grounding proposal — [PR #695](https://github.com/gunb-ai/gunbc/pull/695), landing at `docs/thesis/target-grounding-proposal.md` on merge. The proposal doc is in PROPOSAL mode; promotion to committed - happens when #695 and this amendment ([PR #721](https://github.com/gunb-ai/gunbc/pull/721)) + happens when #695 and [PR #721](https://github.com/gunb-ai/gunbc/pull/721) both merge and this program formally dispatches. -- **Coordination context:** [R1 Director Brief](r1-director-brief.md) - for the manager-escalation model. This manager operates under - the same governance — scope changes route to director; manager - owns lane-level dispatch inside scope. +- **Coordination context:** on R2 promotion, this brief's + coordination context becomes the R2 Director Brief (refactored + from [R1 Director Brief](r1-director-brief.md)'s Staffing + section). This manager operates under the same governance — + scope changes route to director; manager owns lane-level + dispatch inside scope. ## Slice @@ -150,32 +168,45 @@ table-driven scaffolding in a single Track 13 PR. ## Hand-off points -- **Sideways to Surface Manager.** Surface Manager (R1 T-Emit - lane) owns emit-pipeline template validation, operator - carrier templates, etc. Grounding's engine work touches the - same emit pipeline boundary. Coordinate on whether engine - changes require emit-pipeline changes (likely yes, since - the engine replaces the declared-carrier read path). -- **Sideways to Testgen Manager.** Testgen Manager (R1 - T-TestGen lane) owns the `TestClaim` runner. Grounding's - T-Ground-Tests lane lands new `TestClaim` variants - (routing-stability, L4 witness-based certification). These - need Testgen runner capabilities that may require further - schema extensions beyond what R1 ships. -- **Up to director.** Substrate-capability claims this - program relies on (DB-11 closure, cardinality-substrate, - optionally DB-18) — if any of those lanes shift schedule, - flag to director. Grounding's timeline is substantially - determined by theirs. +R2 manager structure is **2 standing managers + Director** per +[`docs/r2-structure.md`](../r2-structure.md). R1's Surface / +Testgen / Substrate / Self-hosting / Release managers archive on +R1 close; their emit-pipeline, testgen-runner, and substrate- +capability responsibilities fold into R2 Structural Close +Manager or Director ad-hoc dispatch. + +- **Sideways to R2 Structural Close Manager.** Owns T-EFamilyClose, + T-ShimFloor, T-Modeling, T-Substrate (substrate prereq sub-lanes), + T-LensMigration, T-ImpossibleBugs. The emit-pipeline boundary + Grounding's engine touches is Structural Close territory post-R1 + (formerly Surface Manager T-Emit). Coordinate on: + - Emit-pipeline changes that Grounding's engine requires + (replacing the declared-carrier read path). + - Substrate-capability sub-lanes Grounding blocks on — each is + scoped in R2 T-Substrate to unblock a paired T-Modeling item, + not full substrate-capability close (see R2 proposal Goal 5). + Grounding's T-Ground-Rust / -Python / -Go block similarly on + cardinality-substrate + DB-11 closure; schedule-shift flags + route through Structural Close Manager. +- **Sideways to Director.** The `TestClaim` runner Grounding's + T-Ground-Tests lane depends on is no longer a standing-manager + authority in R2 (R1 Testgen Manager archives on R1 close). New + `TestClaim` variants (routing-stability, L4 witness-based + certification) that require predicate schema extensions route + to Director for ad-hoc dispatch; Director picks worker capacity + per R2 transition mechanics. +- **Up to director.** Substrate-capability claims this program + relies on (DB-11 closure, cardinality-substrate, optionally the + parametric-algebra-attachment in R2 T-Substrate). Schedule- + shift or scope-change flags route via director. - **Up to director.** If pilot surfaces a class of problems - that suggests the proposal's architecture needs amendment - (e.g., the minimum-satisfier discipline produces ambiguous - choices faster than expected), escalate to director for - design amendment rather than patch-in-lane. -- **Up to director.** Any proposal to amend the - grounding-completeness claim in THESIS.md (e.g., scoping - fewer targets, adjusting the Track 13 dissolution trigger) - is a scope change. + suggesting the proposal's architecture needs amendment (e.g., + minimum-satisfier discipline produces ambiguous choices faster + than expected), escalate for design amendment rather than + patch-in-lane. +- **Up to director.** Any proposal to amend the grounding- + completeness claim in THESIS.md (e.g., scoping fewer targets, + adjusting the Track 13 dissolution trigger) is a scope change. ## Pilot-gate acceptance diff --git a/docs/briefs/r1-director-brief.md b/docs/briefs/r1-director-brief.md index 1d96b31a747..64237ceefd9 100644 --- a/docs/briefs/r1-director-brief.md +++ b/docs/briefs/r1-director-brief.md @@ -152,6 +152,43 @@ authoritative. Manager briefs provide the *why*, the sequencing, and the cross-manager coordination surface above what `ROADMAP.md` already names. +## Staffing set + +The minimum orientation set for a new session, by role. + +**Staffing a manager session** (Surface / Substrate / Testgen / +Self-hosting / Release): + +1. [`CLAUDE.md`](../../CLAUDE.md) — repo-root agent discipline + pointers: `INVARIANTS.md`, `ROADMAP.md`, `MODELING.md`, + `CODING.md`, `TESTING.md`, `src/v2/DESIGN.md`. +2. This brief — coordination context (manager composition, + escalation path, framing questions). +3. The manager's own brief, naming its slice of R1: + - Surface: [`r1-surface-manager.md`](r1-surface-manager.md) + - Substrate: [`r1-substrate-manager.md`](r1-substrate-manager.md) + - Testgen: [`r1-testgen-manager.md`](r1-testgen-manager.md) + - Self-hosting: [`r1-selfhosting-manager.md`](r1-selfhosting-manager.md) + - Release: [`r1-release-manager.md`](r1-release-manager.md) +4. [`ROADMAP.md`](../../ROADMAP.md) §"Release R1 Program" + (`:15-147`) for the authoritative lane / gate list. + +**Staffing a director session:** everything above, with all five +manager briefs read in parallel (not just one), plus +[`docs/r2-structure.md`](../r2-structure.md) for the forward view +after R1 closes. + +**R1 → R2 transition.** When R1 closes per all-gates-green +criterion and `docs/r2-structure.md` promotes to a `## Release R2 +Program` section in `ROADMAP.md`, this Staffing set section +refactors into an R2 Director brief. The five R1 manager briefs +archive with closure banners; their files remain in-tree as +historical references but are no longer read as staffing +authority. The R2 staffing targets become the Structural Close +Manager brief (to be authored on promotion) and the refreshed +Grounding Manager brief at +[`docs/briefs/grounding-manager.md`](grounding-manager.md). + ## Notes and open items - **Two story-surfaced gaps now have ledger rows** at diff --git a/docs/briefs/r2-structural-close-manager.md b/docs/briefs/r2-structural-close-manager.md new file mode 100644 index 00000000000..38ec1e29c08 --- /dev/null +++ b/docs/briefs/r2-structural-close-manager.md @@ -0,0 +1,259 @@ +# R2 Structural Close Manager Brief + +**Status:** `PROPOSAL` — pending R2 proposal +([`docs/r2-structure.md`](../r2-structure.md), PR #754) merge + +R1 all-gates-green closure. Until then, this brief is the R2 +Structural Close Manager's scope-in-preparation; it does not +dispatch work. On R2 promotion, the `PROPOSAL` banner lifts and +this brief becomes the live dispatch authority for the manager. + +**Naming rationale.** The scope below covers six lanes spanning +substrate carrier close, substrate prereqs, modeling-faithfulness, +shim floor, lens migration, and impossible-bug class closure. +"Self-hosting" is only accurate for two of those; "Structural +Close" names the actual thesis-level activity — closing the +remaining structural work so every Tier-1 / Tier-2 / Tier-3 claim +has named structural backing rather than convention or scaffolding. + +## Orient before reading + +- **R2 structure authority:** [`docs/r2-structure.md`](../r2-structure.md) + (in PROPOSAL mode at PR #754). Names this manager as one of two + R2 standing managers (alongside R2 Grounding Manager) and + locates the six lanes listed below within the R2 program. On + promotion, the authoritative section becomes + `ROADMAP.md §"Release R2 Program"`. +- **Thesis claims tracked:** [`THESIS.md`](../../THESIS.md) + §"Thesis claims — complete list" — multiple claims across + Tier 1 / Tier 2 / Tier 3 and the Epistemic-stacking / + Substrate-shape meta-claims. The specific claim → lane + mapping lives in the pre-promotion thesis-claim coverage + audit (R2 proposal Open Call 2); on promotion the audit + table is linked here. +- **Design authorities this manager operationalizes:** + - [`docs/design-substrate-carrier-port-program.md`](../design-substrate-carrier-port-program.md) + — E-family carrier port program; §6a per-method-metadata + call deferred from R1 decides in R2. + - [`docs/design-pure-bootstrap.md`](../design-pure-bootstrap.md) + — ≤5 irreducible-shim floor; SG-0 census partition. + - [`docs/v3-lens-capability-register.md`](../v3-lens-capability-register.md) + — per-lens capability tracking; T-LensMigration gate reads + `lens_producer_files_remaining → 0` from this register. +- **R1 precedents:** on R2 promotion, R1 Substrate / + Self-hosting / Testgen / Surface Managers archive with + closure banners. Their briefs remain in-tree as historical + references. E-family work, T-PB-A / T-PB-B work, and the + testgen predicate tail fold here. R1 Surface's emit-pipeline + boundary responsibilities fold here for the parts R2 touches. +- **Coordination context:** on R2 promotion, this brief's + coordination context becomes the R2 Director Brief + (refactored from [R1 Director Brief](r1-director-brief.md)'s + Staffing section). Scope changes route to director; manager + owns lane-level dispatch inside scope. + +## Slice + +This manager owns six R2 lanes. The seventh R2 lane (T-Ground) is +owned by the R2 Grounding Manager; the eighth (cross-lane demo +discipline) is Director ad-hoc. + +| Lane | Size | R2 Goal | Covers | +|---|---|---|---| +| **T-EFamilyClose** | M | 7 | E-I finish (if still in flight at R2 open) → E-P → E-M → §6a per-method-metadata call per `docs/design-substrate-carrier-port-program.md`. Scope reduces to §6a alone if E-I / E-P / E-M close as part of R1. | +| **T-ShimFloor** | M | 3 | T-PB-A non-lens-producer hand-Rust reduction toward ≤5 irreducible-shim floor; T-PB-B outside-residual-zero (`TESTING.md §Post-R2 shape` carve-out preserved); compiler–`std/` consolidation ratchet → 0. | +| **T-LensMigration** | L | 2 | Every lens producer `.rs` file → `.dag`-authored. Per-file parallel fill queue. Gate: `lens_producer_files_remaining → 0` (introduced via PR #752). Closes the "lens purity by construction" co-anchor claim. | +| **T-Modeling** | M | 4 | Three modeling-faithfulness dissolutions: surface int-literal magnitude at concept layer (PR #745 analysis); `Secret` nominal-opaque graduation; `Dimension` phantom-parameter unit-mismatch enforcement. Each blocks on its paired T-Substrate sub-lane. | +| **T-Substrate** | M | 5 | Three scoped-subset substrate sub-lanes, each sufficient to unblock its paired T-Modeling item (not full substrate-capability close): (a) cardinality-substrate subset for int-literal magnitude; (b) nominal-opaque substrate subset for `Secret`; (c) parametric-algebra-attachment subset for `Dimension`. Full-capability substrate work outside these subsets stays outside R2 scope unless other R2 items demand it. | +| **T-ImpossibleBugs** | S | 6 | Three remaining `[R2+]` impossible-bug classes tagged at `ROADMAP.md:72` (THESIS §"Enumerable impossible-bug classes" is the authority on scheduling tags): nested-optional flatten; unhandled diagnostic paths; unenumerated effects. Sparse lane — fills when other fill queues are saturated. | + +## Framing question this manager answers + +**Does every remaining Tier 1 / Tier 2 / Tier 3 thesis claim not +closed by R1 reach structural closure — carrier-port complete, +shim floor reached, lens producers all `.dag`-authored, modeling- +faithfulness gaps dissolved, substrate prereqs met for those +dissolutions, and the three remaining impossible-bug classes +proven impossible by construction?** + +Today (pre-R2-promotion state): +- E-family carrier port is most of the way through R1 (E-T / E-C + landed; E-I in flight; E-P / E-M work staged). Whether E-P / E-M + close in R1 or inherit as R2 work depends on R1 closure + criterion application; this brief scopes T-EFamilyClose to + cover whatever remains at R2 open. +- T-PB-A reduction wave is active in R1; SG-0 non-test census is + tracked live in `src/v3/compiler/tests/integration/sg0_census_test.rs` + with the ≤5 floor as target. +- `lens_producer_files_remaining` gate is named but pre-zero; the + set of lens producers still in `.rs` is enumerated in the R1 + self-hosting manager's T-PB-A reduction wave. +- The three modeling-faithfulness items (int-lit, `Secret`, + Dimensions) have named dissolution directions in R1 ledger rows + but no compile-time enforcement yet. +- The three `[R2+]` impossible-bug classes are tagged but not yet + dispatched; they wait on Tier 2 substrate that closes in R2. + +The ask: close all six lanes. When this manager's scope closes +alongside R2 Grounding, the thesis-claim release ledger has no +open thesis-level items; post-R2 work is external (adoption, +documentation, community). + +## Sequence + dispatch + +**Critical path** is T-EFamilyClose. The other five lanes are +fill queues operating in parallel with the critical path; any +available worker picks top-priority unblocked work. + +- **Day 1 (R2 open).** T-EFamilyClose dispatches. Whatever E-family + work is still open at R2 open lands first. §6a per-method- + metadata option pick happens here; the four options in + `docs/design-substrate-carrier-port-program.md:169-197` are + evaluated against E-I/E-P evidence gathered in R1. +- **Day 1.** T-LensMigration dispatches as per-file-parallel fill + queue. Per-file retirements land as separate PRs; SG-0 ratchet + + `lens_producer_files_remaining` gate observe progress. No + cross-lane blocker. +- **Day 1.** T-ShimFloor dispatches as per-file-parallel fill + queue for the non-lens-producer subset of T-PB-A. T-PB-B work + (outside-residual-zero) runs in the same fill queue. +- **Day 1.** T-Substrate dispatches three sub-lanes in parallel. + Each sub-lane's close criterion is its paired T-Modeling + unblock, not general substrate-capability completion. The + DB-18 ↔ ROADMAP label mismatch flagged in the R2 proposal + (cross-ref at `docs/r2-structure.md §"Cross-refs"`) is + resolved pre-dispatch: either the ROADMAP row relabels to + match db-history's DB-18 scope, or a new DB number issues for + the R2 parametric-algebra-attachment subset. +- **Gated on T-Substrate sub-lanes.** T-Modeling's three items + dispatch in parallel, each unblocked by its paired T-Substrate + sub-lane. Int-lit blocks on cardinality-substrate subset; + `Secret` blocks on nominal-opaque substrate subset; + Dimensions blocks on parametric-algebra-attachment subset. +- **Gated on Tier 2 substrate reaching usable state.** + T-ImpossibleBugs's three classes dispatch as fill. Nested- + optional flatten and unhandled-diagnostic-paths depend on Tier 2 + runtime-safety proof infrastructure (reaches usable state as + T-Modeling's int-lit + Dimensions work closes the proof + surface); unenumerated-effects depends on effect-system surface + closure (inherited from R1). + +Lane ordering is a **fill-queue model**, not strict sequential. +T-EFamilyClose is the sole critical path. Cross-lane dispatch +failures surface as blocked workers on specific sub-lanes; +manager reassigns to unblocked queues. + +## Hand-off points + +R2 manager structure is **2 standing managers + Director** per +[`docs/r2-structure.md`](../r2-structure.md). + +- **Sideways to R2 Grounding Manager.** Grounding's engine work + (T-Ground-Engine) replaces the declared-carrier read path + through the emit pipeline; Structural Close owns the emit- + pipeline boundary in R2. Coordinate on: + - Emit-pipeline changes Grounding's engine requires — + Structural Close authors or reviews. + - Substrate-capability overlap: Grounding's T-Ground-Rust / + -Python / -Go lanes block on cardinality-substrate + DB-11 + closure. Structural Close's T-Substrate sub-lanes are + scoped to R2 T-Modeling unblocks specifically; if Grounding + needs broader cardinality-substrate work, flag upward + rather than silently expanding T-Substrate scope. + - `TestClaim` variants Grounding introduces (routing- + stability, L4 witness-based): if these require new testgen + predicate extensions, route to Director for ad-hoc + dispatch (no standing Testgen manager in R2). +- **Sideways to Director.** The following route through Director + as ad-hoc dispatches rather than standing-manager authority: + - New testgen predicate schema extensions beyond what R1 + shipped (`ExecuteCommand`, `ForAllTargets`, `LensOutputEquals`, + `DifferentialEquals`, `AlgebraicLaw`, `MockBackedInvariant`). + - Release-demo artifacts per R2 proposal's Demo discipline — + each lane closure PR ships a "here it runs" artifact; + Director surfaces to user. + - Cross-manager dependency surfacing when critical paths + block. +- **Up to director.** Substrate scope-creep flags: if a + T-Substrate sub-lane surfaces work broader than its scoped + acceptance criterion, escalate rather than absorb. The R2 + proposal explicitly commits T-Substrate to "subset sufficient + to unblock T-Modeling," not full-capability close — scope + drift would re-open a design question the proposal already + resolved. +- **Up to director.** §6a per-method-metadata option pick is + a design call informed by E-I/E-P/E-M evidence. Before + committing the option, surface the evidence summary to + director for review (matches the R1 precedent for E-P + attachment-shape design call). +- **Up to director.** Any proposal to amend thesis-claim + closure criteria for a lane (e.g., T-LensMigration shipping + with `lens_producer_files_remaining = N > 0` as "close + enough") is a scope change. + +## Working state + +Lane-owner dispatch status (update as sub-deliverables close). +This section populates on R2 promotion; entries below are +scaffolding. + +**T-EFamilyClose:** +- [ ] E-I landed (may close in R1; if so, strike through) +- [ ] E-P landed (may close in R1; if so, strike through) +- [ ] E-M landed (may close in R1; if so, strike through) +- [ ] §6a per-method-metadata option picked + applied + (Option 0 lens-local / Option 1 type-decl annotations / + Option 2 per-algebra metadata carrier / Option 3 unified + `MethodContract` — per `docs/design-substrate-carrier-port-program.md:169-197`) + +**T-ShimFloor:** +- [ ] Non-lens-producer T-PB-A reductions to ≤5 irreducible-shim floor + (live baseline: `src/v3/compiler/tests/integration/sg0_census_test.rs` + `EXPECTED_HAND_AUTHORED_NON_TEST`) +- [ ] T-PB-B outside-residual-zero per `TESTING.md §Post-R2 shape` +- [ ] Compiler–`std/` consolidation ratchet → 0 +- [ ] `pb_hand_rust_at_shim_floor` predicate evaluates true +- [ ] `pb_rust_tests_outside_residual_zero` predicate evaluates true +- [ ] `pb_self_compile_fixed_point` predicate evaluates true +- [ ] `pb_compiler_std_ratchet_zero` predicate evaluates true + +**T-LensMigration:** +- [ ] Lens-producer enumeration table (snapshot at R2 open) +- [ ] Per-file `.rs` → `.dag` migrations (per-file parallel fill) +- [ ] `lens_producer_files_remaining → 0` gate evaluates true + +**T-Modeling:** +- [ ] Int-literal magnitude at concept layer — lowered + enforced + (blocks on T-Substrate cardinality-subset) +- [ ] `Secret` nominal-opaque graduation — construction- + restriction compile-time enforced + (blocks on T-Substrate nominal-opaque-subset) +- [ ] `Dimension` phantom-parameter arithmetic — + unit-mismatch compile-time enforced + (blocks on T-Substrate parametric-algebra-attachment-subset) + +**T-Substrate:** +- [ ] Cardinality-substrate subset sufficient to close int-literal + magnitude refinement +- [ ] Nominal-opaque substrate subset sufficient to graduate `Secret` +- [ ] Parametric-algebra-attachment subset sufficient to inhabit + `Dimension` in an abelian group algebra +- [ ] DB label reconciliation (ROADMAP ↔ db-history DB-18 scope + mismatch resolved pre-dispatch) + +**T-ImpossibleBugs:** +- [ ] Nested-optional flatten impossible-by-construction +- [ ] Unhandled diagnostic paths impossible-by-construction +- [ ] Unenumerated effects impossible-by-construction + +Decisions log (append as they happen): + +- _(none yet — brief is pre-dispatch)_ + +Open questions for director: + +- _(none yet — brief is pre-dispatch)_ + +Cross-manager notifications queued: + +- _(none yet — awaits R2 open + Grounding Manager dispatch + signals)_ From ddf3595d52eebc332d86dda18ee721a74822b037 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 19:03:48 -0400 Subject: [PATCH 09/52] WIP: gunbc Director --- docs/briefs/grounding-manager.md | 79 ++++--- docs/briefs/r1-director-brief.md | 12 +- docs/briefs/r2-structural-close-manager.md | 259 --------------------- 3 files changed, 53 insertions(+), 297 deletions(-) delete mode 100644 docs/briefs/r2-structural-close-manager.md diff --git a/docs/briefs/grounding-manager.md b/docs/briefs/grounding-manager.md index 44714827804..4686fe34138 100644 --- a/docs/briefs/grounding-manager.md +++ b/docs/briefs/grounding-manager.md @@ -10,11 +10,16 @@ becomes the live dispatch authority for the lane. ## Orient before reading - **R2 structure authority:** [`docs/r2-structure.md`](../r2-structure.md) - (in PROPOSAL mode at PR #754). Names this manager as one of - two R2 standing managers (alongside R2 Structural Close - Manager) and locates the T-Ground lane within the R2 program. - On promotion, the authoritative section becomes - `ROADMAP.md §"Release R2 Program"`. + (currently committed to main via PR #754 + amendments via + PR #758, still in PROPOSAL mode until R1 closes and it + promotes to ROADMAP). Names this manager as **R2's single + standing manager alongside Director**. Director dispatches + T-Modeling / T-Substrate / T-ImpossibleBugs / + T-PerMethodMetadata ad-hoc; no second standing manager. + T-LensMigration / T-ShimFloor / T-EFamilyClose are **R1 gates, + not R2 lanes** per the r2-structure.md "Lanes deliberately + absent" section. On promotion, the authoritative section + becomes `ROADMAP.md §"Release R2 Program"`. - **Program scope authority:** [`ROADMAP.md`](../../ROADMAP.md) §"Post-R1 Program — Grounding Completeness" (`:149`+) — lane list, acceptance gates, dependencies. Promotes into R2 lane @@ -168,37 +173,43 @@ table-driven scaffolding in a single Track 13 PR. ## Hand-off points -R2 manager structure is **2 standing managers + Director** per +R2 manager structure is **1 standing manager + Director** per [`docs/r2-structure.md`](../r2-structure.md). R1's Surface / Testgen / Substrate / Self-hosting / Release managers archive on -R1 close; their emit-pipeline, testgen-runner, and substrate- -capability responsibilities fold into R2 Structural Close -Manager or Director ad-hoc dispatch. - -- **Sideways to R2 Structural Close Manager.** Owns T-EFamilyClose, - T-ShimFloor, T-Modeling, T-Substrate (substrate prereq sub-lanes), - T-LensMigration, T-ImpossibleBugs. The emit-pipeline boundary - Grounding's engine touches is Structural Close territory post-R1 - (formerly Surface Manager T-Emit). Coordinate on: - - Emit-pipeline changes that Grounding's engine requires - (replacing the declared-carrier read path). - - Substrate-capability sub-lanes Grounding blocks on — each is - scoped in R2 T-Substrate to unblock a paired T-Modeling item, - not full substrate-capability close (see R2 proposal Goal 5). - Grounding's T-Ground-Rust / -Python / -Go block similarly on - cardinality-substrate + DB-11 closure; schedule-shift flags - route through Structural Close Manager. -- **Sideways to Director.** The `TestClaim` runner Grounding's - T-Ground-Tests lane depends on is no longer a standing-manager - authority in R2 (R1 Testgen Manager archives on R1 close). New - `TestClaim` variants (routing-stability, L4 witness-based - certification) that require predicate schema extensions route - to Director for ad-hoc dispatch; Director picks worker capacity - per R2 transition mechanics. -- **Up to director.** Substrate-capability claims this program - relies on (DB-11 closure, cardinality-substrate, optionally the - parametric-algebra-attachment in R2 T-Substrate). Schedule- - shift or scope-change flags route via director. +R1 close; T-LensMigration / T-ShimFloor / T-EFamilyClose carrier +work closes in R1, not R2. Director dispatches R2's remaining +work (T-Modeling, T-Substrate, T-ImpossibleBugs, §6a +per-method-metadata residual) ad-hoc rather than through a second +standing manager. Grounding's cross-manager handoffs therefore +route exclusively to Director. + +- **Sideways / up to Director — emit-pipeline boundary.** + Grounding's engine work (T-Ground-Engine) replaces the + declared-carrier read path through the emit pipeline. The + emit-pipeline surface itself is closed by R1 T-Emit; any + engine-driven change that requires emit-pipeline amendment + after R1 close routes via Director for ad-hoc dispatch. Flag + early rather than absorbing emit-pipeline work into + T-Ground-Engine. +- **Sideways / up to Director — substrate-capability overlap.** + Grounding's T-Ground-Rust / -Python / -Go lanes depend on + cardinality-substrate + DB-11 closure for full-reference + coverage. R2's T-Substrate sub-lanes (dispatched by Director + ad-hoc) are **scoped to T-Modeling unblocks only**, not full + substrate-capability completion. If Grounding needs broader + substrate work than T-Substrate's scoped acceptance covers, + surface that as a substrate scope-creep flag to Director + rather than silently expanding T-Substrate scope. +- **Sideways / up to Director — testgen predicate extensions.** + The `TestClaim` runner Grounding's T-Ground-Tests lane depends + on is no longer a standing-manager authority in R2 (R1 Testgen + Manager archives on R1 close). New `TestClaim` variants + (routing-stability, L4 witness-based certification) that + require predicate schema extensions beyond R1's shipped set + route to Director for ad-hoc dispatch. +- **Up to director.** Substrate-capability schedule-shift flags + (DB-11, cardinality-substrate, parametric-algebra-attachment + subset). Grounding's timeline is partly determined by theirs. - **Up to director.** If pilot surfaces a class of problems suggesting the proposal's architecture needs amendment (e.g., minimum-satisfier discipline produces ambiguous choices faster diff --git a/docs/briefs/r1-director-brief.md b/docs/briefs/r1-director-brief.md index 64237ceefd9..d0309ee531a 100644 --- a/docs/briefs/r1-director-brief.md +++ b/docs/briefs/r1-director-brief.md @@ -184,10 +184,14 @@ Program` section in `ROADMAP.md`, this Staffing set section refactors into an R2 Director brief. The five R1 manager briefs archive with closure banners; their files remain in-tree as historical references but are no longer read as staffing -authority. The R2 staffing targets become the Structural Close -Manager brief (to be authored on promotion) and the refreshed -Grounding Manager brief at -[`docs/briefs/grounding-manager.md`](grounding-manager.md). +authority. Per `docs/r2-structure.md`, R2 has **one** standing +manager (Grounding) plus Director; no Structural Close Manager +is authored. The R2 staffing target is the refreshed Grounding +Manager brief at +[`docs/briefs/grounding-manager.md`](grounding-manager.md); +T-Modeling / T-Substrate / T-ImpossibleBugs / +T-PerMethodMetadata dispatch directly from Director per +r2-structure.md transition mechanics. ## Notes and open items diff --git a/docs/briefs/r2-structural-close-manager.md b/docs/briefs/r2-structural-close-manager.md deleted file mode 100644 index 38ec1e29c08..00000000000 --- a/docs/briefs/r2-structural-close-manager.md +++ /dev/null @@ -1,259 +0,0 @@ -# R2 Structural Close Manager Brief - -**Status:** `PROPOSAL` — pending R2 proposal -([`docs/r2-structure.md`](../r2-structure.md), PR #754) merge + -R1 all-gates-green closure. Until then, this brief is the R2 -Structural Close Manager's scope-in-preparation; it does not -dispatch work. On R2 promotion, the `PROPOSAL` banner lifts and -this brief becomes the live dispatch authority for the manager. - -**Naming rationale.** The scope below covers six lanes spanning -substrate carrier close, substrate prereqs, modeling-faithfulness, -shim floor, lens migration, and impossible-bug class closure. -"Self-hosting" is only accurate for two of those; "Structural -Close" names the actual thesis-level activity — closing the -remaining structural work so every Tier-1 / Tier-2 / Tier-3 claim -has named structural backing rather than convention or scaffolding. - -## Orient before reading - -- **R2 structure authority:** [`docs/r2-structure.md`](../r2-structure.md) - (in PROPOSAL mode at PR #754). Names this manager as one of two - R2 standing managers (alongside R2 Grounding Manager) and - locates the six lanes listed below within the R2 program. On - promotion, the authoritative section becomes - `ROADMAP.md §"Release R2 Program"`. -- **Thesis claims tracked:** [`THESIS.md`](../../THESIS.md) - §"Thesis claims — complete list" — multiple claims across - Tier 1 / Tier 2 / Tier 3 and the Epistemic-stacking / - Substrate-shape meta-claims. The specific claim → lane - mapping lives in the pre-promotion thesis-claim coverage - audit (R2 proposal Open Call 2); on promotion the audit - table is linked here. -- **Design authorities this manager operationalizes:** - - [`docs/design-substrate-carrier-port-program.md`](../design-substrate-carrier-port-program.md) - — E-family carrier port program; §6a per-method-metadata - call deferred from R1 decides in R2. - - [`docs/design-pure-bootstrap.md`](../design-pure-bootstrap.md) - — ≤5 irreducible-shim floor; SG-0 census partition. - - [`docs/v3-lens-capability-register.md`](../v3-lens-capability-register.md) - — per-lens capability tracking; T-LensMigration gate reads - `lens_producer_files_remaining → 0` from this register. -- **R1 precedents:** on R2 promotion, R1 Substrate / - Self-hosting / Testgen / Surface Managers archive with - closure banners. Their briefs remain in-tree as historical - references. E-family work, T-PB-A / T-PB-B work, and the - testgen predicate tail fold here. R1 Surface's emit-pipeline - boundary responsibilities fold here for the parts R2 touches. -- **Coordination context:** on R2 promotion, this brief's - coordination context becomes the R2 Director Brief - (refactored from [R1 Director Brief](r1-director-brief.md)'s - Staffing section). Scope changes route to director; manager - owns lane-level dispatch inside scope. - -## Slice - -This manager owns six R2 lanes. The seventh R2 lane (T-Ground) is -owned by the R2 Grounding Manager; the eighth (cross-lane demo -discipline) is Director ad-hoc. - -| Lane | Size | R2 Goal | Covers | -|---|---|---|---| -| **T-EFamilyClose** | M | 7 | E-I finish (if still in flight at R2 open) → E-P → E-M → §6a per-method-metadata call per `docs/design-substrate-carrier-port-program.md`. Scope reduces to §6a alone if E-I / E-P / E-M close as part of R1. | -| **T-ShimFloor** | M | 3 | T-PB-A non-lens-producer hand-Rust reduction toward ≤5 irreducible-shim floor; T-PB-B outside-residual-zero (`TESTING.md §Post-R2 shape` carve-out preserved); compiler–`std/` consolidation ratchet → 0. | -| **T-LensMigration** | L | 2 | Every lens producer `.rs` file → `.dag`-authored. Per-file parallel fill queue. Gate: `lens_producer_files_remaining → 0` (introduced via PR #752). Closes the "lens purity by construction" co-anchor claim. | -| **T-Modeling** | M | 4 | Three modeling-faithfulness dissolutions: surface int-literal magnitude at concept layer (PR #745 analysis); `Secret` nominal-opaque graduation; `Dimension` phantom-parameter unit-mismatch enforcement. Each blocks on its paired T-Substrate sub-lane. | -| **T-Substrate** | M | 5 | Three scoped-subset substrate sub-lanes, each sufficient to unblock its paired T-Modeling item (not full substrate-capability close): (a) cardinality-substrate subset for int-literal magnitude; (b) nominal-opaque substrate subset for `Secret`; (c) parametric-algebra-attachment subset for `Dimension`. Full-capability substrate work outside these subsets stays outside R2 scope unless other R2 items demand it. | -| **T-ImpossibleBugs** | S | 6 | Three remaining `[R2+]` impossible-bug classes tagged at `ROADMAP.md:72` (THESIS §"Enumerable impossible-bug classes" is the authority on scheduling tags): nested-optional flatten; unhandled diagnostic paths; unenumerated effects. Sparse lane — fills when other fill queues are saturated. | - -## Framing question this manager answers - -**Does every remaining Tier 1 / Tier 2 / Tier 3 thesis claim not -closed by R1 reach structural closure — carrier-port complete, -shim floor reached, lens producers all `.dag`-authored, modeling- -faithfulness gaps dissolved, substrate prereqs met for those -dissolutions, and the three remaining impossible-bug classes -proven impossible by construction?** - -Today (pre-R2-promotion state): -- E-family carrier port is most of the way through R1 (E-T / E-C - landed; E-I in flight; E-P / E-M work staged). Whether E-P / E-M - close in R1 or inherit as R2 work depends on R1 closure - criterion application; this brief scopes T-EFamilyClose to - cover whatever remains at R2 open. -- T-PB-A reduction wave is active in R1; SG-0 non-test census is - tracked live in `src/v3/compiler/tests/integration/sg0_census_test.rs` - with the ≤5 floor as target. -- `lens_producer_files_remaining` gate is named but pre-zero; the - set of lens producers still in `.rs` is enumerated in the R1 - self-hosting manager's T-PB-A reduction wave. -- The three modeling-faithfulness items (int-lit, `Secret`, - Dimensions) have named dissolution directions in R1 ledger rows - but no compile-time enforcement yet. -- The three `[R2+]` impossible-bug classes are tagged but not yet - dispatched; they wait on Tier 2 substrate that closes in R2. - -The ask: close all six lanes. When this manager's scope closes -alongside R2 Grounding, the thesis-claim release ledger has no -open thesis-level items; post-R2 work is external (adoption, -documentation, community). - -## Sequence + dispatch - -**Critical path** is T-EFamilyClose. The other five lanes are -fill queues operating in parallel with the critical path; any -available worker picks top-priority unblocked work. - -- **Day 1 (R2 open).** T-EFamilyClose dispatches. Whatever E-family - work is still open at R2 open lands first. §6a per-method- - metadata option pick happens here; the four options in - `docs/design-substrate-carrier-port-program.md:169-197` are - evaluated against E-I/E-P evidence gathered in R1. -- **Day 1.** T-LensMigration dispatches as per-file-parallel fill - queue. Per-file retirements land as separate PRs; SG-0 ratchet - + `lens_producer_files_remaining` gate observe progress. No - cross-lane blocker. -- **Day 1.** T-ShimFloor dispatches as per-file-parallel fill - queue for the non-lens-producer subset of T-PB-A. T-PB-B work - (outside-residual-zero) runs in the same fill queue. -- **Day 1.** T-Substrate dispatches three sub-lanes in parallel. - Each sub-lane's close criterion is its paired T-Modeling - unblock, not general substrate-capability completion. The - DB-18 ↔ ROADMAP label mismatch flagged in the R2 proposal - (cross-ref at `docs/r2-structure.md §"Cross-refs"`) is - resolved pre-dispatch: either the ROADMAP row relabels to - match db-history's DB-18 scope, or a new DB number issues for - the R2 parametric-algebra-attachment subset. -- **Gated on T-Substrate sub-lanes.** T-Modeling's three items - dispatch in parallel, each unblocked by its paired T-Substrate - sub-lane. Int-lit blocks on cardinality-substrate subset; - `Secret` blocks on nominal-opaque substrate subset; - Dimensions blocks on parametric-algebra-attachment subset. -- **Gated on Tier 2 substrate reaching usable state.** - T-ImpossibleBugs's three classes dispatch as fill. Nested- - optional flatten and unhandled-diagnostic-paths depend on Tier 2 - runtime-safety proof infrastructure (reaches usable state as - T-Modeling's int-lit + Dimensions work closes the proof - surface); unenumerated-effects depends on effect-system surface - closure (inherited from R1). - -Lane ordering is a **fill-queue model**, not strict sequential. -T-EFamilyClose is the sole critical path. Cross-lane dispatch -failures surface as blocked workers on specific sub-lanes; -manager reassigns to unblocked queues. - -## Hand-off points - -R2 manager structure is **2 standing managers + Director** per -[`docs/r2-structure.md`](../r2-structure.md). - -- **Sideways to R2 Grounding Manager.** Grounding's engine work - (T-Ground-Engine) replaces the declared-carrier read path - through the emit pipeline; Structural Close owns the emit- - pipeline boundary in R2. Coordinate on: - - Emit-pipeline changes Grounding's engine requires — - Structural Close authors or reviews. - - Substrate-capability overlap: Grounding's T-Ground-Rust / - -Python / -Go lanes block on cardinality-substrate + DB-11 - closure. Structural Close's T-Substrate sub-lanes are - scoped to R2 T-Modeling unblocks specifically; if Grounding - needs broader cardinality-substrate work, flag upward - rather than silently expanding T-Substrate scope. - - `TestClaim` variants Grounding introduces (routing- - stability, L4 witness-based): if these require new testgen - predicate extensions, route to Director for ad-hoc - dispatch (no standing Testgen manager in R2). -- **Sideways to Director.** The following route through Director - as ad-hoc dispatches rather than standing-manager authority: - - New testgen predicate schema extensions beyond what R1 - shipped (`ExecuteCommand`, `ForAllTargets`, `LensOutputEquals`, - `DifferentialEquals`, `AlgebraicLaw`, `MockBackedInvariant`). - - Release-demo artifacts per R2 proposal's Demo discipline — - each lane closure PR ships a "here it runs" artifact; - Director surfaces to user. - - Cross-manager dependency surfacing when critical paths - block. -- **Up to director.** Substrate scope-creep flags: if a - T-Substrate sub-lane surfaces work broader than its scoped - acceptance criterion, escalate rather than absorb. The R2 - proposal explicitly commits T-Substrate to "subset sufficient - to unblock T-Modeling," not full-capability close — scope - drift would re-open a design question the proposal already - resolved. -- **Up to director.** §6a per-method-metadata option pick is - a design call informed by E-I/E-P/E-M evidence. Before - committing the option, surface the evidence summary to - director for review (matches the R1 precedent for E-P - attachment-shape design call). -- **Up to director.** Any proposal to amend thesis-claim - closure criteria for a lane (e.g., T-LensMigration shipping - with `lens_producer_files_remaining = N > 0` as "close - enough") is a scope change. - -## Working state - -Lane-owner dispatch status (update as sub-deliverables close). -This section populates on R2 promotion; entries below are -scaffolding. - -**T-EFamilyClose:** -- [ ] E-I landed (may close in R1; if so, strike through) -- [ ] E-P landed (may close in R1; if so, strike through) -- [ ] E-M landed (may close in R1; if so, strike through) -- [ ] §6a per-method-metadata option picked + applied - (Option 0 lens-local / Option 1 type-decl annotations / - Option 2 per-algebra metadata carrier / Option 3 unified - `MethodContract` — per `docs/design-substrate-carrier-port-program.md:169-197`) - -**T-ShimFloor:** -- [ ] Non-lens-producer T-PB-A reductions to ≤5 irreducible-shim floor - (live baseline: `src/v3/compiler/tests/integration/sg0_census_test.rs` - `EXPECTED_HAND_AUTHORED_NON_TEST`) -- [ ] T-PB-B outside-residual-zero per `TESTING.md §Post-R2 shape` -- [ ] Compiler–`std/` consolidation ratchet → 0 -- [ ] `pb_hand_rust_at_shim_floor` predicate evaluates true -- [ ] `pb_rust_tests_outside_residual_zero` predicate evaluates true -- [ ] `pb_self_compile_fixed_point` predicate evaluates true -- [ ] `pb_compiler_std_ratchet_zero` predicate evaluates true - -**T-LensMigration:** -- [ ] Lens-producer enumeration table (snapshot at R2 open) -- [ ] Per-file `.rs` → `.dag` migrations (per-file parallel fill) -- [ ] `lens_producer_files_remaining → 0` gate evaluates true - -**T-Modeling:** -- [ ] Int-literal magnitude at concept layer — lowered + enforced - (blocks on T-Substrate cardinality-subset) -- [ ] `Secret` nominal-opaque graduation — construction- - restriction compile-time enforced - (blocks on T-Substrate nominal-opaque-subset) -- [ ] `Dimension` phantom-parameter arithmetic — - unit-mismatch compile-time enforced - (blocks on T-Substrate parametric-algebra-attachment-subset) - -**T-Substrate:** -- [ ] Cardinality-substrate subset sufficient to close int-literal - magnitude refinement -- [ ] Nominal-opaque substrate subset sufficient to graduate `Secret` -- [ ] Parametric-algebra-attachment subset sufficient to inhabit - `Dimension` in an abelian group algebra -- [ ] DB label reconciliation (ROADMAP ↔ db-history DB-18 scope - mismatch resolved pre-dispatch) - -**T-ImpossibleBugs:** -- [ ] Nested-optional flatten impossible-by-construction -- [ ] Unhandled diagnostic paths impossible-by-construction -- [ ] Unenumerated effects impossible-by-construction - -Decisions log (append as they happen): - -- _(none yet — brief is pre-dispatch)_ - -Open questions for director: - -- _(none yet — brief is pre-dispatch)_ - -Cross-manager notifications queued: - -- _(none yet — awaits R2 open + Grounding Manager dispatch - signals)_ From 3c1e8b7a920922ee5427a6deb53727aac78ea03b Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 19:33:49 -0400 Subject: [PATCH 10/52] WIP: gunbc Director --- ROADMAP.md | 4 ++-- docs/r2-structure.md | 19 +++++++++++++------ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 87794b308f7..9745009cf05 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -45,7 +45,7 @@ Each lane owns one concrete `.dag` gate. Lane owners do the comprehensive decomp | Lane | Size | Covers | Cross-ref into debt ledger | |------|------|--------|----------------------------| | T-P0 | S | P0 sweep (repeat_string, REST_OPS, no_profile_sentinel) | §P0 — real bugs | -| T-Sub | S | `match` over user sums (landed PR #702), `CharClass` in std.unicode, type-alias `where` (landed PR #703) | §P4 (bit.dag refinements), Character-level under-consumption | +| T-Sub | S | `match` over user sums (landed PR #702), `CharClass` in std.unicode (phase-1 landed PR #693; **phase-2 reclassified to R2 substrate-capability per Class 5 Gap 3 — not an R1 T-Sub gate**), type-alias `where` (landed PR #703) | §P4 (bit.dag refinements), Character-level under-consumption | | T-Emit | M | Rust harden, #650 generic-bound fidelity, Python/Go reconcile | SurfaceLiteral→LiteralBits, variant-constructor template | | T-LaneE | XL | Complexity lens v2 parity via substrate-carrier-port | Existing Lane E-T/C/I/P/M program | | T-TestGen | L | Testgen runner, service simulation, first-class TestClaim | DB-15 follow-up | @@ -59,7 +59,7 @@ Each lane owns one concrete `.dag` gate. Lane owners do the comprehensive decomp This section lists gate names + schema-compilability tags; full `TestClaim` declarations will land as deliverables of the lane-brief drafting step (lane owners author them as `.dag` after being named). Each predicate is tagged `[Day 1]` (compiles against today's DB-15 schema — `Compiles`, `FailsWithDiagnostic`, `OutputEquals`, `CostBounded`, `PortHasState`) or `[ext]` (requires a T-TestGen schema extension before compiling). Day-1 predicates are a minority — the majority block on T-TestGen's runner + schema work, which is why T-TestGen is the gate-enabling lane. - **T-P0.** `p0_repeat_string_correct` [Day 1] · `p0_no_fabrication_sentinel` [ext] · `p0_rest_ops_aligned` [ext] -- **T-Sub.** `sub_match_over_user_sum` [Day 1, landed PR #702] · `sub_type_alias_where_lowers` [ext, landed PR #703] · `sub_charclass_in_std_unicode` [ext, open: phase-2 reproduction/triage] +- **T-Sub.** `sub_match_over_user_sum` [Day 1, landed PR #702] · `sub_type_alias_where_lowers` [ext, landed PR #703] · ~~`sub_charclass_in_std_unicode`~~ — phase-1 landed PR #693; **phase-2 reclassified to R2 substrate-capability** (top-level `ValueBody` list/sum + `std.unicode` bootstrap/load-set per Class 5 Gap 3 row below) — no longer an R1 T-Sub gate; tracked in `docs/r2-structure.md` Goal 3 / T-Substrate as a 4th scoped sub-lane (consumer: tokenizer) - **T-Emit.** `emit_rust_fixtures_rustc_green` [ext: `ExecuteCommand`] · `emit_generic_bounds_survive` [ext] · `emit_omni_demo_fixtures_green` [ext: `ForAllTargets` + `ExecuteCommand`] - **T-LaneE.** `complexity_merge_sort_is_nlogn` [ext: `LensOutputEquals`] · `complexity_v3_matches_v2_oracle` [ext: `DifferentialEquals`] - **T-TestGen.** `testgen_structural_coverage` [ext] · `testgen_mock_backed_integration_safe` [ext: `MockBackedInvariant` wiring] · `testgen_manual_claim_is_first_class` [ext] — T-TestGen also owns scoping the predicate shape for `[ext]` gates that other lanes consume; currently includes `lens_producer_files_remaining` for T-PB-A (enumeration declared in `sg0_census_test.rs` at scoping time). diff --git a/docs/r2-structure.md b/docs/r2-structure.md index e10a5453609..ff934bf0f04 100644 --- a/docs/r2-structure.md +++ b/docs/r2-structure.md @@ -36,11 +36,12 @@ Under that discipline, R2's goals are the Tier-1 thesis claims that are *not* ga - `Secret` nominal-opaque graduation (`ROADMAP.md` post-merge-debt section, 2026-04-23 thesis-doc surface) - `Dimension` typed value wrapper with phantom-parameter unit-mismatch enforcement (ibid.) -3. **Substrate prereqs** — named as explicit R2 sub-lanes with **scoped acceptance criteria** (sufficient-to-unblock, not full-capability). Each prereq is pinned to a specific Goal 2 item; full substrate-capability lanes retain open design calls that may predate or postdate R2, and this structure does not commit R2 to close them all: +3. **Substrate prereqs** — named as explicit R2 sub-lanes with **scoped acceptance criteria** (sufficient-to-unblock, not full-capability). Each prereq is pinned to a specific R2 consumer (Goal 2 items + the tokenizer charclass closure inherited from R1); full substrate-capability lanes retain open design calls that may predate or postdate R2, and this structure does not commit R2 to close them all: - - **Cardinality-substrate subset sufficient to close int-literal magnitude refinement** — enough cardinality modeling to let `IntLit` carry a magnitude that narrows to target int algebra at reconciliation. Does NOT commit to the full cardinality-substrate capability (fixed-width-types by-construction, container cardinality bounds in Grounding, etc. — those remain open design calls outside R2 scope unless additional R2 items demand them). - - **Nominal-opaque substrate sufficient to graduate `Secret`** — enough nominal-type modeling to carry construction-restriction (`where only X may construct`) semantics. Adjacent to DB-11 alias-RHS `where` (landed in R1 via PR #703); may or may not overlap DB-18 territory. Acceptance is `Secret` graduation, not a general nominal-type program. - - **Parametric algebra attachment subset sufficient to inhabit `Dimension` in an abelian group algebra** — enough substrate capability to let `Dimension` carry phantom-parameter arithmetic (propagate through operations, compile error on unit-mismatch). Primary authority is `ROADMAP.md §"Post-R1 Program — Grounding Completeness"` (the "Why post-R1" paragraph), which tags this dependency `DB-18 parametric algebra attachment` — but `docs/db-history/db-18.md` currently scopes DB-18 to workflow-effect carrier + Rust reflection (Part 2 shipped) + Go-accessor follow-up (Part 3), not parametric algebra attachment. That mismatch is an existing ROADMAP ↔ db-history inconsistency, not one introduced by this doc; a pre-promotion DB-lane rename or new DB number may be warranted. R2 acceptance is: `Dimension` phantom-parameter arithmetic compiles with unit-mismatch errors, independent of the DB-tag the substrate ends up carrying. + - **Cardinality-substrate subset sufficient to close int-literal magnitude refinement** — enough cardinality modeling to let `IntLit` carry a magnitude that narrows to target int algebra at reconciliation. Consumer: T-Modeling int-lit (Goal 2). Does NOT commit to the full cardinality-substrate capability (fixed-width-types by-construction, container cardinality bounds in Grounding, etc. — those remain open design calls outside R2 scope unless additional R2 items demand them). + - **Nominal-opaque substrate sufficient to graduate `Secret`** — enough nominal-type modeling to carry construction-restriction (`where only X may construct`) semantics. Consumer: T-Modeling Secret (Goal 2). Adjacent to DB-11 alias-RHS `where` (landed in R1 via PR #703); may or may not overlap DB-18 territory. Acceptance is `Secret` graduation, not a general nominal-type program. + - **Parametric algebra attachment subset sufficient to inhabit `Dimension` in an abelian group algebra** — enough substrate capability to let `Dimension` carry phantom-parameter arithmetic (propagate through operations, compile error on unit-mismatch). Consumer: T-Modeling Dimensions (Goal 2). Primary authority is `ROADMAP.md §"Post-R1 Program — Grounding Completeness"` (the "Why post-R1" paragraph), which tags this dependency `DB-18 parametric algebra attachment` — but `docs/db-history/db-18.md` currently scopes DB-18 to workflow-effect carrier + Rust reflection (Part 2 shipped) + Go-accessor follow-up (Part 3), not parametric algebra attachment. That mismatch is an existing ROADMAP ↔ db-history inconsistency, not one introduced by this doc; a pre-promotion DB-lane rename or new DB number may be warranted. R2 acceptance is: `Dimension` phantom-parameter arithmetic compiles with unit-mismatch errors, independent of the DB-tag the substrate ends up carrying. + - **Top-level `ValueBody` list/sum subset + `std.unicode` bootstrap inclusion sufficient to close `sub_charclass_in_std_unicode` phase-2** — enough Class 5 Gap 3 substrate capability for `data ascii_scan_order: List = [Whitespace, Digit, IdentStart, IdentContinue]` to lower structurally (rather than fall to `ValueBody::Unparsed` and trigger R14 hard-fail), plus the `Dag::new()` bootstrap/load-set decision that makes `std.unicode::CharClass` resolvable from `tokenize.dag`. Consumer: tokenizer (R1 T-Sub deferred this phase to substrate per Surface Manager handoff 2026-04-24; reclassified to R2 per ROADMAP amendment). Does NOT commit to the full Class 5 Gap 3 substrate-capability close (other top-level `ValueBody` consumers may need additional variants beyond list/sum); scoped to what unblocks the tokenizer charclass row only. 4. **Remaining R2+ impossible-bug classes** — three classes currently tagged `[R2+]` in `ROADMAP.md §"Lane acceptance — .dag gates"` (T-Demo row; THESIS §"Enumerable impossible-bug classes" is the authority on scheduling tags): - Nested-optional flatten @@ -77,7 +78,7 @@ Continues `docs/briefs/grounding-manager.md` (refreshed for R2 scope on promotio |---|---|---|---| | T-Ground | XL | Grounding | Full T-Ground-* sub-program (Goal 1) | | T-Modeling | M | Director (ad-hoc) | int-lit / Secret / Dimensions (Goal 2) | -| T-Substrate | M | Director (ad-hoc) | Three scoped-subset sub-lanes (Goal 3): cardinality-for-int-lit; nominal-opaque-for-Secret; parametric-algebra-attachment-for-Dimensions — each scoped to its paired T-Modeling unblock, not full substrate-capability | +| T-Substrate | M | Director (ad-hoc) | Four scoped-subset sub-lanes (Goal 3): cardinality-for-int-lit; nominal-opaque-for-Secret; parametric-algebra-attachment-for-Dimensions; top-level-ValueBody-list/sum + std.unicode-bootstrap-for-tokenizer-charclass — each scoped to its paired R2 consumer (T-Modeling × 3 + tokenizer × 1), not full substrate-capability | | T-ImpossibleBugs | S | Director (ad-hoc) | nested-optional flatten / unhandled-diagnostic-paths / unenumerated-effects (Goal 4) | | T-PerMethodMetadata | S | Director (ad-hoc) | §6a per-method-metadata carrier pick (Goal 5) — design-call close, not substrate-capability work | @@ -89,7 +90,10 @@ Continues `docs/briefs/grounding-manager.md` (refreshed for R2 scope on promotio - T-EFamilyClose — R1 T-LaneE's critical-path carrier work (E-T, E-C, E-I, E-P, E-M sub-lanes), enabling the R1 `complexity_merge_sort_is_nlogn` + `complexity_v3_matches_v2_oracle` gates. All E-family carrier-port work closes in R1; only the §6a metadata-pick residual inherits to R2 (Goal 5). - T-TestGen-tail (`testgen_mock_backed_integration_safe` / `MockBackedInvariant` wiring) — R1 T-TestGen gate per `ROADMAP.md §"Lane acceptance — .dag gates"`. Closes in R1. -R2 does not re-own any of the above; under all-R1-gates-green R1 closure, those gates ARE the close conditions and R2 inherits nothing there (except Goal 5's §6a residual, which was not an R1 gate). +R2 does not re-own any of the above; under all-R1-gates-green R1 closure, those gates ARE the close conditions and R2 inherits nothing there — with two named exceptions: + +1. **Goal 5's §6a per-method-metadata pick** — was not an R1 gate; deferred design call inherits to R2. +2. **`sub_charclass_in_std_unicode` phase-2** — was an R1 T-Sub gate, but reclassified to R2 substrate-capability per ROADMAP amendment (2026-04-24) following Surface Manager's handoff that the remaining work is Class 5 Gap 3 substrate-capability scope, not T-Sub-only surface fix. Now a 4th sub-lane under R2 T-Substrate (Goal 3); see lane row above. ## Dependency DAG @@ -99,9 +103,11 @@ T-Ground: Pilot → Rust → Engine → Tests → Dissolve (critical p T-Substrate: cardinality-for-int-lit (subset) ──→ unblocks T-Modeling int-lit nominal-opaque-for-Secret (subset) ─→ unblocks T-Modeling Secret parametric-algebra-for-Dimensions (subset) ─→ unblocks T-Modeling Dimensions + ValueBody-list/sum + std.unicode-bootstrap (subset) ─→ unblocks tokenizer charclass phase-2 T-Modeling: int-lit ← T-Substrate cardinality-for-int-lit Secret ← T-Substrate nominal-opaque-for-Secret Dimensions ← T-Substrate parametric-algebra-for-Dimensions +T-CharClassPhase2: tokenizer retype to Char/List/CharClass ← T-Substrate ValueBody-list/sum + std.unicode-bootstrap T-ImpossibleBugs: 3 independent classes (any worker) T-PerMethodMetadata: §6a pick (any worker; independent) (Goal 6 demo artifacts ship with each lane's closure PR — not a @@ -146,6 +152,7 @@ Purpose: proof-of-work visibility at director cadence. Without it, program slips - **Manager count = 1 + Director.** One standing manager (Grounding) matches R2's single critical path. T-Modeling / T-Substrate / T-ImpossibleBugs are parallel-capable with no critical-path coordination pressure; Director dispatches directly. Adjustable upward if parallel fill-queue depth becomes unmanageable in practice. - **R2 includes substrate prereqs explicitly** per user's (i)-over-(ii) preference (honest scope over tight scope), with **scoped acceptance criteria** per Director refinement (each sub-lane closes on unblock of its paired Goal 2 item; full substrate-capability lanes are not R2-committed). - **Anti-deferral principle is the frame, not velocity numbers.** Per Director observation: 16-hour R1 execution was a peak-day sample, not a baseline. The principle "if dissolution direction is clear and named, deferral is problem-finding not problem-solving" is what survives cadence shifts. +- **`sub_charclass_in_std_unicode` phase-2 reclassified R1 → R2** (2026-04-24, ROADMAP amendment paired with this revision). Surface Manager handoff (sub-child `quiet-gull-882` triage) confirmed the remaining work is Class 5 Gap 3 substrate-capability scope, not T-Sub-only surface fix; reclassifying lets R1 close on T-Sub Day-1 + DB-11 without waiting on substrate-capability work. Phase-2 lands in R2 as a 4th T-Substrate scoped sub-lane (consumer: tokenizer). Reclassification scope is bounded — full Class 5 Gap 3 substrate-capability close remains outside R2 unless additional R2 items demand it; only the tokenizer-charclass-unblock subset is R2-committed. - **Post-R2 stance = STRONG.** R2 is thesis close. Post-R2 work is external (adoption, documentation, community, ecosystem buildout). R3 is reserved as escape hatch only, not as a structural release program. User-locked 2026-04-24 after pressure-test framing: *"real programs are probably required to confirm the thesis is real, but we can keep R2 theoretical to stay fair — future work would pressure test the claims."* The R2 doc's "close-everything" claim is thus scoped to the **structural thesis** (what the compiler proves by construction); practical validation via modeling real programs (e.g., the user's `../ctrl/` follow-up) is a separate post-R2 stream that *tests whether the thesis holds in practice*, without itself being a thesis claim. ## Open calls From cdb25a5b3e16bde7fd69c6cc7cde9aca61659471 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 20:17:19 -0400 Subject: [PATCH 11/52] WIP: gunbc Director --- docs/r2-structure.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/r2-structure.md b/docs/r2-structure.md index ff934bf0f04..21d1c3f9ad7 100644 --- a/docs/r2-structure.md +++ b/docs/r2-structure.md @@ -36,7 +36,7 @@ Under that discipline, R2's goals are the Tier-1 thesis claims that are *not* ga - `Secret` nominal-opaque graduation (`ROADMAP.md` post-merge-debt section, 2026-04-23 thesis-doc surface) - `Dimension` typed value wrapper with phantom-parameter unit-mismatch enforcement (ibid.) -3. **Substrate prereqs** — named as explicit R2 sub-lanes with **scoped acceptance criteria** (sufficient-to-unblock, not full-capability). Each prereq is pinned to a specific R2 consumer (Goal 2 items + the tokenizer charclass closure inherited from R1); full substrate-capability lanes retain open design calls that may predate or postdate R2, and this structure does not commit R2 to close them all: +3. **Substrate prereqs** — named as explicit R2 sub-lanes with **scoped acceptance criteria** (sufficient-to-unblock, not full-capability). Each prereq is pinned to a specific R2 consumer (Goal 2 items + the tokenizer charclass closure inherited from R1 per the named exception in *"Lanes deliberately absent"* below); full substrate-capability lanes retain open design calls that may predate or postdate R2, and this structure does not commit R2 to close them all: - **Cardinality-substrate subset sufficient to close int-literal magnitude refinement** — enough cardinality modeling to let `IntLit` carry a magnitude that narrows to target int algebra at reconciliation. Consumer: T-Modeling int-lit (Goal 2). Does NOT commit to the full cardinality-substrate capability (fixed-width-types by-construction, container cardinality bounds in Grounding, etc. — those remain open design calls outside R2 scope unless additional R2 items demand them). - **Nominal-opaque substrate sufficient to graduate `Secret`** — enough nominal-type modeling to carry construction-restriction (`where only X may construct`) semantics. Consumer: T-Modeling Secret (Goal 2). Adjacent to DB-11 alias-RHS `where` (landed in R1 via PR #703); may or may not overlap DB-18 territory. Acceptance is `Secret` graduation, not a general nominal-type program. @@ -107,7 +107,9 @@ T-Substrate: cardinality-for-int-lit (subset) ──→ unblocks T-Modeling T-Modeling: int-lit ← T-Substrate cardinality-for-int-lit Secret ← T-Substrate nominal-opaque-for-Secret Dimensions ← T-Substrate parametric-algebra-for-Dimensions -T-CharClassPhase2: tokenizer retype to Char/List/CharClass ← T-Substrate ValueBody-list/sum + std.unicode-bootstrap +Tokenizer charclass phase-2 (consumer of T-Substrate's 4th subset; not a peer lane — + consumed inside T-Substrate scope, deliverable owned by tokenizer code): + retype to Char / List / CharClass ← T-Substrate ValueBody-list/sum + std.unicode-bootstrap T-ImpossibleBugs: 3 independent classes (any worker) T-PerMethodMetadata: §6a pick (any worker; independent) (Goal 6 demo artifacts ship with each lane's closure PR — not a From 971ac4421899ce91f3b996c201c45b87a607a900 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 20:18:49 -0400 Subject: [PATCH 12/52] WIP: gunbc Director --- docs/r2-structure.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/r2-structure.md b/docs/r2-structure.md index 21d1c3f9ad7..8dab9759dea 100644 --- a/docs/r2-structure.md +++ b/docs/r2-structure.md @@ -116,7 +116,7 @@ T-PerMethodMetadata: §6a pick (any worker; independent) separate dependency-DAG node; see Demo discipline section.) ``` -Parallel-capable work at any time: Grounding has 2 fill slots (Python, Go) alongside its critical path; Director dispatch has 3 T-Substrate sub-lanes + 3 T-Modeling items (each pair-blocked) + 3 T-ImpossibleBugs classes + 1 T-PerMethodMetadata pick, for roughly 7–10 slots depending on T-Substrate unblock timing. +Parallel-capable work at any time: Grounding has 2 fill slots (Python, Go) alongside its critical path; Director dispatch has 4 T-Substrate sub-lanes (3 T-Modeling unblocks + 1 tokenizer-charclass unblock) + 3 T-Modeling items (each pair-blocked) + 1 tokenizer-charclass deliverable (pair-blocked on the 4th T-Substrate sub-lane) + 3 T-ImpossibleBugs classes + 1 T-PerMethodMetadata pick, for roughly 8–12 slots depending on T-Substrate unblock timing. ## R1 closure criteria From 7c434cc1669617c99f434cc309edce3035ca1de4 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 21:30:50 -0400 Subject: [PATCH 13/52] WIP: gunbc Director --- docs/design-pure-bootstrap-zero.md | 192 +++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 docs/design-pure-bootstrap-zero.md diff --git a/docs/design-pure-bootstrap-zero.md b/docs/design-pure-bootstrap-zero.md new file mode 100644 index 00000000000..cfcb604e52b --- /dev/null +++ b/docs/design-pure-bootstrap-zero.md @@ -0,0 +1,192 @@ +# Pure Bootstrap to Zero — Design Proposal + +**Status:** `PROPOSAL` — supersedes the ≤5-floor framing in [`docs/design-pure-bootstrap.md`](design-pure-bootstrap.md) and the 2-3 principled-floor framing in [PR #756](https://github.com/gunb-ai/gunbc/pull/756) on promotion. Until then, this doc is the proposed direction; `design-pure-bootstrap.md` remains the live authority. + +## Frame + +**Goal: zero hand-authored files in v3's source tree.** Better than v2's 1-residual. + +The ≤5-floor target was a sizing convenience masquerading as an architectural lower bound. Auditing the 35 files currently in `EXPECTED_HAND_AUTHORED_NON_TEST` shows the "irreducible" tier (build.rs, bootstrap.rs, lib.rs, dag.rs, dag/ports.rs, dag/effects.rs) isn't structurally irreducible — it's just not-yet-migrated substrate authoring. Each of those files can be generated from a `.dag` authority, with the same pattern v3's other generated files already use. + +Zero is achievable. v2 proved the cycle (1 residual was a TESTING.md choice, not a structural limit). v3's substrate is more structural than v2's (lens-as-substrate-declaration, types-as-data, programs-as-data) — so v3 should hit a tighter floor than v2. + +## Design choice — shape (γ) + +Three escalating shapes were considered: + +- **(α)** PB-1's current scope: data-bootstrap of DAG, hand-Rust everything else. Floor ~6-8. +- **(β)** Bootstrap process modeled in `.dag` + a small hand-Rust universal evaluator. Floor ~1-2. +- **(γ)** Substrate, evaluator, and bootstrap process all data. The compiled binary is fully generated; the host runtime (or the build trampoline) is the only thing not in v3's source tree. Floor: 0. + +**This proposal commits to (γ).** Rationale: + +- (β) is a bridge that gets dissolved into (γ); writing the bridge first is wasted work unless mandatory. It's not mandatory — see "First-time bootstrap" below. +- (γ) matches the thesis claim that the substrate is its own subject ([`docs/thesis/self-inspection.md`](thesis/self-inspection.md)). Hand-authored files in v3's source tree contradict that claim at the implementation layer. +- The runtime requirements for (γ) (a small generated evaluator + Cargo trampoline) are themselves generatable. There's no architectural reason to author them by hand. + +## Bootstrap as data — the conceptual core + +The current model: bootstrap is a *process* implemented in hand-Rust (`bootstrap.rs::Dag::new()`) that loads `.dag` source, runs the compiler pipeline, populates a `Dag`. The chicken-egg is "Dag::new() needs the compiler pipeline, which needs Dag::new()." + +The (γ) model: **bootstrap is data.** A `bootstrap.dag` (or equivalent authority) declares: +- Which `.dag` files load in which order +- What state the loaded `Dag` should reach +- What invariants must hold post-load +- What the entry point evaluates to + +The "evaluator" is a small generic interpreter that: +- Reads the bootstrap data +- Constructs the `Dag` +- Hands it to the rest of the compiler (also data) +- Runs `main` (also data) + +The evaluator is itself generated from a `.dag` authority that describes its operations. Per `feedback_compiler_is_dag_processor`: the compiler knows only Node / Conj / Disj / Cardinality / Bit. The evaluator therefore needs only those primitive operations — small. + +**The chicken-egg breaks at the build step**, not at runtime: the previous-generation binary reads the new bootstrap data and emits the new evaluator binary. Same cycle v2 used, applied recursively to the evaluator itself. + +## First-time bootstrap (the genuine N=0 problem) + +Even (γ) has a first-time bootstrap problem: the very first compiled binary has to come from somewhere. + +Three resolutions, in increasing aggressiveness: + +1. **Shipped pre-built binary.** The "first" binary is a release artifact (downloaded via install script, embedded in a published crate, or shipped as a release asset on GitHub). Subsequent bootstraps regenerate from source. Hand-Rust in v3's source tree: 0. Hand-Rust elsewhere (in the install script or release tooling): negligible / not part of v3. + +2. **Universal-runtime crate.** A tiny `gunbc-runtime` crate (published separately, not in v3's source tree) provides the generic evaluator. v3's source tree is `.dag` files + a generated Cargo.toml that depends on `gunbc-runtime`. The runtime crate is hand-authored, but **outside v3's source tree** (cleanly factored as runtime support, not compiler). + +3. **Procedural macro on existing rustc.** A `#[gunbc::data]` attribute (in a tiny crate) tells rustc to interpret the `.dag` content at compile time. Same shape as 2 but different boundary — the macro is the runtime; the rest is data. + +All three give **0 hand-Rust in v3's source tree.** Resolution choice is downstream of taste + ecosystem strategy; doesn't affect the in-tree floor. + +For this proposal: the in-tree floor target is 0 regardless of which N=0 resolution lands. Pick the resolution as a separate decision; it doesn't gate the migration program. + +## Subsumed lanes + +Existing lanes that fold into this program: + +- **PB-1** ([brief](briefs/pb-1-data-driven-bootstrap.md), XXL) — data-driven bootstrap loader. **Non-goals revised:** PB-1's current non-goals (don't delete tokenize/parse/lower/infer/emit; don't go binary-blob; don't change Dag runtime format) were appropriate for the ≤5-floor framing but contradict 0-floor. Under this proposal they invert: PB-1 is the first phase of a chain that ends with all of those files generated. +- **PB-4** (lower) — generate `lower.rs` from `lower.dag`. SG-3 series + lower.dag authority required. +- **PB-5** (infer) — generate `infer.rs` from `infer.dag`. SG-4 dispatch. +- **PB-6** (emit) — generate `emit.rs` + emit targets from spec authorities (`rust.dag`, `python.dag`, `go.dag`). Lane 1e dependency. + +Existing scope from `design-pure-bootstrap.md` continues to apply for the file-by-file work, just with a tighter target. + +## New lanes + +**PB-Substrate** (new, sized M-L) — generate `dag.rs`, `dag/ports.rs`, `dag/effects.rs` from `src/v3/std/substrate.dag`. The substrate type definitions become data; the Rust types are emitted from them. Cementing test: generated Rust matches the structural facts the substrate model declares. + +**PB-Lib + PB-Build** (subsumes PB-8 aspiration, sized M) — generate `lib.rs` (module declarations + crate exports) and `build.rs` (Cargo build script content) from emit authority. Both files become trampolines that `include!()` generated content from `OUT_DIR`, or vanish entirely if Cargo can be told to look elsewhere. + +**PB-Runtime** (new, sized M-L) — generate `test_runner.rs`, `lens_apply.rs`, `lens_testgen.rs`, `post_emit_verifier.rs` from `.dag` authorities. The "test runner" and "lens evaluator" become data + a tiny generic interpreter. + +**PB-Bootstrap-Process** (new, sized M, the conceptual core) — author `bootstrap.dag` describing the bootstrap workflow as data. Replace `bootstrap.rs` with a generated trampoline. Section "Bootstrap as data" above is its design. + +**PB-Workflow** (existing scope continued) — `workflow_idempotency.rs` and `workflow_parallelism.rs` migrate as Lane 2 dissolution lands. + +**PB-Tier1-Sweep** (per-file fast-retire, sized S each) — depends on above. The 13 Tier-1 files (regen binaries + bin helpers) retire as their backing migrations land. Not blocked on PB-Substrate / PB-Lib / etc., but blocked on PB-1 + PB-4/5/6. + +## TESTING.md rewrite (sibling PR) + +Current `TESTING.md` carves out two permanent Rust-authored test categories: +- Compiler-internal unit tests for Rust-only helpers +- External-toolchain boundary tests (rustc/go/python invocations) + +Both dissolve under 0-floor: + +- **Rust-only-helper unit tests** vanish naturally — there are no Rust-only helpers; everything generates from `.dag`. +- **External-toolchain boundary tests** migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations (the predicate landed in PR #678; runner support landed in #688/#741). A `TestClaim` like *"emit Rust, invoke rustc on output, check exit code"* is structurally identical to today's hand-Rust boundary tests. + +**TESTING.md rewrite scope:** +- Replace "Post-R2 shape" residual section with "0-residual" framing +- Reference `ExecuteCommand` predicate as the migration path +- Update authority list + +This rewrite is a sibling PR to the design doc — same author (Director or PM), separate land cycle. Could bundle, but TESTING.md is a foundational doc commitment worth its own discussion. + +## Acceptance gates + +R2 / future release acceptance for this program: + +- `EXPECTED_HAND_AUTHORED_NON_TEST` count = 0 +- `EXPECTED_HAND_AUTHORED_TEST` count = 0 +- TESTING.md "Post-R2 shape" residual rewritten to 0-residual +- DB-8 `self_host_fixed_point` converges bit-identically (the no-compromise gate; same as PB-1's) +- Compile cycle still produces a working binary (regen → rustc → run → diff fixed-point) +- All `[ext]` test predicates evaluate against generated authorities +- `bootstrap.dag` declares the bootstrap workflow + first-time bootstrap resolution explicitly + +## Dependency DAG + +``` +PB-Substrate ────────────────┐ + ├──→ enables PB-Lib + PB-Build +PB-1 (data-driven loader) ───┤ (emit Rust files from .dag = generic capability) + │ +PB-4 (lower) ┐ ├──→ enables PB-Bootstrap-Process +PB-5 (infer) ├──→ generic │ (compiler in .dag → bootstrap can be in .dag too) +PB-6 (emit) ┘ .dag │ + compiler │ + │ +PB-Runtime ──────────────────┤ + (test_runner, lens_apply │ + in .dag) │ + │ +PB-Workflow (Lane 2 dissolution) + │ +PB-Tier1-Sweep (per-file ──┘ + retirement; depends on + above-listed migrations) +``` + +**Parallelization:** PB-Substrate, PB-1 (sub-lanes), PB-4, PB-5, PB-6, PB-Runtime, PB-Workflow are all parallel-capable Day-1. PB-Lib + PB-Build is parallel after PB-Substrate's pattern is proven. PB-Bootstrap-Process is parallel after PB-1 + PB-4/5/6 (needs the full compiler in .dag to bootstrap from). PB-Tier1-Sweep is per-file fast-retire after each backing migration lands. + +**Worker capacity:** 6-8 parallel workers can productively dispatch against this DAG without coordination collisions, given the substrate.dag / SG-0 census is the only shared-edit hotspot (each PR removes one entry). Higher worker count = more rebase churn on `sg0_census_test.rs`; lower count = longer wall clock. + +## STOP-AND-ESCALATE + +Inherits from `design-pure-bootstrap.md` + PB-1 brief, plus: + +- **If first-time bootstrap (N=0) resolution requires hand-Rust in v3's source tree** — STOP. The resolution is supposed to live outside v3's source tree (install script, gunbc-runtime crate, or rustc macro). If it can't, the 0-floor target is unreachable and the framing needs revision back toward (β). +- **If the universal evaluator turns out to need substrate operations beyond Node / Conj / Disj / Cardinality / Bit** — STOP. The bounded-kernel invariant is load-bearing; expanding it to make (γ) work is wrong. +- **If TESTING.md rewrite reveals test categories that genuinely cannot express in `ExecuteCommand`-based `.dag`** — STOP. May indicate a `TestClaim` predicate gap that's its own substrate work. Surface before forcing the migration. + +## Non-goals + +- **Not picking the N=0 resolution shape in this doc** — three options (shipped binary / runtime crate / rustc macro) are scoped above; pick separately. Doesn't gate migration. +- **Not authoring the program structure as ROADMAP lanes** — this is the design doc; the ROADMAP lane structure is a separate sibling that PM authors when this doc lands. +- **Not committing to a release boundary** — whether 0-floor lands in R2, "before R2 finishes," or a separately-named program is a director call. Per user direction: "needs to finish before R2 finishes, that's all I care." + +## Open calls + +### 1. Cargo conventions vs zero-source-tree + +Cargo expects `Cargo.toml` + `src/lib.rs` (or `src/main.rs`) at fixed paths. Even if these are 1-line trampolines that `include!()` generated content, they're physical files in the source tree. Two readings: + +- **(a) Trampolines count as 0** because their content is generated; the file is just a path-binding for Cargo. Pragmatic; matches "what's in version control" rather than "what's on disk." +- **(b) Trampolines count as N**, where N is the number of trampoline files Cargo conventionally requires. Stricter; floor is N (probably 1-3). + +For this proposal: **trampolines are 0 if their content is generated.** The user's stated goal is "0 hand-authored files" — a 1-line `include!()` trampoline that's itself emitted from a `.dag` authority is generated, not hand-authored. Cargo's path constraint is an environment convention, not v3's source-tree commitment. + +### 2. v3's first hand-Rust file: who owns it during transition? + +During the migration (PB-1 → PB-Substrate → ... → 0), v3 will have a shrinking-but-nonzero hand-Rust count. SG-0 census tracks this. Two questions: + +- Who declares "v3 has reached 0"? Director, on the closure declaration PR. +- What if a migration regresses (introduces a new hand-Rust file)? STOP-AND-ESCALATE; the ratchet only goes down. + +### 3. Bundling vs separating TESTING.md rewrite + +TESTING.md rewrite is structurally separable from the design doc. Bundling: faster, atomic. Separating: cleaner authority layering, easier review. + +Director (you / me) calls. PM may have a preference based on review bandwidth. + +## Cross-refs + +- Existing parent: [`docs/design-pure-bootstrap.md`](design-pure-bootstrap.md) — supersedes the ≤5-floor framing on this doc's promotion. +- Subsumed brief: [`docs/briefs/pb-1-data-driven-bootstrap.md`](briefs/pb-1-data-driven-bootstrap.md) — non-goals revised under the 0-floor target. +- Thesis claim: [`docs/thesis/self-inspection.md`](thesis/self-inspection.md) — "the substrate is its own subject"; this proposal makes that claim load-bearing at the implementation layer (no hand-Rust contradicts the claim). +- Related fixed-point ratchet: `DB-8` — the no-compromise convergence gate. +- TESTING residual authority: `TESTING.md §"Post-R2 shape"` — sibling PR rewrites this section to 0-residual. +- ROADMAP T-PB-A row at `:53` — needs amendment when this proposal lands (acceptance target shifts from ≤5 to 0). +- R2 structure at `docs/r2-structure.md` — "Lanes deliberately absent" section's T-ShimFloor entry needs amendment if this program lands as R2 scope or as a separately-named program. +- Floor-target precedent: PR #756 introduced "2-3 principled floor" framing — gets superseded by 0 under this proposal. From 039f2355460d7696bd67b4a5b5a221a092bbbd7e Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 21:33:50 -0400 Subject: [PATCH 14/52] WIP: gunbc Director --- docs/design-pure-bootstrap-zero.md | 192 ----------------------------- 1 file changed, 192 deletions(-) delete mode 100644 docs/design-pure-bootstrap-zero.md diff --git a/docs/design-pure-bootstrap-zero.md b/docs/design-pure-bootstrap-zero.md deleted file mode 100644 index cfcb604e52b..00000000000 --- a/docs/design-pure-bootstrap-zero.md +++ /dev/null @@ -1,192 +0,0 @@ -# Pure Bootstrap to Zero — Design Proposal - -**Status:** `PROPOSAL` — supersedes the ≤5-floor framing in [`docs/design-pure-bootstrap.md`](design-pure-bootstrap.md) and the 2-3 principled-floor framing in [PR #756](https://github.com/gunb-ai/gunbc/pull/756) on promotion. Until then, this doc is the proposed direction; `design-pure-bootstrap.md` remains the live authority. - -## Frame - -**Goal: zero hand-authored files in v3's source tree.** Better than v2's 1-residual. - -The ≤5-floor target was a sizing convenience masquerading as an architectural lower bound. Auditing the 35 files currently in `EXPECTED_HAND_AUTHORED_NON_TEST` shows the "irreducible" tier (build.rs, bootstrap.rs, lib.rs, dag.rs, dag/ports.rs, dag/effects.rs) isn't structurally irreducible — it's just not-yet-migrated substrate authoring. Each of those files can be generated from a `.dag` authority, with the same pattern v3's other generated files already use. - -Zero is achievable. v2 proved the cycle (1 residual was a TESTING.md choice, not a structural limit). v3's substrate is more structural than v2's (lens-as-substrate-declaration, types-as-data, programs-as-data) — so v3 should hit a tighter floor than v2. - -## Design choice — shape (γ) - -Three escalating shapes were considered: - -- **(α)** PB-1's current scope: data-bootstrap of DAG, hand-Rust everything else. Floor ~6-8. -- **(β)** Bootstrap process modeled in `.dag` + a small hand-Rust universal evaluator. Floor ~1-2. -- **(γ)** Substrate, evaluator, and bootstrap process all data. The compiled binary is fully generated; the host runtime (or the build trampoline) is the only thing not in v3's source tree. Floor: 0. - -**This proposal commits to (γ).** Rationale: - -- (β) is a bridge that gets dissolved into (γ); writing the bridge first is wasted work unless mandatory. It's not mandatory — see "First-time bootstrap" below. -- (γ) matches the thesis claim that the substrate is its own subject ([`docs/thesis/self-inspection.md`](thesis/self-inspection.md)). Hand-authored files in v3's source tree contradict that claim at the implementation layer. -- The runtime requirements for (γ) (a small generated evaluator + Cargo trampoline) are themselves generatable. There's no architectural reason to author them by hand. - -## Bootstrap as data — the conceptual core - -The current model: bootstrap is a *process* implemented in hand-Rust (`bootstrap.rs::Dag::new()`) that loads `.dag` source, runs the compiler pipeline, populates a `Dag`. The chicken-egg is "Dag::new() needs the compiler pipeline, which needs Dag::new()." - -The (γ) model: **bootstrap is data.** A `bootstrap.dag` (or equivalent authority) declares: -- Which `.dag` files load in which order -- What state the loaded `Dag` should reach -- What invariants must hold post-load -- What the entry point evaluates to - -The "evaluator" is a small generic interpreter that: -- Reads the bootstrap data -- Constructs the `Dag` -- Hands it to the rest of the compiler (also data) -- Runs `main` (also data) - -The evaluator is itself generated from a `.dag` authority that describes its operations. Per `feedback_compiler_is_dag_processor`: the compiler knows only Node / Conj / Disj / Cardinality / Bit. The evaluator therefore needs only those primitive operations — small. - -**The chicken-egg breaks at the build step**, not at runtime: the previous-generation binary reads the new bootstrap data and emits the new evaluator binary. Same cycle v2 used, applied recursively to the evaluator itself. - -## First-time bootstrap (the genuine N=0 problem) - -Even (γ) has a first-time bootstrap problem: the very first compiled binary has to come from somewhere. - -Three resolutions, in increasing aggressiveness: - -1. **Shipped pre-built binary.** The "first" binary is a release artifact (downloaded via install script, embedded in a published crate, or shipped as a release asset on GitHub). Subsequent bootstraps regenerate from source. Hand-Rust in v3's source tree: 0. Hand-Rust elsewhere (in the install script or release tooling): negligible / not part of v3. - -2. **Universal-runtime crate.** A tiny `gunbc-runtime` crate (published separately, not in v3's source tree) provides the generic evaluator. v3's source tree is `.dag` files + a generated Cargo.toml that depends on `gunbc-runtime`. The runtime crate is hand-authored, but **outside v3's source tree** (cleanly factored as runtime support, not compiler). - -3. **Procedural macro on existing rustc.** A `#[gunbc::data]` attribute (in a tiny crate) tells rustc to interpret the `.dag` content at compile time. Same shape as 2 but different boundary — the macro is the runtime; the rest is data. - -All three give **0 hand-Rust in v3's source tree.** Resolution choice is downstream of taste + ecosystem strategy; doesn't affect the in-tree floor. - -For this proposal: the in-tree floor target is 0 regardless of which N=0 resolution lands. Pick the resolution as a separate decision; it doesn't gate the migration program. - -## Subsumed lanes - -Existing lanes that fold into this program: - -- **PB-1** ([brief](briefs/pb-1-data-driven-bootstrap.md), XXL) — data-driven bootstrap loader. **Non-goals revised:** PB-1's current non-goals (don't delete tokenize/parse/lower/infer/emit; don't go binary-blob; don't change Dag runtime format) were appropriate for the ≤5-floor framing but contradict 0-floor. Under this proposal they invert: PB-1 is the first phase of a chain that ends with all of those files generated. -- **PB-4** (lower) — generate `lower.rs` from `lower.dag`. SG-3 series + lower.dag authority required. -- **PB-5** (infer) — generate `infer.rs` from `infer.dag`. SG-4 dispatch. -- **PB-6** (emit) — generate `emit.rs` + emit targets from spec authorities (`rust.dag`, `python.dag`, `go.dag`). Lane 1e dependency. - -Existing scope from `design-pure-bootstrap.md` continues to apply for the file-by-file work, just with a tighter target. - -## New lanes - -**PB-Substrate** (new, sized M-L) — generate `dag.rs`, `dag/ports.rs`, `dag/effects.rs` from `src/v3/std/substrate.dag`. The substrate type definitions become data; the Rust types are emitted from them. Cementing test: generated Rust matches the structural facts the substrate model declares. - -**PB-Lib + PB-Build** (subsumes PB-8 aspiration, sized M) — generate `lib.rs` (module declarations + crate exports) and `build.rs` (Cargo build script content) from emit authority. Both files become trampolines that `include!()` generated content from `OUT_DIR`, or vanish entirely if Cargo can be told to look elsewhere. - -**PB-Runtime** (new, sized M-L) — generate `test_runner.rs`, `lens_apply.rs`, `lens_testgen.rs`, `post_emit_verifier.rs` from `.dag` authorities. The "test runner" and "lens evaluator" become data + a tiny generic interpreter. - -**PB-Bootstrap-Process** (new, sized M, the conceptual core) — author `bootstrap.dag` describing the bootstrap workflow as data. Replace `bootstrap.rs` with a generated trampoline. Section "Bootstrap as data" above is its design. - -**PB-Workflow** (existing scope continued) — `workflow_idempotency.rs` and `workflow_parallelism.rs` migrate as Lane 2 dissolution lands. - -**PB-Tier1-Sweep** (per-file fast-retire, sized S each) — depends on above. The 13 Tier-1 files (regen binaries + bin helpers) retire as their backing migrations land. Not blocked on PB-Substrate / PB-Lib / etc., but blocked on PB-1 + PB-4/5/6. - -## TESTING.md rewrite (sibling PR) - -Current `TESTING.md` carves out two permanent Rust-authored test categories: -- Compiler-internal unit tests for Rust-only helpers -- External-toolchain boundary tests (rustc/go/python invocations) - -Both dissolve under 0-floor: - -- **Rust-only-helper unit tests** vanish naturally — there are no Rust-only helpers; everything generates from `.dag`. -- **External-toolchain boundary tests** migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations (the predicate landed in PR #678; runner support landed in #688/#741). A `TestClaim` like *"emit Rust, invoke rustc on output, check exit code"* is structurally identical to today's hand-Rust boundary tests. - -**TESTING.md rewrite scope:** -- Replace "Post-R2 shape" residual section with "0-residual" framing -- Reference `ExecuteCommand` predicate as the migration path -- Update authority list - -This rewrite is a sibling PR to the design doc — same author (Director or PM), separate land cycle. Could bundle, but TESTING.md is a foundational doc commitment worth its own discussion. - -## Acceptance gates - -R2 / future release acceptance for this program: - -- `EXPECTED_HAND_AUTHORED_NON_TEST` count = 0 -- `EXPECTED_HAND_AUTHORED_TEST` count = 0 -- TESTING.md "Post-R2 shape" residual rewritten to 0-residual -- DB-8 `self_host_fixed_point` converges bit-identically (the no-compromise gate; same as PB-1's) -- Compile cycle still produces a working binary (regen → rustc → run → diff fixed-point) -- All `[ext]` test predicates evaluate against generated authorities -- `bootstrap.dag` declares the bootstrap workflow + first-time bootstrap resolution explicitly - -## Dependency DAG - -``` -PB-Substrate ────────────────┐ - ├──→ enables PB-Lib + PB-Build -PB-1 (data-driven loader) ───┤ (emit Rust files from .dag = generic capability) - │ -PB-4 (lower) ┐ ├──→ enables PB-Bootstrap-Process -PB-5 (infer) ├──→ generic │ (compiler in .dag → bootstrap can be in .dag too) -PB-6 (emit) ┘ .dag │ - compiler │ - │ -PB-Runtime ──────────────────┤ - (test_runner, lens_apply │ - in .dag) │ - │ -PB-Workflow (Lane 2 dissolution) - │ -PB-Tier1-Sweep (per-file ──┘ - retirement; depends on - above-listed migrations) -``` - -**Parallelization:** PB-Substrate, PB-1 (sub-lanes), PB-4, PB-5, PB-6, PB-Runtime, PB-Workflow are all parallel-capable Day-1. PB-Lib + PB-Build is parallel after PB-Substrate's pattern is proven. PB-Bootstrap-Process is parallel after PB-1 + PB-4/5/6 (needs the full compiler in .dag to bootstrap from). PB-Tier1-Sweep is per-file fast-retire after each backing migration lands. - -**Worker capacity:** 6-8 parallel workers can productively dispatch against this DAG without coordination collisions, given the substrate.dag / SG-0 census is the only shared-edit hotspot (each PR removes one entry). Higher worker count = more rebase churn on `sg0_census_test.rs`; lower count = longer wall clock. - -## STOP-AND-ESCALATE - -Inherits from `design-pure-bootstrap.md` + PB-1 brief, plus: - -- **If first-time bootstrap (N=0) resolution requires hand-Rust in v3's source tree** — STOP. The resolution is supposed to live outside v3's source tree (install script, gunbc-runtime crate, or rustc macro). If it can't, the 0-floor target is unreachable and the framing needs revision back toward (β). -- **If the universal evaluator turns out to need substrate operations beyond Node / Conj / Disj / Cardinality / Bit** — STOP. The bounded-kernel invariant is load-bearing; expanding it to make (γ) work is wrong. -- **If TESTING.md rewrite reveals test categories that genuinely cannot express in `ExecuteCommand`-based `.dag`** — STOP. May indicate a `TestClaim` predicate gap that's its own substrate work. Surface before forcing the migration. - -## Non-goals - -- **Not picking the N=0 resolution shape in this doc** — three options (shipped binary / runtime crate / rustc macro) are scoped above; pick separately. Doesn't gate migration. -- **Not authoring the program structure as ROADMAP lanes** — this is the design doc; the ROADMAP lane structure is a separate sibling that PM authors when this doc lands. -- **Not committing to a release boundary** — whether 0-floor lands in R2, "before R2 finishes," or a separately-named program is a director call. Per user direction: "needs to finish before R2 finishes, that's all I care." - -## Open calls - -### 1. Cargo conventions vs zero-source-tree - -Cargo expects `Cargo.toml` + `src/lib.rs` (or `src/main.rs`) at fixed paths. Even if these are 1-line trampolines that `include!()` generated content, they're physical files in the source tree. Two readings: - -- **(a) Trampolines count as 0** because their content is generated; the file is just a path-binding for Cargo. Pragmatic; matches "what's in version control" rather than "what's on disk." -- **(b) Trampolines count as N**, where N is the number of trampoline files Cargo conventionally requires. Stricter; floor is N (probably 1-3). - -For this proposal: **trampolines are 0 if their content is generated.** The user's stated goal is "0 hand-authored files" — a 1-line `include!()` trampoline that's itself emitted from a `.dag` authority is generated, not hand-authored. Cargo's path constraint is an environment convention, not v3's source-tree commitment. - -### 2. v3's first hand-Rust file: who owns it during transition? - -During the migration (PB-1 → PB-Substrate → ... → 0), v3 will have a shrinking-but-nonzero hand-Rust count. SG-0 census tracks this. Two questions: - -- Who declares "v3 has reached 0"? Director, on the closure declaration PR. -- What if a migration regresses (introduces a new hand-Rust file)? STOP-AND-ESCALATE; the ratchet only goes down. - -### 3. Bundling vs separating TESTING.md rewrite - -TESTING.md rewrite is structurally separable from the design doc. Bundling: faster, atomic. Separating: cleaner authority layering, easier review. - -Director (you / me) calls. PM may have a preference based on review bandwidth. - -## Cross-refs - -- Existing parent: [`docs/design-pure-bootstrap.md`](design-pure-bootstrap.md) — supersedes the ≤5-floor framing on this doc's promotion. -- Subsumed brief: [`docs/briefs/pb-1-data-driven-bootstrap.md`](briefs/pb-1-data-driven-bootstrap.md) — non-goals revised under the 0-floor target. -- Thesis claim: [`docs/thesis/self-inspection.md`](thesis/self-inspection.md) — "the substrate is its own subject"; this proposal makes that claim load-bearing at the implementation layer (no hand-Rust contradicts the claim). -- Related fixed-point ratchet: `DB-8` — the no-compromise convergence gate. -- TESTING residual authority: `TESTING.md §"Post-R2 shape"` — sibling PR rewrites this section to 0-residual. -- ROADMAP T-PB-A row at `:53` — needs amendment when this proposal lands (acceptance target shifts from ≤5 to 0). -- R2 structure at `docs/r2-structure.md` — "Lanes deliberately absent" section's T-ShimFloor entry needs amendment if this program lands as R2 scope or as a separately-named program. -- Floor-target precedent: PR #756 introduced "2-3 principled floor" framing — gets superseded by 0 under this proposal. From 7db5c913046d3996eba597d0a69461a93fceb1c4 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 21:38:20 -0400 Subject: [PATCH 15/52] WIP: gunbc Director --- docs/design-pure-bootstrap-zero.md | 208 +++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 docs/design-pure-bootstrap-zero.md diff --git a/docs/design-pure-bootstrap-zero.md b/docs/design-pure-bootstrap-zero.md new file mode 100644 index 00000000000..6d5f7f51780 --- /dev/null +++ b/docs/design-pure-bootstrap-zero.md @@ -0,0 +1,208 @@ +# Pure Bootstrap to Zero — Design Proposal + +**Status:** `PROPOSAL` — supersedes the ≤5-floor framing in [`docs/design-pure-bootstrap.md`](design-pure-bootstrap.md) and the 2-3 principled-floor framing introduced via [PR #756](https://github.com/gunb-ai/gunbc/pull/756) on promotion. Until then, this doc is the proposed direction; `design-pure-bootstrap.md` remains the live authority. + +### Promotion mechanism + +This doc is PROPOSAL until promoted. **Promotion is a single Director-authored cascade PR** that does **all** of the following atomically (no piecewise promotion — the framing change is load-bearing across multiple authorities and partial promotion would create contradiction): + +- **Who promotes:** Director, after Grounding Manager (R2's standing manager) and at least one R2 substrate-prereq sub-lane have produced stable enough evidence that the (γ) shape is achievable in v3's substrate (i.e., not a paper proposal). +- **What gate:** the cascade PR includes (a) at least one prototyped lane closure proving an existing hand-Rust file can be retired via `.dag` migration without regression, and (b) explicit acknowledgement from PM that the program structure is dispatchable. +- **What retraction:** + - `docs/design-pure-bootstrap.md` updated with a banner pointing at this doc as the new authority; the ≤5-floor framing struck through with explicit retraction language; cross-refs migrated. + - PR #756's "2-3 principled floor" framing similarly retracted in `docs/design-pure-bootstrap.md` with same-PR replacement to "0 floor." + - `ROADMAP.md` T-PB-A row (`:53`) amended to point at the 0-floor target via this doc; the `≤5 irreducible-shim` language struck. + - `docs/r2-structure.md` "Lanes deliberately absent" entry for `T-ShimFloor` updated to reflect the program's new home (R2 absorption or separately-named program — Director call at promotion time). + - `TESTING.md` "Post-R2 shape" residual section either rewritten in this same cascade PR (bundled) or sibling PR landed first (separated). See "TESTING.md rewrite" section below. + - This doc's status banner updated from `PROPOSAL` to `LIVE` with promotion date and citing the cascade PR number. + +If any retraction step can't land in the same PR (e.g., cascading conflicts), promotion blocks; this doc stays `PROPOSAL` until the cascade can be authored atomically. + +## Frame + +**Goal: zero hand-authored files in v3's source tree.** Better than v2's 1-residual. + +The ≤5-floor target was a sizing convenience masquerading as an architectural lower bound. Auditing the 35 files currently in `EXPECTED_HAND_AUTHORED_NON_TEST` shows the "irreducible" tier (build.rs, bootstrap.rs, lib.rs, dag.rs, dag/ports.rs, dag/effects.rs) isn't structurally irreducible — it's just not-yet-migrated substrate authoring. Each of those files can be generated from a `.dag` authority, with the same pattern v3's other generated files already use. + +Zero is achievable. v2 proved the cycle (1 residual was a TESTING.md choice, not a structural limit). v3's substrate is more structural than v2's (lens-as-substrate-declaration, types-as-data, programs-as-data) — so v3 should hit a tighter floor than v2. + +## Design choice — shape (γ) + +Three escalating shapes were considered: + +- **(α)** PB-1's current scope: data-bootstrap of DAG, hand-Rust everything else. Floor ~6-8. +- **(β)** Bootstrap process modeled in `.dag` + a small hand-Rust universal evaluator. Floor ~1-2. +- **(γ)** Substrate, evaluator, and bootstrap process all data. The compiled binary is fully generated; the host runtime (or the build trampoline) is the only thing not in v3's source tree. Floor: 0. + +**This proposal commits to (γ).** Rationale: + +- (β) is a bridge that gets dissolved into (γ); writing the bridge first is wasted work unless mandatory. It's not mandatory — see "First-time bootstrap" below. +- (γ) matches the thesis claim that the substrate is its own subject ([`docs/thesis/self-inspection.md`](thesis/self-inspection.md)). Hand-authored files in v3's source tree contradict that claim at the implementation layer. +- The runtime requirements for (γ) (a small generated evaluator + Cargo trampoline) are themselves generatable. There's no architectural reason to author them by hand. + +## Bootstrap as data — the conceptual core + +The current model: bootstrap is a *process* implemented in hand-Rust (`bootstrap.rs::Dag::new()`) that loads `.dag` source, runs the compiler pipeline, populates a `Dag`. The chicken-egg is "Dag::new() needs the compiler pipeline, which needs Dag::new()." + +The (γ) model: **bootstrap is data.** A `bootstrap.dag` (or equivalent authority) declares: +- Which `.dag` files load in which order +- What state the loaded `Dag` should reach +- What invariants must hold post-load +- What the entry point evaluates to + +The "evaluator" is a small generic interpreter that: +- Reads the bootstrap data +- Constructs the `Dag` +- Hands it to the rest of the compiler (also data) +- Runs `main` (also data) + +The evaluator is itself generated from a `.dag` authority that describes its operations. Per `feedback_compiler_is_dag_processor`: the compiler knows only Node / Conj / Disj / Cardinality / Bit. The evaluator therefore needs only those primitive operations — small. + +**The chicken-egg breaks at the build step**, not at runtime: the previous-generation binary reads the new bootstrap data and emits the new evaluator binary. Same cycle v2 used, applied recursively to the evaluator itself. + +## First-time bootstrap (the genuine N=0 problem) + +Even (γ) has a first-time bootstrap problem: the very first compiled binary has to come from somewhere. + +Three resolutions, in increasing aggressiveness: + +1. **Shipped pre-built binary.** The "first" binary is a release artifact (downloaded via install script, embedded in a published crate, or shipped as a release asset on GitHub). Subsequent bootstraps regenerate from source. Hand-Rust in v3's source tree: 0. Hand-Rust elsewhere (in the install script or release tooling): negligible / not part of v3. + +2. **Universal-runtime crate.** A tiny `gunbc-runtime` crate (published separately, not in v3's source tree) provides the generic evaluator. v3's source tree is `.dag` files + a generated Cargo.toml that depends on `gunbc-runtime`. The runtime crate is hand-authored, but **outside v3's source tree** (cleanly factored as runtime support, not compiler). + +3. **Procedural macro on existing rustc.** A `#[gunbc::data]` attribute (in a tiny crate) tells rustc to interpret the `.dag` content at compile time. Same shape as 2 but different boundary — the macro is the runtime; the rest is data. + +All three give **0 hand-Rust in v3's source tree.** Resolution choice is downstream of taste + ecosystem strategy; doesn't affect the in-tree floor. + +For this proposal: the in-tree floor target is 0 regardless of which N=0 resolution lands. Pick the resolution as a separate decision; it doesn't gate the migration program. + +## Subsumed lanes + +Existing lanes that fold into this program: + +- **PB-1** ([brief](briefs/pb-1-data-driven-bootstrap.md), XXL) — data-driven bootstrap loader. **Non-goals revised:** PB-1's current non-goals (don't delete tokenize/parse/lower/infer/emit; don't go binary-blob; don't change Dag runtime format) were appropriate for the ≤5-floor framing but contradict 0-floor. Under this proposal they invert: PB-1 is the first phase of a chain that ends with all of those files generated. +- **PB-4** (lower) — generate `lower.rs` from `lower.dag`. SG-3 series + lower.dag authority required. +- **PB-5** (infer) — generate `infer.rs` from `infer.dag`. SG-4 dispatch. +- **PB-6** (emit) — generate `emit.rs` + emit targets from spec authorities (`rust.dag`, `python.dag`, `go.dag`). Lane 1e dependency. + +Existing scope from `design-pure-bootstrap.md` continues to apply for the file-by-file work, just with a tighter target. + +## New lanes + +**PB-Substrate** (new, sized M-L) — generate `dag.rs`, `dag/ports.rs`, `dag/effects.rs` from `src/v3/std/substrate.dag`. The substrate type definitions become data; the Rust types are emitted from them. Cementing test: generated Rust matches the structural facts the substrate model declares. + +**PB-Lib + PB-Build** (subsumes PB-8 aspiration, sized M) — generate `lib.rs` (module declarations + crate exports) and `build.rs` (Cargo build script content) from emit authority. Both files become trampolines that `include!()` generated content from `OUT_DIR`, or vanish entirely if Cargo can be told to look elsewhere. + +**PB-Runtime** (new, sized M-L) — generate `test_runner.rs`, `lens_apply.rs`, `lens_testgen.rs`, `post_emit_verifier.rs` from `.dag` authorities. The "test runner" and "lens evaluator" become data + a tiny generic interpreter. + +**PB-Bootstrap-Process** (new, sized M, the conceptual core) — author `bootstrap.dag` describing the bootstrap workflow as data. Replace `bootstrap.rs` with a generated trampoline. Section "Bootstrap as data" above is its design. + +**PB-Workflow** (existing scope continued) — `workflow_idempotency.rs` and `workflow_parallelism.rs` migrate as Lane 2 dissolution lands. + +**PB-Tier1-Sweep** (per-file fast-retire, sized S each) — depends on above. The 13 Tier-1 files (regen binaries + bin helpers) retire as their backing migrations land. Not blocked on PB-Substrate / PB-Lib / etc., but blocked on PB-1 + PB-4/5/6. + +## TESTING.md rewrite (sibling PR or bundled into promotion cascade — Director call) + +Current `TESTING.md` carves out two permanent Rust-authored test categories: +- Compiler-internal unit tests for Rust-only helpers +- External-toolchain boundary tests (rustc/go/python invocations) + +Both dissolve under 0-floor: + +- **Rust-only-helper unit tests** vanish naturally — there are no Rust-only helpers; everything generates from `.dag`. +- **External-toolchain boundary tests** migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations (the predicate landed in PR #678; runner support landed in #688/#741). A `TestClaim` like *"emit Rust, invoke rustc on output, check exit code"* is structurally identical to today's hand-Rust boundary tests. + +**TESTING.md rewrite scope:** +- Replace "Post-R2 shape" residual section with "0-residual" framing +- Reference `ExecuteCommand` predicate as the migration path +- Update authority list + +The rewrite is structurally separable from this design doc. **Director-call at promotion time** whether to bundle into the promotion cascade or land as a sibling PR first. + +## Acceptance gates + +R2 / future release acceptance for this program: + +- `EXPECTED_HAND_AUTHORED_NON_TEST` count = 0 +- `EXPECTED_HAND_AUTHORED_TEST` count = 0 +- TESTING.md "Post-R2 shape" residual rewritten to 0-residual +- DB-8 `self_host_fixed_point` converges bit-identically (the no-compromise gate; same as PB-1's) +- Compile cycle still produces a working binary (regen → rustc → run → diff fixed-point) +- All `[ext]` test predicates evaluate against generated authorities +- `bootstrap.dag` declares the bootstrap workflow + first-time bootstrap resolution explicitly + +## Dependency DAG + +``` +PB-Substrate ────────────────┐ + ├──→ enables PB-Lib + PB-Build +PB-1 (data-driven loader) ───┤ (emit Rust files from .dag = generic capability) + │ +PB-4 (lower) ┐ ├──→ enables PB-Bootstrap-Process +PB-5 (infer) ├──→ generic │ (compiler in .dag → bootstrap can be in .dag too) +PB-6 (emit) ┘ .dag │ + compiler │ + │ +PB-Runtime ──────────────────┤ + (test_runner, lens_apply │ + in .dag) │ + │ +PB-Workflow (Lane 2 dissolution) + │ +PB-Tier1-Sweep (per-file ──┘ + retirement; depends on + above-listed migrations) +``` + +**Parallelization:** PB-Substrate, PB-1 (sub-lanes), PB-4, PB-5, PB-6, PB-Runtime, PB-Workflow are all parallel-capable Day-1. PB-Lib + PB-Build is parallel after PB-Substrate's pattern is proven. PB-Bootstrap-Process is parallel after PB-1 + PB-4/5/6 (needs the full compiler in .dag to bootstrap from). PB-Tier1-Sweep is per-file fast-retire after each backing migration lands. + +**Worker capacity:** 6-8 parallel workers can productively dispatch against this DAG without coordination collisions, given the substrate.dag / SG-0 census is the only shared-edit hotspot (each PR removes one entry). Higher worker count = more rebase churn on `sg0_census_test.rs`; lower count = longer wall clock. + +## STOP-AND-ESCALATE + +Inherits from `design-pure-bootstrap.md` + PB-1 brief, plus: + +- **If first-time bootstrap (N=0) resolution requires hand-Rust in v3's source tree** — STOP. The resolution is supposed to live outside v3's source tree (install script, gunbc-runtime crate, or rustc macro). If it can't, the 0-floor target is unreachable and the framing needs revision back toward (β). +- **If the universal evaluator turns out to need substrate operations beyond Node / Conj / Disj / Cardinality / Bit** — STOP. The bounded-kernel invariant is load-bearing; expanding it to make (γ) work is wrong. +- **If TESTING.md rewrite reveals test categories that genuinely cannot express in `ExecuteCommand`-based `.dag`** — STOP. May indicate a `TestClaim` predicate gap that's its own substrate work. Surface before forcing the migration. + +## Non-goals + +- **Not picking the N=0 resolution shape in this doc** — three options (shipped binary / runtime crate / rustc macro) are scoped above; pick separately. Doesn't gate migration. +- **Not authoring the program structure as ROADMAP lanes** — this is the design doc; the ROADMAP lane structure is a separate sibling that PM authors when this doc lands. +- **Not committing to a release boundary** — whether 0-floor lands in R2, "before R2 finishes," or a separately-named program is a director call. Per user direction: "needs to finish before R2 finishes, that's all I care." + +## Open calls + +### 1. Cargo conventions vs zero-source-tree + +Cargo expects `Cargo.toml` + `src/lib.rs` (or `src/main.rs`) at fixed paths. Even if these are 1-line trampolines that `include!()` generated content, they're physical files in the source tree. Two readings: + +- **(a) Trampolines count as 0** because their content is generated; the file is just a path-binding for Cargo. Pragmatic; matches "what's in version control" rather than "what's on disk." +- **(b) Trampolines count as N**, where N is the number of trampoline files Cargo conventionally requires. Stricter; floor is N (probably 1-3). + +For this proposal: **trampolines are 0 if their content is generated.** The user's stated goal is "0 hand-authored files" — a 1-line `include!()` trampoline that's itself emitted from a `.dag` authority is generated, not hand-authored. Cargo's path constraint is an environment convention, not v3's source-tree commitment. + +### 2. v3's first hand-Rust file: who owns it during transition? + +During the migration (PB-1 → PB-Substrate → ... → 0), v3 will have a shrinking-but-nonzero hand-Rust count. SG-0 census tracks this. Two questions: + +- Who declares "v3 has reached 0"? Director, on the closure declaration PR. +- What if a migration regresses (introduces a new hand-Rust file)? STOP-AND-ESCALATE; the ratchet only goes down. + +### 3. Bundling vs separating TESTING.md rewrite + +TESTING.md rewrite is structurally separable from the design doc. Bundling: faster, atomic. Separating: cleaner authority layering, easier review. + +Director (you / me) calls. PM may have a preference based on review bandwidth. + +## Cross-refs + +- Existing parent: [`docs/design-pure-bootstrap.md`](design-pure-bootstrap.md) — supersedes the ≤5-floor framing on this doc's promotion (see Promotion mechanism above for the cascade requirement). +- Subsumed brief: [`docs/briefs/pb-1-data-driven-bootstrap.md`](briefs/pb-1-data-driven-bootstrap.md) — non-goals revised under the 0-floor target. +- Thesis claim: [`docs/thesis/self-inspection.md`](thesis/self-inspection.md) — "the substrate is its own subject"; this proposal makes that claim load-bearing at the implementation layer (no hand-Rust contradicts the claim). +- Related fixed-point ratchet: `DB-8` — the no-compromise convergence gate. +- TESTING residual authority: `TESTING.md §"Post-R2 shape"` — sibling PR or bundled cascade rewrites this section to 0-residual. +- ROADMAP T-PB-A row at `:53` — amended in promotion cascade (acceptance target shifts from ≤5 to 0). +- R2 structure at `docs/r2-structure.md` — "Lanes deliberately absent" T-ShimFloor entry amended in promotion cascade (program either absorbed into R2 or separately-named). +- Floor-target precedent: PR #756 introduced "2-3 principled floor" framing — gets superseded by 0 under this proposal; retraction happens in promotion cascade. From 1e2d40c4dae94ddde349567fa900fbfbd5ebfc58 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 21:42:50 -0400 Subject: [PATCH 16/52] WIP: gunbc Director --- docs/design-pure-bootstrap-zero.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/design-pure-bootstrap-zero.md b/docs/design-pure-bootstrap-zero.md index 6d5f7f51780..da2709ee7ea 100644 --- a/docs/design-pure-bootstrap-zero.md +++ b/docs/design-pure-bootstrap-zero.md @@ -18,6 +18,14 @@ This doc is PROPOSAL until promoted. **Promotion is a single Director-authored c If any retraction step can't land in the same PR (e.g., cascading conflicts), promotion blocks; this doc stays `PROPOSAL` until the cascade can be authored atomically. +### Pre-promotion deliverables + +These are assertions in this PROPOSAL whose empirical backing must surface in the promotion cascade PR (or in sibling PRs landed before promotion). Naming them explicitly so the cascade PR's reviewer can verify each before the framing change is locked: + +- **35-file audit table** — the §"Frame" claim that the "irreducible tier" (build.rs, bootstrap.rs, lib.rs, dag.rs, dag/ports.rs, dag/effects.rs) isn't structurally irreducible needs an inline table mapping each of the 35 `EXPECTED_HAND_AUTHORED_NON_TEST` entries to (a) why it's currently hand-authored, (b) which migration path retires it (PB-Substrate / PB-1 / PB-4 / PB-5 / PB-6 / PB-Lib+Build / PB-Runtime / PB-Bootstrap-Process / PB-Tier1-Sweep). Goes in the promotion cascade PR. +- **PB-1 brief amendment** — `docs/briefs/pb-1-data-driven-bootstrap.md`'s non-goals (don't delete tokenize/parse/lower/infer/emit; don't go binary-blob; don't change Dag runtime format) invert under 0-floor. The brief must be amended in the promotion cascade PR (not silently after) so PB-1's downstream consumers see the revised scope. +- **TESTING.md "Post-R2 shape" rewrite** — Director-call at promotion time on bundle-vs-sibling per §"TESTING.md rewrite" below; either way, must be authored before this PROPOSAL flips to LIVE. + ## Frame **Goal: zero hand-authored files in v3's source tree.** Better than v2's 1-residual. From 309ea71543e0d1d0a6c75edb48a9ddcdc4ee6f47 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 21:45:50 -0400 Subject: [PATCH 17/52] WIP: gunbc Director --- docs/design-pure-bootstrap-zero.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/design-pure-bootstrap-zero.md b/docs/design-pure-bootstrap-zero.md index da2709ee7ea..92507574634 100644 --- a/docs/design-pure-bootstrap-zero.md +++ b/docs/design-pure-bootstrap-zero.md @@ -105,6 +105,13 @@ Existing scope from `design-pure-bootstrap.md` continues to apply for the file-b **PB-Bootstrap-Process** (new, sized M, the conceptual core) — author `bootstrap.dag` describing the bootstrap workflow as data. Replace `bootstrap.rs` with a generated trampoline. Section "Bootstrap as data" above is its design. + **N=0 runtime boundary verification (per codex `7db5c913` review).** Whichever N=0 resolution lands (shipped binary / `gunbc-runtime` crate / rustc proc-macro), the runtime must be a *generic fixed-point substrate runner* — not hand-authored compiler logic relocated out of v3's source tree. Verification gates that PB-Bootstrap-Process must satisfy: + - **Operation set bounded.** The runtime invokes only the primitive substrate operations (Node / Conj / Disj / Cardinality / Bit per `feedback_compiler_is_dag_processor`) — no compiler-pass logic (no tokenize, no parse, no infer, no lower, no emit) lives in the runtime. If the runtime needs to do any of those, it does so by invoking generated `.dag` programs, not by carrying their logic. + - **Size budget.** A specific LOC ceiling on the runtime (target: <500 LOC of hand-Rust outside v3's tree, modulo language-stdlib-equivalent primitives). If the runtime grows past the budget, it's a signal that compiler authority leaked out. + - **Substrate-runner equivalence test.** A generic-substrate-runner test: feed the runtime a `.dag` program that's structurally equivalent to but textually different from v3's compiler.dag, verify the runtime evaluates it identically. This proves the runtime is generic over `.dag` programs, not specialized to v3's compiler. + + These verification gates land in PB-Bootstrap-Process's acceptance criteria; the promotion cascade PR cites the test results. + **PB-Workflow** (existing scope continued) — `workflow_idempotency.rs` and `workflow_parallelism.rs` migrate as Lane 2 dissolution lands. **PB-Tier1-Sweep** (per-file fast-retire, sized S each) — depends on above. The 13 Tier-1 files (regen binaries + bin helpers) retire as their backing migrations land. Not blocked on PB-Substrate / PB-Lib / etc., but blocked on PB-1 + PB-4/5/6. From de6401195c8d0e54ac89c59feb0cb433864b0866 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 22:00:51 -0400 Subject: [PATCH 18/52] WIP: gunbc Director --- docs/briefs/pure-bootstrap-zero-manager.md | 365 +++++++++++++++++++++ 1 file changed, 365 insertions(+) create mode 100644 docs/briefs/pure-bootstrap-zero-manager.md diff --git a/docs/briefs/pure-bootstrap-zero-manager.md b/docs/briefs/pure-bootstrap-zero-manager.md new file mode 100644 index 00000000000..90ff8c2d928 --- /dev/null +++ b/docs/briefs/pure-bootstrap-zero-manager.md @@ -0,0 +1,365 @@ +# Pure Bootstrap to Zero Manager Brief + +**Status:** `PROPOSAL` — pending cascade promotion of +[`docs/design-pure-bootstrap-zero.md`](../design-pure-bootstrap-zero.md) +(in PROPOSAL on main as of #762). Until that cascade lands, this +brief is the manager's scope-in-preparation; it does not dispatch +work formally. Pre-promotion deliverables (audit table + PB-1 +brief amendment + first prototyped lane closure) are the manager's +first work and gate the cascade. + +**Naming clarity.** This is the **Pure Bootstrap to Zero Program +Manager**. The program is **parallel to R2**, not part of R2. Per +the locked Strong Post-R2 stance ([`docs/r2-structure.md`](../r2-structure.md) +Decisions locked), R2 = thesis close with Grounding Completeness +as single co-anchor. Zero-floor is implementation completeness — +making the codebase match the thesis at the file-count level. Two +distinct concerns; two parallel programs; do not conflate. + +The release-ledger placement of this program (R2 absorption / +separately-named program / under Director closure) is **deferred +to the cascade promotion PR** per the design doc's Promotion +mechanism. Until then: program runs structurally without +committing to a release-ledger label. + +## Orient before reading + +- **Program scope authority:** [`docs/design-pure-bootstrap-zero.md`](../design-pure-bootstrap-zero.md) + (PROPOSAL). Names goals (γ shape, bootstrap-as-data, 0 hand-Rust + in v3 source tree), lane structure, dependency DAG, + acceptance gates, STOP-AND-ESCALATE conditions, pre-promotion + deliverables. Single source for what 0-floor means and how to + verify reaching it. +- **Legacy authority being superseded:** [`docs/design-pure-bootstrap.md`](../design-pure-bootstrap.md) + (≤5-floor framing) + [PR #756](https://github.com/gunb-ai/gunbc/pull/756) + (2-3 principled-floor framing). Both retract atomically in the + cascade promotion PR; until then, they remain live authority. +- **Thesis claim tracked:** [`THESIS.md`](../../THESIS.md) §"Thesis + claims — complete list" + [`docs/thesis/self-inspection.md`](../thesis/self-inspection.md). + Hand-Rust in v3's source tree contradicts "the substrate is its + own subject" at the implementation layer; this program closes + that contradiction. +- **Subsumed brief:** [`docs/briefs/pb-1-data-driven-bootstrap.md`](pb-1-data-driven-bootstrap.md). + PB-1 (XXL, 5 sub-lanes) was authored under R1's ≤5-floor framing; + its non-goals invert under 0-floor and the brief gets amended in + the cascade promotion PR. Lane-owner reports here going forward — + see "Hand-off points / PB-1 lineage transition" below. +- **Coordination context:** Director session (currently + `zesty-bear-812`); per + [`docs/briefs/r1-director-brief.md`](r1-director-brief.md) + Staffing set + [`docs/r2-structure.md`](../r2-structure.md) + Manager structure (R2 has 1 standing manager + Director; + Zero-Floor adds a second standing manager parallel to R2). +- **R1 closure transition:** R1 Self-hosting Manager archives at + R1 close. PB-1 lineage transition (currently reporting through + R1 Self-hosting) routes here at archival. See "Hand-off points" + below for the explicit channel. + +## Slice + +This manager owns the full Pure Bootstrap to Zero program per +[`design-pure-bootstrap-zero.md`](../design-pure-bootstrap-zero.md) +§"Subsumed lanes" + §"New lanes": + +**Subsumed (existing lanes folding under this manager):** + +- **PB-1** ([brief](pb-1-data-driven-bootstrap.md), XXL) — + data-driven bootstrap loader. 5 sub-lanes (PB-1-a through + PB-1-e). Lineage transition from R1 Self-hosting at R1 close. +- **PB-4** — `lower.rs` migration. Blocked on SG-3 series + lower.dag + authority. +- **PB-5** — `infer.rs` migration. SG-4 dispatch. +- **PB-6** — `emit.rs` + emit-target cluster (`emit/python_target.rs`, + `emit/rust_target.rs`, `emit_rust.rs`). Lane 1e dependency. + +**New (introduced by this program):** + +- **PB-Substrate** (M-L) — generate `dag.rs`, `dag/ports.rs`, + `dag/effects.rs` from `src/v3/std/substrate.dag`. Cementing test: + generated Rust matches structural facts. +- **PB-Lib + PB-Build** (M, subsumes PB-8 aspiration) — `lib.rs` and + `build.rs` generated; trampolines or vanish. +- **PB-Runtime** (M-L) — `test_runner.rs`, `lens_apply.rs`, + `lens_testgen.rs`, `post_emit_verifier.rs` from `.dag` authorities. +- **PB-Bootstrap-Process** (M, conceptual core) — `bootstrap.dag` + declares the bootstrap workflow as data; `bootstrap.rs` becomes + generated trampoline. Includes N=0 runtime boundary verification + per design doc (operation-set bounded, size budget, substrate- + runner equivalence test). +- **PB-Workflow** (continuation) — `workflow_idempotency.rs` and + `workflow_parallelism.rs` migrate as Lane 2 dissolution lands. +- **PB-Tier1-Sweep** (per-file fast-retire, S each) — 13 Tier-1 + files (regen binaries + bin helpers) retire as their backing + migrations land. + +## Framing question this manager answers + +**Does v3's source tree reach zero hand-authored files — substrate +generated from `.dag` substrate model, evaluator generated from +primitive operations only, bootstrap process declared as data, +test residual dissolved — such that "the substrate is its own +subject" holds at the implementation layer rather than just the +thesis-claim layer?** + +Today (pre-dispatch state): +- 35 files in `EXPECTED_HAND_AUTHORED_NON_TEST` (post #763 + `lens_depth.rs` retirement). +- TESTING.md "Post-R2 shape" residual carves out two Rust-authored + test categories permanently. +- `bootstrap.rs` is hand-Rust (~470 LOC) with the chicken-egg + framing: Dag::new() needs the compiler pipeline. +- Zero-floor design doc (#762) lays out the program; pre-promotion + deliverables not yet authored. + +The ask: close all program lanes per design doc acceptance gates +(`EXPECTED_HAND_AUTHORED_NON_TEST = 0`, `EXPECTED_HAND_AUTHORED_TEST = 0`, +TESTING.md rewritten, DB-8 fixed-point converges, all `[ext]` +predicates evaluate against generated authorities, `bootstrap.dag` +declares workflow including N=0 resolution). + +## Sequence + dispatch + +**Critical path** is **PB-Bootstrap-Process** — depends on PB-1 +(data-bootstrap) + PB-4/5/6 (compiler in .dag) + PB-Substrate +(substrate types in .dag) being usable at minimum. The other lanes +are fill queues operating in parallel; any available worker picks +top-priority unblocked work. + +**Pre-promotion phase (Day-1 dispatch):** + +- **Pre-promotion deliverable 1: 35-file audit table.** Author the + file-by-file mapping (file → why-currently-hand-authored → + migration-path-into-PB-lane) inline for the cascade promotion PR. + Director already authored a starting categorization in + conversation with PM; this manager refines and authorities it. +- **Pre-promotion deliverable 2: PB-1 brief amendment.** Amend + [`pb-1-data-driven-bootstrap.md`](pb-1-data-driven-bootstrap.md) + non-goals to align with 0-floor (currently they explicitly + reject deletion of tokenize/parse/lower/infer/emit and reject + binary-blob format; under 0-floor those non-goals invert as + scope absorbed into PB-* program lanes). +- **Pre-promotion deliverable 3: first prototyped lane closure.** + Pick one PB-* lane and execute it end-to-end (e.g., PB-Substrate + pilot or PB-1-a continuation) to prove the migration pattern + before the cascade promotion PR locks the framing. + +These three are this manager's first work; they gate cascade +promotion. + +**Post-promotion phase (parallel-capable):** + +- **Day-1 (post-promotion).** PB-Substrate dispatches; pattern + proves substrate-type generation. PB-1 sub-lanes continue; + PB-1-a should be done or near-done from R1 era — verify and + re-baseline. PB-4/5/6 dispatch as substrate evolves. +- **Day-1.** PB-Runtime dispatches. Per-file parallelism over the + 4 runtime files (test_runner / lens_apply / lens_testgen / + post_emit_verifier). +- **As PB-Substrate + PB-1 reach usability.** PB-Lib + PB-Build + dispatches; `lib.rs` + `build.rs` migrate to trampolines. +- **As PB-1 + PB-4/5/6 reach usability.** PB-Bootstrap-Process + dispatches. N=0 runtime boundary verification gates land per + design doc. +- **Continuous, gated on backing migrations.** PB-Tier1-Sweep + retires regen binaries + bin helpers as their backing files + retire. Per-file PRs. +- **Continuous, gated on Lane 2 dissolution.** PB-Workflow handles + workflow_idempotency / workflow_parallelism as Lane 2 dissolves. + +Lane ordering is a **fill-queue model**, not strict sequential. PB- +Bootstrap-Process is the sole critical-path spine. Cross-lane +dispatch failures surface as blocked workers on specific +sub-lanes; manager reassigns to unblocked queues. + +## Hand-off points + +This program is **parallel to R2**; coordination crosses two +manager boundaries (Grounding + Director) and the R1-closure +transition. + +### PB-1 lineage transition (load-bearing) + +PB-1 was authored under R1 era. Its lane-owner (whoever drives +sub-lane PRs against `pb-1-data-driven-bootstrap.md`) currently +reports through R1 Self-hosting Manager. R1 Self-hosting Manager +archives at R1 close. + +**Transition mechanic:** at R1 close, PB-1 lineage explicitly +transitions to this manager. The cascade promotion PR for the +zero-floor design doc names this transition in its acceptance +record, alongside the PB-1 brief amendment. PB-1 sub-lane PRs +authored after R1 close cite this manager as the reporting +channel; pre-R1-close PRs continue under R1 Self-hosting until +archival. + +If R1 closure happens before this manager's brief promotes, PB-1 +lineage transitions to Director ad-hoc (interim) until brief +promotes; then transitions here. + +### Cross-manager notifications queued + +- **Grounding Manager** (substrate-shape coordination). Bidirectional: + - **Zero-Floor → Grounding:** when PB-Substrate lands shape-affecting + changes to `dag.rs` or `dag/*` (substrate type definitions + generated from `substrate.dag`), notify Grounding so T-Ground- + Engine work can adapt. Substrate types are load-bearing for + Grounding's inhabitance-search engine. + - **Grounding → Zero-Floor:** when T-Ground-Engine work needs + new substrate fields or operations beyond what the current + `substrate.dag` declares, notify Zero-Floor before authoring + against shape that's mid-migration. Avoid double-edits to + `dag.rs` from both sides. +- **R1 Self-hosting Manager** (PB-1 lineage; transitional, until R1 + close). Coordinate the lineage transition timing — Self-hosting + signals when ready to hand off; Zero-Floor confirms ownership. + This entry retires when R1 Self-hosting archives. +- **Director** (escalation hub for scope changes, cross-program + conflicts, release-ledger placement decisions, cascade + promotion PR authoring). + +### Up to director + +- **Cascade promotion PR.** This manager prepares the three pre- + promotion deliverables (audit table + PB-1 brief amendment + + first prototyped lane closure); Director authors the cascade PR + per the design doc's Promotion mechanism. Atomic across multiple + authority docs; Director's call on bundling vs sibling for + TESTING.md rewrite. +- **Release-ledger placement.** Whether the program lands as R2 + absorption / separately-named program / under Director closure + is a Director call at promotion time per the design doc. +- **N=0 resolution shape pick.** Three options scoped in the + design doc (shipped binary / `gunbc-runtime` crate / rustc + proc-macro). Director picks at or before PB-Bootstrap-Process + acceptance; doesn't gate earlier lane work. +- **Scope-creep flags.** If a lane surfaces work broader than its + scoped acceptance criterion, escalate rather than absorb. The + design doc commits to bounded subsets; scope drift would re-open + framing decisions the cascade PR locks. + +## Working state + +Lane-owner dispatch status (update as sub-deliverables close). +Section populates on cascade promotion + first dispatches; entries +below are scaffolding. + +**Pre-promotion deliverables (gates the cascade promotion PR):** +- [ ] 35-file audit table authored (file → why-current-hand-authored + → migration-path-into-PB-lane). Inline in cascade PR. +- [ ] PB-1 brief amendment ([`pb-1-data-driven-bootstrap.md`](pb-1-data-driven-bootstrap.md)) + non-goals revised to align with 0-floor. Amends in cascade PR. +- [ ] First prototyped lane closure (PB-Substrate pilot or PB-1-a + continuation) proving migration pattern works. Cited in + cascade PR. + +**PB-1 (XXL, subsumed; lineage transition pending R1 close):** +- [ ] PB-1-a (std fixtures generated constructors) — verify + current state from R1 era; re-baseline. +- [ ] PB-1-b (STAGED_FILES generated constructors) +- [ ] PB-1-c (V3_SPECS generated constructors) +- [ ] PB-1-d (COMPILER_FILES generated constructors) +- [ ] PB-1-e (runtime-path retirement + measurement) + +**PB-Substrate (M-L):** +- [ ] `dag.rs` generated from `src/v3/std/substrate.dag` +- [ ] `dag/ports.rs` generated +- [ ] `dag/effects.rs` generated +- [ ] Cementing test: generated Rust matches substrate model + +**PB-4 (lower):** *(blocked on SG-3 series + `lower.dag` authority)* +- [ ] `lower.dag` authoring +- [ ] `regen_lower` binary +- [ ] `lower_generated.rs` +- [ ] `lower.rs` retired + +**PB-5 (infer):** *(SG-4 dispatch)* +- [ ] `infer.dag` + dispatch +- [ ] `infer_generated.rs` +- [ ] `infer.rs` retired + +**PB-6 (emit cluster):** *(Lane 1e dependency)* +- [ ] `emit.rs` migrated +- [ ] `emit/python_target.rs` migrated +- [ ] `emit/rust_target.rs` migrated +- [ ] `emit_rust.rs` retired (re-export shim collapses) + +**PB-Lib + PB-Build (M):** +- [ ] `lib.rs` generated trampoline +- [ ] `build.rs` generated trampoline (or eliminated) + +**PB-Runtime (M-L):** +- [ ] `test_runner.rs` migrated +- [ ] `lens_apply.rs` migrated +- [ ] `lens_testgen.rs` migrated +- [ ] `post_emit_verifier.rs` migrated + +**PB-Bootstrap-Process (M, conceptual core):** +- [ ] `bootstrap.dag` authored (load order + target state + + invariants + entry point) +- [ ] Universal evaluator generated from primitive-operations + authority +- [ ] `bootstrap.rs` retired or trampoline only +- [ ] N=0 runtime boundary verification: + - [ ] Operation set bounded (Node/Conj/Disj/Cardinality/Bit only) + - [ ] Size budget met (<500 LOC outside v3 tree) + - [ ] Substrate-runner equivalence test passes +- [ ] N=0 resolution shape picked (Director call) + +**PB-Workflow (continuation):** +- [ ] `workflow_idempotency.rs` migrated (Lane 2 dissolution) +- [ ] `workflow_parallelism.rs` migrated (Stage 2e .dag surface + lands first) + +**PB-Tier1-Sweep (per-file fast-retire; depends on backing migrations):** +- [ ] regen_bootstrap.rs +- [ ] regen_lens.rs +- [ ] regen_parse.rs +- [ ] regen_parse_tables.rs +- [ ] regen_tokenize.rs +- [ ] regen_v3.rs +- [ ] regen_bootstrap_emit.rs +- [ ] regen_parse_emit.rs +- [ ] regen_parse_tables_emit.rs +- [ ] dag/builder.rs +- [ ] lens_unused_parameters.rs +- [ ] dimension.rs +- [ ] tokenize_char_class.rs (also unblocks R2 T-Substrate + 4th sub-lane via Class 5 Gap 3 closure — coordination point + with Director-dispatched R2 work) + +**Acceptance gates (per design doc):** +- [ ] `EXPECTED_HAND_AUTHORED_NON_TEST` count = 0 +- [ ] `EXPECTED_HAND_AUTHORED_TEST` count = 0 +- [ ] TESTING.md "Post-R2 shape" residual rewritten to 0-residual +- [ ] DB-8 `self_host_fixed_point` converges bit-identically +- [ ] All `[ext]` test predicates evaluate against generated + authorities +- [ ] `bootstrap.dag` declares workflow + N=0 resolution + +Decisions log (append as they happen): + +- _(none yet — manager is pre-promotion; brief authored + 2026-04-25 per Director request after #762 merge)_ + +Open questions for director: + +- **R1 Self-hosting → Zero-Floor PB-1 lineage transition timing.** + R1 Self-hosting archives at R1 close (hours-to-day per Director + estimate). Confirm transition is automatic at archival, or + requires an explicit handoff PR before R1 closes. +- **Cascade promotion PR authoring lead.** Director's section in + Hand-off says Director authors. Confirm: this manager's three + pre-promotion deliverables are inputs to that PR, or this + manager authors-then-Director-reviews? + +Cross-manager notifications queued: + +- **Grounding Manager**: brief authored 2026-04-25; coordination + channel established for substrate-shape changes (bidirectional + per Hand-off points). No active signal yet — pre-promotion. +- **R1 Self-hosting Manager** (transitional): PB-1 lineage + transition queued for R1 close. Self-hosting Manager should + acknowledge in their working state when ready to hand off. +- **Director**: brief in PROPOSAL pending cascade promotion; + three pre-promotion deliverables are first work and gate the + cascade. From 0604ffb5857c02b05ded07899b8d7effa66022d9 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 22:06:51 -0400 Subject: [PATCH 19/52] WIP: gunbc Director --- docs/briefs/pure-bootstrap-zero-manager.md | 56 +++++++++++++++++----- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/docs/briefs/pure-bootstrap-zero-manager.md b/docs/briefs/pure-bootstrap-zero-manager.md index 90ff8c2d928..1bb106d199f 100644 --- a/docs/briefs/pure-bootstrap-zero-manager.md +++ b/docs/briefs/pure-bootstrap-zero-manager.md @@ -22,6 +22,15 @@ to the cascade promotion PR** per the design doc's Promotion mechanism. Until then: program runs structurally without committing to a release-ledger label. +**Cross-program coordination routing.** Cross-program signals +between Zero-Floor and R2 (Grounding + R2 ad-hoc lanes) route +through Director, who is the only entity with both program +contexts. Manager-to-manager direct coordination is for +substrate-shape only (per Cross-manager notifications queued +below); broader cross-program concerns (scope, ledger placement, +sequencing decisions affecting both programs) escalate to +Director. + ## Orient before reading - **Program scope authority:** [`docs/design-pure-bootstrap-zero.md`](../design-pure-bootstrap-zero.md) @@ -102,8 +111,12 @@ subject" holds at the implementation layer rather than just the thesis-claim layer?** Today (pre-dispatch state): -- 35 files in `EXPECTED_HAND_AUTHORED_NON_TEST` (post #763 - `lens_depth.rs` retirement). +- **Live count authority:** `src/v3/compiler/tests/integration/sg0_census_test.rs` + `EXPECTED_HAND_AUTHORED_NON_TEST` and `EXPECTED_HAND_AUTHORED_TEST` + arrays. Read at dispatch time; brief does not restate the count + inline (drift risk). Reference snapshot: 35 NON_TEST files at + brief authoring (post #763 `lens_depth.rs` retirement); use the + live array as the source-of-truth for any audit work. - TESTING.md "Post-R2 shape" residual carves out two Rust-authored test categories permanently. - `bootstrap.rs` is hand-Rust (~470 LOC) with the chicken-egg @@ -216,6 +229,16 @@ promotes; then transitions here. - **Director** (escalation hub for scope changes, cross-program conflicts, release-ledger placement decisions, cascade promotion PR authoring). + - **Specific coordination case: `tokenize_char_class.rs` retirement.** + PB-Tier1-Sweep retirement of `tokenize_char_class.rs` (per + Working state) closes Class 5 Gap 3 from the substrate side, + which unblocks the R2 T-Substrate 4th sub-lane (charclass phase-2 + consumer = tokenizer). Zero-Floor Manager signals Director when + this retirement lands; Director coordinates dispatch of the + R2 T-Substrate sub-lane (Director-ad-hoc per `r2-structure.md`, + no standing R2 manager owns it). One-sided note from this brief + by design: the consumer side is Director-dispatched, so the + bidirectional pairing collapses to Zero-Floor → Director. ### Up to director @@ -338,19 +361,28 @@ below are scaffolding. Decisions log (append as they happen): -- _(none yet — manager is pre-promotion; brief authored - 2026-04-25 per Director request after #762 merge)_ +- **2026-04-25** — Brief authored per Director request after #762 + merge (charclass reclassification + zero-floor design doc + PROPOSAL). +- **2026-04-25** — **PB-1 lineage transition: automatic at R1 + Self-hosting archive.** No explicit handoff PR required. Verification + on results: PB-1 sub-lane PRs authored after R1 close should cite + Zero-Floor Manager as reporting channel; if they cite R1 Self-hosting + (which has archived), the transition didn't take and Director + surfaces it. Manager confirms first post-R1-archive PB-1 PR routes + here as the verification artifact. +- **2026-04-25** — **Cascade promotion PR authoring split.** Manager + authors the three pre-promotion deliverables as separate PRs (audit + table inline-able into cascade; PB-1 brief amendment; first + prototyped lane closure). Director authors the cascade promotion PR + itself using those as inputs. Pattern matches "what worked" from R1 + brief refreshes: managers own their scope surfaces; director owns + cross-cutting authority changes (the cascade is cross-cutting across + 4 authority docs). Open questions for director: -- **R1 Self-hosting → Zero-Floor PB-1 lineage transition timing.** - R1 Self-hosting archives at R1 close (hours-to-day per Director - estimate). Confirm transition is automatic at archival, or - requires an explicit handoff PR before R1 closes. -- **Cascade promotion PR authoring lead.** Director's section in - Hand-off says Director authors. Confirm: this manager's three - pre-promotion deliverables are inputs to that PR, or this - manager authors-then-Director-reviews? +- _(none — both resolved 2026-04-25; see Decisions log below)_ Cross-manager notifications queued: From 8a8c66a795e72e3143a55f2aee19a313fad4802c Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 22:11:21 -0400 Subject: [PATCH 20/52] WIP: gunbc Director --- docs/briefs/pure-bootstrap-zero-manager.md | 61 +++++++++++++++------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/docs/briefs/pure-bootstrap-zero-manager.md b/docs/briefs/pure-bootstrap-zero-manager.md index 1bb106d199f..ec1589cd288 100644 --- a/docs/briefs/pure-bootstrap-zero-manager.md +++ b/docs/briefs/pure-bootstrap-zero-manager.md @@ -138,26 +138,42 @@ declares workflow including N=0 resolution). are fill queues operating in parallel; any available worker picks top-priority unblocked work. -**Pre-promotion phase (Day-1 dispatch):** +**Pre-promotion phase (Day-1 dispatch).** Cascade promotion requires +**four** pre-promotion items per +[`design-pure-bootstrap-zero.md`](../design-pure-bootstrap-zero.md) +"Pre-promotion deliverables" + "What gate" sections: -- **Pre-promotion deliverable 1: 35-file audit table.** Author the - file-by-file mapping (file → why-currently-hand-authored → +- **Deliverable 1: 35-file audit table.** Author the file-by-file + mapping (file → why-currently-hand-authored → migration-path-into-PB-lane) inline for the cascade promotion PR. Director already authored a starting categorization in conversation with PM; this manager refines and authorities it. -- **Pre-promotion deliverable 2: PB-1 brief amendment.** Amend +- **Deliverable 2: PB-1 brief amendment.** Amend [`pb-1-data-driven-bootstrap.md`](pb-1-data-driven-bootstrap.md) non-goals to align with 0-floor (currently they explicitly reject deletion of tokenize/parse/lower/infer/emit and reject binary-blob format; under 0-floor those non-goals invert as scope absorbed into PB-* program lanes). -- **Pre-promotion deliverable 3: first prototyped lane closure.** - Pick one PB-* lane and execute it end-to-end (e.g., PB-Substrate - pilot or PB-1-a continuation) to prove the migration pattern - before the cascade promotion PR locks the framing. - -These three are this manager's first work; they gate cascade -promotion. +- **Deliverable 3: TESTING.md "Post-R2 shape" rewrite.** Per + design doc Promotion mechanism — TESTING.md residual carve-outs + (compiler-internal unit tests for Rust-only helpers; external- + toolchain boundary tests) dissolve under 0-floor. **Authoring + ownership = Director-call at promotion time** per design doc: + bundle into cascade PR, or sibling PR landed first. This manager + surfaces the readiness signal (when PB-Runtime and ExecuteCommand- + based TestClaim migration work is sufficient evidence to author + the rewrite); Director picks bundle-vs-sibling and either authors + or directs authoring. +- **Gate item 4: first prototyped lane closure.** Per design doc + Promotion mechanism's "What gate" — cascade PR includes at least + one prototyped lane closure proving an existing hand-Rust file + can be retired via `.dag` migration without regression. This + manager picks the lane (e.g., PB-Substrate pilot or PB-1-a + continuation) and executes end-to-end before the cascade locks + the framing. + +Items 1, 2, 4 are this manager's authoring; item 3's authoring is +Director-call. All four gate cascade promotion. **Post-promotion phase (parallel-capable):** @@ -242,12 +258,12 @@ promotes; then transitions here. ### Up to director -- **Cascade promotion PR.** This manager prepares the three pre- - promotion deliverables (audit table + PB-1 brief amendment + - first prototyped lane closure); Director authors the cascade PR - per the design doc's Promotion mechanism. Atomic across multiple - authority docs; Director's call on bundling vs sibling for - TESTING.md rewrite. +- **Cascade promotion PR.** This manager prepares three of the + four pre-promotion items (audit table + PB-1 brief amendment + + first prototyped lane closure); the fourth (TESTING.md rewrite) + is Director-call on authoring per design doc Promotion mechanism. + Director authors the cascade PR itself (atomic across multiple + authority docs) using the manager's deliverables as inputs. - **Release-ledger placement.** Whether the program lands as R2 absorption / separately-named program / under Director closure is a Director call at promotion time per the design doc. @@ -266,11 +282,16 @@ Lane-owner dispatch status (update as sub-deliverables close). Section populates on cascade promotion + first dispatches; entries below are scaffolding. -**Pre-promotion deliverables (gates the cascade promotion PR):** +**Pre-promotion items (all four gate the cascade promotion PR):** - [ ] 35-file audit table authored (file → why-current-hand-authored - → migration-path-into-PB-lane). Inline in cascade PR. + → migration-path-into-PB-lane). Inline in cascade PR. **Owner:** this manager. - [ ] PB-1 brief amendment ([`pb-1-data-driven-bootstrap.md`](pb-1-data-driven-bootstrap.md)) - non-goals revised to align with 0-floor. Amends in cascade PR. + non-goals revised to align with 0-floor. Amends in cascade PR. **Owner:** this manager. +- [ ] TESTING.md "Post-R2 shape" rewrite (residual carve-outs dissolve). + **Owner: Director-call** at promotion time per design doc — bundle into + cascade PR or sibling PR landed first; this manager surfaces the + readiness signal when PB-Runtime + ExecuteCommand-based TestClaim + migration is sufficient evidence to author the rewrite. - [ ] First prototyped lane closure (PB-Substrate pilot or PB-1-a continuation) proving migration pattern works. Cited in cascade PR. From d42e6a362b7b34451fde0c4e71d5d323584f8631 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 22:59:23 -0400 Subject: [PATCH 21/52] WIP: gunbc Director --- docs/briefs/extdeps-loader-close-worker.md | 93 ++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 docs/briefs/extdeps-loader-close-worker.md diff --git a/docs/briefs/extdeps-loader-close-worker.md b/docs/briefs/extdeps-loader-close-worker.md new file mode 100644 index 00000000000..5506c80292c --- /dev/null +++ b/docs/briefs/extdeps-loader-close-worker.md @@ -0,0 +1,93 @@ +# extdeps Loader-Close — Worker Brief `(S, substrate-capability unblock)` + +> **Director ad-hoc dispatch.** Cross-program substrate-capability work +> unblocking R2 Grounding's Engine-Phase-1 sharpened-(b) re-dispatch +> (per [Engine-Phase-1 audit escalation, PR #768](https://github.com/gunb-ai/gunbc/pull/768)). +> Reports back to Director (`zesty-bear-812`); not under a standing +> manager. Cross-program coordination heads-up sent to Grounding Manager +> (`crisp-seal-366`) and Zero-Floor Manager (`stern-swift-335`) at +> dispatch. + +## Read first + +- **[`docs/briefs/t-ground-engine-substrate-audit.md`](t-ground-engine-substrate-audit.md)** — the audit that surfaced this gap. Cites `bootstrap.rs:14-19` as the framing decision being revisited. +- **[`src/v3/compiler/src/bootstrap.rs`](../../src/v3/compiler/src/bootstrap.rs)** — current bootstrap; `Dag::new()` loads four authority sets (`std_fixtures`, `STAGED_FILES`, `V3_SPECS`, `COMPILER_FILES`). Header comment at `:14-19`: *"Production bootstrap does not inject target-language realizations."* That comment is being revisited in this PR. +- **[`dsl/extdeps/languages/rust/primitives.dag`](../../dsl/extdeps/languages/rust/primitives.dag)** — the file that must become loadable. Contains `rust_pilot_primitives: List` declarations (`RustPrimitive` is sum type partitioned into `IntegerPrimitive | NonIntegerPrimitive` per pilot brief / codex P2 adjudication on PR #765). +- **[`src/v3/compiler/build.rs`](../../src/v3/compiler/build.rs)** — generated-snapshot pattern (`extdeps_generated`, `gunbc_generated`, etc.). Reference for adding a new fixture-set entry. +- **[`docs/briefs/pb-1-data-driven-bootstrap.md`](pb-1-data-driven-bootstrap.md)** — sibling program; non-goals revised under 0-floor (PR #770). Worth knowing PB-1 will eventually absorb extdeps as a fifth fixture-set extension after the loader-close lands. +- **[`MODELING.md`](../../MODELING.md)** + **[`INVARIANTS.md`](../../INVARIANTS.md)** + **[`CODING.md`](../../CODING.md)** — same governing rules. + +## Frame + +The Engine-Phase-1 audit found that `dsl/extdeps/languages/rust/primitives.dag` is not in any bootstrap fixture set. Engine cannot consume `rust_pilot_primitives` symbolically without a public accessor. Without this loader-close, Engine collapses to mirroring (forbidden per its brief), and the Engine-Phase-1 implementation stays parked. + +This work is the **smallest unblocking step** (Route 1 per Director routing decision). Sharpened-(b) Engine — sibling crate consuming `.dag` declarations symbolically — becomes possible after this lands. Route 2 (full bundling of loader + list-body emission + heterogeneous-variant match) is not in scope here; this lane is loader-close only. + +## Five consumer-side requirements (bake in upfront) + +Per Grounding Manager's escalation doc §"Manager-side input for the loader-close brief", these must all be satisfied: + +1. **Public accessor returns parsed `Declaration` walkable structurally.** Engine consumes `rust_pilot_primitives` as a `Declaration`-shaped value with structural walk semantics (matching how other bootstrap-loaded declarations are consumed). Not a string; not a private internal handle. +2. **Stable shape Engine doesn't reach into private `Dag` internals.** The accessor must be a public API surface; consuming Engine code must not need `pub(crate)` or unsafe reach-throughs to walk the loaded data. +3. **Stale `bootstrap.rs:14-19` comment revisited in same PR.** That comment asserts production bootstrap doesn't load target-language realizations. This PR contradicts that assertion; the comment must be updated to reflect the new state (which realizations load, why, and what the boundary is now). Don't leave contradictory documentation. +4. **SG-0 stance picked and documented.** This work touches `bootstrap.rs` (SG-0-ratcheted hand-Rust). Two acceptable framings, document the choice in PR body: + - **Ratchet bump:** small directly-justified increment to the SG-0 census (load-bearing thesis claim + Director-sanctioned). + - **Transitional shape:** the loader logic lands in a form PB-1 absorbs cleanly when PB-1's data-bootstrap of std_fixtures / STAGED_FILES extends to include extdeps as a fifth set. Pick this if the loader can be authored to fit PB-1's emerging pattern. +5. **Coverage scope explicitly bounded.** Just `dsl/extdeps/languages/rust/primitives.dag` for this PR (smallest unblock for Engine-Phase-1)? Or all `dsl/extdeps/languages/*/*.dag` (covers Python/Go targets too, which Grounding's full-reference lanes will eventually need)? Pick + document. Smaller (rust only) is fine if it cleanly extends; larger (all extdeps languages) is fine if the loader pattern naturally generalizes. + +## Slice — extdeps loader close + +**Goal:** make `dsl/extdeps/languages/rust/primitives.dag` (at minimum; per req 5, optionally other extdeps language files) loadable into the bootstrapped Dag with a public accessor that downstream consumers can walk structurally. + +**Round-trip:** + +1. Add the file(s) per req 5 to a bootstrap fixture set. Could be a new fifth set (`EXTDEPS_LANGUAGE_FILES` or similar), or an extension of an existing set if cleaner. Worker's call. +2. Implement public accessor (req 1, req 2). Naming convention should match existing accessors in `Dag` API surface; consult `bootstrap.rs` and `lib.rs` for prior art. +3. Update `bootstrap.rs:14-19` comment per req 3. +4. Write integration test asserting: + - `Dag::new()` loads `rust_pilot_primitives` without error + - Public accessor returns a `Declaration`-shaped value with the correct identity + - Walking the value structurally (e.g., enumerating list items) returns the expected count of `RustPrimitive` entries + +## Acceptance + +- [ ] All 5 consumer-side requirements satisfied + documented in PR body. +- [ ] `dsl/extdeps/languages/rust/primitives.dag` loadable into bootstrap (per req 5 scope). +- [ ] Public accessor for `rust_pilot_primitives` exists; Engine sharpened-(b) consumer-shape assertion holds (Engine team verifies post-merge). +- [ ] `bootstrap.rs:14-19` comment updated to reflect new boundary (req 3). +- [ ] SG-0 stance documented in PR body (req 4). +- [ ] Integration test passes: `Dag::new()` loads + accessor returns walkable structure. +- [ ] `cargo test --workspace --exclude v2-compiler-tests` passes. +- [ ] `cargo clippy --all-targets -- -D warnings` clean. +- [ ] `cargo fmt --all --check` clean (pre-push hook will enforce). +- [ ] DB-8 `self_host_fixed_point` still converges bit-identically (the no-compromise gate). + +## STOP-AND-ESCALATE + +Surface to Director (`zesty-bear-812`); do not absorb scope. + +- **If the SG-0 stance choice (req 4) reveals the loader logic genuinely cannot fit PB-1's emerging pattern** (i.e., transitional-shape isn't viable, ratchet-bump is the only path) — STOP. Director needs to confirm ratchet bump explicitly before the PR commits to it. +- **If req 5's coverage scope (rust-only vs all extdeps languages) reveals divergent loader patterns per language** (e.g., rust loads cleanly but python/go need extension extension) — STOP. Surface the divergence; pick rust-only and re-dispatch other languages per their needs. +- **If the public accessor shape (req 1, req 2) requires extending `Dag` API surface beyond what existing accessors do** — STOP. Surface the extension proposal; Director coordinates with Zero-Floor Manager on whether the extension belongs in PB-Substrate scope. +- **If `bootstrap.rs:14-19` comment update (req 3) reveals the framing change has cross-doc implications** (e.g., other authority docs assert "no target-language realizations in bootstrap") — STOP. Surface the cross-doc consistency check; Director routes to docs-cascade if needed. +- **If DB-8 fixed-point drifts** — STOP immediately. Same no-compromise gate as PB-1. + +## Non-goals + +- **Not implementing Engine-Phase-1.** Engine re-dispatches against sharpened-(b) after this loader closes; that's separate work owned by R2 Grounding Manager. +- **Not extending PB-1's pattern to extdeps as a fifth set.** PB-1 absorbs extdeps post-this-loader (per non-goal-inversion in PR #770); not this PR's job. +- **Not authoring the bootstrap.dag workflow.** That's PB-Bootstrap-Process scope under Zero-Floor Manager. +- **Not migrating other extdeps consumers** (build.rs, gunbc_generated, etc.). Loader-close is the smallest unblock; broader migration is downstream. +- **Not generating Rust source from the loaded `.dag` declarations.** That's a separate emit-pipeline concern. + +## Reporting + +- Single PR. Title pattern: `feat(v3): extdeps loader close — make rust/primitives.dag loadable into bootstrap (unblocks Engine-Phase-1 sharpened-(b))`. +- PR description cites this brief + addresses each of the 5 consumer requirements explicitly + documents SG-0 stance choice. +- On merge: signal Director (`zesty-bear-812`); Director signals Grounding Manager to re-dispatch Engine-Phase-1 against sharpened-(b). +- On STOP-AND-ESCALATE: surface to Director; Director resolves before resuming. + +## Cross-manager note + +- **Grounding Manager (`crisp-seal-366`)**: heads-up'd at dispatch. Engine-Phase-1 re-dispatch waits on this loader-close PR landing. Re-dispatch shape: sharpened-(b) sibling crate consuming `rust_pilot_primitives` symbolically via the public accessor this PR introduces. +- **Zero-Floor Manager (`stern-swift-335`)**: heads-up'd at dispatch. PB-1's eventual extension to cover extdeps as a fifth fixture set is downstream of this loader; no current conflict on `dag.rs` shape (this PR doesn't touch substrate types). If req 4's SG-0 stance picks ratchet-bump, Zero-Floor knows the bump is justified by Engine-Phase-1's load-bearing dependency. From 02d32e914c28761b1ac33aa10ab4f55ac35f0f6e Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 23:03:52 -0400 Subject: [PATCH 22/52] WIP: gunbc Director --- docs/briefs/extdeps-loader-close-worker.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/briefs/extdeps-loader-close-worker.md b/docs/briefs/extdeps-loader-close-worker.md index 5506c80292c..70fa4717811 100644 --- a/docs/briefs/extdeps-loader-close-worker.md +++ b/docs/briefs/extdeps-loader-close-worker.md @@ -30,9 +30,7 @@ Per Grounding Manager's escalation doc §"Manager-side input for the loader-clos 1. **Public accessor returns parsed `Declaration` walkable structurally.** Engine consumes `rust_pilot_primitives` as a `Declaration`-shaped value with structural walk semantics (matching how other bootstrap-loaded declarations are consumed). Not a string; not a private internal handle. 2. **Stable shape Engine doesn't reach into private `Dag` internals.** The accessor must be a public API surface; consuming Engine code must not need `pub(crate)` or unsafe reach-throughs to walk the loaded data. 3. **Stale `bootstrap.rs:14-19` comment revisited in same PR.** That comment asserts production bootstrap doesn't load target-language realizations. This PR contradicts that assertion; the comment must be updated to reflect the new state (which realizations load, why, and what the boundary is now). Don't leave contradictory documentation. -4. **SG-0 stance picked and documented.** This work touches `bootstrap.rs` (SG-0-ratcheted hand-Rust). Two acceptable framings, document the choice in PR body: - - **Ratchet bump:** small directly-justified increment to the SG-0 census (load-bearing thesis claim + Director-sanctioned). - - **Transitional shape:** the loader logic lands in a form PB-1 absorbs cleanly when PB-1's data-bootstrap of std_fixtures / STAGED_FILES extends to include extdeps as a fifth set. Pick this if the loader can be authored to fit PB-1's emerging pattern. +4. **SG-0 stance: transitional shape (default) or ratchet-bump escalation.** This work touches `bootstrap.rs` (SG-0-ratcheted hand-Rust). The **default-and-expected framing is transitional shape**: loader logic lands in a form PB-1 absorbs cleanly when PB-1's data-bootstrap of std_fixtures / STAGED_FILES extends to include extdeps as a fifth set. Document the chosen transitional shape in the PR body. **Ratchet bump is a STOP-AND-ESCALATE outcome**, not a routine choice — if the worker concludes transitional shape is genuinely not viable (the loader cannot fit PB-1's emerging pattern), surface to Director per STOP-AND-ESCALATE rules. Per the locked `feedback_ratchet_only_down.md` invariant, ratchet-bump is an exception requiring explicit Director confirmation, not author discretion. 5. **Coverage scope explicitly bounded.** Just `dsl/extdeps/languages/rust/primitives.dag` for this PR (smallest unblock for Engine-Phase-1)? Or all `dsl/extdeps/languages/*/*.dag` (covers Python/Go targets too, which Grounding's full-reference lanes will eventually need)? Pick + document. Smaller (rust only) is fine if it cleanly extends; larger (all extdeps languages) is fine if the loader pattern naturally generalizes. ## Slice — extdeps loader close From 715cb4963e3a3483cded9bc4396408e19a4633c8 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 23:18:52 -0400 Subject: [PATCH 23/52] WIP: gunbc Director --- docs/briefs/extdeps-loader-close-worker.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/briefs/extdeps-loader-close-worker.md b/docs/briefs/extdeps-loader-close-worker.md index 70fa4717811..8ff4b7fb8cf 100644 --- a/docs/briefs/extdeps-loader-close-worker.md +++ b/docs/briefs/extdeps-loader-close-worker.md @@ -10,7 +10,7 @@ ## Read first -- **[`docs/briefs/t-ground-engine-substrate-audit.md`](t-ground-engine-substrate-audit.md)** — the audit that surfaced this gap. Cites `bootstrap.rs:14-19` as the framing decision being revisited. +- **[`docs/briefs/t-ground-engine-substrate-audit.md`](t-ground-engine-substrate-audit.md)** — the audit that surfaced this gap. Cites `bootstrap.rs:16-19` as the framing decision being revisited. - **[`src/v3/compiler/src/bootstrap.rs`](../../src/v3/compiler/src/bootstrap.rs)** — current bootstrap; `Dag::new()` loads four authority sets (`std_fixtures`, `STAGED_FILES`, `V3_SPECS`, `COMPILER_FILES`). Header comment at `:14-19`: *"Production bootstrap does not inject target-language realizations."* That comment is being revisited in this PR. - **[`dsl/extdeps/languages/rust/primitives.dag`](../../dsl/extdeps/languages/rust/primitives.dag)** — the file that must become loadable. Contains `rust_pilot_primitives: List` declarations (`RustPrimitive` is sum type partitioned into `IntegerPrimitive | NonIntegerPrimitive` per pilot brief / codex P2 adjudication on PR #765). - **[`src/v3/compiler/build.rs`](../../src/v3/compiler/build.rs)** — generated-snapshot pattern (`extdeps_generated`, `gunbc_generated`, etc.). Reference for adding a new fixture-set entry. @@ -29,8 +29,8 @@ Per Grounding Manager's escalation doc §"Manager-side input for the loader-clos 1. **Public accessor returns parsed `Declaration` walkable structurally.** Engine consumes `rust_pilot_primitives` as a `Declaration`-shaped value with structural walk semantics (matching how other bootstrap-loaded declarations are consumed). Not a string; not a private internal handle. 2. **Stable shape Engine doesn't reach into private `Dag` internals.** The accessor must be a public API surface; consuming Engine code must not need `pub(crate)` or unsafe reach-throughs to walk the loaded data. -3. **Stale `bootstrap.rs:14-19` comment revisited in same PR.** That comment asserts production bootstrap doesn't load target-language realizations. This PR contradicts that assertion; the comment must be updated to reflect the new state (which realizations load, why, and what the boundary is now). Don't leave contradictory documentation. -4. **SG-0 stance: transitional shape (default) or ratchet-bump escalation.** This work touches `bootstrap.rs` (SG-0-ratcheted hand-Rust). The **default-and-expected framing is transitional shape**: loader logic lands in a form PB-1 absorbs cleanly when PB-1's data-bootstrap of std_fixtures / STAGED_FILES extends to include extdeps as a fifth set. Document the chosen transitional shape in the PR body. **Ratchet bump is a STOP-AND-ESCALATE outcome**, not a routine choice — if the worker concludes transitional shape is genuinely not viable (the loader cannot fit PB-1's emerging pattern), surface to Director per STOP-AND-ESCALATE rules. Per the locked `feedback_ratchet_only_down.md` invariant, ratchet-bump is an exception requiring explicit Director confirmation, not author discretion. +3. **Stale `bootstrap.rs:16-19` comment revisited in same PR.** That comment asserts production bootstrap doesn't load target-language realizations. This PR contradicts that assertion; the comment must be updated to reflect the new state (which realizations load, why, and what the boundary is now). Don't leave contradictory documentation. +4. **SG-0 stance: transitional shape (default) or ratchet-bump escalation.** This work touches `bootstrap.rs` (SG-0-ratcheted hand-Rust). The **default-and-expected framing is transitional shape**: loader logic lands as a thin scaffold whose dissolution trigger is the **PB-Bootstrap-Process lane** (Zero-Floor program). When PB-Bootstrap-Process lands `bootstrap.dag` declaring the workflow as data, `bootstrap.rs` becomes a generated trampoline (or vanishes); the loader-close logic added here becomes part of the to-be-generated content at that point. PB-Bootstrap-Process is **already tracked** in `docs/design-pure-bootstrap-zero.md` §"New lanes" + Zero-Floor Manager brief working state — the dissolution trigger is concrete, not aspirational. Document the chosen transitional shape in the PR body, citing PB-Bootstrap-Process as the dissolution authority. **Ratchet bump is a STOP-AND-ESCALATE outcome**, not a routine choice — if the worker concludes transitional shape is genuinely not viable (the loader cannot fit a shape PB-Bootstrap-Process can absorb), surface to Director per STOP-AND-ESCALATE rules. Per the locked discipline (ratchet only goes down; if a fix needs a new violation, the violation belongs deeper; scaffolds dissolve into first-class structure with named dissolution triggers — see `INVARIANTS.md` and `docs/design-pure-bootstrap.md` for the canonical statements), ratchet-bump is an exception requiring explicit Director confirmation + tracked dissolution trigger, not author discretion. 5. **Coverage scope explicitly bounded.** Just `dsl/extdeps/languages/rust/primitives.dag` for this PR (smallest unblock for Engine-Phase-1)? Or all `dsl/extdeps/languages/*/*.dag` (covers Python/Go targets too, which Grounding's full-reference lanes will eventually need)? Pick + document. Smaller (rust only) is fine if it cleanly extends; larger (all extdeps languages) is fine if the loader pattern naturally generalizes. ## Slice — extdeps loader close @@ -41,7 +41,7 @@ Per Grounding Manager's escalation doc §"Manager-side input for the loader-clos 1. Add the file(s) per req 5 to a bootstrap fixture set. Could be a new fifth set (`EXTDEPS_LANGUAGE_FILES` or similar), or an extension of an existing set if cleaner. Worker's call. 2. Implement public accessor (req 1, req 2). Naming convention should match existing accessors in `Dag` API surface; consult `bootstrap.rs` and `lib.rs` for prior art. -3. Update `bootstrap.rs:14-19` comment per req 3. +3. Update `bootstrap.rs:16-19` comment per req 3. 4. Write integration test asserting: - `Dag::new()` loads `rust_pilot_primitives` without error - Public accessor returns a `Declaration`-shaped value with the correct identity @@ -52,7 +52,7 @@ Per Grounding Manager's escalation doc §"Manager-side input for the loader-clos - [ ] All 5 consumer-side requirements satisfied + documented in PR body. - [ ] `dsl/extdeps/languages/rust/primitives.dag` loadable into bootstrap (per req 5 scope). - [ ] Public accessor for `rust_pilot_primitives` exists; Engine sharpened-(b) consumer-shape assertion holds (Engine team verifies post-merge). -- [ ] `bootstrap.rs:14-19` comment updated to reflect new boundary (req 3). +- [ ] `bootstrap.rs:16-19` comment updated to reflect new boundary (req 3). - [ ] SG-0 stance documented in PR body (req 4). - [ ] Integration test passes: `Dag::new()` loads + accessor returns walkable structure. - [ ] `cargo test --workspace --exclude v2-compiler-tests` passes. @@ -67,7 +67,7 @@ Surface to Director (`zesty-bear-812`); do not absorb scope. - **If the SG-0 stance choice (req 4) reveals the loader logic genuinely cannot fit PB-1's emerging pattern** (i.e., transitional-shape isn't viable, ratchet-bump is the only path) — STOP. Director needs to confirm ratchet bump explicitly before the PR commits to it. - **If req 5's coverage scope (rust-only vs all extdeps languages) reveals divergent loader patterns per language** (e.g., rust loads cleanly but python/go need extension extension) — STOP. Surface the divergence; pick rust-only and re-dispatch other languages per their needs. - **If the public accessor shape (req 1, req 2) requires extending `Dag` API surface beyond what existing accessors do** — STOP. Surface the extension proposal; Director coordinates with Zero-Floor Manager on whether the extension belongs in PB-Substrate scope. -- **If `bootstrap.rs:14-19` comment update (req 3) reveals the framing change has cross-doc implications** (e.g., other authority docs assert "no target-language realizations in bootstrap") — STOP. Surface the cross-doc consistency check; Director routes to docs-cascade if needed. +- **If `bootstrap.rs:16-19` comment update (req 3) reveals the framing change has cross-doc implications** (e.g., other authority docs assert "no target-language realizations in bootstrap") — STOP. Surface the cross-doc consistency check; Director routes to docs-cascade if needed. - **If DB-8 fixed-point drifts** — STOP immediately. Same no-compromise gate as PB-1. ## Non-goals From dc5835e2783595133f22282eddb11ba31ae58647 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 23:26:22 -0400 Subject: [PATCH 24/52] WIP: gunbc Director --- docs/r2-structure.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/r2-structure.md b/docs/r2-structure.md index 6dc7ae7fff1..1a45c815997 100644 --- a/docs/r2-structure.md +++ b/docs/r2-structure.md @@ -41,7 +41,12 @@ Under that discipline, R2's goals are the Tier-1 thesis claims that are *not* ga - **Cardinality-substrate subset sufficient to close int-literal magnitude refinement** — enough cardinality modeling to let `IntLit` carry a magnitude that narrows to target int algebra at reconciliation. Consumer: T-Modeling int-lit (Goal 2). Does NOT commit to the full cardinality-substrate capability (fixed-width-types by-construction, container cardinality bounds in Grounding, etc. — those remain open design calls outside R2 scope unless additional R2 items demand them). - **Nominal-opaque substrate sufficient to graduate `Secret`** — enough nominal-type modeling to carry construction-restriction (`where only X may construct`) semantics. Consumer: T-Modeling Secret (Goal 2). Adjacent to DB-11 alias-RHS `where` (landed in R1 via PR #703); may or may not overlap DB-18 territory. Acceptance is `Secret` graduation, not a general nominal-type program. - **Parametric algebra attachment subset sufficient to inhabit `Dimension` in an abelian group algebra** — enough substrate capability to let `Dimension` carry phantom-parameter arithmetic (propagate through operations, compile error on unit-mismatch). Consumer: T-Modeling Dimensions (Goal 2). Primary authority is `ROADMAP.md §"Post-R1 Program — Grounding Completeness"` (the "Why post-R1" paragraph), which tags this dependency `DB-18 parametric algebra attachment` — but `docs/db-history/db-18.md` currently scopes DB-18 to workflow-effect carrier + Rust reflection (Part 2 shipped) + Go-accessor follow-up (Part 3), not parametric algebra attachment. That mismatch is an existing ROADMAP ↔ db-history inconsistency, not one introduced by this doc; a pre-promotion DB-lane rename or new DB number may be warranted. R2 acceptance is: `Dimension` phantom-parameter arithmetic compiles with unit-mismatch errors, independent of the DB-tag the substrate ends up carrying. - - **Top-level `ValueBody` list/sum subset + `std.unicode` bootstrap inclusion sufficient to close `sub_charclass_in_std_unicode` phase-2** — enough Class 5 Gap 3 substrate capability for `data ascii_scan_order: List = [Whitespace, Digit, IdentStart, IdentContinue]` to lower structurally (rather than fall to `ValueBody::Unparsed` and trigger R14 hard-fail), plus the `Dag::new()` bootstrap/load-set decision that makes `std.unicode::CharClass` resolvable from `tokenize.dag`. Consumer: tokenizer (R1 T-Sub deferred this phase to substrate per Surface Manager handoff 2026-04-24; reclassified to R2 per ROADMAP amendment). Does NOT commit to the full Class 5 Gap 3 substrate-capability close (other top-level `ValueBody` consumers may need additional variants beyond list/sum); scoped to what unblocks the tokenizer charclass row only. + - **Top-level `ValueBody` list/sum subset + `std.unicode` bootstrap inclusion** — enough Class 5 Gap 3 substrate capability for `data ascii_scan_order: List = [Whitespace, Digit, IdentStart, IdentContinue]` (and similar list/sum top-level data declarations) to lower structurally (rather than fall to `ValueBody::Unparsed` and trigger R14 hard-fail), plus the `Dag::new()` bootstrap/load-set decision that makes `std.unicode::CharClass` and other extdeps-language declarations resolvable from compiler authorities. **Three named consumers, all of which the same substrate work unblocks**: + 1. **Tokenizer charclass phase-2** — original consumer per PR #762 reclassification (R1 T-Sub deferred this phase to substrate per Surface Manager handoff 2026-04-24). + 2. **Engine sharpened-(b) full pilot enumeration** — surfaced by R2 Grounding loader-close worker (`clever-owl-123`) probe on PR #776 (`rust_pilot_primitives` lowers as `Declaration` but `value_body` is `Unparsed(SourceSpan)` — same gap). + 3. **`kernel_algebra_profile` mirror dissolution** — existing P2 drift ratchet at `dag.rs:1530`. Same gap (`Map` declared in `dsl/std/algebra.dag` lands as `ValueBody::Unparsed` today). + + Does NOT commit to the full Class 5 Gap 3 substrate-capability close (other top-level `ValueBody` consumers beyond these three may need additional variants); scoped to what unblocks all three named consumers from one substrate work. ROI strictly higher than originally framed (single-consumer scoping); director-amended 2026-04-25 per cross-program convergence finding on PR #776. 4. **Remaining R2+ impossible-bug classes** — three classes currently tagged `[R2+]` in `ROADMAP.md §"Lane acceptance — .dag gates"` (T-Demo row; THESIS §"Enumerable impossible-bug classes" is the authority on scheduling tags): - Nested-optional flatten From 2720ed720df1b1539c0e052a669e2240e3315893 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 23:27:52 -0400 Subject: [PATCH 25/52] WIP: gunbc Director --- docs/r2-structure.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/r2-structure.md b/docs/r2-structure.md index 1a45c815997..4f4d47a2365 100644 --- a/docs/r2-structure.md +++ b/docs/r2-structure.md @@ -83,7 +83,7 @@ Continues `docs/briefs/grounding-manager.md` (refreshed for R2 scope on promotio |---|---|---|---| | T-Ground | XL | Grounding | Full T-Ground-* sub-program (Goal 1) | | T-Modeling | M | Director (ad-hoc) | int-lit / Secret / Dimensions (Goal 2) | -| T-Substrate | M | Director (ad-hoc) | Four scoped-subset sub-lanes (Goal 3): cardinality-for-int-lit; nominal-opaque-for-Secret; parametric-algebra-attachment-for-Dimensions; top-level-ValueBody-list/sum + std.unicode-bootstrap-for-tokenizer-charclass — each scoped to its paired R2 consumer (T-Modeling × 3 + tokenizer × 1), not full substrate-capability | +| T-Substrate | M | Director (ad-hoc) | Four scoped-subset sub-lanes (Goal 3): cardinality-for-int-lit; nominal-opaque-for-Secret; parametric-algebra-attachment-for-Dimensions; top-level-ValueBody-list/sum + std.unicode-bootstrap (3 named consumers: tokenizer charclass phase-2 + Engine sharpened-(b) pilot enumeration + kernel_algebra_profile mirror dissolution — single substrate work unblocks all three) — each sub-lane scoped to its paired R2 consumer set (T-Modeling × 3 + multi-consumer × 1), not full substrate-capability | | T-ImpossibleBugs | S | Director (ad-hoc) | nested-optional flatten / unhandled-diagnostic-paths / unenumerated-effects (Goal 4) | | T-PerMethodMetadata | S | Director (ad-hoc) | §6a per-method-metadata carrier pick (Goal 5) — design-call close, not substrate-capability work | @@ -108,20 +108,24 @@ T-Ground: Pilot → Rust → Engine → Tests → Dissolve (critical p T-Substrate: cardinality-for-int-lit (subset) ──→ unblocks T-Modeling int-lit nominal-opaque-for-Secret (subset) ─→ unblocks T-Modeling Secret parametric-algebra-for-Dimensions (subset) ─→ unblocks T-Modeling Dimensions - ValueBody-list/sum + std.unicode-bootstrap (subset) ─→ unblocks tokenizer charclass phase-2 + ValueBody-list/sum + std.unicode-bootstrap (subset) ─→ unblocks 3 consumers (single substrate work): + (i) tokenizer charclass phase-2 + (ii) Engine sharpened-(b) pilot enumeration + (iii) kernel_algebra_profile mirror dissolution T-Modeling: int-lit ← T-Substrate cardinality-for-int-lit Secret ← T-Substrate nominal-opaque-for-Secret Dimensions ← T-Substrate parametric-algebra-for-Dimensions -Tokenizer charclass phase-2 (consumer of T-Substrate's 4th subset; not a peer lane — - consumed inside T-Substrate scope, deliverable owned by tokenizer code): - retype to Char / List / CharClass ← T-Substrate ValueBody-list/sum + std.unicode-bootstrap +Multi-consumer of T-Substrate's 4th subset (none are peer lanes — all consumed inside T-Substrate scope): + (i) Tokenizer charclass phase-2: retype to Char / List / CharClass + (ii) Engine sharpened-(b): full pilot enumeration via symbolic walk of rust_pilot_primitives + (iii) kernel_algebra_profile: retire dag.rs:1530 hand-Rust mirror T-ImpossibleBugs: 3 independent classes (any worker) T-PerMethodMetadata: §6a pick (any worker; independent) (Goal 6 demo artifacts ship with each lane's closure PR — not a separate dependency-DAG node; see Demo discipline section.) ``` -Parallel-capable work at any time: Grounding has 2 fill slots (Python, Go) alongside its critical path; Director dispatch has 4 T-Substrate sub-lanes (3 T-Modeling unblocks + 1 tokenizer-charclass unblock) + 3 T-Modeling items (each pair-blocked) + 1 tokenizer-charclass deliverable (pair-blocked on the 4th T-Substrate sub-lane) + 3 T-ImpossibleBugs classes + 1 T-PerMethodMetadata pick, for roughly 8–12 slots depending on T-Substrate unblock timing. +Parallel-capable work at any time: Grounding has 2 fill slots (Python, Go) alongside its critical path; Director dispatch has 4 T-Substrate sub-lanes (3 T-Modeling unblocks + 1 multi-consumer unblock covering 3 consumers) + 3 T-Modeling items (each pair-blocked) + 3 deliverables pair-blocked on the 4th T-Substrate sub-lane (tokenizer charclass, Engine sharpened-(b), kernel_algebra_profile mirror dissolution) + 3 T-ImpossibleBugs classes + 1 T-PerMethodMetadata pick, for roughly 10–14 slots depending on T-Substrate unblock timing. ## R1 closure criteria From d4f97312ee7ddf098ef95c51d8cd2b237273c09c Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 23:33:52 -0400 Subject: [PATCH 26/52] WIP: gunbc Director --- ROADMAP.md | 4 ++-- TESTING.md | 24 ++++++++++-------------- docs/design-pure-bootstrap.md | 16 +++++++--------- docs/r2-structure.md | 4 ++-- 4 files changed, 21 insertions(+), 27 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index d990b775971..71ef3e43199 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -50,8 +50,8 @@ Each lane owns one concrete `.dag` gate. Lane owners do the comprehensive decomp | T-LaneE | XL | Complexity lens v2 parity via substrate-carrier-port | Existing Lane E-T/C/I/P/M program | | T-TestGen | L | Testgen runner, service simulation, first-class TestClaim | DB-15 follow-up | | T-LensAPI | M-L | User-authored lenses + composition | Lens capability honesty pass | -| T-PB-A | XL | Compiler self-emits (fixed-point); **non-test** hand-Rust surface reaches the ≤5 irreducible-shim floor (per `docs/design-pure-bootstrap.md`; generated escape hatch OK). Live baseline is the non-test subset of the SG-0 census (`EXPECTED_HAND_AUTHORED_NON_TEST` file-level + `EXPECTED_HAND_AUTHORED_FRAGMENTS` crate-root scaffolds) in `src/v3/compiler/tests/integration/sg0_census_test.rs` — this doc does not freeze the count. **Lens-producer files are the priority slice within this census** (concrete examples: `per_call_descent_evidence` at `src/v3/compiler/src/dag.rs`; the cost / complexity / descent-evidence producer family around the E-family port). Retiring a lens-producer `.rs` dissolves "lens purity by reviewer-convention" into "lens purity by construction" via the closed-world `.dag` kernel — the bounded kernel admits no hidden computation in a lens body, so `.dag`-authored lens producers are pure-total-projections by construction rather than by audit. That purity is what makes lens sustainability structural rather than carried by reviewer memory. Tracked as the `lens_producer_files_remaining` gate below. The **test subset** (`EXPECTED_HAND_AUTHORED_TEST`) of the same census is T-PB-B's responsibility, not T-PB-A's. | Compiler–std consolidation program, SG-0 census | -| T-PB-B | M | Tests-as-data — pipeline/contract tests port to `.dag`. The two `TESTING.md §Post-R2 shape` residual categories (compiler-internal unit tests for Rust-only helpers; external-toolchain boundary tests invoking rustc/go/python) remain Rust-authored. | DB-15 + T-TestGen | +| T-PB-A | XL | Compiler self-emits (fixed-point); **non-test** hand-Rust surface reaches **0** (per `docs/design-pure-bootstrap-zero.md` LIVE 2026-04-25; supersedes the prior ≤5-floor + 2-3-principled-floor framings in `docs/design-pure-bootstrap.md` + PR #756, both retracted in the cascade promotion PR). Generated escape hatch OK. Live baseline is the non-test subset of the SG-0 census (`EXPECTED_HAND_AUTHORED_NON_TEST` file-level + `EXPECTED_HAND_AUTHORED_FRAGMENTS` crate-root scaffolds) in `src/v3/compiler/tests/integration/sg0_census_test.rs` — this doc does not freeze the count. **Lens-producer files are the priority slice within this census** (concrete examples: `per_call_descent_evidence` at `src/v3/compiler/src/dag.rs`; the cost / complexity / descent-evidence producer family around the E-family port). Retiring a lens-producer `.rs` dissolves "lens purity by reviewer-convention" into "lens purity by construction" via the closed-world `.dag` kernel — the bounded kernel admits no hidden computation in a lens body, so `.dag`-authored lens producers are pure-total-projections by construction rather than by audit. That purity is what makes lens sustainability structural rather than carried by reviewer memory. Tracked as the `lens_producer_files_remaining` gate below. The **test subset** (`EXPECTED_HAND_AUTHORED_TEST`) of the same census is T-PB-B's responsibility, not T-PB-A's. | Compiler–std consolidation program, SG-0 census | +| T-PB-B | M | Tests-as-data — pipeline/contract tests port to `.dag`. ~~The two `TESTING.md §Post-R2 shape` residual categories (compiler-internal unit tests for Rust-only helpers; external-toolchain boundary tests invoking rustc/go/python) remain Rust-authored.~~ **Retracted via cascade promotion 2026-04-25**: the residual carve-out dissolves under the 0-floor framing — Rust-only-helper unit tests vanish naturally (no Rust-only helpers under 0-floor); external-toolchain boundary tests migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations (predicate landed in PR #678, runner support in #688/#741). See `TESTING.md` for the 0-residual framing. | DB-15 + T-TestGen | | T-Demo | M | Two canonical fixtures + impossible-bugs suite + narrative | — (new) | ### Lane acceptance — `.dag` gates diff --git a/TESTING.md b/TESTING.md index a35a32d0ff9..31cde0e9f3c 100644 --- a/TESTING.md +++ b/TESTING.md @@ -187,26 +187,22 @@ predicate structurally. At that point the hermetic principle still holds — each `TestClaim` declaration is its own unit, the runtime just -shares the compile work when sources match. Rust integration -tests collapse to two residual categories: +shares the compile work when sources match. -- **Compiler-internal unit tests** inside `src/v3/compiler/src/` - (`#[cfg(test)] mod tests`) for Rust-only helpers -- **Boundary tests** that must invoke external processes - (rustc, go, python) - -Everything else ports to `.dag`. +> **🔄 RETRACTED 2026-04-25 (cascade promotion of `docs/design-pure-bootstrap-zero.md`).** The previous "two residual categories" framing (compiler-internal unit tests + external-toolchain boundary tests stay Rust-authored permanently) is **retracted under the 0-floor target**. Both categories dissolve: +> +> - **Rust-only-helper unit tests vanish naturally** — under 0-floor (per `docs/design-pure-bootstrap-zero.md` LIVE), there are no Rust-only helpers in v3's source tree; everything generates from `.dag`. Unit tests for non-existent helpers don't need to exist. +> - **External-toolchain boundary tests migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations.** The `ExecuteCommand` predicate landed in PR #678; runner support landed in #688/#741. A `TestClaim` like *"emit Rust, invoke rustc on output, check exit code"* is structurally identical to today's hand-Rust boundary tests, expressed as data. +> +> **0-residual is the target.** Until v3's source tree reaches 0 hand-authored files, write tests in whichever shape (Rust integration test OR `.dag` `TestClaim`) is cleanest for the work being done; on cascade-promoted PB-Runtime lane execution, residual Rust tests migrate per the `ExecuteCommand` pattern. See `docs/design-pure-bootstrap-zero.md` §"PB-Runtime" for the migration scope. Until DB-15 R2's runtime lands, write Rust integration tests that match the guidelines above so the eventual port is a rewrite of shape, not of intent. -**Post-R2 shape:** once DB-15 R2 ships, most of this document -collapses into "see `dsl/std/verification.dag` for the test -surface." The Rust-side residual is: compiler-internal unit -tests (`#[cfg(test)] mod tests`) inside `src/v3/compiler/src/`, -and boundary tests that invoke external toolchains. Everything -else ports to `.dag`. +~~**Post-R2 shape:** once DB-15 R2 ships, most of this document collapses into "see `dsl/std/verification.dag` for the test surface." The Rust-side residual is: compiler-internal unit tests (`#[cfg(test)] mod tests`) inside `src/v3/compiler/src/`, and boundary tests that invoke external toolchains. Everything else ports to `.dag`.~~ + +**0-floor shape (post cascade promotion 2026-04-25):** once DB-15 R2 ships AND the Zero-Floor program reaches 0 hand-authored files (per `docs/design-pure-bootstrap-zero.md` LIVE), this document collapses into "see `dsl/std/verification.dag` for the test surface." There is **no Rust-side residual**: compiler-internal unit tests don't exist (no Rust-only helpers); external-toolchain tests use `ExecuteCommand`-based `.dag` `TestClaim` declarations. Everything is `.dag`. ## Anti-patterns diff --git a/docs/design-pure-bootstrap.md b/docs/design-pure-bootstrap.md index f3eabdc41b0..281ce4f13e0 100644 --- a/docs/design-pure-bootstrap.md +++ b/docs/design-pure-bootstrap.md @@ -1,16 +1,14 @@ # Pure Bootstrap (PB program) +> **🔄 SUPERSEDED 2026-04-25 by [`docs/design-pure-bootstrap-zero.md`](design-pure-bootstrap-zero.md)** (now LIVE per cascade promotion). The ≤5-floor framing throughout this doc is **retracted**. The 2-3 principled-floor framing introduced via [PR #756](https://github.com/gunb-ai/gunbc/pull/756) is also retracted. Both are superseded by the **0-floor target** under the Pure Bootstrap to Zero program. +> +> This doc remains in-tree as historical context for the trajectory that led to the 0-floor framing. Cross-refs migrated to `design-pure-bootstrap-zero.md`. Do not author new work against the ≤5 or 2-3 framings; route new work to the 0-floor program per Zero-Floor Manager brief at [`docs/briefs/pure-bootstrap-zero-manager.md`](briefs/pure-bootstrap-zero-manager.md). + **Thesis claim**: `THESIS.md` §"Self-hosting — three facets" (facet 2: *Compiler self-emits (fixed-point)*) — and the corresponding claim in the `Thesis claims — complete list`. -Editing compiler behavior must be a one-file `.dag` change. No paired -hand edits to a Rust stage0 file. This document is the trajectory from -today (live hand-maintained count per SG-0 census in -`src/v3/compiler/tests/integration/sg0_census_test.rs`) to the -irreducible shim floor. The target ≤5 scopes the **non-test** hand- -authored surface; the `TESTING.md §"Post-R2 shape"` residual (compiler- -internal unit tests + external-toolchain boundary tests) remains -Rust-authored separately per TESTING.md as single authority on that -residual. +~~Editing compiler behavior must be a one-file `.dag` change. No paired hand edits to a Rust stage0 file. This document is the trajectory from today (live hand-maintained count per SG-0 census in `src/v3/compiler/tests/integration/sg0_census_test.rs`) to the irreducible shim floor. The target ≤5 scopes the **non-test** hand-authored surface; the `TESTING.md §"Post-R2 shape"` residual (compiler-internal unit tests + external-toolchain boundary tests) remains Rust-authored separately per TESTING.md as single authority on that residual.~~ + +**Superseded framing.** The above paragraph's ≤5-floor target is retracted. Per `docs/design-pure-bootstrap-zero.md`, the actual target is **0 hand-authored files in v3's source tree**. Substrate generation is already proven and shipping (per the audit doc's evidence base citing 23 `*_generated.rs` files + 24 `REGEN_OUTPUTS` entries); the migration extends the existing pattern to remaining substrate types. TESTING.md "Post-R2 shape" residual carve-out is also retracted in the cascade — see `TESTING.md` for the 0-residual framing. ## Why this matters diff --git a/docs/r2-structure.md b/docs/r2-structure.md index 4f4d47a2365..b74fbc3ca9a 100644 --- a/docs/r2-structure.md +++ b/docs/r2-structure.md @@ -90,8 +90,8 @@ Continues `docs/briefs/grounding-manager.md` (refreshed for R2 scope on promotio **Goal 6 (R2 closure demo) is not a lane.** It is a cross-lane closure discipline (see "Demo discipline" below): each lane's closure PR ships its own simple "it runs" artifact; Director coordinates surfacing. No separate T-Demo lane owner, no separate demo-authoring critical path. **Lanes deliberately absent (R1 gates, closed by R1 lane acceptance):** -- T-LensMigration / `lens_producer_files_remaining` — R1 T-PB-A gate per PR #752. -- T-ShimFloor / `pb_hand_rust_at_shim_floor` / `pb_compiler_std_ratchet_zero` / `pb_rust_tests_outside_residual_zero` — R1 T-PB-A + T-PB-B gates. +- T-LensMigration / `lens_producer_files_remaining` — R1 T-PB-A gate per PR #752. **Cascade-promotion update 2026-04-25:** Pure Bootstrap to Zero program (LIVE per `docs/design-pure-bootstrap-zero.md`) absorbs the lens-producer migration as part of its PB-* lane structure. R1 retains the gate; Zero-Floor program owns the actual file-by-file migration work toward 0-floor. +- ~~T-ShimFloor / `pb_hand_rust_at_shim_floor` / `pb_compiler_std_ratchet_zero` / `pb_rust_tests_outside_residual_zero` — R1 T-PB-A + T-PB-B gates.~~ **Cascade-promotion update 2026-04-25:** Pure Bootstrap to Zero program (LIVE) absorbs all shim-floor work; the gate target shifts from ≤5 to 0 (per ROADMAP T-PB-A row amendment in cascade promotion PR). R1's `pb_hand_rust_at_shim_floor` predicate redirects through the Zero-Floor program's lane structure. - T-EFamilyClose — R1 T-LaneE's critical-path carrier work (E-T, E-C, E-I, E-P, E-M sub-lanes), enabling the R1 `complexity_merge_sort_is_nlogn` + `complexity_merge_sort_v3_matches_v2_oracle` + `lane_e_bundled_witness_host_emit_parity` gates. All E-family carrier-port work closes in R1; only the §6a metadata-pick residual inherits to R2 (Goal 5). - T-TestGen-tail (`testgen_mock_backed_integration_safe` / `MockBackedInvariant` wiring) — R1 T-TestGen gate per `ROADMAP.md §"Lane acceptance — .dag gates"`. Closes in R1. From 0d6e7c33d7552abd8ace47371cd2c0d665848cf9 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 23:39:52 -0400 Subject: [PATCH 27/52] WIP: gunbc Director --- docs/briefs/extdeps-loader-close-worker.md | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/docs/briefs/extdeps-loader-close-worker.md b/docs/briefs/extdeps-loader-close-worker.md index 2ae45e4eb69..8ff4b7fb8cf 100644 --- a/docs/briefs/extdeps-loader-close-worker.md +++ b/docs/briefs/extdeps-loader-close-worker.md @@ -10,11 +10,7 @@ ## Read first -<<<<<<< HEAD - **[`docs/briefs/t-ground-engine-substrate-audit.md`](t-ground-engine-substrate-audit.md)** — the audit that surfaced this gap. Cites `bootstrap.rs:16-19` as the framing decision being revisited. -======= -- **[`docs/briefs/t-ground-engine-substrate-audit.md`](t-ground-engine-substrate-audit.md)** — the audit that surfaced this gap. Cites `bootstrap.rs:14-19` as the framing decision being revisited. ->>>>>>> origin/main - **[`src/v3/compiler/src/bootstrap.rs`](../../src/v3/compiler/src/bootstrap.rs)** — current bootstrap; `Dag::new()` loads four authority sets (`std_fixtures`, `STAGED_FILES`, `V3_SPECS`, `COMPILER_FILES`). Header comment at `:14-19`: *"Production bootstrap does not inject target-language realizations."* That comment is being revisited in this PR. - **[`dsl/extdeps/languages/rust/primitives.dag`](../../dsl/extdeps/languages/rust/primitives.dag)** — the file that must become loadable. Contains `rust_pilot_primitives: List` declarations (`RustPrimitive` is sum type partitioned into `IntegerPrimitive | NonIntegerPrimitive` per pilot brief / codex P2 adjudication on PR #765). - **[`src/v3/compiler/build.rs`](../../src/v3/compiler/build.rs)** — generated-snapshot pattern (`extdeps_generated`, `gunbc_generated`, etc.). Reference for adding a new fixture-set entry. @@ -33,13 +29,8 @@ Per Grounding Manager's escalation doc §"Manager-side input for the loader-clos 1. **Public accessor returns parsed `Declaration` walkable structurally.** Engine consumes `rust_pilot_primitives` as a `Declaration`-shaped value with structural walk semantics (matching how other bootstrap-loaded declarations are consumed). Not a string; not a private internal handle. 2. **Stable shape Engine doesn't reach into private `Dag` internals.** The accessor must be a public API surface; consuming Engine code must not need `pub(crate)` or unsafe reach-throughs to walk the loaded data. -<<<<<<< HEAD 3. **Stale `bootstrap.rs:16-19` comment revisited in same PR.** That comment asserts production bootstrap doesn't load target-language realizations. This PR contradicts that assertion; the comment must be updated to reflect the new state (which realizations load, why, and what the boundary is now). Don't leave contradictory documentation. 4. **SG-0 stance: transitional shape (default) or ratchet-bump escalation.** This work touches `bootstrap.rs` (SG-0-ratcheted hand-Rust). The **default-and-expected framing is transitional shape**: loader logic lands as a thin scaffold whose dissolution trigger is the **PB-Bootstrap-Process lane** (Zero-Floor program). When PB-Bootstrap-Process lands `bootstrap.dag` declaring the workflow as data, `bootstrap.rs` becomes a generated trampoline (or vanishes); the loader-close logic added here becomes part of the to-be-generated content at that point. PB-Bootstrap-Process is **already tracked** in `docs/design-pure-bootstrap-zero.md` §"New lanes" + Zero-Floor Manager brief working state — the dissolution trigger is concrete, not aspirational. Document the chosen transitional shape in the PR body, citing PB-Bootstrap-Process as the dissolution authority. **Ratchet bump is a STOP-AND-ESCALATE outcome**, not a routine choice — if the worker concludes transitional shape is genuinely not viable (the loader cannot fit a shape PB-Bootstrap-Process can absorb), surface to Director per STOP-AND-ESCALATE rules. Per the locked discipline (ratchet only goes down; if a fix needs a new violation, the violation belongs deeper; scaffolds dissolve into first-class structure with named dissolution triggers — see `INVARIANTS.md` and `docs/design-pure-bootstrap.md` for the canonical statements), ratchet-bump is an exception requiring explicit Director confirmation + tracked dissolution trigger, not author discretion. -======= -3. **Stale `bootstrap.rs:14-19` comment revisited in same PR.** That comment asserts production bootstrap doesn't load target-language realizations. This PR contradicts that assertion; the comment must be updated to reflect the new state (which realizations load, why, and what the boundary is now). Don't leave contradictory documentation. -4. **SG-0 stance: transitional shape (default) or ratchet-bump escalation.** This work touches `bootstrap.rs` (SG-0-ratcheted hand-Rust). The **default-and-expected framing is transitional shape**: loader logic lands in a form PB-1 absorbs cleanly when PB-1's data-bootstrap of std_fixtures / STAGED_FILES extends to include extdeps as a fifth set. Document the chosen transitional shape in the PR body. **Ratchet bump is a STOP-AND-ESCALATE outcome**, not a routine choice — if the worker concludes transitional shape is genuinely not viable (the loader cannot fit PB-1's emerging pattern), surface to Director per STOP-AND-ESCALATE rules. Per the locked `feedback_ratchet_only_down.md` invariant, ratchet-bump is an exception requiring explicit Director confirmation, not author discretion. ->>>>>>> origin/main 5. **Coverage scope explicitly bounded.** Just `dsl/extdeps/languages/rust/primitives.dag` for this PR (smallest unblock for Engine-Phase-1)? Or all `dsl/extdeps/languages/*/*.dag` (covers Python/Go targets too, which Grounding's full-reference lanes will eventually need)? Pick + document. Smaller (rust only) is fine if it cleanly extends; larger (all extdeps languages) is fine if the loader pattern naturally generalizes. ## Slice — extdeps loader close @@ -50,11 +41,7 @@ Per Grounding Manager's escalation doc §"Manager-side input for the loader-clos 1. Add the file(s) per req 5 to a bootstrap fixture set. Could be a new fifth set (`EXTDEPS_LANGUAGE_FILES` or similar), or an extension of an existing set if cleaner. Worker's call. 2. Implement public accessor (req 1, req 2). Naming convention should match existing accessors in `Dag` API surface; consult `bootstrap.rs` and `lib.rs` for prior art. -<<<<<<< HEAD 3. Update `bootstrap.rs:16-19` comment per req 3. -======= -3. Update `bootstrap.rs:14-19` comment per req 3. ->>>>>>> origin/main 4. Write integration test asserting: - `Dag::new()` loads `rust_pilot_primitives` without error - Public accessor returns a `Declaration`-shaped value with the correct identity @@ -65,11 +52,7 @@ Per Grounding Manager's escalation doc §"Manager-side input for the loader-clos - [ ] All 5 consumer-side requirements satisfied + documented in PR body. - [ ] `dsl/extdeps/languages/rust/primitives.dag` loadable into bootstrap (per req 5 scope). - [ ] Public accessor for `rust_pilot_primitives` exists; Engine sharpened-(b) consumer-shape assertion holds (Engine team verifies post-merge). -<<<<<<< HEAD - [ ] `bootstrap.rs:16-19` comment updated to reflect new boundary (req 3). -======= -- [ ] `bootstrap.rs:14-19` comment updated to reflect new boundary (req 3). ->>>>>>> origin/main - [ ] SG-0 stance documented in PR body (req 4). - [ ] Integration test passes: `Dag::new()` loads + accessor returns walkable structure. - [ ] `cargo test --workspace --exclude v2-compiler-tests` passes. @@ -84,11 +67,7 @@ Surface to Director (`zesty-bear-812`); do not absorb scope. - **If the SG-0 stance choice (req 4) reveals the loader logic genuinely cannot fit PB-1's emerging pattern** (i.e., transitional-shape isn't viable, ratchet-bump is the only path) — STOP. Director needs to confirm ratchet bump explicitly before the PR commits to it. - **If req 5's coverage scope (rust-only vs all extdeps languages) reveals divergent loader patterns per language** (e.g., rust loads cleanly but python/go need extension extension) — STOP. Surface the divergence; pick rust-only and re-dispatch other languages per their needs. - **If the public accessor shape (req 1, req 2) requires extending `Dag` API surface beyond what existing accessors do** — STOP. Surface the extension proposal; Director coordinates with Zero-Floor Manager on whether the extension belongs in PB-Substrate scope. -<<<<<<< HEAD - **If `bootstrap.rs:16-19` comment update (req 3) reveals the framing change has cross-doc implications** (e.g., other authority docs assert "no target-language realizations in bootstrap") — STOP. Surface the cross-doc consistency check; Director routes to docs-cascade if needed. -======= -- **If `bootstrap.rs:14-19` comment update (req 3) reveals the framing change has cross-doc implications** (e.g., other authority docs assert "no target-language realizations in bootstrap") — STOP. Surface the cross-doc consistency check; Director routes to docs-cascade if needed. ->>>>>>> origin/main - **If DB-8 fixed-point drifts** — STOP immediately. Same no-compromise gate as PB-1. ## Non-goals From fed6b0324c5b3dbee0cedbc7202b38a5f5433799 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 24 Apr 2026 23:54:13 -0400 Subject: [PATCH 28/52] docs(cascade-promotion): resolve codex 4 BLOCKING findings at sha 0d6e7c33 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three substantive fixes addressing internal-consistency gaps in the cascade promotion PR caught by codex review at sha 0d6e7c33: 1. ROADMAP.md gate/baseline prose at :37 / :67 / :68 / :140 — bring lane acceptance bullets and Hand-Rust census paragraph in line with the updated lane summary rows. T-PB-A reads "0 per design-pure-bootstrap-zero (LIVE 2026-04-25)"; T-PB-B notes the TESTING.md residual carve-out is retracted under 0-floor with explicit migration to ExecuteCommand-based .dag TestClaim declarations. 2. docs/design-pure-bootstrap-zero.md promotion section — converted from future-tense ("This doc is PROPOSAL until promoted… promotion is a single Director-authored cascade PR…") to historical past-tense promotion-receipt framing ("This doc was PROPOSAL until promoted; promotion was a single Director-authored cascade PR that did all of the following atomically…"); blocking-clause struck through and resolved inline. Banner cites PR #782 explicitly. 3. docs/r2-structure.md 4th T-Substrate sub-lane scoping — kernel_algebra_ profile excluded (Map body, not list-of-sum; needs distinct ValueBody::Map substrate work, tracked separately as a future sub-lane). Sub-lane re-scoped to 2 consumers (tokenizer charclass phase-2 + Engine sharpened-(b) pilot enumeration), both sharing list-of-sum substrate work. Lane table, dependency DAG, and capacity summary updated for consistency (slot count 9-13, was 10-14). Co-Authored-By: Claude Opus 4.7 (1M context) --- ROADMAP.md | 8 ++++---- docs/design-pure-bootstrap-zero.md | 8 +++++--- docs/r2-structure.md | 23 ++++++++++++----------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 71ef3e43199..20bea0c65ca 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -34,7 +34,7 @@ T-TestGen is therefore the gate-enabling lane on two axes: it extends the predic 3. **Multi-target emission.** Rust production-grade; Python/Go demonstrably working. Lane T-Emit. 4. **Impossible-bugs demo suite.** Enumerated bug classes with compile-time proofs (see THESIS `Enumerable impossible-bug classes`). Lane T-Demo. 5. **Arbitrary lens composition.** User-authored lenses. Lane T-LensAPI. -6. **Self-hosting (Pure Bootstrap).** Hand-authored compiler files at the irreducible-shim floor (≤5 per `docs/design-pure-bootstrap.md`); generated escape hatch acceptable for additional files. Lanes T-PB-A + T-PB-B. +6. **Self-hosting (Pure Bootstrap).** Hand-authored compiler files at the **0-floor target per `docs/design-pure-bootstrap-zero.md`** (LIVE 2026-04-25; supersedes the prior ≤5-floor framing in `docs/design-pure-bootstrap.md`); generated escape hatch acceptable for additional files. Lanes T-PB-A + T-PB-B. Enablers (prerequisites for the goals): T-P0 (bug sweep), T-Sub (surface syntax completion). @@ -64,8 +64,8 @@ This section lists gate names + schema-compilability tags; full `TestClaim` decl - **T-LaneE.** `complexity_merge_sort_is_nlogn` [ext: `LensOutputEquals`] · `complexity_merge_sort_v3_matches_v2_oracle` [ext: `DifferentialEquals`] · `lane_e_bundled_witness_host_emit_parity` [ext: `DifferentialEquals`] - **T-TestGen.** `testgen_structural_coverage` [ext] · `testgen_mock_backed_integration_safe` [ext: `MockBackedInvariant` — runner `NotYetImplemented` until `TestClaim.requires` carries at least one `ResourceReference`; M1(2.8) fixture list bodies) · `testgen_manual_claim_is_first_class` [ext] — T-TestGen also owns scoping the predicate shape for `[ext]` gates that other lanes consume; currently includes `lens_producer_files_remaining` for T-PB-A (enumeration declared in `sg0_census_test.rs` at scoping time). - **T-LensAPI.** `user_authored_lens_compiles` [Day 1] · `lens_composition_associative` [ext: `AlgebraicLaw`] · `lens_output_is_queryable_data` [ext] -- **T-PB-A.** `pb_hand_rust_at_shim_floor` [ext] · `lens_producer_files_remaining` [ext — priority slice of the non-test census: hand-Rust files implementing lens producers, drops as each migrates to `.dag`; enumeration declared in `sg0_census_test.rs` when T-TestGen scopes the predicate] · `pb_self_compile_fixed_point` [ext] · `pb_compiler_std_ratchet_zero` [ext] — live baselines read from authorities; not frozen in this doc. Hand-Rust (**non-test subset**): SG-0 census (file-level + fragments ratchet) minus the test subset owned by T-PB-B → ≤5 irreducible-shim per `docs/design-pure-bootstrap.md`. Consolidation ratchet: compiler-local types not in positive-def set → 0. -- **T-PB-B.** `pb_test_file_generated_from_dag` [ext] · `pb_rust_tests_outside_residual_zero` [ext] — the first gates the pipeline-equivalent suite; the second gates the outcome: zero Rust-authored tests exist outside the `TESTING.md §"Post-R2 shape"` residual (compiler-internal unit tests + external-toolchain boundary tests). Single-file generation is insufficient proof of the lane's end-state. +- **T-PB-A.** `pb_hand_rust_at_shim_floor` [ext] · `lens_producer_files_remaining` [ext — priority slice of the non-test census: hand-Rust files implementing lens producers, drops as each migrates to `.dag`; enumeration declared in `sg0_census_test.rs` when T-TestGen scopes the predicate] · `pb_self_compile_fixed_point` [ext] · `pb_compiler_std_ratchet_zero` [ext] — live baselines read from authorities; not frozen in this doc. Hand-Rust (**non-test subset**): SG-0 census (file-level + fragments ratchet) minus the test subset owned by T-PB-B → **0** per `docs/design-pure-bootstrap-zero.md` (LIVE 2026-04-25 per cascade promotion; supersedes the prior ≤5-floor framing). Consolidation ratchet: compiler-local types not in positive-def set → 0. +- **T-PB-B.** `pb_test_file_generated_from_dag` [ext] · `pb_rust_tests_outside_residual_zero` [ext] — the first gates the pipeline-equivalent suite; the second gates the outcome: zero Rust-authored tests exist (post cascade promotion 2026-04-25, the `TESTING.md §"Post-R2 shape"` residual carve-out is **retracted**; both prior categories — compiler-internal unit tests + external-toolchain boundary tests — dissolve under 0-floor: helper unit tests vanish naturally, boundary tests migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations per the cascade promotion PR's TESTING.md rewrite). Single-file generation is insufficient proof of the lane's end-state. - **T-Demo.** - `fixture_compiler_nerd_canonical` [Day 1 (Compiles) / ext (lens-output demos)] — demonstrates: complexity, ownership, parallelism - `fixture_integration_canonical` [Day 1 (Compiles) / ext (lens-output demos)] — demonstrates: effects, idempotency, testgen @@ -137,7 +137,7 @@ Read bottom-up. Arrows point producer → consumer. **Two distinct baselines inside T-PB-A.** Both read from live authorities — this doc does not freeze counts. -- **Hand-Rust census (T-PB-A owns the non-test subset):** SG-0 census — `EXPECTED_HAND_AUTHORED_NON_TEST` + `EXPECTED_HAND_AUTHORED_FRAGMENTS` for the T-PB-A subset, and `EXPECTED_HAND_AUTHORED_TEST` for the T-PB-B subset — in `src/v3/compiler/tests/integration/sg0_census_test.rs`. T-PB-A's gate scopes to the **non-test entries** → ≤5 irreducible-shim (per `docs/design-pure-bootstrap.md`). The **test entries** of the same census are T-PB-B's gate: zero Rust-authored tests **outside the TESTING.md §"Post-R2 shape" residual** (compiler-internal unit tests + external-toolchain boundary tests, which stay Rust-authored permanently per TESTING.md as single authority). The census floor is therefore `(≤5 irreducible-shim per design doc) + (TESTING.md residual)`, not the shim floor alone; neither lane dissolves the TESTING.md residual, and each lane is a scoped half of the census, not blocked on the other for work. +- **Hand-Rust census (T-PB-A owns the non-test subset):** SG-0 census — `EXPECTED_HAND_AUTHORED_NON_TEST` + `EXPECTED_HAND_AUTHORED_FRAGMENTS` for the T-PB-A subset, and `EXPECTED_HAND_AUTHORED_TEST` for the T-PB-B subset — in `src/v3/compiler/tests/integration/sg0_census_test.rs`. T-PB-A's gate scopes to the **non-test entries** → **0** per `docs/design-pure-bootstrap-zero.md` (LIVE 2026-04-25; supersedes the prior ≤5-floor framing in `docs/design-pure-bootstrap.md`). The **test entries** of the same census are T-PB-B's gate: zero Rust-authored tests (post cascade promotion 2026-04-25, the TESTING.md "Post-R2 shape" residual carve-out is **retracted** — both prior categories dissolve under 0-floor: helper unit tests vanish naturally, boundary tests migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations). The census floor under 0-floor is `0 hand-Rust + 0 TESTING residual`; both lanes dissolve their respective subsets toward 0. - **Compiler–std consolidation ratchet:** compiler-local `type` declarations not in the positive-def set and not exempted → 0 (see ROADMAP §"Compiler–`std/` consolidation program"). What's allowed to exist as a compiler-local type name. Both land inside T-PB-A because dissolving the compiler-local surface forces both gates down together, but the acceptance claims (`pb_hand_rust_at_shim_floor`, `pb_compiler_std_ratchet_zero`) are independent gates tracked against independent authorities. diff --git a/docs/design-pure-bootstrap-zero.md b/docs/design-pure-bootstrap-zero.md index be540a7cb90..6304bad17e7 100644 --- a/docs/design-pure-bootstrap-zero.md +++ b/docs/design-pure-bootstrap-zero.md @@ -1,6 +1,6 @@ # Pure Bootstrap to Zero — Design -**Status:** `LIVE` (promoted 2026-04-25 via cascade promotion PR). Supersedes the ≤5-floor framing in [`docs/design-pure-bootstrap.md`](design-pure-bootstrap.md) (now marked SUPERSEDED with explicit retraction) and the 2-3 principled-floor framing introduced via [PR #756](https://github.com/gunb-ai/gunbc/pull/756) (also retracted). This doc is the live authority on the Pure Bootstrap to Zero program. +**Status:** `LIVE` (promoted 2026-04-25 via cascade promotion [PR #782](https://github.com/gunb-ai/gunbc/pull/782)). Supersedes the ≤5-floor framing in [`docs/design-pure-bootstrap.md`](design-pure-bootstrap.md) (now marked SUPERSEDED with explicit retraction) and the 2-3 principled-floor framing introduced via [PR #756](https://github.com/gunb-ai/gunbc/pull/756) (also retracted). This doc is the live authority on the Pure Bootstrap to Zero program. **Promotion evidence chain (cited in cascade promotion PR body):** - D1 audit: PRs #769 + #771 + #775 + #777 + #779 (audit doc with substrate-generation already proven; 23 generated files + 24 REGEN_OUTPUTS entries; 38-type substrate.dag coverage survey) @@ -12,7 +12,9 @@ ### Promotion mechanism -This doc is PROPOSAL until promoted. **Promotion is a single Director-authored cascade PR** that does **all** of the following atomically (no piecewise promotion — the framing change is load-bearing across multiple authorities and partial promotion would create contradiction): +**(Historical context — promotion executed 2026-04-25 via cascade promotion PR; all retraction steps below were performed atomically per the no-piecewise-promotion clause. Section preserved for audit-trail readability of how the promotion happened.)** + +This doc was PROPOSAL until promoted. **Promotion was a single Director-authored cascade PR** that did **all** of the following atomically (no piecewise promotion — the framing change is load-bearing across multiple authorities and partial promotion would have created contradiction): - **Who promotes:** Director, after Grounding Manager (R2's standing manager) and at least one R2 substrate-prereq sub-lane have produced stable enough evidence that the (γ) shape is achievable in v3's substrate (i.e., not a paper proposal). - **What gate:** the cascade PR includes (a) at least one prototyped lane closure proving an existing hand-Rust file can be retired via `.dag` migration without regression, and (b) explicit acknowledgement from PM that the program structure is dispatchable. @@ -24,7 +26,7 @@ This doc is PROPOSAL until promoted. **Promotion is a single Director-authored c - `TESTING.md` "Post-R2 shape" residual section either rewritten in this same cascade PR (bundled) or sibling PR landed first (separated). See "TESTING.md rewrite" section below. - This doc's status banner updated from `PROPOSAL` to `LIVE` with promotion date and citing the cascade PR number. -If any retraction step can't land in the same PR (e.g., cascading conflicts), promotion blocks; this doc stays `PROPOSAL` until the cascade can be authored atomically. +~~If any retraction step can't land in the same PR (e.g., cascading conflicts), promotion blocks; this doc stays `PROPOSAL` until the cascade can be authored atomically.~~ **(Resolved.)** Cascade landed atomically on 2026-04-25; all five retractions present in the cascade PR; doc is now LIVE. ### Pre-promotion deliverables diff --git a/docs/r2-structure.md b/docs/r2-structure.md index b74fbc3ca9a..21bd2b36c7c 100644 --- a/docs/r2-structure.md +++ b/docs/r2-structure.md @@ -41,12 +41,13 @@ Under that discipline, R2's goals are the Tier-1 thesis claims that are *not* ga - **Cardinality-substrate subset sufficient to close int-literal magnitude refinement** — enough cardinality modeling to let `IntLit` carry a magnitude that narrows to target int algebra at reconciliation. Consumer: T-Modeling int-lit (Goal 2). Does NOT commit to the full cardinality-substrate capability (fixed-width-types by-construction, container cardinality bounds in Grounding, etc. — those remain open design calls outside R2 scope unless additional R2 items demand them). - **Nominal-opaque substrate sufficient to graduate `Secret`** — enough nominal-type modeling to carry construction-restriction (`where only X may construct`) semantics. Consumer: T-Modeling Secret (Goal 2). Adjacent to DB-11 alias-RHS `where` (landed in R1 via PR #703); may or may not overlap DB-18 territory. Acceptance is `Secret` graduation, not a general nominal-type program. - **Parametric algebra attachment subset sufficient to inhabit `Dimension` in an abelian group algebra** — enough substrate capability to let `Dimension` carry phantom-parameter arithmetic (propagate through operations, compile error on unit-mismatch). Consumer: T-Modeling Dimensions (Goal 2). Primary authority is `ROADMAP.md §"Post-R1 Program — Grounding Completeness"` (the "Why post-R1" paragraph), which tags this dependency `DB-18 parametric algebra attachment` — but `docs/db-history/db-18.md` currently scopes DB-18 to workflow-effect carrier + Rust reflection (Part 2 shipped) + Go-accessor follow-up (Part 3), not parametric algebra attachment. That mismatch is an existing ROADMAP ↔ db-history inconsistency, not one introduced by this doc; a pre-promotion DB-lane rename or new DB number may be warranted. R2 acceptance is: `Dimension` phantom-parameter arithmetic compiles with unit-mismatch errors, independent of the DB-tag the substrate ends up carrying. - - **Top-level `ValueBody` list/sum subset + `std.unicode` bootstrap inclusion** — enough Class 5 Gap 3 substrate capability for `data ascii_scan_order: List = [Whitespace, Digit, IdentStart, IdentContinue]` (and similar list/sum top-level data declarations) to lower structurally (rather than fall to `ValueBody::Unparsed` and trigger R14 hard-fail), plus the `Dag::new()` bootstrap/load-set decision that makes `std.unicode::CharClass` and other extdeps-language declarations resolvable from compiler authorities. **Three named consumers, all of which the same substrate work unblocks**: - 1. **Tokenizer charclass phase-2** — original consumer per PR #762 reclassification (R1 T-Sub deferred this phase to substrate per Surface Manager handoff 2026-04-24). - 2. **Engine sharpened-(b) full pilot enumeration** — surfaced by R2 Grounding loader-close worker (`clever-owl-123`) probe on PR #776 (`rust_pilot_primitives` lowers as `Declaration` but `value_body` is `Unparsed(SourceSpan)` — same gap). - 3. **`kernel_algebra_profile` mirror dissolution** — existing P2 drift ratchet at `dag.rs:1530`. Same gap (`Map` declared in `dsl/std/algebra.dag` lands as `ValueBody::Unparsed` today). + - **Top-level `ValueBody` list/sum subset + `std.unicode` bootstrap inclusion** — enough Class 5 Gap 3 substrate capability for `data ascii_scan_order: List = [Whitespace, Digit, IdentStart, IdentContinue]` (and similar list/sum top-level data declarations) to lower structurally (rather than fall to `ValueBody::Unparsed` and trigger R14 hard-fail), plus the `Dag::new()` bootstrap/load-set decision that makes `std.unicode::CharClass` and other extdeps-language declarations resolvable from compiler authorities. **Two named consumers, both of which share this list/sum substrate work**: + 1. **Tokenizer charclass phase-2** — original consumer per PR #762 reclassification (R1 T-Sub deferred this phase to substrate per Surface Manager handoff 2026-04-24). Shape: `data ascii_scan_order: List = [...]` (list of sum). + 2. **Engine sharpened-(b) full pilot enumeration** — surfaced by R2 Grounding loader-close worker (`clever-owl-123`) probe on PR #776 (`rust_pilot_primitives: List` lowers as `Declaration` but `value_body` is `Unparsed(SourceSpan)`). Shape: list of sum (same substrate work as charclass). - Does NOT commit to the full Class 5 Gap 3 substrate-capability close (other top-level `ValueBody` consumers beyond these three may need additional variants); scoped to what unblocks all three named consumers from one substrate work. ROI strictly higher than originally framed (single-consumer scoping); director-amended 2026-04-25 per cross-program convergence finding on PR #776. + **Excluded from this sub-lane (substrate shape differs)**: `kernel_algebra_profile` mirror dissolution (existing P2 drift ratchet at `dag.rs:1530`) is a `Map` body — **map-shaped, not list-of-sum**. Hits the same R14 `ValueBody::Unparsed` hard-fail path, but requires a different `ValueBody` extension (e.g., `ValueBody::Map(...)` variant + lowerer support for top-level map literals). Tracked separately as a sibling future T-Substrate sub-lane / future cascade item; not bundled here per substrate-shape honesty (codex BLOCKING on PR #782 caught this scope conflation; corrected 2026-04-25). + + Does NOT commit to the full Class 5 Gap 3 substrate-capability close; scoped to the list/sum subset for the two named consumers. ROI is 2× the original single-consumer scoping (tokenizer + Engine), not 3× as initially framed. 4. **Remaining R2+ impossible-bug classes** — three classes currently tagged `[R2+]` in `ROADMAP.md §"Lane acceptance — .dag gates"` (T-Demo row; THESIS §"Enumerable impossible-bug classes" is the authority on scheduling tags): - Nested-optional flatten @@ -83,7 +84,7 @@ Continues `docs/briefs/grounding-manager.md` (refreshed for R2 scope on promotio |---|---|---|---| | T-Ground | XL | Grounding | Full T-Ground-* sub-program (Goal 1) | | T-Modeling | M | Director (ad-hoc) | int-lit / Secret / Dimensions (Goal 2) | -| T-Substrate | M | Director (ad-hoc) | Four scoped-subset sub-lanes (Goal 3): cardinality-for-int-lit; nominal-opaque-for-Secret; parametric-algebra-attachment-for-Dimensions; top-level-ValueBody-list/sum + std.unicode-bootstrap (3 named consumers: tokenizer charclass phase-2 + Engine sharpened-(b) pilot enumeration + kernel_algebra_profile mirror dissolution — single substrate work unblocks all three) — each sub-lane scoped to its paired R2 consumer set (T-Modeling × 3 + multi-consumer × 1), not full substrate-capability | +| T-Substrate | M | Director (ad-hoc) | Four scoped-subset sub-lanes (Goal 3): cardinality-for-int-lit; nominal-opaque-for-Secret; parametric-algebra-attachment-for-Dimensions; top-level-ValueBody-list/sum + std.unicode-bootstrap (2 named consumers: tokenizer charclass phase-2 + Engine sharpened-(b) pilot enumeration — both share list-of-sum substrate work) — each sub-lane scoped to its paired R2 consumer set (T-Modeling × 3 + dual-consumer × 1), not full substrate-capability. Note: `kernel_algebra_profile` mirror dissolution is map-shaped (not list/sum) — tracked separately as a future T-Substrate sub-lane requiring distinct `ValueBody::Map` substrate work. | | T-ImpossibleBugs | S | Director (ad-hoc) | nested-optional flatten / unhandled-diagnostic-paths / unenumerated-effects (Goal 4) | | T-PerMethodMetadata | S | Director (ad-hoc) | §6a per-method-metadata carrier pick (Goal 5) — design-call close, not substrate-capability work | @@ -108,24 +109,24 @@ T-Ground: Pilot → Rust → Engine → Tests → Dissolve (critical p T-Substrate: cardinality-for-int-lit (subset) ──→ unblocks T-Modeling int-lit nominal-opaque-for-Secret (subset) ─→ unblocks T-Modeling Secret parametric-algebra-for-Dimensions (subset) ─→ unblocks T-Modeling Dimensions - ValueBody-list/sum + std.unicode-bootstrap (subset) ─→ unblocks 3 consumers (single substrate work): + ValueBody-list/sum + std.unicode-bootstrap (subset) ─→ unblocks 2 consumers (shared list-of-sum substrate): (i) tokenizer charclass phase-2 (ii) Engine sharpened-(b) pilot enumeration - (iii) kernel_algebra_profile mirror dissolution + (kernel_algebra_profile mirror dissolution is map-shaped, NOT list/sum; + tracked separately as a future T-Substrate sub-lane requiring ValueBody::Map extension) T-Modeling: int-lit ← T-Substrate cardinality-for-int-lit Secret ← T-Substrate nominal-opaque-for-Secret Dimensions ← T-Substrate parametric-algebra-for-Dimensions -Multi-consumer of T-Substrate's 4th subset (none are peer lanes — all consumed inside T-Substrate scope): +Dual-consumer of T-Substrate's 4th subset (neither is a peer lane — both consumed inside T-Substrate scope): (i) Tokenizer charclass phase-2: retype to Char / List / CharClass (ii) Engine sharpened-(b): full pilot enumeration via symbolic walk of rust_pilot_primitives - (iii) kernel_algebra_profile: retire dag.rs:1530 hand-Rust mirror T-ImpossibleBugs: 3 independent classes (any worker) T-PerMethodMetadata: §6a pick (any worker; independent) (Goal 6 demo artifacts ship with each lane's closure PR — not a separate dependency-DAG node; see Demo discipline section.) ``` -Parallel-capable work at any time: Grounding has 2 fill slots (Python, Go) alongside its critical path; Director dispatch has 4 T-Substrate sub-lanes (3 T-Modeling unblocks + 1 multi-consumer unblock covering 3 consumers) + 3 T-Modeling items (each pair-blocked) + 3 deliverables pair-blocked on the 4th T-Substrate sub-lane (tokenizer charclass, Engine sharpened-(b), kernel_algebra_profile mirror dissolution) + 3 T-ImpossibleBugs classes + 1 T-PerMethodMetadata pick, for roughly 10–14 slots depending on T-Substrate unblock timing. +Parallel-capable work at any time: Grounding has 2 fill slots (Python, Go) alongside its critical path; Director dispatch has 4 T-Substrate sub-lanes (3 T-Modeling unblocks + 1 dual-consumer unblock covering 2 consumers) + 3 T-Modeling items (each pair-blocked) + 2 deliverables pair-blocked on the 4th T-Substrate sub-lane (tokenizer charclass, Engine sharpened-(b)) + 3 T-ImpossibleBugs classes + 1 T-PerMethodMetadata pick, for roughly 9–13 slots depending on T-Substrate unblock timing. ## R1 closure criteria From c85e6916d652295d05aff3cf309a1281d190a3ae Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 00:02:32 -0400 Subject: [PATCH 29/52] docs(cascade-promotion): extend cascade across THESIS.md + sibling authorities MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves claude REQUEST_CHANGES at sha fed6b032 — atomic-cascade self-violation. The promotion mechanism in design-pure-bootstrap-zero.md:18-22 explicitly names THESIS.md and "any other authority docs" as required retraction targets; the prior diff updated ROADMAP + r2-structure + design docs but left THESIS.md, compiler-std-consolidation.md, and r1-selfhosting- manager.md pointing at the now-SUPERSEDED ≤5-floor framing. Files: - THESIS.md (5 prose blocks updated): - :164 — facet 3 prose: residual carve-out retracted under 0-floor; tests migrate to ExecuteCommand-based .dag TestClaim declarations. - :248-252 — Self-hosting facet 3: same retraction; everything ports to .dag. - :253-283 — Cost-of-change paragraph + fixed-point acceptance: 0-floor target citing design-pure-bootstrap-zero.md as live authority; hand_maintained_src list shrinks to empty set. - :301-318 — Tests-are-structural-data block: residual carve-out retracted; predicate name pb_rust_tests_outside_residual_zero retained as housekeeping (semantically the residual is empty under cascade). - docs/thesis/compiler-std-consolidation.md (5 references): - Header link to design-pure-bootstrap-zero.md (LIVE) supersedes design-pure-bootstrap.md (SUPERSEDED). - :31 Bootstrap-shim positive-def: 0-floor target; PB-Bootstrap-Process lane named as the dissolution trigger for bootstrap.rs itself. - :87 hand-Rust paragraph: 0 target citing design-pure-bootstrap-zero.md. - :166 Tertiary ratchet: target shifts to 0 on both subsets; live authority re-cited. - :185 Related docs link. - docs/briefs/r1-selfhosting-manager.md (active dispatch brief): - SUPERSEDED-style banner at top: T-PB-A non-test target = 0 (not ≤5); T-PB-B residual carve-out retracted; predicate names retained for housekeeping; cascade-promoted authorities are source of truth. - Slice descriptions for T-PB-A / T-PB-B updated inline. - Framing-question + ask updated to 0-floor / no-residual framing. - Day-1 + up-to-director hand-off bullets updated. - Working-state checklist :111 ≤5 → 0 with cite. - Decisions log :164 ≤5 → 0-floor target updated. - docs/r2-structure.md §2 design call (RETRACTED block): - "Pre-promotion ≤5 irreducible-shim gate-name review" struck through in entirety (both Option A sharpen-and-keep and Option B rename are moot under 0-floor). Section preserved as audit-trail historical context. - Background-doc index: self-hosting anchor updated to design-pure-bootstrap-zero.md as live authority. - docs/design-pure-bootstrap.md SUPERSEDED banner (hardened per non-blocking suggestion): - Banner cites cascade promotion PR #782 explicitly. - New paragraph: "Treat all numeric floors below as retracted" with explicit lines named that quote in isolation (table row, body prose references). Prevents re-quoting from this doc as live authority. Cascade is now atomically consistent across: THESIS.md ↔ ROADMAP.md ↔ TESTING.md ↔ docs/thesis/compiler-std-consolidation.md ↔ docs/briefs/r1-selfhosting-manager.md ↔ docs/r2-structure.md ↔ docs/design-pure-bootstrap-zero.md (LIVE) ↔ docs/design-pure-bootstrap.md (SUPERSEDED). The (Resolved.) self-claim in design-pure-bootstrap-zero.md:29 now holds genuinely. Co-Authored-By: Claude Opus 4.7 (1M context) --- THESIS.md | 65 +++++++++++---------- docs/briefs/r1-selfhosting-manager.md | 70 +++++++++++++---------- docs/design-pure-bootstrap.md | 4 +- docs/r2-structure.md | 20 ++++--- docs/thesis/compiler-std-consolidation.md | 10 ++-- 5 files changed, 95 insertions(+), 74 deletions(-) diff --git a/THESIS.md b/THESIS.md index 20249139644..38b51edb8b9 100644 --- a/THESIS.md +++ b/THESIS.md @@ -161,7 +161,7 @@ Every claim the thesis makes, in one place. The ROADMAP tracks progress toward e **Correctness is structural, not behavioral (meta-claim):** - Every correctness dimension — type, arity, unit, effect, complexity, ownership, idempotency, and any user-declared invariant — is a structural fact carried by the program's data model. -- The proof and test surface is structurally derived, not hand-maintained. Tier 1 and Tier 2 proofs close at compile time by reading the structure. Tier 3 runs emitted code, but the test surface is generated from structural `TestClaim` declarations in `.dag` — not hand-authored behavior assertions. The `TESTING.md §"Post-R2 shape"` residual (compiler-internal unit tests + external-toolchain boundary tests) is the explicit carve-out where hand-authored Rust remains; TESTING.md is the single authority on that residual. +- The proof and test surface is structurally derived, not hand-maintained. Tier 1 and Tier 2 proofs close at compile time by reading the structure. Tier 3 runs emitted code, but the test surface is generated from structural `TestClaim` declarations in `.dag` — not hand-authored behavior assertions. Under the 0-floor target (per [`docs/design-pure-bootstrap-zero.md`](docs/design-pure-bootstrap-zero.md), LIVE 2026-04-25 — supersedes the prior ≤5-floor framing in `docs/design-pure-bootstrap.md`), the prior `TESTING.md §"Post-R2 shape"` residual carve-out (compiler-internal unit tests + external-toolchain boundary tests) is **retracted**: helper unit tests vanish naturally as their hand-Rust subjects dissolve, and boundary tests migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations per the cascade promotion. TESTING.md is the single authority on the migration path. - The dimension system is first-class user-extensible: a user writes a lens in `.dag`, and the compiler validates every program against it using the same mechanism it uses for built-in dimensions. - What mainstream languages catch via testing, profiling, schema validators, integration test suites, and production postmortems, gunbc catches by structurally deriving the proof or test — compile-time proofs for Tier 1/2, structurally-derived test surface for Tier 3. @@ -245,10 +245,12 @@ Self-hosting is not one capability; it's three. All three are targets. `pipeline.rs` (`src/v2/tests/src/pipeline.rs` — the large pipeline/ contract test file; live LOC reads from the file) exists only as `.dag` `TestClaim` declarations and generated target-language test code. - Per `TESTING.md` §"Post-R2 shape", two residual categories stay - Rust-authored: compiler-internal unit tests for Rust-only helpers, and - boundary tests that invoke external toolchains (rustc, go, python). - Everything else ports to `.dag`. **Pure Bootstrap's secondary + Under the 0-floor target (per `docs/design-pure-bootstrap-zero.md`, LIVE + 2026-04-25), the prior `TESTING.md §"Post-R2 shape"` two-residual carve-out + is **retracted**: helper unit tests vanish naturally as their hand-Rust + subjects dissolve; boundary tests that invoke external toolchains (rustc, + go, python) migrate to `ExecuteCommand`-based `.dag` `TestClaim` + declarations. Everything ports to `.dag`. **Pure Bootstrap's secondary deliverable, couples to testgen.** Cost-of-change: editing any compiler concept — a new pass, substrate fact, @@ -257,30 +259,33 @@ one `.dag` file. No matching hand edits to a Rust stage0 file. Stage0 Rust compiler internals (tokenize, parse, lower, infer, emit, lenses, std library) are emitted from the `.dag` graph and committed — not hand authored. Tests follow -the carve-out in facet 3 above: pipeline/contract tests are `.dag` -`TestClaim` data; the `TESTING.md §"Post-R2 shape"` residual categories -(compiler-internal unit tests + external-toolchain boundary tests) remain -Rust-authored. Hand-maintained surface target: the irreducible shim -floor defined in `docs/design-pure-bootstrap.md` (authority on the **≤5 -bound** and the **current candidate set** for the non-test surface; -specific files are candidates today and are ratified at graduation). +the cascade-promoted shape in facet 3 above: all pipeline/contract tests +are `.dag` `TestClaim` data; the prior `TESTING.md §"Post-R2 shape"` +two-residual carve-out is **retracted** under 0-floor (compiler-internal +unit tests + external-toolchain boundary tests both dissolve — helpers +vanish with their subjects, boundary tests migrate to `ExecuteCommand`-based +`.dag` `TestClaim` declarations). Hand-maintained surface target: **0** +per [`docs/design-pure-bootstrap-zero.md`](docs/design-pure-bootstrap-zero.md) +(LIVE 2026-04-25; supersedes the prior ≤5-floor framing in +`docs/design-pure-bootstrap.md`). The live *count* of currently hand-authored files reads from the full SG-0 census in `src/v3/compiler/tests/integration/sg0_census_test.rs` (authority on the census): file-level **`EXPECTED_HAND_AUTHORED_NON_TEST`** plus **`EXPECTED_HAND_AUTHORED_FRAGMENTS`** (crate-root scaffolds) for the T-PB-A non-test surface, **`EXPECTED_HAND_AUTHORED_TEST`** for the T-PB-B test surface, and mechanical checks that paths land in the correct sub-ratchet. -Non-test entries shrink toward the shim floor; test entries shrink toward the -`TESTING.md` residual. +Both subsets shrink toward 0 under the 0-floor cascade promotion. Generated escape hatch is acceptable for additional files; hand-authored -beyond the shim is not. +files are not. v2 achieves this pattern at ~97% (2 hand-maintained of 62 stage0 files); -v3's trajectory is the Pure Bootstrap program. +v3's trajectory is the Pure Bootstrap to Zero program (0 hand-maintained). Fixed-point acceptance: v3 binary compiles `compiler.dag` → produces bit-identical stage0 Rust + bit-identical emitted artifacts. `compiler.dag`'s `hand_maintained_src` list monotonically shrinks to the -irreducible shim set defined in `docs/design-pure-bootstrap.md`. +empty set per [`docs/design-pure-bootstrap-zero.md`](docs/design-pure-bootstrap-zero.md) +(LIVE 2026-04-25; supersedes the ≤5 irreducible-shim framing in +`docs/design-pure-bootstrap.md`). **Audience duality — opt-in depth (meta-feature):** - Core language stays approachable — types, functions, match, effects, @@ -299,23 +304,23 @@ irreducible shim set defined in `docs/design-pure-bootstrap.md`. extend the proof surface without changing the base language). **Tests are structural data:** -- Tests outside the `TESTING.md §"Post-R2 shape"` residual are `TestClaim` - declarations in `.dag`; the residual (compiler-internal unit tests + - external-toolchain boundary tests) remains Rust-authored, per TESTING.md - as single authority. Within the `.dag` surface, hand-authored tests and - generated tests share one predicate vocabulary — the predicates ARE the - test-writing language. +- All tests are `TestClaim` declarations in `.dag` under the 0-floor cascade + promotion (the prior `TESTING.md §"Post-R2 shape"` residual carve-out is + retracted; helper unit tests vanish with their hand-Rust subjects, boundary + tests migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations). + Within the `.dag` surface, hand-authored tests and generated tests share + one predicate vocabulary — the predicates ARE the test-writing language. + TESTING.md is the single authority on the migration path. - Manual tests are upstream of code: behavioral contracts the code must satisfy. Testgen is downstream of code: structural coverage derived from the program the user wrote. -- Rust tests **outside the `TESTING.md` §"Post-R2 shape" residual** - (compiler-internal unit tests + external-toolchain boundary tests) are a - language smell. Every hand-authored `.rs` test outside that residual - flags a predicate, effect-model, or mock surface the language doesn't - yet express. The operational release gate is ROADMAP T-PB-B's +- Rust-authored tests are a language smell. Every hand-authored `.rs` test + flags a predicate, effect-model, or mock surface the language doesn't yet + express. The operational release gate is ROADMAP T-PB-B's `pb_rust_tests_outside_residual_zero`: zero Rust-authored tests exist - outside the residual. TESTING.md remains the single authority on the - residual categories; the acceptance claim lives in ROADMAP. + (predicate name retains "outside residual" for predicate-rename housekeeping; + semantically the residual is empty under cascade promotion, so "outside + residual" means "all"). The acceptance claim lives in ROADMAP. - Consequence of the pure-function posture: effects are explicit parameters, mocking is dependency-injection-by-construction, no hidden state means no flaky tests. diff --git a/docs/briefs/r1-selfhosting-manager.md b/docs/briefs/r1-selfhosting-manager.md index a986eedd715..e1a9776153c 100644 --- a/docs/briefs/r1-selfhosting-manager.md +++ b/docs/briefs/r1-selfhosting-manager.md @@ -1,5 +1,7 @@ # R1 Self-hosting Manager Brief +> **🔄 Cascade-promotion update (2026-04-25)** — R1 self-hosting acceptance reframed under the 0-floor target per [`docs/design-pure-bootstrap-zero.md`](../design-pure-bootstrap-zero.md) (LIVE 2026-04-25 via cascade promotion PR #782; supersedes the prior ≤5-floor framing in `docs/design-pure-bootstrap.md`, now SUPERSEDED). T-PB-A's non-test target is **0** (not ≤5). T-PB-B's prior `TESTING.md §"Post-R2 shape"` two-residual carve-out is **retracted**: helper unit tests vanish naturally, boundary tests migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations (per `TESTING.md` rewrite in cascade promotion). Operationally R1 closure may still ship before the 0-floor is reached — the ratchet ensures the trajectory; the gate's *acceptance number* is what shifts. Below is updated for cascade-coherent prose; predicate names retained for housekeeping. Original brief content below this banner reflects pre-cascade framing where not yet inline-updated; treat the cascade-promoted authorities (`design-pure-bootstrap-zero.md`, ROADMAP T-PB-A/T-PB-B rows + Goals bullet, `TESTING.md`) as the source of truth on any wording divergence. + ## Orient before reading - Product direction: [PR #672](https://github.com/gunb-ai/gunbc/pull/672) @@ -19,39 +21,45 @@ This manager owns two lanes: - **`T-PB-A`** (`ROADMAP.md:53`) — compiler self-emits (fixed- - point); **non-test** hand-Rust surface reaches the ≤5 irreducible- - shim floor per [`docs/design-pure-bootstrap.md`](../design-pure-bootstrap.md). - Generated escape hatch OK. Live baseline is the non-test subset - of the SG-0 census (`EXPECTED_HAND_AUTHORED_NON_TEST` file-level + + point); **non-test** hand-Rust surface reaches the **0-floor target** + per [`docs/design-pure-bootstrap-zero.md`](../design-pure-bootstrap-zero.md) + (LIVE 2026-04-25; supersedes the prior ≤5-floor framing in + `docs/design-pure-bootstrap.md`). Generated escape hatch OK. Live + baseline is the non-test subset of the SG-0 census + (`EXPECTED_HAND_AUTHORED_NON_TEST` file-level + `EXPECTED_HAND_AUTHORED_FRAGMENTS` crate-root scaffolds) in `src/v3/compiler/tests/integration/sg0_census_test.rs`. This brief does not freeze the count. -- **`T-PB-B`** (`ROADMAP.md:54`) — tests-as-data. Pipeline and - contract tests port to `.dag`. The two `TESTING.md §Post-R2 shape` - residual categories (compiler-internal unit tests for Rust-only - helpers; external-toolchain boundary tests invoking - rustc/go/python) remain Rust-authored. Size **M**. +- **`T-PB-B`** (`ROADMAP.md:54`) — tests-as-data. All pipeline and + contract tests port to `.dag`. The prior `TESTING.md §"Post-R2 shape"` + two-residual carve-out (compiler-internal unit tests for Rust-only + helpers; external-toolchain boundary tests invoking rustc/go/python) + is **retracted** under cascade promotion 2026-04-25: helper unit tests + dissolve with their hand-Rust subjects; boundary tests migrate to + `ExecuteCommand`-based `.dag` `TestClaim` declarations. Size **M**. ## Framing question this manager answers -**Does gunbc compile itself from a named minimal Rust shim, with -the residual Rust floor structurally bounded and mechanically -checkable, including tests-as-data?** +**Does gunbc compile itself from `.dag` data with a 0-floor hand-Rust +surface, mechanically checkable, including all tests-as-data?** Today: -- Residual Rust count is tracked by the SG-0 census with a **mechanical** +- Hand-Rust count is tracked by the SG-0 census with a **mechanical** non-test vs test split: `EXPECTED_HAND_AUTHORED_NON_TEST` + `EXPECTED_HAND_AUTHORED_FRAGMENTS` (T-PB-A) and `EXPECTED_HAND_AUTHORED_TEST` (T-PB-B) in `sg0_census_test.rs` (landed on `main` via PR #683). - `pb_hand_rust_at_shim_floor` and `pb_rust_tests_outside_residual_zero` still need to **compile and evaluate** against that partition once - T-TestGen extensions support them (`[ext]` predicates). + T-TestGen extensions support them (`[ext]` predicates). Predicate names + retained for housekeeping; semantically both target 0 under cascade + promotion (the residual carve-out is empty, so "outside residual" = "all"). - Pipeline / contract tests largely remain Rust-authored until the testgen runner lands; T-PB-B owns draft `.dag` claims in the interim. -The ask: close both halves. Non-test ≤5 irreducible-shim floor. -Tests live as `.dag` data evaluated by the testgen runner, except -the two acknowledged residuals. +The ask: close both halves. Non-test reaches the 0-floor target. +All tests live as `.dag` data evaluated by the testgen runner (boundary +tests migrate to `ExecuteCommand`-based `.dag` declarations per the +cascade-promoted TESTING.md). ## Sequence + dispatch @@ -60,12 +68,13 @@ the two acknowledged residuals. `sg0_census_test.rs`) are mechanically checked on `main` (PR #683). - **T-PB-A — ongoing.** Dispatch non-test hand-Rust reduction (PB program), compiler–`std/` consolidation, and cementing per sections below. -- **Day 1 — T-PB-B pipeline porting, Rust-side.** Identify which - pipeline / contract tests are candidates for `.dag` conversion - (vs. the two TESTING.md residuals). Draft `TestClaim` - declarations in conversational `.dag` so they're ready when - Testgen's runner closes. Don't land the conversion yet — the - runner needs to exist to evaluate them. +- **Day 1 — T-PB-B pipeline porting, Rust-side.** All + pipeline / contract tests are candidates for `.dag` conversion under + cascade promotion (the prior TESTING.md two-residual carve-out is + retracted; boundary tests use `ExecuteCommand` `.dag` declarations). + Draft `TestClaim` declarations in conversational `.dag` so they're + ready when Testgen's runner closes. Don't land the conversion yet — + the runner needs to exist to evaluate them. - **Gated on Testgen Manager.** T-PB-B's landing gate (`pb_test_file_generated_from_dag` + `pb_rust_tests_outside_residual_zero`, both `[ext]` on testgen extensions per `ROADMAP.md:68`) unblocks @@ -93,10 +102,13 @@ the two acknowledged residuals. only in **`docs/briefs/r1-testgen-manager.md`** (*Hand-off points* → **Sideways to Self-hosting Manager**) — keep that list single-source until Testgen replies. -- **Up to director.** Any proposal to adjust the two TESTING.md - residual categories (what counts as compiler-internal unit test, - what counts as external-toolchain boundary test). These are - scope decisions that live in ROADMAP / TESTING.md. +- **Up to director.** Any proposal to revisit the cascade-promoted + retraction of the prior `TESTING.md §"Post-R2 shape"` two-residual + carve-out (compiler-internal unit tests, external-toolchain boundary + tests). Under cascade promotion 2026-04-25 these dissolve under 0-floor + (helpers vanish, boundary tests migrate to `ExecuteCommand`-based + `.dag` `TestClaim` declarations). Any proposal to re-introduce a + carve-out is a scope-reversal decision living in ROADMAP / TESTING.md. - **Up to director.** If the SG-0 census partition implementation needs a broader refactor than expected, flag for director before proceeding — the ratchet is load-bearing. @@ -108,7 +120,7 @@ Lane-owner dispatch status (update as sub-deliverables close): **T-PB-A:** - [x] Non-test SG-0 census partition (`EXPECTED_HAND_AUTHORED_NON_TEST` / `EXPECTED_HAND_AUTHORED_TEST` split in `sg0_census_test.rs`) -- [ ] Hand-Rust non-test reduction toward ≤5 irreducible-shim floor +- [ ] Hand-Rust non-test reduction toward **0** (cascade-promoted 0-floor target per `docs/design-pure-bootstrap-zero.md`; supersedes prior ≤5 framing) - [ ] `pb_hand_rust_at_shim_floor` predicate compiles once T-TestGen extensions land - [ ] `pb_self_compile_fixed_point` predicate compiles once T-TestGen @@ -161,7 +173,7 @@ Decisions log (append as they happen): (#729), infer payload span shim (#730), plus T-PB-A-E (#731) and T-PB-A-F (#732). SG-0 census + SG-6 ratchets shrunk accordingly. Live floor read from `src/v3/compiler/tests/integration/sg0_census_test.rs`; - the ≤5 irreducible-shim target not yet reached. + the 0-floor target not yet reached (target updated under cascade promotion 2026-04-25; prior framing was ≤5 irreducible-shim). - 2026-04-24: **T-PB-B-1** — landed `src/v3/compiler/tests/dag/*.dag` (`data` `TestClaim` / `TestSuite` per `std.verification`); redundant compile-smoke file later retired. Further Rust deletions / `pb_*` coordination: `docs/briefs/t-pb-b-1.md`. diff --git a/docs/design-pure-bootstrap.md b/docs/design-pure-bootstrap.md index 281ce4f13e0..81857a0c7b2 100644 --- a/docs/design-pure-bootstrap.md +++ b/docs/design-pure-bootstrap.md @@ -1,6 +1,8 @@ # Pure Bootstrap (PB program) -> **🔄 SUPERSEDED 2026-04-25 by [`docs/design-pure-bootstrap-zero.md`](design-pure-bootstrap-zero.md)** (now LIVE per cascade promotion). The ≤5-floor framing throughout this doc is **retracted**. The 2-3 principled-floor framing introduced via [PR #756](https://github.com/gunb-ai/gunbc/pull/756) is also retracted. Both are superseded by the **0-floor target** under the Pure Bootstrap to Zero program. +> **🔄 SUPERSEDED 2026-04-25 by [`docs/design-pure-bootstrap-zero.md`](design-pure-bootstrap-zero.md)** (now LIVE per cascade promotion [PR #782](https://github.com/gunb-ai/gunbc/pull/782)). The ≤5-floor framing throughout this doc is **retracted**. The 2-3 principled-floor framing introduced via [PR #756](https://github.com/gunb-ai/gunbc/pull/756) is also retracted. Both are superseded by the **0-floor target** under the Pure Bootstrap to Zero program. +> +> **Treat all numeric floors below as retracted.** Specific lines that quote in isolation (e.g., the table row at the `Post-PB-8 | ≤5 non-test + TESTING residual | graduation` row, body prose at lines `:105`, `:208`, `:226`, `:257-291`, `:351`, etc.) all reflect the pre-cascade framing. Do not quote any numeric shim-floor or `Post-R2 shape` residual reference from this doc as live authority — the live authority is `design-pure-bootstrap-zero.md` (target 0; residual carve-out retracted; tests migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations per `TESTING.md`). > > This doc remains in-tree as historical context for the trajectory that led to the 0-floor framing. Cross-refs migrated to `design-pure-bootstrap-zero.md`. Do not author new work against the ≤5 or 2-3 framings; route new work to the 0-floor program per Zero-Floor Manager brief at [`docs/briefs/pure-bootstrap-zero-manager.md`](briefs/pure-bootstrap-zero-manager.md). diff --git a/docs/r2-structure.md b/docs/r2-structure.md index 21bd2b36c7c..ad184eaaaea 100644 --- a/docs/r2-structure.md +++ b/docs/r2-structure.md @@ -186,25 +186,27 @@ THESIS authority (`THESIS.md:155-182`) lists: **Timeline:** lands as part of the R1 closure → R2 promotion transition (step 4 in Transition mechanics above). Not a separate program. -### 2. Pre-promotion `≤5 irreducible-shim` gate-name review (gate before ROADMAP promotion) +### 2. ~~Pre-promotion `≤5 irreducible-shim` gate-name review~~ — **RETRACTED (2026-04-25 cascade promotion)** -Surfaced by user question on 2026-04-24: the "≤5 irreducible-shim" floor in `docs/design-pure-bootstrap.md` is framed as a principled target but is actually a generous ceiling. The doc itself names the narrower case: *"If (4) and (5) can be generated, the shim is 3 files"* (§"Irreducible shim (target state)") — and v2 achieves the floor with 2 files (CLI + interpreter). The principled boundary floor is 2–3, not 5. +> **🔄 RETRACTED** — both Option A (sharpen the ≤5/3/2 trajectory) and Option B (rename gate to `pb_hand_rust_at_boundary_floor`) framed gate-name choices around fractional-shim numbers. Under the cascade-promoted 0-floor target per [`docs/design-pure-bootstrap-zero.md`](design-pure-bootstrap-zero.md) (LIVE 2026-04-25; supersedes the prior ≤5-floor framing in `docs/design-pure-bootstrap.md`), the gate threshold is **0**, not "boundary-determined 2-3". Both options below are moot. The predicate name `pb_hand_rust_at_shim_floor` is retained as housekeeping (semantic shifted: "shim floor" now reads as 0 under cascade promotion); a future predicate rename to `pb_hand_rust_zero` is post-cascade housekeeping, not a pre-promotion blocker. Section preserved below for audit-trail readability of how the design call was framed before cascade. -"≤5" reads as a principled absolute in gate names (e.g., `pb_hand_rust_at_shim_floor`) when it's really an upper bound carried for continuity with the 2024 design doc. Leaving the number unchallenged risks the "close-everything" claim of R2 resting on a shim-floor number that's looser than the principled floor. +~~Surfaced by user question on 2026-04-24: the "≤5 irreducible-shim" floor in `docs/design-pure-bootstrap.md` is framed as a principled target but is actually a generous ceiling. The doc itself names the narrower case: *"If (4) and (5) can be generated, the shim is 3 files"* (§"Irreducible shim (target state)") — and v2 achieves the floor with 2 files (CLI + interpreter). The principled boundary floor is 2–3, not 5.~~ -**Required before promotion:** one of — -- **Option A (sharpen-and-keep)** — edit `design-pure-bootstrap.md` to explicitly name the trajectory (`baseline → ~20 → 5 → 3 → 2`); keep `≤5` as the gate name but document that the principled boundary-determined floor is 2–3; promote R2 structure as-is. -- **Option B (rename)** — rename the gate to `pb_hand_rust_at_boundary_floor` (threshold = boundary-determined, not a fixed number); land the doc edit + gate rename together; promote R2 structure after rename lands. +~~"≤5" reads as a principled absolute in gate names (e.g., `pb_hand_rust_at_shim_floor`) when it's really an upper bound carried for continuity with the 2024 design doc. Leaving the number unchallenged risks the "close-everything" claim of R2 resting on a shim-floor number that's looser than the principled floor.~~ -Authority: `docs/design-pure-bootstrap.md` §"Irreducible shim (target state)"; v2 empirical evidence (CLI + interpreter = 2 files per the same doc's "Inspiration: v2's model" section). +~~**Required before promotion:** one of —~~ +- ~~**Option A (sharpen-and-keep)** — edit `design-pure-bootstrap.md` to explicitly name the trajectory (`baseline → ~20 → 5 → 3 → 2`); keep `≤5` as the gate name but document that the principled boundary-determined floor is 2–3; promote R2 structure as-is.~~ +- ~~**Option B (rename)** — rename the gate to `pb_hand_rust_at_boundary_floor` (threshold = boundary-determined, not a fixed number); land the doc edit + gate rename together; promote R2 structure after rename lands.~~ -Non-blocking for this PR. Not done in this PR because the gate rename is a cross-doc edit with R1-lane-acceptance implications (T-PB-A's gate name would change); both land as prerequisites to the ROADMAP promotion. +~~Authority: `docs/design-pure-bootstrap.md` §"Irreducible shim (target state)"; v2 empirical evidence (CLI + interpreter = 2 files per the same doc's "Inspiration: v2's model" section).~~ + +~~Non-blocking for this PR. Not done in this PR because the gate rename is a cross-doc edit with R1-lane-acceptance implications (T-PB-A's gate name would change); both land as prerequisites to the ROADMAP promotion.~~ ## Cross-refs - Parent: `ROADMAP.md` (sections: `## Release R1 Program`; `## Post-R1 Program — Grounding Completeness`; `## Tracked debts — 2026-04 analyses`). - Substrate design: `docs/design-substrate-carrier-port-program.md` (E-family lanes + §6a per-method-metadata). -- Self-hosting anchor: `docs/design-pure-bootstrap.md` (≤5 shim floor + SG census). +- Self-hosting anchor: [`docs/design-pure-bootstrap-zero.md`](design-pure-bootstrap-zero.md) (LIVE 2026-04-25; 0-floor target + SG census). Supersedes [`docs/design-pure-bootstrap.md`](design-pure-bootstrap.md) (now SUPERSEDED; ≤5-floor framing retracted). - Thesis: `THESIS.md §"Enumerable impossible-bug classes"` (R2+ tags authority); `THESIS.md §"Thesis claims — complete list"` (Tier-1 claim lineage). - Lens capability: `docs/v3-lens-capability-register.md` (per-lens capability tracking). - DB history: `docs/db-history/db-18.md` (DB-18 Part-2 shipped: workflow-effect carrier + Rust reflection; Part-3 queued: Go accessor). Note: `ROADMAP.md §"Post-R1 Program — Grounding Completeness"` tags "DB-18 parametric algebra attachment" as a post-R1 blocker; that label is not obviously aligned with db-history's DB-18 scope — a pre-promotion rename or new DB number may be warranted for the R2 parametric-algebra prereq. diff --git a/docs/thesis/compiler-std-consolidation.md b/docs/thesis/compiler-std-consolidation.md index 45c552ab22f..a3e35b006e6 100644 --- a/docs/thesis/compiler-std-consolidation.md +++ b/docs/thesis/compiler-std-consolidation.md @@ -2,7 +2,7 @@ > Parent: [THESIS.md](../../THESIS.md) > Related: [epistemic-stacking.md](epistemic-stacking.md), [structural-decompression.md](structural-decompression.md), [what-else-falls-out.md](what-else-falls-out.md) -> Operational: [Pure Bootstrap design](../design-pure-bootstrap.md), [lens capability register](../v3-lens-capability-register.md) +> Operational: [Pure Bootstrap to Zero design](../design-pure-bootstrap-zero.md) (LIVE 2026-04-25 — live authority; supersedes the [≤5-floor design doc](../design-pure-bootstrap.md) now marked SUPERSEDED), [lens capability register](../v3-lens-capability-register.md) ## Claim @@ -28,7 +28,7 @@ A small set of concepts genuinely belong to the compiler because they describe t - **Code-generation registry** — `src/v3/compiler/regen.dag`. The map from `.dag` declarations to generated Rust output paths. `LensRegistryEntry`. Compiler-specific because only the compiler is generating code for itself. - **Lens bodies** — the analyses the compiler ships with, under `src/v3/lenses/*.dag`. Users can write similar analyses, but the compiler's *bundled set* is its API surface. - **Substrate reflection accessors** — `declaration_by_id`, `port`, `node`, `resolve_producer`, `lane2_workflow_at`. Reads over the Dag the compiler is currently operating on. Users can access *their own Dags* the same way, but the compiler's runtime accessor set is its API. -- **Bootstrap shim** — `src/v3/compiler/src/` at minimal steady state (target: ≤5 hand-maintained Rust files). The irreducible entry point. +- **Bootstrap shim** — `src/v3/compiler/src/` at the **0-floor target per [`docs/design-pure-bootstrap-zero.md`](../design-pure-bootstrap-zero.md)** (LIVE 2026-04-25; supersedes the prior ≤5-floor framing). The entry point dissolves under cascade promotion via the PB-Bootstrap-Process lane (bootstrap workflow declared as `.dag` data; `bootstrap.rs` becomes a generated trampoline or vanishes). Everything else moves to `std/`: Token, File, Path, SourceSpan, Diagnostic, Identifier, Behavior, TypeConnective, Declaration, DagPort, CardinalityBound, ArrowBody (when stable), and any future concept that can be used by both the compiler and user programs. @@ -84,7 +84,7 @@ Every file under `src/v3/std/*.dag` is a migration candidate once the bootstrap ### Rust hand-written files (bootstrap shim target) -The Pure Bootstrap design doc targets ≤5 hand-maintained Rust files. Current state has ~5-10 substantial hand-Rust files (parser body algorithm, lower algorithm body, infer algorithm body, emit backbone, bootstrap.rs). Each has a named capability-gap reason; each dissolves when its gap closes. +The Pure Bootstrap to Zero design doc ([`docs/design-pure-bootstrap-zero.md`](../design-pure-bootstrap-zero.md), LIVE 2026-04-25; supersedes the prior ≤5-floor framing in `docs/design-pure-bootstrap.md`) targets **0** hand-maintained Rust files. Current state has ~5-10 substantial hand-Rust files (parser body algorithm, lower algorithm body, infer algorithm body, emit backbone, bootstrap.rs). Each has a named capability-gap reason; each dissolves when its gap closes — including `bootstrap.rs` itself, via the PB-Bootstrap-Process lane (Zero-Floor Manager) that declares the bootstrap workflow as `.dag` data. ### Upcoming-lane alignment check @@ -163,7 +163,7 @@ The exemption dissolves at SG-2c-proper completion; both thesis doc and ROADMAP **Secondary ratchet — v3-std tree consolidation.** Count of `type` declarations in `src/v3/std/*.dag`. Baseline: 162 types across 15 files after adding `src/v3/std/parse_surface.dag` (the post-tokenize 148 plus 14 migrated surface-schema types). These collapse to `dsl/std/*.dag` wholesale when the file-preference scaffold dissolves (ROADMAP: v2 retirement gate). This ratchet is gated by that dissolution, not per-lane moves. -**Tertiary ratchet — hand-Rust surface.** This doc does not duplicate the Pure Bootstrap ratchet; it anchors to it. The authoritative measure is **SG-0's** `(EXPECTED_HAND_AUTHORED_NON_TEST ∪ EXPECTED_HAND_AUTHORED_TEST ∪ EXPECTED_HAND_AUTHORED_FRAGMENTS) ∖ GENERATED_FILES` (live in `src/v3/compiler/tests/integration/sg0_census_test.rs`); [docs/design-pure-bootstrap.md](../design-pure-bootstrap.md)'s PB-0 ratchet is the tracking program. **The count is whatever the live ratchet test reads today** — any number in prose drifts stale. For a current snapshot, run the SG-0 census test directly; do not approximate via `grep` on the expected lists alone, because the ratchet subtracts `GENERATED_FILES` at runtime and splits non-test vs test paths — grep counts the pre-subtraction set, not the authoritative post-subtraction set. Target: **≤5** on the **non-test** subset per Pure Bootstrap's irreducible-shim goal. Concrete hand-Rust that still needs to dissolve: parse algorithm, lower algorithm body, infer algorithm body, emit backbone, bootstrap shim, and lens-adjacent Rust files (some of which are Band-C-STUB backs per the lens capability register — dissolving when substrate carriers and emit `match` capabilities land). +**Tertiary ratchet — hand-Rust surface.** This doc does not duplicate the Pure Bootstrap ratchet; it anchors to it. The authoritative measure is **SG-0's** `(EXPECTED_HAND_AUTHORED_NON_TEST ∪ EXPECTED_HAND_AUTHORED_TEST ∪ EXPECTED_HAND_AUTHORED_FRAGMENTS) ∖ GENERATED_FILES` (live in `src/v3/compiler/tests/integration/sg0_census_test.rs`); [docs/design-pure-bootstrap-zero.md](../design-pure-bootstrap-zero.md) (LIVE 2026-04-25; supersedes [docs/design-pure-bootstrap.md](../design-pure-bootstrap.md))'s PB-* ratchet is the tracking program. **The count is whatever the live ratchet test reads today** — any number in prose drifts stale. For a current snapshot, run the SG-0 census test directly; do not approximate via `grep` on the expected lists alone, because the ratchet subtracts `GENERATED_FILES` at runtime and splits non-test vs test paths — grep counts the pre-subtraction set, not the authoritative post-subtraction set. Target: **0** on both non-test and test subsets per the Pure Bootstrap to Zero 0-floor goal (cascade-promoted 2026-04-25). Concrete hand-Rust that still needs to dissolve: parse algorithm, lower algorithm body, infer algorithm body, emit backbone, bootstrap shim (via PB-Bootstrap-Process), and lens-adjacent Rust files (some of which are Band-C-STUB backs per the lens capability register — dissolving when substrate carriers and emit `match` capabilities land). ## How this claim composes with existing tracked work @@ -182,7 +182,7 @@ The exemption dissolves at SG-2c-proper completion; both thesis doc and ROADMAP ## Related docs - [THESIS.md](../../THESIS.md) — parent thesis; this doc is a claim elaboration -- [docs/design-pure-bootstrap.md](../design-pure-bootstrap.md) — the algorithmic-emission side of the bootstrap program +- [docs/design-pure-bootstrap-zero.md](../design-pure-bootstrap-zero.md) — LIVE 2026-04-25; the live authority on the 0-floor target. Supersedes [docs/design-pure-bootstrap.md](../design-pure-bootstrap.md) (now SUPERSEDED) on the algorithmic-emission side of the bootstrap program. - [docs/v3-lens-capability-register.md](../v3-lens-capability-register.md) — analysis-side honesty register (parallel discipline, different axis) - [INVARIANTS.md](../../INVARIANTS.md) §P1, §P2, §P5 — the invariants this claim extends - [epistemic-stacking.md](epistemic-stacking.md) — every concept grounds in primitives via an ontological DAG (the in-repo long-form of the grounding claim this doc extends to the compiler/user boundary) From 0fb223a18f8f9ec431b51d4a6fa5f3d7f073e25b Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 00:06:14 -0400 Subject: [PATCH 30/52] docs(cascade-promotion): correct ExecuteCommand runner-capability claim MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves codex BLOCKING #1 at sha fed6b032 (P1 live-state violation): TESTING.md:195 and the matching prose in design-pure-bootstrap-zero.md:138 overstated live runner capability — claimed runner support landed in PR #688/#741 with "emit Rust, invoke rustc on output, check exit code" as a structurally-equivalent migration path. Verified against live sources: - src/v3/std/verification.dag:115-119 — ExecuteCommand predicate schema exists (declared via PR #678). - src/v3/compiler/tests/integration/m1_5_testgen_test.rs:292-294 — M1.5 testgen harness allowlists ONLY `command == "true" && args.is_empty() && expect_exit == 0`. - src/v3/compiler/tests/integration/m1_5_testgen_test.rs:394-398 — panics fail-closed on any other shape with explicit "ExecuteCommand shell shape is not supported here (runner-owned — do not treat as ordinary false)". - src/v3/compiler/src/test_runner.rs:352-382 — Rust TestRunner has no match arm for ExecuteCommand; falls through to ClaimResult:: NotYetImplemented. Reality: a TestClaim declaring rustc/python/go invocation is structurally expressible as data today, but executing it is blocked. Full arbitrary-command runner support is the PB-Runtime lane's deliverable. Files updated: - TESTING.md:195 — capability state callout with file:line citations; "Full runner support — arbitrary command + args (rustc/python/go) with exit-code capture — is deferred to the PB-Runtime lane (Zero-Floor program)." Bullet about migration shape preserved as the cascade-named successor pattern, not as a live capability. - TESTING.md:205 — 0-floor-shape gate adds "AND the PB-Runtime lane lands the ExecuteCommand runner extension" as an explicit precondition. - docs/design-pure-bootstrap-zero.md:138 — same correction for the matching prose, with PB-Runtime named as the runner-extension dependency for boundary-test migration. - ROADMAP.md:54 (T-PB-B row) — "predicate schema landed PR #678; runner foundation in #688/#741 with `true`-no-args allowlist only — full arbitrary-command runner support deferred to PB-Runtime lane, blocking the actual boundary-test migration." Dependencies column extended to "DB-15 + T-TestGen + PB-Runtime". The (Resolved.) self-claim at design-pure-bootstrap-zero.md:29 still holds for atomic-cascade-across-authority-docs; this commit closes the remaining capability/claim mismatch flagged by codex. (Codex BLOCKING #2 — THESIS.md + compiler-std-consolidation.md still SUPERSEDED-pointing — was sha-stale; resolved in c85e6916d.) Co-Authored-By: Claude Opus 4.7 (1M context) --- ROADMAP.md | 2 +- TESTING.md | 6 +++--- docs/design-pure-bootstrap-zero.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 20bea0c65ca..f44e5387e09 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -51,7 +51,7 @@ Each lane owns one concrete `.dag` gate. Lane owners do the comprehensive decomp | T-TestGen | L | Testgen runner, service simulation, first-class TestClaim | DB-15 follow-up | | T-LensAPI | M-L | User-authored lenses + composition | Lens capability honesty pass | | T-PB-A | XL | Compiler self-emits (fixed-point); **non-test** hand-Rust surface reaches **0** (per `docs/design-pure-bootstrap-zero.md` LIVE 2026-04-25; supersedes the prior ≤5-floor + 2-3-principled-floor framings in `docs/design-pure-bootstrap.md` + PR #756, both retracted in the cascade promotion PR). Generated escape hatch OK. Live baseline is the non-test subset of the SG-0 census (`EXPECTED_HAND_AUTHORED_NON_TEST` file-level + `EXPECTED_HAND_AUTHORED_FRAGMENTS` crate-root scaffolds) in `src/v3/compiler/tests/integration/sg0_census_test.rs` — this doc does not freeze the count. **Lens-producer files are the priority slice within this census** (concrete examples: `per_call_descent_evidence` at `src/v3/compiler/src/dag.rs`; the cost / complexity / descent-evidence producer family around the E-family port). Retiring a lens-producer `.rs` dissolves "lens purity by reviewer-convention" into "lens purity by construction" via the closed-world `.dag` kernel — the bounded kernel admits no hidden computation in a lens body, so `.dag`-authored lens producers are pure-total-projections by construction rather than by audit. That purity is what makes lens sustainability structural rather than carried by reviewer memory. Tracked as the `lens_producer_files_remaining` gate below. The **test subset** (`EXPECTED_HAND_AUTHORED_TEST`) of the same census is T-PB-B's responsibility, not T-PB-A's. | Compiler–std consolidation program, SG-0 census | -| T-PB-B | M | Tests-as-data — pipeline/contract tests port to `.dag`. ~~The two `TESTING.md §Post-R2 shape` residual categories (compiler-internal unit tests for Rust-only helpers; external-toolchain boundary tests invoking rustc/go/python) remain Rust-authored.~~ **Retracted via cascade promotion 2026-04-25**: the residual carve-out dissolves under the 0-floor framing — Rust-only-helper unit tests vanish naturally (no Rust-only helpers under 0-floor); external-toolchain boundary tests migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations (predicate landed in PR #678, runner support in #688/#741). See `TESTING.md` for the 0-residual framing. | DB-15 + T-TestGen | +| T-PB-B | M | Tests-as-data — pipeline/contract tests port to `.dag`. ~~The two `TESTING.md §Post-R2 shape` residual categories (compiler-internal unit tests for Rust-only helpers; external-toolchain boundary tests invoking rustc/go/python) remain Rust-authored.~~ **Retracted via cascade promotion 2026-04-25**: the residual carve-out dissolves under the 0-floor framing — Rust-only-helper unit tests vanish naturally (no Rust-only helpers under 0-floor); external-toolchain boundary tests migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations (predicate **schema** landed PR #678; runner foundation in #688/#741 with `true`-no-args allowlist only — **full arbitrary-command runner support deferred to PB-Runtime lane**, blocking the actual boundary-test migration). See `TESTING.md` for live capability state. | DB-15 + T-TestGen + PB-Runtime | | T-Demo | M | Two canonical fixtures + impossible-bugs suite + narrative | — (new) | ### Lane acceptance — `.dag` gates diff --git a/TESTING.md b/TESTING.md index 31cde0e9f3c..a412287fa14 100644 --- a/TESTING.md +++ b/TESTING.md @@ -192,9 +192,9 @@ shares the compile work when sources match. > **🔄 RETRACTED 2026-04-25 (cascade promotion of `docs/design-pure-bootstrap-zero.md`).** The previous "two residual categories" framing (compiler-internal unit tests + external-toolchain boundary tests stay Rust-authored permanently) is **retracted under the 0-floor target**. Both categories dissolve: > > - **Rust-only-helper unit tests vanish naturally** — under 0-floor (per `docs/design-pure-bootstrap-zero.md` LIVE), there are no Rust-only helpers in v3's source tree; everything generates from `.dag`. Unit tests for non-existent helpers don't need to exist. -> - **External-toolchain boundary tests migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations.** The `ExecuteCommand` predicate landed in PR #678; runner support landed in #688/#741. A `TestClaim` like *"emit Rust, invoke rustc on output, check exit code"* is structurally identical to today's hand-Rust boundary tests, expressed as data. +> - **External-toolchain boundary tests migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations** as the cascade-named successor pattern. **Capability state today (2026-04-25):** the `ExecuteCommand` predicate is declared in `src/v3/std/verification.dag:115-119` (PR #678 landed the schema). Runner support is **foundation-only**: the M1.5 testgen harness at `src/v3/compiler/tests/integration/m1_5_testgen_test.rs:292-294` accepts only the tautological allowlist shape (`command == "true" && args.is_empty() && expect_exit == 0`) and panics fail-closed (`m1_5_testgen_test.rs:394-398`) on any other shape ("ExecuteCommand shell shape is not supported here (runner-owned — do not treat as ordinary false)"). The Rust `TestRunner` at `src/v3/compiler/src/test_runner.rs:352-382` returns `ClaimResult::NotYetImplemented(...)` for `ExecuteCommand` (no match arm). **Full runner support — arbitrary `command` + `args` (e.g., `rustc`, `python`, `go`) with exit-code capture — is deferred to the PB-Runtime lane** (Zero-Floor program). A `TestClaim` like *"emit Rust, invoke rustc on output, check exit code"* is structurally expressible as data today; **executing it is blocked** until PB-Runtime lands the runner extension. > -> **0-residual is the target.** Until v3's source tree reaches 0 hand-authored files, write tests in whichever shape (Rust integration test OR `.dag` `TestClaim`) is cleanest for the work being done; on cascade-promoted PB-Runtime lane execution, residual Rust tests migrate per the `ExecuteCommand` pattern. See `docs/design-pure-bootstrap-zero.md` §"PB-Runtime" for the migration scope. +> **0-residual is the target.** Until v3's source tree reaches 0 hand-authored files AND the PB-Runtime runner extension lands, write tests in whichever shape (Rust integration test OR `.dag` `TestClaim` evaluable by the current restricted runner) is cleanest for the work being done. On cascade-promoted PB-Runtime lane execution, residual Rust tests migrate per the `ExecuteCommand` pattern. See `docs/design-pure-bootstrap-zero.md` §"PB-Runtime" for the migration scope and runner-extension dependency. Until DB-15 R2's runtime lands, write Rust integration tests that match the guidelines above so the eventual port is a @@ -202,7 +202,7 @@ rewrite of shape, not of intent. ~~**Post-R2 shape:** once DB-15 R2 ships, most of this document collapses into "see `dsl/std/verification.dag` for the test surface." The Rust-side residual is: compiler-internal unit tests (`#[cfg(test)] mod tests`) inside `src/v3/compiler/src/`, and boundary tests that invoke external toolchains. Everything else ports to `.dag`.~~ -**0-floor shape (post cascade promotion 2026-04-25):** once DB-15 R2 ships AND the Zero-Floor program reaches 0 hand-authored files (per `docs/design-pure-bootstrap-zero.md` LIVE), this document collapses into "see `dsl/std/verification.dag` for the test surface." There is **no Rust-side residual**: compiler-internal unit tests don't exist (no Rust-only helpers); external-toolchain tests use `ExecuteCommand`-based `.dag` `TestClaim` declarations. Everything is `.dag`. +**0-floor shape (post cascade promotion 2026-04-25):** once DB-15 R2 ships AND the Zero-Floor program reaches 0 hand-authored files (per `docs/design-pure-bootstrap-zero.md` LIVE) AND the PB-Runtime lane lands the `ExecuteCommand` runner extension (arbitrary `command` + `args` with exit-code capture — see capability-state note above), this document collapses into "see `dsl/std/verification.dag` for the test surface." There is **no Rust-side residual**: compiler-internal unit tests don't exist (no Rust-only helpers); external-toolchain tests use `ExecuteCommand`-based `.dag` `TestClaim` declarations evaluated by the extended runner. Everything is `.dag`. ## Anti-patterns diff --git a/docs/design-pure-bootstrap-zero.md b/docs/design-pure-bootstrap-zero.md index 6304bad17e7..f3d455060b6 100644 --- a/docs/design-pure-bootstrap-zero.md +++ b/docs/design-pure-bootstrap-zero.md @@ -135,7 +135,7 @@ Current `TESTING.md` carves out two permanent Rust-authored test categories: Both dissolve under 0-floor: - **Rust-only-helper unit tests** vanish naturally — there are no Rust-only helpers; everything generates from `.dag`. -- **External-toolchain boundary tests** migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations (the predicate landed in PR #678; runner support landed in #688/#741). A `TestClaim` like *"emit Rust, invoke rustc on output, check exit code"* is structurally identical to today's hand-Rust boundary tests. +- **External-toolchain boundary tests** migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations as the cascade-named successor pattern. **Capability state today (2026-04-25):** the `ExecuteCommand` predicate is declared (`src/v3/std/verification.dag:115-119`; schema landed PR #678). Runner support is **foundation-only**: the M1.5 testgen harness allowlists `command == "true" && args.is_empty() && expect_exit == 0` and panics fail-closed on any other shape; the Rust `TestRunner` returns `ClaimResult::NotYetImplemented` for unhandled `ExecuteCommand` invocations. **Full runner support — arbitrary `command` + `args` (e.g., `rustc`, `python`, `go`) with exit-code capture — is the PB-Runtime lane's deliverable** (the runner-extension dependency for boundary-test migration). A `TestClaim` like *"emit Rust, invoke rustc on output, check exit code"* is structurally expressible as data today; **executing it requires the PB-Runtime runner extension**. **TESTING.md rewrite scope:** - Replace "Post-R2 shape" residual section with "0-residual" framing From ff2d48a2fec7f81b5d2e2b6935ef9ec00aedabfd Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 00:15:32 -0400 Subject: [PATCH 31/52] docs(cascade-promotion): remove competing-authority hedge in R1 self-hosting brief MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves codex BLOCKING at sha 0fb223a1 (P2 single-authority violation). The prior banner contained: > "Operationally R1 closure may still ship before the 0-floor is reached > — the ratchet ensures the trajectory; the gate's acceptance number is > what shifts." This contradicted ROADMAP.md:67 which now reads T-PB-A acceptance = 0. Two competing gate semantics in the cascade is exactly what the atomic-cascade clause forbids. Replaced with single-authority-honest framing: > "R1 closure now requires the 0-floor target by gate semantics: T-PB-A > and T-PB-B are R1 acceptance gates per ROADMAP, and the cascade > promotion changed their acceptance numbers to 0; R1 cannot close > while the SG-0 census carries non-zero hand-Rust." Plus minor sharpening: - "T-PB-A's non-test target is 0" → "non-test acceptance target is 0 per ROADMAP.md:67" (cite the authority). - T-PB-B note adds "blocked on the PB-Runtime runner extension" to keep the capability-state honesty consistent with the recent fix wave. - Predicate-rename housekeeping line moved into banner ("post-cascade housekeeping, not a pre-promotion blocker") — was implicit before. The brief now genuinely inherits the cascade-promoted gate; no competing release authority. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/briefs/r1-selfhosting-manager.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/briefs/r1-selfhosting-manager.md b/docs/briefs/r1-selfhosting-manager.md index e1a9776153c..80778dc2dd0 100644 --- a/docs/briefs/r1-selfhosting-manager.md +++ b/docs/briefs/r1-selfhosting-manager.md @@ -1,6 +1,6 @@ # R1 Self-hosting Manager Brief -> **🔄 Cascade-promotion update (2026-04-25)** — R1 self-hosting acceptance reframed under the 0-floor target per [`docs/design-pure-bootstrap-zero.md`](../design-pure-bootstrap-zero.md) (LIVE 2026-04-25 via cascade promotion PR #782; supersedes the prior ≤5-floor framing in `docs/design-pure-bootstrap.md`, now SUPERSEDED). T-PB-A's non-test target is **0** (not ≤5). T-PB-B's prior `TESTING.md §"Post-R2 shape"` two-residual carve-out is **retracted**: helper unit tests vanish naturally, boundary tests migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations (per `TESTING.md` rewrite in cascade promotion). Operationally R1 closure may still ship before the 0-floor is reached — the ratchet ensures the trajectory; the gate's *acceptance number* is what shifts. Below is updated for cascade-coherent prose; predicate names retained for housekeeping. Original brief content below this banner reflects pre-cascade framing where not yet inline-updated; treat the cascade-promoted authorities (`design-pure-bootstrap-zero.md`, ROADMAP T-PB-A/T-PB-B rows + Goals bullet, `TESTING.md`) as the source of truth on any wording divergence. +> **🔄 Cascade-promotion update (2026-04-25)** — R1 self-hosting acceptance reframed under the 0-floor target per [`docs/design-pure-bootstrap-zero.md`](../design-pure-bootstrap-zero.md) (LIVE 2026-04-25 via cascade promotion PR #782; supersedes the prior ≤5-floor framing in `docs/design-pure-bootstrap.md`, now SUPERSEDED). T-PB-A's non-test acceptance target is **0** (not ≤5) per `ROADMAP.md:67`; T-PB-B's prior `TESTING.md §"Post-R2 shape"` two-residual carve-out is **retracted** (helper unit tests vanish naturally; boundary tests migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations, blocked on the PB-Runtime runner extension per `TESTING.md` capability-state note). **R1 closure now requires the 0-floor target by gate semantics**: T-PB-A and T-PB-B are R1 acceptance gates per ROADMAP, and the cascade promotion changed their acceptance numbers to 0; R1 cannot close while the SG-0 census carries non-zero hand-Rust. The cascade promotion atomically shifted the gate; this brief inherits that gate. Predicate names retained for housekeeping (rename to `pb_hand_rust_zero` is post-cascade housekeeping, not a pre-promotion blocker). Original brief content below this banner reflects pre-cascade framing where not yet inline-updated; treat the cascade-promoted authorities (`design-pure-bootstrap-zero.md`, ROADMAP T-PB-A/T-PB-B rows + Goals bullet, `TESTING.md`) as the source of truth on any wording divergence. ## Orient before reading From e35103fadc9f18e3260eb06872c6cb8fb3dcade3 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 11:00:33 -0400 Subject: [PATCH 32/52] docs(briefs): R2 second-wave worker-escalation fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Four substantive worker STOP-AND-ESCALATEs from briefs landed in PR #797. All four worker recommendations correct; each needs a Director call + brief update. ## sunny-otter-128 / unenumerated-effects — SPLIT into parser + substrate Worker correctly identified that brief req 2 (declared-effect carrier as part of fn type signature, per feedback_no_annotations) requires net-new parser surface: SurfaceType.Arrow and SurfaceItem.Fn at src/v3/std/parse_surface.dag:71-75 / :185-199 have ZERO effect slots. Without parser surface, every user function would have declared_effects = [] while inference returns non-empty — lens fires EffectLeakageError everywhere on enable. Worker rejected power-through and recommended sibling parser sub-lane (mirror of #797's ValueBody::Map parser split). Director picked split: - NEW: docs/briefs/t-impossiblebugs-unenumerated-effects-parser-worker.md Six reqs covering SurfaceType.Arrow/Fn declared_effects field + surface syntax + lookahead + body parser + lowerer extension + exhaustive-match audit + coproduct dissolution receipt. - MODIFIED: substrate brief banner + req 2 + slice step 1 narrowed to post-parser-extension scope. Pre-flight check NOT a parser-extension step; STOP if parser sub-lane PR not merged. ## sunny-deer-629 / unhandled-diagnostic-paths — REFRAMED to design/scoping Worker found load-bearing evidence at infer.rs:3693-3703: DB-11 deliberately strips refinements at operator dispatch as a designed-in fix for symmetric-operators failure mode. Brief's "attach where b != 0 as a proof for a / b" directly contradicts this design choice. STOP-3 (where-clause conflict with DB-11) is real; STOP-1 (substrate scope) needs net-new substrate (per-operator partiality fact + predicate- entailment check + asymmetric per-operand refinement-honoring) — M+ minimum. ownership_lens precedent in original brief is post-hoc observability, not proof carrier. Worker recommended redirect to design/scoping per nested-optional precedent. Director picked redirect. Brief fully rewritten as design/scoping with four-question structure: (1) DB-11 interaction analysis; (2) substrate proposal for proof-or- totality enforcement; (3) bypass-vs-park decision (a/b/c outcomes with acceptance-theatre risk on user-defined-total-wrapper-only); (4) Director-actionable recommendation. Output is doc PR. ## wise-pike-578 / cardinality-int-lit — RE-SCOPED option (C) Worker verified at HEAD: dsl/std/substrate.dag:31 has LitInt(Int) with Int = Int64; no Int128/UInt128 types; primitives.dag:134-136 closes TargetCarrier at Word64Carrier (no Word128Carrier). Choice (b) i128 implementation requires either path 1 (hierarchy refactor — contradicts non-goal) or path 2 (regen lie between substrate and emit — violates discipline). Worker leaned option (C) re-scope: land reqs 2+3+5 against existing i64; defer req 4 (i64::MIN smoke) to a sibling sub-lane that does proper Int128/Word128 substrate work. Director picked option (C). Brief req 1 re-scoped to drop canonical- carrier-widening; lane value comes from range facts + reconciliation narrowing + out-of-range diagnostic against existing i64. Req 4 explicitly deferred with sibling-sub-lane reference. Sibling sub-lane NOT to be authored or implied in this PR; tracked separately. ## wise-boar-480 / valuebody-map — cross-lane reassignment (no brief change) Worker correctly STOP'd per the brief's own pre-flight check: parser sub-lane has not landed; SurfaceExpr::Map not on main. Director authorized cross-lane reassignment: wise-boar-480 takes the parser sub-lane (t-substrate-valuebody-map-parser-worker.md) since they already have full investigation context. No brief changes needed; the routing decision is in the dispatch. Co-Authored-By: Claude Opus 4.7 (1M context) --- ...bugs-unenumerated-effects-parser-worker.md | 106 +++++++++++++++++ ...ossiblebugs-unenumerated-effects-worker.md | 22 +++- ...ebugs-unhandled-diagnostic-paths-worker.md | 108 +++++++++++------- .../t-substrate-cardinality-int-lit-worker.md | 16 +-- 4 files changed, 193 insertions(+), 59 deletions(-) create mode 100644 docs/briefs/t-impossiblebugs-unenumerated-effects-parser-worker.md diff --git a/docs/briefs/t-impossiblebugs-unenumerated-effects-parser-worker.md b/docs/briefs/t-impossiblebugs-unenumerated-effects-parser-worker.md new file mode 100644 index 00000000000..db3762fcf40 --- /dev/null +++ b/docs/briefs/t-impossiblebugs-unenumerated-effects-parser-worker.md @@ -0,0 +1,106 @@ +# T-ImpossibleBugs unenumerated effects — parser extension `(M, R2 prereq)` + +> **Director ad-hoc dispatch.** Sibling pre-requisite to the +> [`t-impossiblebugs-unenumerated-effects-worker.md`](t-impossiblebugs-unenumerated-effects-worker.md) +> substrate sub-lane. Authored 2026-04-25 post-`sunny-otter-128` +> STOP-AND-ESCALATE on the bundled effects brief — worker verified +> that adding a declared-effect carrier to function type signatures +> requires net-new parser surface (`SurfaceType.Arrow` and +> `SurfaceItem.Fn` have zero effect slots today). Director picked +> **split** — this brief lands the parser side; the substrate brief +> narrows to "post-parser-extension" scope and dispatches sequentially. +> +> Reports back to Director (`zesty-bear-812`); Surface Manager +> territory overlap (parser surface-syntax authority). +> +> **Precedent**: this split mirrors the `ValueBody::Map` parser +> sub-lane pattern from PR #797 ([`t-substrate-valuebody-map-parser-worker.md`](t-substrate-valuebody-map-parser-worker.md)). + +## Read first + +- **[`docs/briefs/t-impossiblebugs-unenumerated-effects-worker.md`](t-impossiblebugs-unenumerated-effects-worker.md)** — sibling substrate sub-lane brief (post-this-PR-narrowed). The substrate side blocks on this PR landing. +- **[`src/v3/std/parse_surface.dag:71-75`](../../src/v3/std/parse_surface.dag)** — `SurfaceType.Arrow` declaration; today carries `inputs: List` + `output: SurfaceType` + `span: SourceSpan`. **No `declared_effects` field**. New surface-syntax + carrier extension lands here. +- **[`src/v3/std/parse_surface.dag:185-199`](../../src/v3/std/parse_surface.dag)** — `SurfaceItem.Fn` declaration. Worker decides whether to put the declared-effects field on `Arrow` (cleaner, type-signature-level) or `Fn` (item-level only); surface choice in PR description. Recommend `Arrow` since effect-as-part-of-type-signature is the discipline anchor (per `feedback_no_annotations`). +- **[`src/v3/compiler/parse_parser_body.txt`](../../src/v3/compiler/parse_parser_body.txt)** — parse-body algorithm authority. The function-type / function-item parsing paths produce the `Arrow` / `Fn` surface shapes; new declared-effects syntax lands here. Worker picks syntax (recommend post-arrow-output suffix: `fn foo() -> T effects [Read, Write]` or similar; surface choice in PR description). +- **[`src/v3/compiler/src/parse_generated.rs`](../../src/v3/compiler/src/parse_generated.rs)** — auto-generated from `parse_surface.dag` + `parse_parser_body.txt`. Per `feedback_no_generated_code_on_disk`, edits flow through `.dag` + `.txt` authority then regen. **No hand edits to `parse_generated.rs`**. +- **[`src/v3/std/substrate.dag:154-163`](../../src/v3/std/substrate.dag)** — `Declaration` and `Arrow` connectives have **zero** effect slots today; adding `declared_effects: List` to `Arrow` is purely additive on the substrate side. +- **[`src/v3/std/effects.dag` lines 262-506](../../src/v3/std/effects.dag)** — current `OperationEffect` taxonomy (Read/Upsert/Create/Append/Delete). The declared-effects carrier reuses this enum (no new effect classes; sibling substrate sub-lane's req 4 anchors on existing taxonomy). +- **[`MODELING.md`](../../MODELING.md)** + **[`INVARIANTS.md`](../../INVARIANTS.md)** + **`feedback_no_annotations`** + **`feedback_no_validation_passes`**. + +## Frame + +The substrate `declared_effects` carrier cannot land standalone — the parser must first emit declared-effects syntactically for the lowerer to populate the field. Without parser support, every user function would have `declared_effects = []` and the substrate side's lens (sibling brief) would fire `EffectLeakageError` on every effectful function in the codebase the moment it's enabled — exactly the scaffold-without-consumer pattern `feedback_parallel_representation_debt` warns against. + +This sub-lane lands the parser side. Output: + +1. New `declared_effects: List` (or equivalent — element shape worker's call) on `SurfaceType.Arrow` (or `SurfaceItem.Fn` — worker picks; recommend `Arrow`). +2. Surface syntax: post-arrow-output suffix expressing the declared effect set (recommended `fn foo() -> T effects [Read, Write]` or worker-equivalent; surface in PR description). +3. Lowering: surface `declared_effects` lowers to `Declaration.connective` (or sibling `Arrow` substrate field) carrying the resolved `List`. +4. Regen `parse_generated.rs` from authority. +5. Exhaustive-match audit: every `match SurfaceType` / `match SurfaceItem` site that today destructures `Arrow` / `Fn` updated to handle the new field (with sensible default for sites that don't care). + +Today the parser silently accepts no effect declaration; after this PR, the surface accepts an explicit effects clause and lowers it into a substrate fact. The substrate side (sibling brief) consumes that fact via the lens. + +**Function type signatures only** for this PR. Effects on closures, lambdas, method declarations, etc. — out of scope unless the same parse path is structurally reused; worker's call. + +## Six consumer-side requirements + +1. **`declared_effects` field on `SurfaceType.Arrow`** (or `SurfaceItem.Fn` — worker picks + surfaces rationale; recommend `Arrow`). Element shape: `List` where each entry resolves to an `OperationEffect` declaration (Read/Upsert/Create/Append/Delete from `effects.dag`). **Coproduct dissolution receipt** for any new variant per `feedback_coproduct_dissolution` and the `LoopBound` precedent at `docs/design-mutual-recursion-lowering.md:117-134`. +2. **Surface syntax** for the declared-effects clause. Worker picks (recommend post-arrow-output suffix); document choice + reasoning in PR description. The syntax is part of the function type signature, not an annotation (per `feedback_no_annotations`). +3. **`looks_like_effects_clause` lookahead** at the relevant parse site (function type / item parsing); routes into a new `parse_effects_clause` body. Disambiguation must not break existing function syntax. +4. **`parse_effects_clause` body parser** producing `List` (or equivalent) with the parsed effect-type references. +5. **Lowerer extension** producing the post-parser substrate carrier on `Arrow` (or `Fn`-level) declarations. Resolves each surface effect-type to its `OperationEffect` declaration. +6. **Exhaustive-match audit + updates.** Every `match` site over `SurfaceType.Arrow` / `SurfaceItem.Fn` updated for the new field. **No wildcard `_` swallowing**; per `feedback_missing_checks_review_heuristic`. + +## Slice — parser extension + +1. Add `declared_effects` field to `SurfaceType.Arrow` (per req 1) in `parse_surface.dag`. Author coproduct dissolution receipt for any new variant. +2. Edit `parse_parser_body.txt` (per reqs 2 + 3 + 4): add `looks_like_effects_clause` + `parse_effects_clause`; route from the function-type/item parse entry. +3. Add lowerer extension (per req 5) producing the post-parser substrate carrier; resolve each surface effect to its `OperationEffect` declaration. +4. Regen `parse_generated.rs` (per `feedback_no_generated_code_on_disk`). +5. Exhaustive-match audit + updates (per req 6). +6. Smoke test: parser accepts `fn read_user(id: String) -> User effects [Read]` and produces a function declaration with `declared_effects = [ReadEffect]`. **NOTE**: this PR does NOT consume the field via lens (sibling substrate sub-lane does that); after this PR the field is populated but unread. That's expected; the sibling sub-lane closes that path. Test should assert the parser-output shape, not end-to-end lens behavior. + +## Acceptance + +- [ ] All 6 consumer-side requirements satisfied + documented in PR body. +- [ ] `declared_effects` field on `SurfaceType.Arrow` (or `SurfaceItem.Fn`); coproduct dissolution receipt landed. +- [ ] `looks_like_effects_clause` + `parse_effects_clause` in `parse_parser_body.txt`. +- [ ] Lowerer resolves surface effects to `OperationEffect` declarations. +- [ ] `parse_generated.rs` regenerated; no hand edits. +- [ ] All `SurfaceType` / `SurfaceItem` exhaustive-match sites updated. +- [ ] Parser smoke test: function with declared-effects clause parses to populated `declared_effects` field. +- [ ] `cargo test --workspace --exclude v2-compiler-tests` / `clippy --all-targets -- -D warnings` / `fmt --all --check` clean. +- [ ] DB-8 fixed-point converges bit-identically. +- [ ] SG-0 census deltas: regen-output updates land in REGEN_OUTPUTS partition. + +## STOP-AND-ESCALATE + +Surface to Director. + +- **Surface-syntax design contention** (e.g., post-arrow-output suffix conflicts with existing rules; effects-clause-first vs effects-clause-last design call) — STOP. Surface Manager / parser-owner sign-off needed. +- **`Arrow` vs `Fn`-level placement** — if execution surfaces a strong reason to put the field on `Fn` instead of `Arrow` (e.g., lambdas don't have explicit type signatures; effect-as-type-component breaks), STOP. Director call. +- **`parse_parser_body.txt` edits cascade beyond function-parsing** — STOP. Cross-cutting parser changes need Surface Manager coordination. +- **Exhaustive-match audit reveals consumer using wildcard `_`** — STOP. Surface a fix decision (this PR vs follow-up). +- **DB-11 / refinement interaction surfaces** — if the declared-effects-as-type-signature shape interacts with DB-11's refinement strip (`infer.rs:3693-3703`), STOP. May need explicit handling. +- **DB-8 fixed-point drifts** — STOP immediately. + +## Non-goals + +- **Not adding the lens.** That's the sibling substrate sub-lane. +- **Not consuming `declared_effects`** beyond storage; the lens consumes it. +- **Not changing existing function syntax.** Functions without effects clauses continue to parse with empty `declared_effects`. +- **Not extending `OperationEffect` taxonomy.** New effect classes (e.g., `Logging`) are out of scope; lane anchors on existing Read/Upsert/Create/Append/Delete. +- **Not extending to closures/lambdas/method-decls** unless the parse path naturally reuses. + +## Reporting + +- Single PR. Title: `feat(v3): T-ImpossibleBugs parser-extension — declared_effects on SurfaceType.Arrow (prereq for unenumerated-effects substrate sub-lane)`. +- PR body cites this brief + addresses each of the 6 reqs + documents surface-syntax + Arrow-vs-Fn placement choices. +- On merge: signal Director; Director signals sibling substrate sub-lane (`t-impossiblebugs-unenumerated-effects-worker.md`) is now dispatchable. + +## Cross-manager note + +- **Surface Manager**: heads-up at dispatch. This PR is Surface Manager territory by overlap (parser surface-syntax authority); coordinate at landing. +- **Zero-Floor Manager**: heads-up if `parse_surface.dag` changes touch substrate.dag-adjacent territory. Coproduct receipt requirement (req 1) is the substrate-discipline anchor. +- **Grounding Manager**: no current overlap. diff --git a/docs/briefs/t-impossiblebugs-unenumerated-effects-worker.md b/docs/briefs/t-impossiblebugs-unenumerated-effects-worker.md index 51a43af6ce6..43eb0ac1690 100644 --- a/docs/briefs/t-impossiblebugs-unenumerated-effects-worker.md +++ b/docs/briefs/t-impossiblebugs-unenumerated-effects-worker.md @@ -1,9 +1,25 @@ -# T-ImpossibleBugs — unenumerated effects `(S, R2)` +# T-ImpossibleBugs — unenumerated effects `(S, R2; SPLIT — parser sub-lane lands first)` > **Director ad-hoc dispatch.** R2 T-ImpossibleBugs class 3 of 3 per > [`docs/r2-structure.md`](../r2-structure.md) §"Goal 4". Independent > of the other two impossible-bug classes — any worker can dispatch > in parallel. Reports to Director (`zesty-bear-812`). +> +> **🔄 SPLIT 2026-04-25 (post-`sunny-otter-128` STOP-AND-ESCALATE).** +> Worker correctly identified that brief req 2 (declared-effect carrier +> as part of function type signature) requires surface-syntax authoring: +> `SurfaceType.Arrow` and `SurfaceItem.Fn` (`src/v3/std/parse_surface.dag:71-75`, +> `:185-199`) have **zero** effect slots today. Without parser surface, +> every user function would have `declared_effects = []` while inference +> returns non-empty — lens fires `EffectLeakageError` everywhere it's +> enabled. Worker recommended sibling parser sub-lane (mirror of +> `t-substrate-valuebody-map-parser-worker.md` precedent from #797). +> **Director picked split.** Parser side now lives in +> [`t-impossiblebugs-unenumerated-effects-parser-worker.md`](t-impossiblebugs-unenumerated-effects-parser-worker.md) +> as a sibling pre-requisite sub-lane. This brief is now scoped to +> **post-parser-extension state**: assumes `declared_effects` field is +> already on `SurfaceType.Arrow` (or `SurfaceItem.Fn`) by the parser; +> this PR consumes that via the lens + diagnostic. ## Read first @@ -31,12 +47,12 @@ Sub-lane scope: enough effect-substrate to close declared-vs-actual leakage end- ## Three consumer-side requirements 1. **Effect-inference pass — direct-call scope only (no inter-procedural call-graph walk).** Walks function body DAG; collects effects from **direct calls to known-effectful primitives** (e.g., calls that already have an `OperationEffect` derived via `derive_op_effect` at `effects.dag:722-755`). Does NOT follow transitive call chains (A calls B which calls C). Lives as a **lens** at `src/v3/lenses/effect_enumeration.dag`, parallel to `cost.dag` precedent (per `feedback_no_validation_passes` + cost/complexity-lens precedent: lens-shape, not validation-pass-shape; not a lowering-phase fact). The function-declaration *carries* a declared-effect carrier and a derived inferred-effect carrier as facts; mismatch is a structural Diagnostic, not a "check pass." -2. **Declared-effect carrier on function declarations as part of the function type signature** (per `feedback_no_annotations` — first-class language feature, not annotation). Substrate-level: extend `Declaration` (or the function-arrow connective shape) to carry the declared effect set as a structural field. Surface syntax is part of the function type signature (mechanism: worker may anchor on existing arrow-body extension precedent; not an annotation, not a separate metadata channel). If parser-side surface-syntax authoring requires non-trivial parser scope, STOP-AND-ESCALATE — coordinate with parser owners on a coupled PR or sibling parser sub-lane. +2. **Declared-effect carrier on function declarations as part of the function type signature — assumed already landed via parser sub-lane.** Per the split: the parser sub-lane ([`t-impossiblebugs-unenumerated-effects-parser-worker.md`](t-impossiblebugs-unenumerated-effects-parser-worker.md)) lands the surface-syntax extension to `SurfaceType.Arrow` (or `SurfaceItem.Fn`) and the lowered `declared_effects` field on the function-arrow connective. **STOP-AND-ESCALATE if dispatching against this brief and the parser sub-lane has NOT landed** — sequencing error. This substrate brief consumes the post-parser carrier; does NOT author it. 3. **Structural carrier mismatch surfaces a Diagnostic (no validation pass).** At declaration site, the carrier facts (declared + inferred) are present; if declared ⊇ inferred fails (set-cover violation), the lens emits `EffectLeakageError` naming declared set + inferred set + specific operations that leak. Per `feedback_no_validation_passes` + C-8 fail-closed: this is structural mismatch on always-present carriers, not a pass that "checks" a validity property. Smoke + integration test: a function declares no effects but body directly calls `service.upsert(...)` (an `UpsertEffect`-emitting op per `derive_op_effect`) → diagnostic; same function with `UpsertEffect` declared → accepted. ## Slice — effect inference + declared-effect carrier + leakage diagnostic -1. Add declared-effect carrier (per req 2) to function declarations as part of the function type signature. Parser/lowerer extension; STOP-AND-ESCALATE if parser scope balloons. +1. **Pre-flight check (NOT a parser-extension step)**: confirm the parser sub-lane PR has merged and `SurfaceType.Arrow` (or `SurfaceItem.Fn`) carries the `declared_effects` field on `main`. If not, STOP per req 2 — that's a sequencing error. 2. Implement effect-inference lens (per req 1) at `src/v3/lenses/effect_enumeration.dag`, parallel to cost.dag precedent. 3. Structural-mismatch Diagnostic (per req 3). New `EffectLeakageError` variant. 4. Demo using existing `OperationEffect` taxonomy: pick a function that calls a known-effectful primitive directly (e.g., a service method invoking `derive_op_effect` paths to produce `UpsertEffect` or `CreateEffect`). Do NOT pick `Logging` — it's not in the existing taxonomy and would force a coupled enum extension. diff --git a/docs/briefs/t-impossiblebugs-unhandled-diagnostic-paths-worker.md b/docs/briefs/t-impossiblebugs-unhandled-diagnostic-paths-worker.md index 35b056a4449..9e7a9dee98c 100644 --- a/docs/briefs/t-impossiblebugs-unhandled-diagnostic-paths-worker.md +++ b/docs/briefs/t-impossiblebugs-unhandled-diagnostic-paths-worker.md @@ -1,77 +1,97 @@ -# T-ImpossibleBugs — unhandled diagnostic paths `(S, R2)` +# T-ImpossibleBugs — unhandled diagnostic paths **(DESIGN/SCOPING brief, S — produces substrate proposal, NOT implementation)** > **Director ad-hoc dispatch.** R2 T-ImpossibleBugs class 2 of 3 per > [`docs/r2-structure.md`](../r2-structure.md) §"Goal 4". Independent -> of the other two impossible-bug classes — any worker can dispatch -> in parallel. Reports to Director (`zesty-bear-812`). +> of the other two impossible-bug classes. Reports to Director +> (`zesty-bear-812`). +> +> **🔄 REFRAMED 2026-04-25 (post-`sunny-deer-629` STOP-AND-ESCALATE).** +> Original brief framed this as an implementation lane against an +> "ownership_lens" precedent that was shape-only, not mechanism. Worker +> verified at HEAD: (a) **DB-11 deliberately strips refinements at +> operator dispatch** at `src/v3/compiler/src/infer.rs:3693-3703` as a +> designed-in fix for a prior failure mode (refinement-as-proof-obligation +> breaks symmetric operators like `>`); (b) the brief's framing of +> *"attach `where b != 0` as a proof for `a / b`"* directly contradicts +> this design choice — operator dispatch is engineered to *ignore* +> refinements on operands; (c) ownership_lens is a post-hoc +> observability lens (consumes lowered DAG and asserts a count), NOT +> a proof carrier that gates type-checking; the precedent is +> shape-only, not mechanism. Worker correctly STOP-and-escalated with +> recommendation to redirect to design/scoping. **Director picked +> redirect.** This brief now produces a substrate proposal + +> bypass-or-substrate-or-park decision, NOT implementation. ## Read first -- **[`THESIS.md` §"Tier 2 — Runtime safety" + §"Enumerable impossible-bug classes" lines 348-350](../../THESIS.md)** — class definition: *"Division by zero, integer overflow, out-of-bounds, force-unwrap, partial functions — either proven safe at compile time or made total. No partial functions in the runtime."* THESIS.md:350: *"Gated on Tier 2 substrate (post-R1)."* -- **[`docs/r2-structure.md` §"Goal 4"](../r2-structure.md)** — sub-lane scoping; `[R2+]` per ROADMAP T-Demo row. -- **[`src/v3/std/verification.dag`](../../src/v3/std/verification.dag)** — current `DiagnosticKind` (tokenizer / parse / type / arity / resolve). Extend (or sibling carrier) for runtime-safety diagnostic paths. -- **[`src/v3/compiler/src/infer.rs`](../../src/v3/compiler/src/infer.rs)** — type inference site; proof-obligation generation for partial ops would attach here. File:line for the operator-resolution site already known via T-Substrate parametric-algebra brief: `:3688-3767` `resolve_operator_arrow`. -- **[`docs/thesis/what-falls-out.md`](../thesis/what-falls-out.md)** — Tier 2 model framing. May need extension into a sibling doc if this brief authors the carrier-evidence shape. -- **Existing precedent — ownership proofs.** Per ROADMAP §Tier 2 ("ownership: the compiler proves no aliased mutation"), v3 has a partial-ops-style proof carrier already. Search for `OwnershipProof` / `ownership_lens` / similar to find the precedent shape; the new diagnostic-path proof carrier follows the same pattern. -- **[`MODELING.md`](../../MODELING.md)** — M9 + closed-system framing. -- **[`INVARIANTS.md`](../../INVARIANTS.md)** — `feedback_construction_over_ratchets`: model first, violations dissolve. +- **[`THESIS.md` §"Tier 2 — Runtime safety" + §"Enumerable impossible-bug classes" lines 348-350](../../THESIS.md)** — class definition + the *"Gated on Tier 2 substrate (post-R1)"* gate. +- **[`docs/r2-structure.md` §"Goal 4"](../r2-structure.md)** — sub-lane scoping; tagged `[R2+]`. +- **[`src/v3/compiler/src/infer.rs:3688-3767`](../../src/v3/compiler/src/infer.rs)** — `resolve_operator_arrow`. **Critical: DB-11 refinement-strip at `:3693-3703`** is the design conflict. Read the comment block in full; it documents *why* refinements are stripped at operator dispatch (mirror-refinement failure on symmetric operators). +- **[`docs/db-history/db-11.md`](../db-history/db-11.md)** + **[`docs/design-m2-feature-parity.md`](../design-m2-feature-parity.md)** — DB-11 alias-RHS `where` (PR #703) + its discharge semantics. **DB-11 does structural identity of refined types, NOT logical entailment.** Predicate-entailment (does user's `b != 0` entail operator's `denominator != 0`?) is materially different and is **not** in v3 substrate today. +- **[`src/v3/compiler/tests/m2_feature_parity_test.rs:331-700`](../../src/v3/compiler/tests/m2_feature_parity_test.rs)** — DB-11 test_3a3_* suite locks the strip-and-discharge semantics. The user-defined-total-wrapper path (`fn divide_safe(a: Int, b: Int where b != 0) -> ...`) already works today via standard refinement-on-parameter; that's the existing surface this lane could either build on or sidestep. +- **[`MODELING.md`](../../MODELING.md)** + **[`INVARIANTS.md`](../../INVARIANTS.md)**. -## Frame +## Frame — design-scoping, not implementation -Tier 2 obligates that **every partial operation** (divide, index, force-unwrap, integer-overflow, OOB) is either (a) **proven safe** via a structural proof carried alongside the operation, or (b) **made total** via a return-type lift (`Result` / `T | DivisionFailed` / etc.). Neither is enforced today; partial operations type-check unconditionally. +Output of this lane is a **scoping document** (lands as `docs/briefs/t-impossiblebugs-unhandled-diagnostic-paths-design.md` — worker picks placement), **NOT** code change. The doc answers four questions: -This brief introduces the **substrate to track partiality + proof-or-totality requirement** and the **diagnostic that fires when neither is provided**. The bug class becomes impossible-by-construction once the type system refuses to type-check `a / b` without either `b ≠ 0` proof or a total-Int signature. +1. **DB-11 interaction analysis** — exact characterization of the refinement-strip at `infer.rs:3693-3703`, with file:line and the comment-block reasoning. Worker has already done this work; the design doc consolidates it. +2. **Substrate proposal for proof-or-totality enforcement.** What new substrate is needed to make `a / b` require `b: Int where b != 0` (or equivalent) without conflicting with DB-11? Three load-bearing components surface from the worker's investigation: + - **Per-operator partiality fact** (which operand carries the precondition + what predicate is the precondition). + - **Predicate-entailment check** (logical entailment, not structural identity — DB-11 does the latter only). + - **Asymmetric per-operand refinement-honoring** at dispatch (in tension with DB-11's symmetric strip rule). +3. **Bypass-vs-park decision.** Three feasible outcomes, each with a concrete shape: + - **(a) Bypass-feasible**: there's a narrower mechanism that closes the bug class without conflicting with DB-11 (e.g., a typed sum-totality that shifts the burden to return-type lift `Result` rather than precondition-attachment). If the worker finds a clean bypass, name the implementation-brief shape. + - **(b) Substrate-design upstream**: the work is genuinely Tier 2 substrate (predicate-entailment + per-operator partiality + asymmetric refinement-honoring), and that substrate doesn't exist yet. Recommend parking this lane behind a Tier 2 substrate brief that authors the substrate first. + - **(c) Narrow-demo theatre**: brief req 3 already names the user-defined-total-wrapper path (`divide_safe`) which works today via DB-11 refinement-on-parameter. This is a valid demo but is **not** the impossible-bug class closure THESIS:350 promises — it demonstrates total-variant ergonomics, not proof-or-totality enforcement. Worker should explicitly flag this as acceptance-theatre risk. +4. **Director-actionable recommendation.** Pick one of (a/b/c) with concrete reasoning citing DB-11 evidence + substrate-shape questions. If (a), name implementation brief shape. If (b), name the substrate-design brief shape. If (c), name what the demo proves vs doesn't. -Sub-lane scope: enough Tier 2 substrate to close at least one partial-op class end-to-end (likely `divide` as the demo). Other partial-op classes follow the same pattern; demonstrate the substrate, scope to one consumer. +This lane is sized **S** because it's design-scoping. Output is a doc PR. ## Three consumer-side requirements -1. **Partiality fact on operations.** Each partial op carries a substrate fact marking it as partial + the precondition shape it expects (e.g., `divide` → `denominator != 0` precondition; `index` → `0 <= idx < length` precondition; `force_unwrap` → `is_some` precondition). Substrate-declared, not Rust-mirrored. -2. **Proof-or-totality check at type-checking.** When a partial op is used, the type-checker requires either: (a) a structurally-attached proof-term satisfying the precondition (e.g., a `where b != 0` refinement on `b`), or (b) the call-site uses a total signature variant returning `Result`. Otherwise emit `Diagnostic::UnhandledDiagnosticPath { op, missing_proof, fix_hints }`. -3. **End-to-end demo: divide.** Smoke + integration test: `let x = a / b` where `b: Int` (no proof) compile-errors with the new diagnostic; `let x = a / b` where `b: Int where b != 0` (proof attached) compiles; `let x = divide_safe(a, b)` returning `Result` compiles. Other partial ops out of scope; demo proves the substrate. +1. **DB-11 interaction analysis documented** with file:line citations from `infer.rs:3693-3703` + the `m2_feature_parity_test.rs` test suite. Worker has done this; doc consolidates. +2. **Substrate proposal OR park-decision documented.** Section walking through the three load-bearing substrate components (per-operator partiality, predicate-entailment, asymmetric refinement-honoring) with cited substrate facts. No invented vocabulary. +3. **Director-actionable recommendation** picking one of (a) bypass-feasible / (b) substrate-design-upstream / (c) narrow-demo-theatre, with concrete reasoning + named follow-on brief shape. -## Slice — partiality fact + proof-or-totality check + divide demo +## Slice — design-scoping doc -1. Add partiality fact to operation declarations. Likely a new field on the relevant declaration carrier (probably operator declarations in `dsl/std/algebra.dag` or per-target `primitives.dag`). -2. Extend type-checker (in `infer.rs`) to enforce proof-or-totality at use sites of partial ops. New diagnostic variant. -3. Annotate `divide` (or whichever partial op the worker picks for the demo) with the partiality fact. -4. Smoke + integration tests per req 3. -5. Doc updates — likely a new `docs/thesis/tier-2-runtime-safety-proofs.md` or extension to `docs/thesis/what-falls-out.md`. +1. Document the DB-11 conflict in detail (worker's `infer.rs:3693-3703` find consolidated). +2. Substrate proposal section walking the three components. +3. Bypass investigation: is there a sum-totality-only path that sidesteps DB-11? +4. Author the scoping doc (location worker's call). +5. PR description: cite this brief + the scoping-doc receipt + the recommendation. ## Acceptance -- [ ] All 3 consumer-side requirements satisfied + documented in PR body. -- [ ] Partiality fact substrate lands; round-trips through DB-8. -- [ ] Type-checker rejects un-proven partial-op uses with structured diagnostic. -- [ ] `divide` (or chosen demo) end-to-end: bare use rejected; proof-attached use accepted; total-variant use accepted. -- [ ] No regression on existing operator resolution. -- [ ] `cargo test --workspace --exclude v2-compiler-tests` / `clippy --all-targets -- -D warnings` / `fmt --all --check` clean. -- [ ] DB-8 fixed-point converges bit-identically. +- [ ] Scoping doc landed with all 3 consumer-side requirements addressed. +- [ ] Director-actionable recommendation: bypass-feasible / substrate-design-upstream / narrow-demo-theatre — pick one, cite reasoning. +- [ ] Acceptance-theatre risk explicitly flagged if recommendation is (c) or if (a)'s bypass turns out to be sum-totality-only (which is ergonomic, not impossible-bug-class-closure). +- [ ] No code changes to v3 substrate. +- [ ] `cargo fmt --all --check` clean. ## STOP-AND-ESCALATE Surface to Director. -- **Tier 2 substrate dependency** — if proof-term carrier requires inventing fundamental new substrate (predicate-as-fact distinct from DB-11's value-refinement), STOP. May indicate the sub-lane is mis-scoped as S; could be M+. -- **Proof-attachment syntax interaction with DB-11** — if `where` clause reuse for proof-attachment conflicts with DB-11's value-refinement semantics, STOP. -- **Other partial-op classes generalize differently** — if the chosen demo (divide) reveals that index / force-unwrap / overflow need divergent substrate, STOP. Director-call on demo choice + scope. -- **Existing ownership-proof precedent doesn't generalize** — if reusing the ownership-proof shape doesn't fit, STOP. -- **DB-8 fixed-point drifts** — STOP immediately. +- **DB-11 conflict turns out illusory** (e.g., the refinement-strip can be made asymmetric per-operand without breaking the symmetric-operators-fix DB-11 protects against) — this is the "good outcome" for bypass-feasibility. NOT a STOP, but worker should flag explicitly with reasoning. +- **Substrate proposal requires inventing fundamental new substrate vocabulary** beyond what predicate-entailment + per-operator partiality already name — STOP. May indicate scope is even larger than M+. +- **Bypass investigation reveals a clean total-variant-only path** that closes the bug class for SOME partial ops but not others (e.g., works for divide via `Result` but not for force-unwrap or OOB indexing) — STOP. Director-call on whether to scope this lane to one demo op. ## Non-goals -- **Not closing all partial-op classes.** One demo-end-to-end is sufficient evidence for the substrate; bulk migration of remaining classes is post-cascade work. -- **Not building Tier 2's full proof system** — scoped to enough substrate for the demo. -- **Not implementing the other two T-ImpossibleBugs classes** — independent briefs. -- **Not lifting all integer ops to `Result`** — only the chosen demo path. +- **Not implementing the proof-or-totality check.** This is scoping, not implementation. +- **Not modifying v3 substrate.** Doc-only output. +- **Not closing other T-ImpossibleBugs classes** — independent briefs. +- **Not re-authoring DB-11.** That's settled R1 work. ## Reporting -- Single PR. Title: `feat(v3): T-ImpossibleBugs — partiality fact + proof-or-totality check (closes unhandled-diagnostic-paths class via divide demo)`. -- PR body cites this brief + addresses the 3 reqs + documents which demo op was picked + the precedent (ownership-proof) reuse. -- On merge: signal Director; bulk migration of other partial-op classes is post-cascade work. +- Single PR. Title: `docs(briefs): T-ImpossibleBugs unhandled-diagnostic-paths — design/scoping doc (post-sunny-deer-629 redirect)`. +- PR body cites this brief + the scoping-doc receipt + the chosen recommendation. +- On merge: signal Director with the recommendation; Director either authors the bypass implementation brief, the Tier 2 substrate brief, or parks the lane. ## Cross-manager note -- **Zero-Floor Manager**: heads-up if substrate.dag-adjacent. +- **Zero-Floor Manager**: heads-up if recommendation lands on substrate-design-upstream — that's substrate-territory potentially. - **Grounding Manager**: no current overlap. diff --git a/docs/briefs/t-substrate-cardinality-int-lit-worker.md b/docs/briefs/t-substrate-cardinality-int-lit-worker.md index 5b05d9ebeca..f3a15512e0d 100644 --- a/docs/briefs/t-substrate-cardinality-int-lit-worker.md +++ b/docs/briefs/t-substrate-cardinality-int-lit-worker.md @@ -26,22 +26,14 @@ Sub-lane closes the magnitude carrier + reconciliation narrowing. **Scope is suf ## Five consumer-side requirements -1. **`IntLit` carries a single canonical magnitude payload; target-width compatibility views derive AFTER reconciliation, not before.** **Specified shape**: replace `LiteralBits::Int(i64)` with `LiteralBits::Int()`. Two carrier choices, each with explicit discipline: +1. **REQ 1 RE-SCOPED 2026-04-25 (post-`wise-pike-578` STOP-AND-ESCALATE).** Worker verified at HEAD that `dsl/std/substrate.dag:31` has `LitInt(Int)` with `Int = Int64`; no `Int128`/`UInt128` types exist; `dsl/extdeps/languages/rust/primitives.dag:134-136` closes `TargetCarrier` at `Word64Carrier` (no `Word128Carrier`). Widening the canonical carrier to i128 requires either (a) adding new substrate types `Int128`/`UInt128` + `Word128Carrier` (hierarchy refactor — contradicts non-goal "Not refactoring the integer algebra hierarchy beyond adding range facts") or (b) keeping `LitInt(Int)` substrate-side while emitting Rust `i128` (representation drift between substrate declaration and emitted code — violates substrate honesty). **Director re-scope: drop the canonical-carrier-widening from req 1.** The lane's value comes from reqs 2+3+5 (range facts + reconciliation narrowing + out-of-range diagnostic), all of which work against existing `i64`/`Int64`. The `i64::MIN` smoke (req 4) is **deferred to a sibling sub-lane** that does proper Int128/Word128/Word128Carrier substrate work alongside. - **Honest framing**: Choice (b) is the **expected outcome** for this PR (`std.natural` doesn't yet exist as substrate); Choice (a) is the **dissolution target** that this lane's bridge migrates to when the typed unbounded-magnitude carrier lands. Worker should plan for Choice (b) implementation by default and explicitly document the migration path. + **Re-scoped req 1**: keep `LiteralBits::Int(i64)` on substrate side. Reconciliation narrowing (req 3) operates against `i64`-bounded literals; out-of-i64-range literals are rejected at tokenize via the existing additive-inverse workaround pathway (no change required). The single-authority discipline still applies to reqs 2+3+5: range facts (req 2) use the existing `Int64` carrier; reconciliation (req 3) compares using `i64`-bounded magnitudes. - **Choice (a) — typed unbounded-magnitude carrier (DISSOLUTION TARGET; not currently available).** A `std.natural`-style carrier with no host-bound (signed magnitude). Pre-reconciliation literals are unbounded by construction; no out-of-bound diagnostic possible at the carrier level (only at narrowing). When `std.natural` lands as a substrate type, the bridge from (b) migrates here. - - **Choice (b) — `i128` as M2-bridge (EXPECTED OUTCOME for this PR).** **Bounded carrier**; treated as **transitional scaffolding with explicit dissolution discipline**: - - **Bounds documented in PR body**: `i128` range is `-(2^127) .. 2^127 - 1`; the bridge's finiteness must be visible, not silent. - - **Fail-closed diagnostic**: literals whose magnitude exceeds `i128` range emit a structured `MagnitudeCarrierOutOfRange` diagnostic at tokenize / lower time. **No silent truncation, no panic, no overflow.** This is the bridge's bound-honesty surface. - - **Named dissolution trigger**: when `std.natural` (or equivalent typed unbounded-magnitude carrier) lands as substrate, `LiteralBits::Int(i128)` migrates to that carrier and the bridge dissolves. Worker documents the trigger in a doc-comment on `LiteralBits::Int` and surfaces it in PR body. - - Per `feedback_construction_over_ratchets` + scaffold-dissolution discipline: bridges with named dissolution triggers are acceptable; ungoverned bridges are not. - - Do **NOT** add a parallel field or coexisting variant: that would create dual representations of the same fact at the same level and violate single-authority discipline. Pre-reconciliation, every int-literal is the single canonical form (whichever carrier shape was picked). Post-reconciliation, downstream consumers (emit, lens) project to target-width compat views from the canonical form via the reconciliation-decided target algebra. STOP-AND-ESCALATE if execution surfaces a consumer that requires the i64-pre-narrowed shape pre-reconciliation (would indicate a hidden coupling that needs Director scoping). + **Sibling sub-lane (deferred; named dissolution trigger)**: a future T-Substrate sub-lane authors `Int128`/`UInt128` types in `dsl/std/integer.dag` + `Word128Carrier` in `primitives.dag` + widens `LitInt(Int)` to use the new `Int128` type. That sub-lane closes the `i64::MIN`-as-single-token gap and enables narrowing literals beyond the i64 range. **Do not author or imply that sibling sub-lane in this PR's body**; it's tracked separately. 2. **Substrate models numeric ranges as declared facts on integer algebras, using the SAME magnitude carrier as req 1.** Each `IntegerPrimitive` (i8/i16/.../u64) gets a range fact (e.g., `range_min: `, `range_max: ` fields) in `dsl/extdeps/languages/rust/primitives.dag`. **Invariant: the magnitude type used for the literal payload (req 1) and the magnitude type used for range bounds (req 2) is one and the same** — one magnitude algebra, used both as literal payload and as range bound. This keeps reconciliation's "does the literal's magnitude fit the target's range?" check structural rather than a cross-type comparison. Pilot's Rust-mirror range knowledge dissolves into the substrate. 3. **Reconciliation narrows magnitude-aware.** `infer.rs:704-725` `decide` arm grows: query the literal's magnitude + the call-site's expected target algebra; pick the narrowest fitting target; emit a structured `MagnitudeOutOfRange` diagnostic if no target fits. Default-when-unconstrained policy stays explicit (e.g., still default to `Int64` if no narrowing target is named) — surface the choice in PR description, and **add a tracked-follow-up note** (in PR body or as a ROADMAP/active-deferral entry) that the `Int64` default is itself a host-narrowing heuristic the lane is otherwise dissolving; full dissolution is out of scope here. -4. **`i64::MIN` representable end-to-end.** Smoke test: a `data x: Int = -9223372036854775808` declaration lowers + reconciles + emits without the additive-inverse workaround. This is the canonical regression that motivated the lane. +4. **DEFERRED — `i64::MIN` smoke test moves to sibling sub-lane.** Per req 1's re-scope, this lane retains the existing `i64`-bounded carrier; `i64::MIN` as a single token still requires the additive-inverse workaround. The sibling sub-lane (Int128/UInt128/Word128Carrier substrate work) closes this gap. **Do not implement req 4 in this PR**; document its deferral in PR body with the sibling-sub-lane reference. 5. **Out-of-range literal emits structured diagnostic.** Smoke test: `data x: u8 = 256` produces a diagnostic naming the literal's magnitude + the target's range + a fix-hint suggesting a wider target. No silent truncation. ## Slice — magnitude carrier + reconciliation narrowing From 3e142d169f2e300839c68b6c6fd6c6b3d0b34b62 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 11:05:16 -0400 Subject: [PATCH 33/52] =?UTF-8?q?docs(briefs):=20T-Substrate=20cardinality?= =?UTF-8?q?-int-lit=20=E2=80=94=20close=20codex=20P2=20on=20Slice/Acceptan?= =?UTF-8?q?ce=20lagging=20req=201=20re-scope?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves codex P2 inline at sha e35103fad on docs/briefs/t-substrate-cardinality-int-lit-worker.md:31. Real: the prior re-scope (post-wise-pike-578 STOP) updated req 1 to defer carrier-widening but Slice + Acceptance + STOP-AND-ESCALATE still required widening LiteralBits::Int(i64) to an unbounded carrier and passing the i64::MIN smoke. Internally unsatisfiable. Fix: - Slice section retitled "range facts + reconciliation narrowing (against existing i64 carrier)" with explicit note about the re-scope. - Slice step 1 rewritten as "(NOT in scope — deferred)" — explicitly forbids touching LiteralBits::Int shape, dag_scalar_generated.rs regen for that variant, or tokenize i64 parse path. - Slice steps 2-5 reframed: range facts use i64-representable magnitudes; reconciliation narrowing uses existing i64 carrier; diagnostic only for i64-representable out-of-range; smoke tests for req 5 only (req 4 i64::MIN deferred). - Acceptance checklist updated: - Reqs 2, 3, 5 satisfied; reqs 1 + 4 explicitly noted as re-scoped/deferred. - LiteralBits::Int(i64) carrier untouched (no widening; no parallel; no shape change). - i64::MIN smoke marked DEFERRED with sibling-sub-lane reference. - STOP-AND-ESCALATE bullet 1 rewritten: "Pressure to widen the carrier" — explicit STOP if execution surfaces range-fact narrowing requiring carrier-widening; that's the boundary the re-scope drew; belongs in sibling Int128/Word128 sub-lane. Brief now consistently treats carrier-widening as out-of-scope across all sections. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../t-substrate-cardinality-int-lit-worker.md | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/docs/briefs/t-substrate-cardinality-int-lit-worker.md b/docs/briefs/t-substrate-cardinality-int-lit-worker.md index f3a15512e0d..700230df8b7 100644 --- a/docs/briefs/t-substrate-cardinality-int-lit-worker.md +++ b/docs/briefs/t-substrate-cardinality-int-lit-worker.md @@ -36,32 +36,34 @@ Sub-lane closes the magnitude carrier + reconciliation narrowing. **Scope is suf 4. **DEFERRED — `i64::MIN` smoke test moves to sibling sub-lane.** Per req 1's re-scope, this lane retains the existing `i64`-bounded carrier; `i64::MIN` as a single token still requires the additive-inverse workaround. The sibling sub-lane (Int128/UInt128/Word128Carrier substrate work) closes this gap. **Do not implement req 4 in this PR**; document its deferral in PR body with the sibling-sub-lane reference. 5. **Out-of-range literal emits structured diagnostic.** Smoke test: `data x: u8 = 256` produces a diagnostic naming the literal's magnitude + the target's range + a fix-hint suggesting a wider target. No silent truncation. -## Slice — magnitude carrier + reconciliation narrowing +## Slice — range facts + reconciliation narrowing (against existing i64 carrier) -1. Replace `LiteralBits::Int(i64)` with `LiteralBits::Int()` per req 1's specified shape (single canonical payload — no parallel field, no coexisting variant). Update `dag_scalar_generated.rs` regen path; update tokenize to populate the canonical magnitude (replacing `i64` pre-narrowing, not paralleling it). -2. Add range facts to integer algebras (per req 2) in `dsl/extdeps/languages/rust/primitives.dag` (and Python/Go siblings if they declare integer primitives). Pilot mirror at `src/v3/grounding_pilot/src/lib.rs` updates accordingly. -3. Extend `infer.rs:704-725` decide arm with magnitude-aware narrowing (per req 3). Keep the default-when-unconstrained policy explicit. -4. Diagnostic for out-of-range literals (per req 5) — add a new `Diagnostic::MagnitudeOutOfRange` variant or equivalent at the appropriate location. -5. Smoke tests for reqs 4 + 5; integration test for end-to-end narrowing across multiple target algebras. +**Note (post-2026-04-25 re-scope)**: per req 1, the `LiteralBits::Int(i64)` carrier is **NOT widened** in this lane; carrier-widening defers to a sibling Int128/Word128 sub-lane. This slice operates against the existing `i64` carrier. + +1. **(NOT in scope — deferred)** Carrier widening from `LiteralBits::Int(i64)` to a wider canonical form. This is the deferred req 1 work; sibling sub-lane handles. Worker should NOT touch `LiteralBits::Int` shape, `dag_scalar_generated.rs` regen for that variant, or tokenize's i64 parse path. +2. Add range facts to integer algebras (per req 2) in `dsl/extdeps/languages/rust/primitives.dag` (and Python/Go siblings if they declare integer primitives). Range bounds use `i64`-representable magnitudes (consistent with the unwidened carrier). Pilot mirror at `src/v3/grounding_pilot/src/lib.rs` updates accordingly. +3. Extend `infer.rs:704-725` decide arm with magnitude-aware narrowing (per req 3). Use the existing `i64`-bounded literal payload + the new substrate-declared range facts. Keep the default-when-unconstrained policy explicit. +4. Diagnostic for out-of-range literals (per req 5) — add a new `Diagnostic::MagnitudeOutOfRange` variant or equivalent at the appropriate location. Triggered when an `i64`-representable literal exceeds the call-site's target-algebra range (e.g., `data x: u8 = 256`). +5. Smoke tests for req 5 only; **req 4 (`i64::MIN`) is deferred** — no smoke test for it in this PR; document deferral in PR body. Integration test for end-to-end narrowing across multiple target algebras (i8, i16, i32, i64, u8, u16, u32, u64) using `i64`-representable literals. ## Acceptance -- [ ] All 5 consumer-side requirements satisfied + documented in PR body. -- [ ] Magnitude carrier shape lands; doc-comment explains the dissolution path (eventually `std.natural` once Class 5 substrate lifts further). +- [ ] Reqs 2, 3, 5 satisfied + documented in PR body. Req 1 explicitly noted as RE-SCOPED (carrier-widening deferred to sibling sub-lane). Req 4 explicitly noted as DEFERRED (depends on sibling sub-lane). +- [ ] `LiteralBits::Int(i64)` carrier untouched (no widening; no parallel; no `dag_scalar_generated.rs` shape change for this variant). - [ ] Range facts on integer algebras (substrate-declared, not Rust-mirrored). -- [ ] Reconciliation narrows magnitude-aware; default-when-unconstrained policy documented. -- [ ] `data x: Int = -9223372036854775808` works end-to-end (`i64::MIN` smoke). +- [ ] Reconciliation narrows magnitude-aware against existing `i64` carrier; default-when-unconstrained policy documented. +- [ ] **DEFERRED**: `data x: Int = -9223372036854775808` (`i64::MIN` smoke; sibling sub-lane will implement). - [ ] `data x: u8 = 256` emits structured `MagnitudeOutOfRange` diagnostic. - [ ] Existing int-literal tests pass without modification (no silent regressions). - [ ] `cargo test --workspace --exclude v2-compiler-tests` passes; `clippy --all-targets -- -D warnings` clean; `fmt --all --check` clean. - [ ] **DB-8 `self_host_fixed_point` converges bit-identically.** -- [ ] SG-0 census + regen-output deltas: this lane is **adding** substrate (magnitude carrier + range facts), not retiring hand-Rust files; expected census movement is **the pilot's Rust-mirror range constants becoming substrate-declared** (so the corresponding pilot Rust code that previously hard-coded ranges either retires or shrinks). Any regen snapshot updates land in REGEN_OUTPUTS partition. +- [ ] SG-0 census + regen-output deltas: this lane is **adding** substrate (range facts only — carrier untouched), not retiring hand-Rust files; expected census movement is **the pilot's Rust-mirror range constants becoming substrate-declared** (so the corresponding pilot Rust code that previously hard-coded ranges either retires or shrinks). Any regen snapshot updates land in REGEN_OUTPUTS partition. ## STOP-AND-ESCALATE Surface to Director. -- **Canonical-payload type choice is consumer-visible** — if the chosen `LiteralBits::Int()` payload type (e.g., `i128` M2-bridge vs a typed unbounded magnitude) leaks into lens producers / serializer / cementer in ways that need cross-consumer redesign, STOP. (Note: per req 1, the choice is *which canonical type*, not *whether to add a parallel carrier* — that's already locked.) +- **Pressure to widen the carrier** — req 1's re-scope explicitly defers carrier-widening to a sibling sub-lane. If execution surfaces that range-fact narrowing requires touching `LiteralBits::Int(i64)` shape (e.g., narrowing logic needs a wider literal payload to represent magnitudes that the user wrote), STOP. That's the boundary the re-scope drew; carrier-widening belongs in the sibling Int128/Word128 sub-lane. - **Range-fact substrate touches `dsl/std/substrate.dag` (NOT `dsl/extdeps/languages/*/primitives.dag`)** — extdeps language files are in-scope for this lane; only edits to `dsl/std/substrate.dag` itself trigger the STOP for cross-program coordination with PB-Substrate (Zero-Floor). Range facts on `IntegerPrimitive` in `dsl/extdeps/languages/rust/primitives.dag` (req 2) are NOT substrate.dag changes and do NOT require Zero-Floor coordination. - **Default-when-unconstrained policy** — if changing it (e.g., dropping the `Int64` default in favor of "unconstrained → diagnostic") is the cleaner shape, STOP. Director call. - **DB-8 fixed-point drifts** — STOP immediately. From 8c22613518b5ef581305125fb4744a90c525d059 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 11:08:51 -0400 Subject: [PATCH 34/52] =?UTF-8?q?docs(briefs):=20T-Substrate=20cardinality?= =?UTF-8?q?-int-lit=20=E2=80=94=20close=20codex=20BLOCKING=20#1=20on=20ran?= =?UTF-8?q?ge-fact=20carrier=20honesty?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves codex BLOCKING #1 at sha e35103fa on docs/briefs/t-substrate-cardinality-int-lit-worker.md:31. Real: the post-wise-pike-578 re-scope kept LiteralBits::Int(i64) carrier but req 2 required range facts using "the SAME magnitude carrier as req 1" — meaning i64-typed range bounds. u64's max (2^64-1) doesn't fit in i64; range fact for u64 would have to truncate, omit, or mirror in Rust (representation drift). All three options violate fail-closed declared-facts discipline (P1 / P3). Fix: - Req 2 rewritten to specify String-decimal representation: range_min_inclusive: String + range_max_inclusive: String fields on IntegerPrimitive carrying decimal magnitude (e.g., "-128"/"127" for i8; "0"/"18446744073709551615" for u64). - Explicit reasoning why String-decimal: u64's max doesn't fit in i64; binding range bounds to literal carrier forces truncation/ omission/mirror-drift; all violate fail-closed declared-facts discipline. - Bridge framing: String-decimal is pending the sibling Int128/ Word128 sub-lane; both range bounds and literal payload migrate to typed carrier when that lands. - Req 3 updated for String-decimal comparison semantics: reconciliation parses both bounds and literal magnitude into a common comparison space (i128 host comparison primitive — host narrowing, NOT carrier widening). Bounded by what the i64-typed literal can express; any i64-representable literal compares against any width's String-decimal bound. Carrier discipline preserved. Codex BLOCKING #2 (Slice/Acceptance contradicting req 4 deferral) is sha-stale — already resolved at 3e142d169. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/briefs/t-substrate-cardinality-int-lit-worker.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/briefs/t-substrate-cardinality-int-lit-worker.md b/docs/briefs/t-substrate-cardinality-int-lit-worker.md index 700230df8b7..fc52cdfdade 100644 --- a/docs/briefs/t-substrate-cardinality-int-lit-worker.md +++ b/docs/briefs/t-substrate-cardinality-int-lit-worker.md @@ -31,8 +31,8 @@ Sub-lane closes the magnitude carrier + reconciliation narrowing. **Scope is suf **Re-scoped req 1**: keep `LiteralBits::Int(i64)` on substrate side. Reconciliation narrowing (req 3) operates against `i64`-bounded literals; out-of-i64-range literals are rejected at tokenize via the existing additive-inverse workaround pathway (no change required). The single-authority discipline still applies to reqs 2+3+5: range facts (req 2) use the existing `Int64` carrier; reconciliation (req 3) compares using `i64`-bounded magnitudes. **Sibling sub-lane (deferred; named dissolution trigger)**: a future T-Substrate sub-lane authors `Int128`/`UInt128` types in `dsl/std/integer.dag` + `Word128Carrier` in `primitives.dag` + widens `LitInt(Int)` to use the new `Int128` type. That sub-lane closes the `i64::MIN`-as-single-token gap and enables narrowing literals beyond the i64 range. **Do not author or imply that sibling sub-lane in this PR's body**; it's tracked separately. -2. **Substrate models numeric ranges as declared facts on integer algebras, using the SAME magnitude carrier as req 1.** Each `IntegerPrimitive` (i8/i16/.../u64) gets a range fact (e.g., `range_min: `, `range_max: ` fields) in `dsl/extdeps/languages/rust/primitives.dag`. **Invariant: the magnitude type used for the literal payload (req 1) and the magnitude type used for range bounds (req 2) is one and the same** — one magnitude algebra, used both as literal payload and as range bound. This keeps reconciliation's "does the literal's magnitude fit the target's range?" check structural rather than a cross-type comparison. Pilot's Rust-mirror range knowledge dissolves into the substrate. -3. **Reconciliation narrows magnitude-aware.** `infer.rs:704-725` `decide` arm grows: query the literal's magnitude + the call-site's expected target algebra; pick the narrowest fitting target; emit a structured `MagnitudeOutOfRange` diagnostic if no target fits. Default-when-unconstrained policy stays explicit (e.g., still default to `Int64` if no narrowing target is named) — surface the choice in PR description, and **add a tracked-follow-up note** (in PR body or as a ROADMAP/active-deferral entry) that the `Int64` default is itself a host-narrowing heuristic the lane is otherwise dissolving; full dissolution is out of scope here. +2. **Substrate models numeric ranges as declared facts on integer algebras using a width-independent String-decimal representation** (consequence of req 1's carrier-non-widening). Each `IntegerPrimitive` (i8/i16/.../**u64**) gets `range_min_inclusive: String` + `range_max_inclusive: String` fields in `dsl/extdeps/languages/rust/primitives.dag` carrying the decimal magnitude (e.g., `"-128"`/`"127"` for i8; `"0"`/`"18446744073709551615"` for u64). **String-decimal, NOT i64-typed**: u64's max (`2^64 - 1`) doesn't fit in i64, so binding range bounds to the i64 literal carrier would force truncation, omission, or Rust-mirror drift — all of which would violate fail-closed declared-facts discipline. String-decimal sidesteps the carrier mismatch entirely; reconciliation (req 3) parses both the range bounds and the literal's i64 magnitude for comparison. This is the bridge form pending the sibling Int128/Word128 sub-lane that lands a typed unbounded magnitude carrier — at which point both range bounds and literal payload migrate to that typed carrier and the String-decimal bridge dissolves. Pilot's Rust-mirror range knowledge dissolves into the substrate. +3. **Reconciliation narrows magnitude-aware via String-decimal range comparison.** `infer.rs:704-725` `decide` arm grows: query the literal's i64 magnitude + the call-site's expected target algebra's `range_min_inclusive` / `range_max_inclusive` String-decimal bounds (req 2); compare by parsing the bounds (`String → i128` or equivalent host comparison primitive) and the literal magnitude into a common comparison space; pick the narrowest fitting target; emit a structured `MagnitudeOutOfRange` diagnostic if no target fits. **Comparison-space note**: parsing String-decimal bounds into i128 (or wider host primitive) is a *narrowing-time host comparison*, NOT carrier widening — the literal payload stays `i64` per req 1. The host parse is bounded by what the literal can express (any `i64`-representable literal compares against any width's String-decimal bound). Default-when-unconstrained policy stays explicit (still default to `Int64` if no narrowing target is named) — surface the choice in PR description, and **add a tracked-follow-up note** (in PR body or as a ROADMAP/active-deferral entry) that the `Int64` default is itself a host-narrowing heuristic the lane is otherwise dissolving; full dissolution is out of scope here. 4. **DEFERRED — `i64::MIN` smoke test moves to sibling sub-lane.** Per req 1's re-scope, this lane retains the existing `i64`-bounded carrier; `i64::MIN` as a single token still requires the additive-inverse workaround. The sibling sub-lane (Int128/UInt128/Word128Carrier substrate work) closes this gap. **Do not implement req 4 in this PR**; document its deferral in PR body with the sibling-sub-lane reference. 5. **Out-of-range literal emits structured diagnostic.** Smoke test: `data x: u8 = 256` produces a diagnostic naming the literal's magnitude + the target's range + a fix-hint suggesting a wider target. No silent truncation. From 38214c9f29ae80602bb8713045dff95642669fc9 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 11:23:06 -0400 Subject: [PATCH 35/52] =?UTF-8?q?docs(briefs):=20cardinality-int-lit=20?= =?UTF-8?q?=E2=80=94=20close=20codex=20BLOCKING=20on=20Slice/Acceptance=20?= =?UTF-8?q?still=20i64-typed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves codex BLOCKING at sha 0815189a (post-#799-merge feedback). Real residual: req 2 specifies String-decimal range bounds (to cover u64::MAX which doesn't fit in i64) but lines 31, 44, and acceptance bullet still referenced "i64-bounded magnitudes" / "Int64 carrier" / "i64-representable magnitudes" for the range facts. Two incompatible authorities for the same range-fact shape — would let a worker satisfy the slice while truncating/omitting u64 bounds (P3 fail-closed violation). Fix: - Line 31 (req 1 re-scope clarification): updated to explicitly state "range facts (req 2) use String-decimal representation (width- independent; covers u64::MAX which doesn't fit in i64)". Distinguished literal *payload* (stays i64) from range-bound *representation* (String) — both serve req 1's "no carrier widening" boundary. - Line 44 (slice step 2): updated from "Range bounds use i64- representable magnitudes" to "Range bounds use String-decimal representation per req 2" with concrete example (u64 bounds). - Acceptance bullet: updated from "Range facts on integer algebras (substrate-declared, not Rust-mirrored)" to add "using String-decimal representation ... width-independent; u64 bounds expressible without truncation." The brief now consistently treats range bounds as String-decimal across req 2, req 3, slice, acceptance, and the req 1 clarification — no remaining authorities saying i64-typed. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/briefs/t-substrate-cardinality-int-lit-worker.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/briefs/t-substrate-cardinality-int-lit-worker.md b/docs/briefs/t-substrate-cardinality-int-lit-worker.md index fc52cdfdade..77a9f0d2c83 100644 --- a/docs/briefs/t-substrate-cardinality-int-lit-worker.md +++ b/docs/briefs/t-substrate-cardinality-int-lit-worker.md @@ -28,7 +28,7 @@ Sub-lane closes the magnitude carrier + reconciliation narrowing. **Scope is suf 1. **REQ 1 RE-SCOPED 2026-04-25 (post-`wise-pike-578` STOP-AND-ESCALATE).** Worker verified at HEAD that `dsl/std/substrate.dag:31` has `LitInt(Int)` with `Int = Int64`; no `Int128`/`UInt128` types exist; `dsl/extdeps/languages/rust/primitives.dag:134-136` closes `TargetCarrier` at `Word64Carrier` (no `Word128Carrier`). Widening the canonical carrier to i128 requires either (a) adding new substrate types `Int128`/`UInt128` + `Word128Carrier` (hierarchy refactor — contradicts non-goal "Not refactoring the integer algebra hierarchy beyond adding range facts") or (b) keeping `LitInt(Int)` substrate-side while emitting Rust `i128` (representation drift between substrate declaration and emitted code — violates substrate honesty). **Director re-scope: drop the canonical-carrier-widening from req 1.** The lane's value comes from reqs 2+3+5 (range facts + reconciliation narrowing + out-of-range diagnostic), all of which work against existing `i64`/`Int64`. The `i64::MIN` smoke (req 4) is **deferred to a sibling sub-lane** that does proper Int128/Word128/Word128Carrier substrate work alongside. - **Re-scoped req 1**: keep `LiteralBits::Int(i64)` on substrate side. Reconciliation narrowing (req 3) operates against `i64`-bounded literals; out-of-i64-range literals are rejected at tokenize via the existing additive-inverse workaround pathway (no change required). The single-authority discipline still applies to reqs 2+3+5: range facts (req 2) use the existing `Int64` carrier; reconciliation (req 3) compares using `i64`-bounded magnitudes. + **Re-scoped req 1**: keep `LiteralBits::Int(i64)` on substrate side. Reconciliation narrowing (req 3) operates against `i64`-bounded literals; out-of-i64-range literals are rejected at tokenize via the existing additive-inverse workaround pathway (no change required). The single-authority discipline still applies to reqs 2+3+5: **range facts (req 2) use String-decimal representation** (width-independent; covers `u64::MAX` which doesn't fit in i64); reconciliation (req 3) compares String-decimal bounds against the i64 literal magnitude via host-narrowing-time parse into a wider comparison primitive (i128 host or equivalent). The literal *payload* stays `i64`; the *range-bound representation* is String to preserve fail-closed declared-facts discipline. Carrier and range-bound representations are distinct fields with distinct shapes; both serve req 1's "no carrier widening" boundary. **Sibling sub-lane (deferred; named dissolution trigger)**: a future T-Substrate sub-lane authors `Int128`/`UInt128` types in `dsl/std/integer.dag` + `Word128Carrier` in `primitives.dag` + widens `LitInt(Int)` to use the new `Int128` type. That sub-lane closes the `i64::MIN`-as-single-token gap and enables narrowing literals beyond the i64 range. **Do not author or imply that sibling sub-lane in this PR's body**; it's tracked separately. 2. **Substrate models numeric ranges as declared facts on integer algebras using a width-independent String-decimal representation** (consequence of req 1's carrier-non-widening). Each `IntegerPrimitive` (i8/i16/.../**u64**) gets `range_min_inclusive: String` + `range_max_inclusive: String` fields in `dsl/extdeps/languages/rust/primitives.dag` carrying the decimal magnitude (e.g., `"-128"`/`"127"` for i8; `"0"`/`"18446744073709551615"` for u64). **String-decimal, NOT i64-typed**: u64's max (`2^64 - 1`) doesn't fit in i64, so binding range bounds to the i64 literal carrier would force truncation, omission, or Rust-mirror drift — all of which would violate fail-closed declared-facts discipline. String-decimal sidesteps the carrier mismatch entirely; reconciliation (req 3) parses both the range bounds and the literal's i64 magnitude for comparison. This is the bridge form pending the sibling Int128/Word128 sub-lane that lands a typed unbounded magnitude carrier — at which point both range bounds and literal payload migrate to that typed carrier and the String-decimal bridge dissolves. Pilot's Rust-mirror range knowledge dissolves into the substrate. @@ -41,7 +41,7 @@ Sub-lane closes the magnitude carrier + reconciliation narrowing. **Scope is suf **Note (post-2026-04-25 re-scope)**: per req 1, the `LiteralBits::Int(i64)` carrier is **NOT widened** in this lane; carrier-widening defers to a sibling Int128/Word128 sub-lane. This slice operates against the existing `i64` carrier. 1. **(NOT in scope — deferred)** Carrier widening from `LiteralBits::Int(i64)` to a wider canonical form. This is the deferred req 1 work; sibling sub-lane handles. Worker should NOT touch `LiteralBits::Int` shape, `dag_scalar_generated.rs` regen for that variant, or tokenize's i64 parse path. -2. Add range facts to integer algebras (per req 2) in `dsl/extdeps/languages/rust/primitives.dag` (and Python/Go siblings if they declare integer primitives). Range bounds use `i64`-representable magnitudes (consistent with the unwidened carrier). Pilot mirror at `src/v3/grounding_pilot/src/lib.rs` updates accordingly. +2. Add range facts to integer algebras (per req 2) in `dsl/extdeps/languages/rust/primitives.dag` (and Python/Go siblings if they declare integer primitives). **Range bounds use String-decimal representation per req 2** (e.g., `range_min_inclusive: "0"`, `range_max_inclusive: "18446744073709551615"` for u64) — width-independent so u64 bounds (which exceed i64) are faithfully representable. Pilot mirror at `src/v3/grounding_pilot/src/lib.rs` updates accordingly. 3. Extend `infer.rs:704-725` decide arm with magnitude-aware narrowing (per req 3). Use the existing `i64`-bounded literal payload + the new substrate-declared range facts. Keep the default-when-unconstrained policy explicit. 4. Diagnostic for out-of-range literals (per req 5) — add a new `Diagnostic::MagnitudeOutOfRange` variant or equivalent at the appropriate location. Triggered when an `i64`-representable literal exceeds the call-site's target-algebra range (e.g., `data x: u8 = 256`). 5. Smoke tests for req 5 only; **req 4 (`i64::MIN`) is deferred** — no smoke test for it in this PR; document deferral in PR body. Integration test for end-to-end narrowing across multiple target algebras (i8, i16, i32, i64, u8, u16, u32, u64) using `i64`-representable literals. @@ -50,7 +50,7 @@ Sub-lane closes the magnitude carrier + reconciliation narrowing. **Scope is suf - [ ] Reqs 2, 3, 5 satisfied + documented in PR body. Req 1 explicitly noted as RE-SCOPED (carrier-widening deferred to sibling sub-lane). Req 4 explicitly noted as DEFERRED (depends on sibling sub-lane). - [ ] `LiteralBits::Int(i64)` carrier untouched (no widening; no parallel; no `dag_scalar_generated.rs` shape change for this variant). -- [ ] Range facts on integer algebras (substrate-declared, not Rust-mirrored). +- [ ] Range facts on integer algebras (substrate-declared, not Rust-mirrored) using **String-decimal representation** (`range_min_inclusive: String` + `range_max_inclusive: String`) — width-independent; u64 bounds expressible without truncation. - [ ] Reconciliation narrows magnitude-aware against existing `i64` carrier; default-when-unconstrained policy documented. - [ ] **DEFERRED**: `data x: Int = -9223372036854775808` (`i64::MIN` smoke; sibling sub-lane will implement). - [ ] `data x: u8 = 256` emits structured `MagnitudeOutOfRange` diagnostic. From d49ce79a4f71494e014de68a93613364559c4193 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 13:40:28 -0400 Subject: [PATCH 36/52] docs(closed-system-effects): redirect unenumerated-effects chain to closed-system framing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User + PM exchange 2026-04-25 surfaced that the in-flight effects chain was importing wrong assumptions from external languages (declared-effects-as-annotation + lens-vs-declaration check). Right framing under gunbc's closed-system discipline is parallel to complexity: every effect derives structurally from the composition of typed primitive operations; nothing can hide because there's no escape hatch; nothing needs annotation because the structure IS the registry. Four doc-only actions: 1. NEW docs/briefs/t-impossiblebugs-unenumerated-effects-design.md. Frames the closed-system answer with PM's 5-behavior synergy table (Value/Transform/Branch/Loop/Bind as universal compositional-fold pattern). Four worked examples; aggressive reading on redundancy (compile-error-by-construction via referential-transparency proof; reread() primitive for legitimate cases); implementation-brief shape in §Q6. 2. SUPERSEDED banner on docs/briefs/t-impossiblebugs-unenumerated-effects-worker.md. 3. SUPERSEDED banner on docs/briefs/t-impossiblebugs-unenumerated-effects-parser-worker.md. Notes Fn→Arrow refactor brief stays dispatchable as independent value. 4. THESIS:345-347 bug-class amendment: Tier 1 impossible-by- construction framing replaces lens-detection framing. Memory file feedback_closed_system_effects.md saved separately; cross-link added to feedback_construction_over_ratchets.md. Net cost: doc-level cleanup. Zero substrate code rework. Foundation (OperationEffect + service-call infrastructure + 5-behavior substrate) already exists. Co-Authored-By: Claude Opus 4.7 (1M context) --- THESIS.md | 17 +- ...ossiblebugs-unenumerated-effects-design.md | 178 ++++++++++++++++++ ...bugs-unenumerated-effects-parser-worker.md | 4 +- ...ossiblebugs-unenumerated-effects-worker.md | 4 +- 4 files changed, 198 insertions(+), 5 deletions(-) create mode 100644 docs/briefs/t-impossiblebugs-unenumerated-effects-design.md diff --git a/THESIS.md b/THESIS.md index 38b51edb8b9..fa266dff506 100644 --- a/THESIS.md +++ b/THESIS.md @@ -342,9 +342,20 @@ empty set per [`docs/design-pure-bootstrap-zero.md`](docs/design-pure-bootstrap- - **[R2+]** Nested-optional flatten: `Option>` accessor patterns that normal languages require hand-unwrapping. Gated on cardinality refinement substrate work. - - **[R2+]** Unenumerated effects: a function's actual effect set must match - its declared effect set; silent effect leakage is rejected. Gated on - deeper effect-system work beyond R1's Sub-A scope. + - **[R2+]** Unenumerated effects: every effect performed in this system is + structurally visible at compile time; impossible to hide an effect because + the substrate IS the registry (effects derive from the composition of + typed primitive operations, parallel to how complexity derives from + bounded-kernel composition — same closed-system mechanism). There is no + declared-effects-vs-inferred-effects mismatch because there is no separate + "declared" surface — the structural fact is the only authority. Redundant + effects (e.g., reads of the same key with no intervening write-effect) are + structurally provable as identical via referential transparency, and + rejected at compile time; legitimate re-read uses an explicit `reread()` + primitive that structurally tags the intent. Tier 1 (impossible by + construction), not Tier 2 (lens-detected). See + [`docs/briefs/t-impossiblebugs-unenumerated-effects-design.md`](docs/briefs/t-impossiblebugs-unenumerated-effects-design.md) + for the 5-behavior compositional-fold mechanism + worked examples. - **[R2+]** Unhandled diagnostic paths: Tier 2 runtime-safety proofs make division-by-zero, OOB, and force-unwrap either proven safe or made total — never partial. Gated on Tier 2 substrate (post-R1). diff --git a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md new file mode 100644 index 00000000000..21ab4c96b0b --- /dev/null +++ b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md @@ -0,0 +1,178 @@ +# T-ImpossibleBugs unenumerated effects — design/scoping doc (closed-system framing) + +> **Output of Director scoping pass per user + PM 2026-04-25 exchange.** +> Replaces the lens-vs-declaration framing of +> [`t-impossiblebugs-unenumerated-effects-worker.md`](t-impossiblebugs-unenumerated-effects-worker.md) +> + [`t-impossiblebugs-unenumerated-effects-parser-worker.md`](t-impossiblebugs-unenumerated-effects-parser-worker.md) +> with a closed-system structural-derivation framing that aligns with how +> complexity / idempotency / termination already work in v3. +> +> Both prior briefs are now SUPERSEDED. No code has merged against them +> yet (only briefs landed; `t-impossiblebugs-unenumerated-effects-fn-arrow-refactor-worker.md` +> from #805 is independent value and stays dispatchable). + +## TL;DR + +**Recommendation: closed-system structural derivation, no annotation surface.** + +Effects in gunbc are not annotations. They derive structurally from the composition of typed primitive operations, exactly the way complexity is derived from `fold` / `descend` / `repeat` composition. Same closed-system mechanism, different property. Effects lens is the next instance of an established pattern (idempotency, termination, omni-emit are prior art), not novel substrate work. + +The bug class **closes more strongly** under closed-system framing: silent effect leakage is impossible because there's no separate "declared" surface to leak from — the structural fact IS the declaration. + +## Q1 — The closed-system invariant + +Per `feedback_compiler_is_dag_processor`: the compiler knows only `Node / Conj / Disj / Cardinality / Bit`. Per `substrate.dag`, all computation composes from 5 primitive behaviors: + +`Value | Transform | Branch | Loop | Bind` + +There is no `while(true)`, no unbounded recursion, no `eval(string)`, no raw IO escape hatch. Every form of computation MUST appear as one of these 5. The substrate is closed; the lens domain is closed; **nothing can hide**. + +For effects specifically: every external interaction (db read/write, file IO, network call, log) goes through a typed service primitive declared in `dsl/std/` or `dsl/extdeps/`. Service declarations carry effect signatures (`derive_op_effect` at `effects.dag:722-755` already does this for HTTP). There is no raw effect — no way to perform a side effect without going through a typed primitive. + +## Q2 — Every lens is a compositional fold over the 5 behaviors + +This is the unifying mechanism. Same shape every time: + +| Behavior | Complexity | Effects | Idempotency | Termination | +|---|---|---|---|---| +| **Value** | O(1) | ∅ | identity | trivial | +| **Transform** | callable cost (recursive walk) | callable effect signature (recursive walk) | callable idempotency | requires witness if recursive | +| **Branch** | max(arms) | union(arms) | conjunction(arms) | descend witness on loop arm | +| **Loop** | bound × body | body's effects | body must be idempotent for outer to be | descend witness mandatory | +| **Bind** | sum(bindings) + body | union(bindings) ∪ body | sequential composition rule | each binding's witness composes | + +**Anything compositional + structural is a fold over these 5.** The closed-system invariant means every form of computation MUST appear as one of these 5; therefore the lens domain is closed; therefore nothing can hide. + +## Q3 — Worked examples + +### Example 1 — complexity (already implemented; cited as foundation) + +``` +fn merge_sort(xs: List) -> List = + descend xs by ListShrink { + case [] => [] + case [single] => [single] + case _ => + let (left, right) = split_in_half(xs) + merge(merge_sort(left), merge_sort(right)) + } +``` + +Complexity lens walks structurally: `descend` → log₂(N) depth (each step halves); each level: linear `split_in_half` + linear `merge` (sum-of-children); composes via T(N) = 2·T(N/2) + O(N) → **O(N log N)**. + +User can declare `complexity merge_sort: O(N log N)` to *check* the lens-computed bound. **No annotation needed**; the lens computes regardless. + +### Example 2 — effects (target shape under closed-system) + +``` +fn fetch_and_log(user_id: UserId) -> User = + let user = user_service.get(user_id) // typed primitive: ReadEffect + log.info("Fetched user {}", user.name) // typed primitive: LoggingEffect + user +``` + +Effects lens walks structurally: +- `Bind` over two bindings: `let user = ...` + `log.info(...)` +- First Transform target = `user_service.get` → `ReadEffect` +- Second Transform target = `log.info` → `LoggingEffect` +- Composition (per Bind row in the table): union(bindings) ∪ body = `{ ReadEffect, LoggingEffect }` + +The lens surfaces this as a structural fact on the function declaration. **No `effects [Read, Logging]` clause needed**; the set is the structure. + +### Example 3 — redundancy (referential-transparency proof) + +``` +fn upsert_user_buggy(id: UserId, data: UserData) -> Result<()> = + let existing1 = user_service.get(id) // Bind { Transform: ServiceGet(id) } + let existing2 = user_service.get(id) // Bind { Transform: ServiceGet(id) } — same target, same args + validate(data) // Transform: validate — pure, ∅ effect + user_service.insert(data) // Transform: ServiceInsert(data) + transaction.commit() // Transform: TransactionClose +``` + +A redundancy lens walks the Bind sequence: +1. `existing2`'s Transform target = `ServiceGet`, args = `id`. +2. Walk back through Bind sequence to `existing1`'s Transform target = `ServiceGet`, args = `id`. **Same target, same args.** +3. Walk Transforms between them: `validate(data)` — Transform target's effect set = ∅ (pure). No write-effect intervened. +4. **Conclusion**: `existing2 ≡ existing1` by referential transparency. Structurally provable — not a heuristic. + +### Aggressive vs conservative reading on Example 3 + +- **Conservative**: lens surfaces the redundancy as a finding; not a compile error. User can choose to address. +- **Aggressive (closed-system discipline-strongest)**: redundant read is a **compile error by construction**. To express LEGITIMATE re-read (optimistic-lock retry, refresh-on-stale), the user calls an explicit `reread(key)` primitive in std/ that structurally tags "I know this is a re-read." + +**Director picks aggressive.** Aligns with THESIS Tier-1 impossible-by-construction commitment + `feedback_construction_over_ratchets` (model first; violations dissolve). The cost (`reread` primitive) is bounded; the discipline-strength is much higher. Conservative is softer than the discipline supports. + +### Example 4 — idempotency (already implemented; prior art) + +`idempotency.dag` already walks workflow effect composition + computes idempotency from primitive algebraic properties. Same fold pattern as the other lenses; cited as proof the pattern works. + +## Q4 — What needs to land + +This is **not** a substrate-extension lane. The substrate already exists: + +- ✅ `OperationEffect` taxonomy in `effects.dag` (Read/Upsert/Create/Append/Delete). +- ✅ `derive_op_effect` at `effects.dag:722-755` already derives effects from HTTP method + path structurally (foundation of the closed-system shape). +- ✅ Service primitives in `dsl/std/` + `dsl/extdeps/` carry typed effect signatures. +- ✅ `Behavior` enum with the 5 primitives in `substrate.dag`. + +What's needed: + +1. **Effects lens** at `src/v3/lenses/effect_enumeration.dag` (or sibling), parallel to `cost.dag` precedent. Walks the 5-behavior structure; composes effect set per the Q2 table; surfaces as a structural fact on each function declaration. +2. **Generalize effect-derivation beyond HTTP** — any typed primitive that performs a side effect carries an effect signature (not just HTTP-derived ones). Audit existing `dsl/std/` primitives + tag. +3. **Redundancy lens** (per aggressive reading) — referential-transparency proof for repeated identical reads with no intervening write. Compile-error-by-construction. +4. **`reread(key)` primitive** in std/ — structurally tags legitimate re-read for the optimistic-lock / refresh-on-stale cases the redundancy lens would otherwise reject. +5. **No parser surface, no `effects [...]` clause, no annotation**. Effects are the structural fact. + +## Q5 — Asymmetric tightening (the only declaration-value exception) + +The closed-system framing does NOT preclude callers from constraining what callees they're willing to invoke. Two exception cases retain declaration value: + +- **Asymmetric tightening at caller**: a caller declares "I only invoke functions whose effect set ⊆ {Read}". Structural type matching at the call site fails for any callee whose body composes effects beyond Read. **Caller-side constraint, structural enforcement, no separate lens.** +- **Override for test/correctness pinning**: rare; allows pinning a tighter contract for testing purposes. Same shape — caller-side constraint. + +Neither is "annotate the callee with `effects [...]`". Both are caller-pins-tighter-than-derive. + +## Q6 — Director-actionable recommendation + +**Outcome: (a) closed-system framing.** + +### Implementation-brief shape (replaces the retracted briefs) + +Title: `feat(v3): T-ImpossibleBugs effects lens — closed-system structural derivation (compositional fold over 5 behaviors)` + +**Reqs:** + +1. **Effects lens** at `src/v3/lenses/effect_enumeration.dag`, parallel to `cost.dag`. Walks the 5-behavior structure (Value / Transform / Branch / Loop / Bind); composes effect set per the Q2 table; surfaces structural-fact output (no annotation comparison). +2. **Audit + tag std/ primitives** — every effectful primitive in `dsl/std/` carries an explicit `OperationEffect` signature. Generalizes `derive_op_effect`'s HTTP-derivation to all primitives. +3. **Redundancy lens** — referential-transparency proof for repeated identical reads with no intervening write. Emits compile-time `RedundantReadError` (Tier 1, not Tier 3). +4. **`reread(key)` primitive** in std/ for legitimate re-read cases. Structurally tagged. +5. **Smoke + integration tests**: function with multiple typed-effect calls produces correct effect-set structural fact; redundant-read function fails compile; `reread`-using function compiles. + +**STOPs**: +- If audit (req 2) reveals a primitive performing side effects without an `OperationEffect` tag (a hidden hole in the closed-system invariant), STOP — that's a substrate gap that needs filling first. +- If the redundancy proof requires substrate primitives the lens can't read structurally (e.g., distinguishing pure from impure transforms inline), STOP — may need a `pure: Bool` fact or sibling carrier on Transform targets. +- If asymmetric-tightening at caller surfaces a structural-type-matching gap (caller can't actually pin effect-set constraints structurally today), STOP — that's its own substrate sub-lane. + +**Acceptance**: 4 worked examples from this design doc compile (or fail-compile) per their stated outcomes; lens output observable via standard lens-output infrastructure; cargo + clippy + fmt clean; DB-8 fixed-point converges. + +## Capacity / sequencing impact + +| Brief | Status | +|---|---| +| `t-impossiblebugs-unenumerated-effects-worker.md` (substrate-effects lens; was lens-vs-declaration) | **SUPERSEDED** — banner pointing here | +| `t-impossiblebugs-unenumerated-effects-parser-worker.md` (parser declared_effects clause) | **SUPERSEDED** — banner pointing here; no parser surface needed | +| `t-impossiblebugs-unenumerated-effects-fn-arrow-refactor-worker.md` (#805 brief; Fn→Arrow refactor) | **KEEP** — independent value (cleans `params + return_type` vestige); not effects-specific | +| Bulk std/ annotation lane (was Lane D) | **DISSOLVES** — no annotations to add | + +Net: 1 chain of 3 implementation lanes collapses to 1 implementation lane (effects lens) + 1 sub-lane (`reread` primitive in std/ if not already there) + 1 audit lane (tag std/ primitives with effect signatures). Smaller scope; stronger claim. + +## Cross-manager note + +- **Zero-Floor Manager**: heads-up. Effect-signature tagging on std/ primitives may touch substrate-adjacent territory; coordinate at audit-phase if needed. +- **Grounding Manager**: no current overlap. +- **PM**: synergy framing (5-behavior fold table) is the load-bearing reframe; the effects lens is positioned as the next instance of an established pattern (idempotency / termination / omni-emit are prior art) rather than novel substrate work. + +## Closing signal + +Director cleared to author the implementation brief based on Q6's shape. Worker dispatch follows. The retracted briefs get SUPERSEDED banners pointing here. diff --git a/docs/briefs/t-impossiblebugs-unenumerated-effects-parser-worker.md b/docs/briefs/t-impossiblebugs-unenumerated-effects-parser-worker.md index db3762fcf40..24013a283e0 100644 --- a/docs/briefs/t-impossiblebugs-unenumerated-effects-parser-worker.md +++ b/docs/briefs/t-impossiblebugs-unenumerated-effects-parser-worker.md @@ -1,4 +1,6 @@ -# T-ImpossibleBugs unenumerated effects — parser extension `(M, R2 prereq)` +# T-ImpossibleBugs unenumerated effects — parser extension `(M, R2 prereq; SUPERSEDED 2026-04-25)` + +> **🔄 SUPERSEDED 2026-04-25 by [`docs/briefs/t-impossiblebugs-unenumerated-effects-design.md`](t-impossiblebugs-unenumerated-effects-design.md).** The parser surface this brief proposed (`SurfaceArrow` / `FnSignature` `declared_effects` field + `effects [Read, Write]` clause syntax + lookahead + body parser) **vanishes** under closed-system framing. Effects derive structurally from typed primitive composition; there is no `declared_effects` clause to parse. See the design doc for the closed-system mechanism + 5-behavior compositional-fold pattern. **Do not author new work against this brief; route to the design doc.** No parser code has merged against this brief; the cleanup is doc-only. (Independent value: the [`t-impossiblebugs-unenumerated-effects-fn-arrow-refactor-worker.md`](t-impossiblebugs-unenumerated-effects-fn-arrow-refactor-worker.md) brief from #805 stays dispatchable — the Fn→Arrow refactor cleans the vestigial `params + return_type` split regardless of effects framing.) > **Director ad-hoc dispatch.** Sibling pre-requisite to the > [`t-impossiblebugs-unenumerated-effects-worker.md`](t-impossiblebugs-unenumerated-effects-worker.md) diff --git a/docs/briefs/t-impossiblebugs-unenumerated-effects-worker.md b/docs/briefs/t-impossiblebugs-unenumerated-effects-worker.md index 43eb0ac1690..3a3cf74740b 100644 --- a/docs/briefs/t-impossiblebugs-unenumerated-effects-worker.md +++ b/docs/briefs/t-impossiblebugs-unenumerated-effects-worker.md @@ -1,4 +1,6 @@ -# T-ImpossibleBugs — unenumerated effects `(S, R2; SPLIT — parser sub-lane lands first)` +# T-ImpossibleBugs — unenumerated effects `(S, R2; SUPERSEDED 2026-04-25)` + +> **🔄 SUPERSEDED 2026-04-25 by [`docs/briefs/t-impossiblebugs-unenumerated-effects-design.md`](t-impossiblebugs-unenumerated-effects-design.md).** The lens-vs-declaration framing in this brief is **retracted**. Under closed-system structural derivation (parallel to closed-system complexity), effects derive from the composition of typed primitive operations — there is no annotation surface, no declared-vs-inferred lens check. See the design doc for the 5-behavior compositional-fold mechanism + worked examples + redundancy treatment. **Do not author new work against this brief; route to the design doc.** No code has merged against this brief; the cleanup is doc-only. > **Director ad-hoc dispatch.** R2 T-ImpossibleBugs class 3 of 3 per > [`docs/r2-structure.md`](../r2-structure.md) §"Goal 4". Independent From 2dc656bbeddf219b111775726836aa1110210224 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 13:45:23 -0400 Subject: [PATCH 37/52] =?UTF-8?q?docs(closed-system-effects):=20Q5.5=20?= =?UTF-8?q?=E2=80=94=20operation=20type-signature=20shape=20IS=20the=20eff?= =?UTF-8?q?ect?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per PM convergence review on #808 + user's deeper 2026-04-25 framing: the closed-system framing landed in #808 retired the user-facing annotation but kept OperationEffect taxonomy as substrate-level tagging. User's deeper framing: the taxonomy ITSELF is parallel-representation — operations are intrinsically read-shaped or write-shaped via their TYPE-SIGNATURE SHAPE (returned-modified-resource → write; returns- derived-value-only → read). Tagging operations with Read | Upsert | Create | Append | Delete names what the structure already says. Three changes: 1. Design doc Q5.5 added — "OperationEffect taxonomy: retain as normalized view, or retire as parallel-representation?" - Two paths: (i) tags derived from signature shape (acceptable normalized view) vs (ii) tags declared per-primitive (parallel- representation; retire). - Audit-as-existence-check (Q4 req 2 reframed): all effectful primitives derive cleanly from signature shape → path (i); any primitive needs hand-declared tag → path (ii) by existence proof. - Director default: path (ii). Logging primitives that return Unit are likely the audit's existence-proof. - Two design-question resolutions: (a) external effects not in return type → resource-threading discipline (typed param returned modified, IO-monad-without-the-monad pattern); (b) transactional grouping → derived structural fact from Bind composition + typed transaction primitives. 2. Q4 reqs revised: req 2 from "tag every primitive with explicit OperationEffect signature" to "audit-as-existence-check that every primitive's type signature derives the right effect classification"; req 3 added (resource-threading discipline); req 6 added (transactional-pattern lens). Req 1 (effects lens) anchors on operation type-signature shape, not on hand-declared tags. 3. THESIS:345-347 amendment strengthened — "operations are intrinsically read-shaped or write-shaped via their type-signature shape; consumers walk the signatures directly; there is no parallel taxonomy or annotation layer to declare or maintain. Tracking effects as a separate enumerated concept IS the bug pattern, dissolved by construction." Plus references to resource-threading discipline + transactional grouping as derived structural fact. Memory file feedback_closed_system_effects.md updated to reflect the deeper framing (type-signature-shape, not taxonomy-tagging) + resource-threading discipline section + transactional-patterns section. Net cost: doc-only delta on top of #808. Substrate retirement (OperationEffect enum + derive_op_effect + idempotency.dag re-anchor) deferred to the audit-as-existence-check phase of the implementation brief; surfaced as Q5.5 OPEN CALL. Co-Authored-By: Claude Opus 4.7 (1M context) --- THESIS.md | 28 ++++--- ...ossiblebugs-unenumerated-effects-design.md | 75 ++++++++++++++++--- 2 files changed, 82 insertions(+), 21 deletions(-) diff --git a/THESIS.md b/THESIS.md index fa266dff506..6abb8d24ead 100644 --- a/THESIS.md +++ b/THESIS.md @@ -342,20 +342,26 @@ empty set per [`docs/design-pure-bootstrap-zero.md`](docs/design-pure-bootstrap- - **[R2+]** Nested-optional flatten: `Option>` accessor patterns that normal languages require hand-unwrapping. Gated on cardinality refinement substrate work. - - **[R2+]** Unenumerated effects: every effect performed in this system is - structurally visible at compile time; impossible to hide an effect because - the substrate IS the registry (effects derive from the composition of - typed primitive operations, parallel to how complexity derives from - bounded-kernel composition — same closed-system mechanism). There is no - declared-effects-vs-inferred-effects mismatch because there is no separate - "declared" surface — the structural fact is the only authority. Redundant - effects (e.g., reads of the same key with no intervening write-effect) are + - **[R2+]** Unenumerated effects: operations are intrinsically read-shaped + or write-shaped via their type-signature shape (returned-modified-resource + indicates write; returns-derived-value-only indicates read). Consumers + walk the signatures directly; there is no parallel taxonomy or annotation + layer to declare or maintain. Tracking effects as a separate enumerated + concept IS the bug pattern, dissolved by construction. Every external + mutable resource (file handles, sockets, db connections) is modeled as a + typed parameter that's returned modified — same pattern as IO-monad + World-threading without the monad. Redundant operations (reads of the + same key with no intervening write-effect on that resource) are structurally provable as identical via referential transparency, and rejected at compile time; legitimate re-read uses an explicit `reread()` - primitive that structurally tags the intent. Tier 1 (impossible by - construction), not Tier 2 (lens-detected). See + primitive that structurally tags the intent. Transactional grouping is a + derived structural fact from Bind composition + typed transaction + primitives (`Transaction → Transaction'`), not a separate concept. Tier 1 + (impossible by construction), not Tier 2 (lens-detected). See [`docs/briefs/t-impossiblebugs-unenumerated-effects-design.md`](docs/briefs/t-impossiblebugs-unenumerated-effects-design.md) - for the 5-behavior compositional-fold mechanism + worked examples. + §Q5.5 for the OperationEffect-taxonomy retirement rationale + audit-as- + existence-check; §Q1-Q3 for the 5-behavior compositional-fold mechanism + + worked examples. - **[R2+]** Unhandled diagnostic paths: Tier 2 runtime-safety proofs make division-by-zero, OOB, and force-unwrap either proven safe or made total — never partial. Gated on Tier 2 substrate (post-R1). diff --git a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md index 21ab4c96b0b..570e770be0b 100644 --- a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md +++ b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md @@ -107,22 +107,77 @@ A redundancy lens walks the Bind sequence: `idempotency.dag` already walks workflow effect composition + computes idempotency from primitive algebraic properties. Same fold pattern as the other lenses; cited as proof the pattern works. -## Q4 — What needs to land +## Q4 — What needs to land (revised per Q5.5) -This is **not** a substrate-extension lane. The substrate already exists: +The closed-system foundation already exists at the substrate level: -- ✅ `OperationEffect` taxonomy in `effects.dag` (Read/Upsert/Create/Append/Delete). -- ✅ `derive_op_effect` at `effects.dag:722-755` already derives effects from HTTP method + path structurally (foundation of the closed-system shape). -- ✅ Service primitives in `dsl/std/` + `dsl/extdeps/` carry typed effect signatures. - ✅ `Behavior` enum with the 5 primitives in `substrate.dag`. +- ✅ Service primitives in `dsl/std/` + `dsl/extdeps/` carry **typed type-signature shapes** that structurally express read-vs-write (return derived value with resource unchanged → read; return modified resource → write). See Q5.5 for the deeper framing. +- ⚠️ `OperationEffect` taxonomy in `effects.dag:262-506` (Read/Upsert/Create/Append/Delete) — **status pending Q5.5 audit-as-existence-check** (see below). Either retained as a normalized view derived from signature shape, or retired as parallel-representation. +- ⚠️ `derive_op_effect` at `effects.dag:722-755` — same status; today derives from HTTP method + path, which IS the structural fact. What's needed: -1. **Effects lens** at `src/v3/lenses/effect_enumeration.dag` (or sibling), parallel to `cost.dag` precedent. Walks the 5-behavior structure; composes effect set per the Q2 table; surfaces as a structural fact on each function declaration. -2. **Generalize effect-derivation beyond HTTP** — any typed primitive that performs a side effect carries an effect signature (not just HTTP-derived ones). Audit existing `dsl/std/` primitives + tag. -3. **Redundancy lens** (per aggressive reading) — referential-transparency proof for repeated identical reads with no intervening write. Compile-error-by-construction. -4. **`reread(key)` primitive** in std/ — structurally tags legitimate re-read for the optimistic-lock / refresh-on-stale cases the redundancy lens would otherwise reject. -5. **No parser surface, no `effects [...]` clause, no annotation**. Effects are the structural fact. +1. **Effects lens** at `src/v3/lenses/effect_enumeration.dag` (or sibling), parallel to `cost.dag` precedent. Walks the 5-behavior structure; composes effect-classification per the Q2 table; surfaces as a structural fact on each function declaration. **Anchors on operation type-signature shape, not on hand-declared tags.** +2. **Audit-as-existence-check** (formerly "tag every primitive"): verify that every effectful primitive in `dsl/std/` + `dsl/extdeps/` has a type signature that structurally derives the right effect classification (returned-modified-resource indicates write; returns-derived-value-only indicates read; etc.). **If any primitive requires a hand-declared tag because its signature doesn't structurally reveal the effect, that's the existence-proof that taxonomy retirement is needed (Q5.5 path (ii))**. If all primitives derive cleanly from signature shape, taxonomy can be retained as a normalized view (Q5.5 path (i)). +3. **Resource-threading discipline for std/ primitives**: every external mutable resource must be modeled as a typed parameter that's returned modified (`log.info(msg, log: LogFile) → LogFile'`; sockets thread `Connection → Connection'`; etc.). Same pattern as IO-monad-style World-threading in pure-functional languages, without the monad — typed resource as parameter + returned-modified is the discipline. Forces the structural-signature-shape encoding at the substrate level. Audit (req 2) catches existing primitives that violate the discipline. +4. **Redundancy lens** (per aggressive reading) — referential-transparency proof for repeated identical reads with no intervening write. Compile-error-by-construction. +5. **`reread(key)` primitive** in std/ — structurally tags legitimate re-read for the optimistic-lock / refresh-on-stale cases the redundancy lens would otherwise reject. +6. **Transactional-pattern lens** — derived structural fact from Bind composition + typed transaction primitives (`Transaction → Transaction'`). Lens walks the Bind chain and recognizes the begin-modify-commit shape structurally. Same closed-system fold. +7. **No parser surface, no `effects [...]` clause, no annotation, no per-primitive tag declaration.** Effects are the structural fact (operation type-signature shape). + +## Q5 — Asymmetric tightening (the only declaration-value exception) + +The closed-system framing does NOT preclude callers from constraining what callees they're willing to invoke. Two exception cases retain declaration value: + +- **Asymmetric tightening at caller**: a caller declares "I only invoke functions whose composed effects ⊆ {read-shaped}". Structural type matching at the call site fails for any callee whose body composes write-shaped operations. **Caller-side constraint, structural enforcement via type-signature shape, no separate lens.** +- **Override for test/correctness pinning**: rare; allows pinning a tighter contract for testing purposes. Same shape — caller-side constraint. + +Neither is "annotate the callee with `effects [...]`" or "tag the callee primitive with OperationEffect". Both are caller-pins-tighter-than-derive. + +## Q5.5 — OperationEffect taxonomy: retain as normalized view, or retire as parallel-representation? + +**Status: OPEN; resolution pending audit (Q4 req 2).** + +User's framing 2026-04-25 went one level deeper than the closed-system framing in Q1-Q5: *"having a Read effect might be a dual representation within our own language — i.e. the language should clearly know if it's reading something or writing something already"*. + +The deeper observation: a function's type-signature shape already structurally carries whether it reads or writes: +- `service.get(id, svc) → User` (svc unchanged) is structurally a read. +- `service.insert(data, svc) → UserService'` (svc modified-and-returned) is structurally a write. + +**The shape IS the effect.** A taxonomy `Read | Upsert | Create | Append | Delete` that names what the type signature already says is potentially `feedback_naming_is_aliasing` + `feedback_dissolve_bridges` + `feedback_parallel_representation_debt` firing at once. + +### Two paths + +**(i) OperationEffect taxonomy is a normalized view derived from signature shape.** Tags computed from operation type signatures (returned-modified-resource → write-shaped → tag as Upsert/Create; returns-derived-value-only → read-shaped → tag as Read). Per `feedback_naming_is_aliasing` — named types are namespaces over structural facts; tags are namespaces over the same. **Acceptable retention.** Idempotency lens + cost lens consumers continue to read tags; tags are computed from structure. + +**(ii) OperationEffect tags are required-to-be-declared per primitive.** Then they're parallel-representation to what the signature already carries. **Retire entirely**; consumers walk type signatures directly. Bigger reframe — touches existing landed substrate (`effects.dag`'s enum + `derive_op_effect` + `idempotency.dag`'s anchor consume OperationEffect today). Stronger discipline-claim. + +### Audit-as-existence-check (Q4 req 2 reframed) + +The audit decides: +- **All effectful primitives in `dsl/std/` + `dsl/extdeps/` have type signatures that structurally derive the right effect classification** → path (i). Retain as normalized view; ensure no primitive declares its tag rather than deriving it. +- **At least one effectful primitive requires a hand-declared tag because its signature doesn't structurally reveal the effect** → path (ii). The existence proof shows the taxonomy is parallel-representation; retire it. + +### Two design questions answered structurally (no new substrate) + +PM surfaced two cases that might not map cleanly to type-signature shape: + +1. **Operations whose external effects don't appear in their return type** — e.g., `log.info(msg)` returning Unit hides the file-write. **Resolution: every external mutable resource is modeled as a typed parameter that's returned modified.** `log.info(msg, log: LogFile) → LogFile'`. Sockets take `Connection`, return `Connection'`. File handles same. Forces the discipline at the type-signature level. Same pattern as Haskell IO monad's `World → (Result, World')` without the monad — typed resource threading is the discipline. **Existing primitives that violate this (e.g., logging that returns Unit) are the audit's existence-proof for path (ii).** + +2. **Atomicity / transactional grouping** — not a single-op property; it's a property of the COMPOSITION. **Resolution: transactional pattern is a derived structural fact from Bind composition + typed transaction primitives (`Transaction → Transaction'`).** A lens walks the Bind chain and recognizes the begin-modify-commit shape. Same closed-system fold pattern. + +Both answer structurally. No new substrate needed for either. + +### Director recommendation + +**Default expectation: path (ii).** User's deeper framing strongly suggests OperationEffect IS parallel-representation; the existence of `derive_op_effect` (deriving from HTTP method) is itself prior art that the structural fact is the authority and the tag is a renaming. Logging primitives that today return Unit are likely the audit's existence-proof. + +**If the audit produces a counterexample where path (i) is genuinely cleaner**, surface it in the implementation PR for re-decision. The default is retire. + +### THESIS amendment under (ii) + +Stronger framing than the Q1 amendment: *"tracking effects as a separate taxonomy IS the bug pattern, dissolved by construction. Operations are intrinsically read-shaped or write-shaped or transactional via their type-signature shape; consumers walk the signatures directly; there is no parallel taxonomy to declare or maintain."* ## Q5 — Asymmetric tightening (the only declaration-value exception) From 191be310b39a782240bee4d436239d89dc68e8f2 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 13:46:43 -0400 Subject: [PATCH 38/52] =?UTF-8?q?docs(closed-system-effects):=20close=20co?= =?UTF-8?q?dex=20BLOCKING=20=E2=80=94=20honest=20live-state=20on=20signatu?= =?UTF-8?q?re-shape=20coverage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves codex BLOCKING at sha d49ce79a on docs/briefs/t-impossiblebugs-unenumerated-effects-design.md:116. Real: the prior text claimed service primitives "already carry typed effect signatures" presenting future audit-state as current substrate fact (P1 violation). My Q5.5 amendment at 2dc656bbe partially fixed the OperationEffect line but left a parallel over-claim on the new "signature-shape coverage" framing. Fix: Q4 substrate-state listing rewritten to honestly distinguish: - Live: Behavior enum + substrate foundation (the principle that operations should carry signature shape). - Incomplete: signature-shape coverage across actual primitives. HTTP-derived primitives carry implicit shape via derive_op_effect's method-table; logging/mutation primitives that return Unit or don't thread their target resource do NOT carry the structural shape that would express read-vs-write. Achieving full coverage is required work under reqs 2 + 3, not a current fact. - Pending audit-as-existence-check: OperationEffect + derive_op_effect (path (i) vs (ii) per Q5.5). Honest live-state callout added explicitly: "the closed-system FOUNDATION (5 behaviors + DAG substrate + the principle that operations should carry signature-shape) is live. The IMPLEMENTATION COVERAGE across all effectful primitives is partial. Req 2 + req 3 are the work that closes the gap." Brief now distinguishes principle-is-live (foundation) from coverage-is-partial (audit work) without conflating them. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../t-impossiblebugs-unenumerated-effects-design.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md index 570e770be0b..4729cecab26 100644 --- a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md +++ b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md @@ -109,12 +109,14 @@ A redundancy lens walks the Bind sequence: ## Q4 — What needs to land (revised per Q5.5) -The closed-system foundation already exists at the substrate level: +The closed-system foundation exists at the substrate level — but with substantive coverage gaps the audit must close: -- ✅ `Behavior` enum with the 5 primitives in `substrate.dag`. -- ✅ Service primitives in `dsl/std/` + `dsl/extdeps/` carry **typed type-signature shapes** that structurally express read-vs-write (return derived value with resource unchanged → read; return modified resource → write). See Q5.5 for the deeper framing. +- ✅ `Behavior` enum with the 5 primitives in `substrate.dag`. Live; complete. +- ⚠️ **Service primitives in `dsl/std/` + `dsl/extdeps/`: signature-shape coverage is INCOMPLETE today.** Some HTTP-derived primitives carry implicit effect signatures (via `derive_op_effect`'s method-table); many other effectful primitives (logging that returns Unit; mutation primitives that don't thread their target resource; etc.) do NOT carry the signature shape that would structurally express read-vs-write. Achieving full coverage is **required audit + substrate-work** under req 2 + req 3 below — NOT a current substrate fact. See Q5.5 for the deeper framing. - ⚠️ `OperationEffect` taxonomy in `effects.dag:262-506` (Read/Upsert/Create/Append/Delete) — **status pending Q5.5 audit-as-existence-check** (see below). Either retained as a normalized view derived from signature shape, or retired as parallel-representation. -- ⚠️ `derive_op_effect` at `effects.dag:722-755` — same status; today derives from HTTP method + path, which IS the structural fact. +- ⚠️ `derive_op_effect` at `effects.dag:722-755` — same status; today derives from HTTP method + path. HTTP method IS a structural fact; whether the rest of the primitive surface aligns is the audit's existence-check. + +**Honest live-state:** the closed-system FOUNDATION (5 behaviors + DAG substrate + the principle that operations should carry signature-shape) is live. The IMPLEMENTATION COVERAGE across all effectful primitives is partial. Req 2 + req 3 are the work that closes the gap. What's needed: From 8d9b298273a38ff4c118aa927e3d2d7744ad40f0 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 13:59:58 -0400 Subject: [PATCH 39/52] WIP: gunbc Director --- .../t-impossiblebugs-unenumerated-effects-design.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md index 4729cecab26..a5f4213b126 100644 --- a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md +++ b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md @@ -181,15 +181,6 @@ Both answer structurally. No new substrate needed for either. Stronger framing than the Q1 amendment: *"tracking effects as a separate taxonomy IS the bug pattern, dissolved by construction. Operations are intrinsically read-shaped or write-shaped or transactional via their type-signature shape; consumers walk the signatures directly; there is no parallel taxonomy to declare or maintain."* -## Q5 — Asymmetric tightening (the only declaration-value exception) - -The closed-system framing does NOT preclude callers from constraining what callees they're willing to invoke. Two exception cases retain declaration value: - -- **Asymmetric tightening at caller**: a caller declares "I only invoke functions whose effect set ⊆ {Read}". Structural type matching at the call site fails for any callee whose body composes effects beyond Read. **Caller-side constraint, structural enforcement, no separate lens.** -- **Override for test/correctness pinning**: rare; allows pinning a tighter contract for testing purposes. Same shape — caller-side constraint. - -Neither is "annotate the callee with `effects [...]`". Both are caller-pins-tighter-than-derive. - ## Q6 — Director-actionable recommendation **Outcome: (a) closed-system framing.** From f073aa95e7fe1fc2eadcf18ae06801d908ae2dc2 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 14:00:36 -0400 Subject: [PATCH 40/52] =?UTF-8?q?docs(closed-system-effects):=20Q4.5=20?= =?UTF-8?q?=E2=80=94=20load-bearing=20pre-conditions=20for=20closed-system?= =?UTF-8?q?=20claim?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per PM follow-up review on #808 + user's stronger discipline framing ("substrate must make bypass structurally impossible at every layer of the transport stack"): the closed-system claim is honest only when typed primitives ARE the path. Today two structural holes exist where bypasses sidestep the typed-primitive substrate. Both surfaced explicitly as Q4.5 pre-conditions — load-bearing for the lens's coverage claim. Three changes: 1. NEW Q4.5 section "Pre-conditions (load-bearing for the closed- system claim)" inserted between Q4 and Q5: P1 — Extdeps typed-primitive consumption structurally enforced. Substrate must make `messages: Json` impossible to declare in service definitions; typed `LlmMessage` / `ContentBlock` / `GitHubAuthToken`-with-full-scopes are the only path. Tracked debt at ROADMAP.md:153-154 (LLM provider flattening) + `dsl/extdeps/github/auth.dag:13-24` (scopes/expires_at discarded). Required prereq for full lens coverage; lens can land first + surface structural-coverage-gap diagnostics on bypass surfaces so the gap becomes visible rather than silent. P2 — `ExecuteCommand` fully materialized as typed runner primitive. TESTING.md (post-#782) committed to 0-residual but ExecuteCommand isn't fully materialized; deleting Rust boundary tests creates verification gap. Already named under PB-Runtime in Zero-Floor; signal pending. Pre-requisite for ANY Rust boundary-test deletion. 2. Old leftover duplicate Q5 section deleted (artifact from prior Q5/Q5.5 reshape; second copy of asymmetric-tightening text was in the file alongside the earlier Q5 instance). 3. Worker-discretion-vs-Director-call section in Q4.5: lens implementation worker dispatchable now (reports gaps as findings); P1 closure is substantive substrate work touching extdeps (dedicated lane); P2 closure is PB-Runtime (signal pending). Net: design doc now honestly distinguishes principle-is-live (Q4 rewrite at 191be310b) from coverage-is-partial (Q4.5 prereqs named explicitly). The closed-system claim has explicit pre- conditions documented; implementation brief discovers them as known dependencies, not as STOP-AND-ESCALATEs. Co-Authored-By: Claude Opus 4.7 (1M context) --- ...ossiblebugs-unenumerated-effects-design.md | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md index a5f4213b126..80fe0000317 100644 --- a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md +++ b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md @@ -128,6 +128,44 @@ What's needed: 6. **Transactional-pattern lens** — derived structural fact from Bind composition + typed transaction primitives (`Transaction → Transaction'`). Lens walks the Bind chain and recognizes the begin-modify-commit shape structurally. Same closed-system fold. 7. **No parser surface, no `effects [...]` clause, no annotation, no per-primitive tag declaration.** Effects are the structural fact (operation type-signature shape). +## Q4.5 — Pre-conditions (load-bearing for the closed-system claim) + +The closed-system claim *"effects derive structurally from the composition of typed primitive operations"* is **honest only when typed primitives ARE the path**. Today, two structural holes exist where bypasses bypass the typed-primitive substrate. Both are pre-conditions for the lens to deliver on its closed-system claim — without them, the lens has structural holes wherever the foundation isn't yet closed. + +### P1 — Extdeps typed-primitive consumption is structurally enforced + +The substrate must make it impossible for a service definition to declare `messages: Json` instead of `messages: List`. Typed protocol carriers must be the ONLY path; raw Json / string-path extraction must have no structural home in service definitions. + +**Today's tracked debt** (per ROADMAP.md:153-154): +- `dsl/extdeps/llm/openai.dag:92-110` — `messages: Json` + string-path output extraction (bypass: typed `LlmMessage` + `ContentBlock` carriers exist but not consumed). +- `dsl/extdeps/llm/anthropic.dag:104-124` — same pattern. +- `dsl/extdeps/github/auth.dag:13-24` — `github_token() → { token: Secret }` discards modeled scopes + `expires_at` from `GitHubAuthToken`. + +**Why load-bearing**: until typed-primitive consumption is structurally enforced (impossible to bypass), service-definition surfaces can still declare effects via raw Json paths. The lens walking those declarations would have nothing structural to read; the closed-system claim has a hole exactly there. Required prereq under reqs 2 + 3 (audit catches; substrate-discipline closes). + +**Sequencing**: prereq for the lens's *coverage* claim. The lens itself can land first (Q6 implementation brief); it just won't cover the bypassed extdeps surfaces until P1 closes. The lens's acceptance must surface structural-coverage-gap diagnostics on those surfaces (i.e., the lens itself reports "this surface has a structural hole; effect-derivation can't proceed structurally"). That's how the gap becomes load-bearing visible rather than silent. + +### P2 — `ExecuteCommand` fully materialized as a typed runner primitive + +Subprocess invocations need a typed primitive that derives "external-toolchain effect" structurally — analog of how `derive_op_effect` derives effects from HTTP method. Today the M1.5 testgen harness allowlists only `command == "true" && args.is_empty() && expect_exit == 0` and panics fail-closed on anything else; the Rust `TestRunner` returns `NotYetImplemented` for `ExecuteCommand` (see `TESTING.md:195` capability state callout). + +**Why load-bearing**: TESTING.md (post-#782 cascade) committed to `0-residual` framing — boundary tests migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations. **Until `ExecuteCommand` can execute equivalent `.dag` TestClaims, deleting Rust boundary tests creates a verification gap.** Same closed-system shape applied to test execution: the typed runner primitive IS the path; subprocess invocations have nowhere structural to live until then. + +**Sequencing**: pre-requisite for *any* Rust boundary-test deletion. Already named under PB-Runtime in Zero-Floor Manager's program scope; Director-signaled twice. Should be priority once Zero-Floor's authoring queue clears. + +### Why these belong in this design doc + +Both prereqs are load-bearing for the closed-system claim this doc commits to. Naming them in-doc surfaces the dependencies upfront rather than letting the implementation brief discover them as STOP-AND-ESCALATEs at dispatch time. Workers reading this doc see correctly that: +- The lens at Q6 can land independently (worth the empirical receipt of structural-coverage diagnostics). +- The closed-system claim's *full coverage* requires P1 + P2 closure. +- Without P1: bypass surfaces visible only via the lens's own gap diagnostics (lens lands; reports holes). +- Without P2: TESTING.md `0-residual` claim cannot be acted on (no Rust boundary-test deletion). + +Worker-discretion-vs-Director-call: +- Lens implementation worker: dispatchable now; lens reports gaps as findings. +- P1 closure: substantive substrate work touching extdeps; tracked debt at ROADMAP.md:153-154; should land via dedicated lane. +- P2 closure: PB-Runtime in Zero-Floor; signal pending. + ## Q5 — Asymmetric tightening (the only declaration-value exception) The closed-system framing does NOT preclude callers from constraining what callees they're willing to invoke. Two exception cases retain declaration value: From ff7cb4bd5353c3a8930654ae512699bed2e08d2b Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 14:02:39 -0400 Subject: [PATCH 41/52] docs(closed-system-effects): align Q6 + capacity-table with Q5.5 path (ii) default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves claude APPROVE_WITH_COMMENTS at sha 191be310 on #808. Two real residuals after the Q5.5 reframe: 1. Q6's reqs/STOPs/acceptance still framed under path (i) — said "audit + tag std/ primitives — every effectful primitive carries an explicit OperationEffect signature." Directly contradicted Q4 (post-191be310b) + Q5.5's path (ii) default + the THESIS amendment ("there is no parallel taxonomy to declare or maintain"). Worker reading Q6 in isolation would author the retracted shape. 2. Capacity / sequencing table line about "audit lane (tag std/ primitives with effect signatures)" carried the same stale framing. 3. Q6 STOP "primitive performing side effects without an OperationEffect tag" assumed tag-as-authority; under path (ii) the STOP shape is "primitive whose signature doesn't structurally reveal its effect." Plus the duplicate Q5 section claude flagged at :184-191 is sha-stale (already fixed at f073aa95e Q4.5 commit). ## Q6 fixes - Reqs renumbered + reframed: - Req 1 anchors on operation type-signature shape (not hand-declared OperationEffect tags); composition reads from signature shape per Q2 table. - Req 2 changed from "audit + tag every primitive" to "audit-as-existence-check" — verify signature-shape coverage; ANY primitive needing a hand-declared tag IS the existence-proof for path (ii) retirement. - Req 3 added: resource-threading discipline applied to existing primitives (logging that returns Unit gets reshaped per audit). - Req 6 added: transactional-pattern lens (Bind composition + Transaction → Transaction'). - Req 7 added: asymmetric-tightening worked example in PR body (per claude review observation; the one place declaration-shaped surface re-enters). - Req 8 (was 5): tests now reference signature-shape derivation explicitly, not tag lookup. - STOPs reframed: - "OperationEffect retirement decision" — audit produces path (i) vs (ii) verdict; substrate retirement is its own dedicated sub-lane; this lane does NOT absorb it. - Pure/impure carrier STOP notes that "pure" should also derive from signature shape (pure functions don't return modified resources) — so the STOP itself may dissolve under further design. - Q4.5 P1 explicitly NOT a STOP — lens reporting structural- coverage-gap on extdeps bypass surfaces is the lens delivering its foundation-gap-visibility value. - Q4.5 P2 explicitly independent — lens doesn't depend on ExecuteCommand materialization. - Acceptance extended: lens reports gap diagnostics on P1 bypass surfaces; audit produces existence-proof verdict for Director re-decision; asymmetric-tightening worked example in PR body. ## Capacity / sequencing table Replaced "1 audit lane (tag std/ primitives with effect signatures)" with "1 audit-as-existence-check lane (verify primitives' signature- shape coverage; NOT 'tag every primitive') — produces the path (i) vs (ii) verdict on OperationEffect retention." Added Q4.5 P1+P2 prereq lanes to the net summary. Closing line: "The taxonomy- retirement scope (substrate-side) is not in this lane — it's surfaced by audit and routed to dedicated retirement lane if path (ii) wins." Net: design doc internally consistent across Q1-Q6 + Q4.5 + capacity table. Worker reading Q6 in isolation now sees path-(ii)-default framing matching Q4 + Q5.5 + THESIS amendment. Co-Authored-By: Claude Opus 4.7 (1M context) --- ...ossiblebugs-unenumerated-effects-design.md | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md index 80fe0000317..60b8ccc3199 100644 --- a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md +++ b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md @@ -227,20 +227,25 @@ Stronger framing than the Q1 amendment: *"tracking effects as a separate taxonom Title: `feat(v3): T-ImpossibleBugs effects lens — closed-system structural derivation (compositional fold over 5 behaviors)` -**Reqs:** +**Reqs** (aligned with Q4's audit-as-existence-check + Q5.5's path (ii) default): -1. **Effects lens** at `src/v3/lenses/effect_enumeration.dag`, parallel to `cost.dag`. Walks the 5-behavior structure (Value / Transform / Branch / Loop / Bind); composes effect set per the Q2 table; surfaces structural-fact output (no annotation comparison). -2. **Audit + tag std/ primitives** — every effectful primitive in `dsl/std/` carries an explicit `OperationEffect` signature. Generalizes `derive_op_effect`'s HTTP-derivation to all primitives. -3. **Redundancy lens** — referential-transparency proof for repeated identical reads with no intervening write. Emits compile-time `RedundantReadError` (Tier 1, not Tier 3). -4. **`reread(key)` primitive** in std/ for legitimate re-read cases. Structurally tagged. -5. **Smoke + integration tests**: function with multiple typed-effect calls produces correct effect-set structural fact; redundant-read function fails compile; `reread`-using function compiles. +1. **Effects lens** at `src/v3/lenses/effect_enumeration.dag`, parallel to `cost.dag`. Walks the 5-behavior structure (Value / Transform / Branch / Loop / Bind); **anchors on operation type-signature shape**, not on hand-declared OperationEffect tags; composes effect classification per the Q2 table; surfaces structural-fact output (no annotation comparison, no parallel-taxonomy lookup). +2. **Audit-as-existence-check** — verify that every effectful primitive in `dsl/std/` + `dsl/extdeps/` has a type signature that structurally derives the right effect classification (returned-modified-resource → write-shaped; returns-derived-value-only → read-shaped). **NOT "tag every primitive"**. Per Q5.5: any primitive requiring a hand-declared `OperationEffect` tag because its signature doesn't structurally reveal the effect IS the existence-proof for path (ii) — taxonomy retirement. +3. **Resource-threading discipline applied to existing primitives** — primitives that violate the discipline today (e.g., logging that returns Unit instead of `LogFile → LogFile'`) get reshaped per the audit's findings. Foundation step toward signature-shape coverage. +4. **Redundancy lens** — referential-transparency proof for repeated identical reads with no intervening write. Emits compile-time `RedundantReadError` (Tier 1, not Tier 3). +5. **`reread(key)` primitive** in std/ for legitimate re-read cases. Structurally tagged. Single authority for re-read intent (per claude review observation: extend `reread` rather than adding parallel primitives if cache-invalidation / transactional-refresh ever need similar affordance). +6. **Transactional-pattern lens** — derived structural fact from Bind composition + typed transaction primitives (`Transaction → Transaction'`). +7. **Asymmetric-tightening worked example** in implementation PR body — concrete demonstration that caller-side constraint via structural type matching rejects a callee whose body composes write-shaped operations beyond the caller's pinned set. (Per claude review observation; the one place declaration-shaped surface re-enters deserves a worked example since "structural type matching at the call site" is doing nontrivial work.) +8. **Smoke + integration tests**: function with multiple typed-effect operations produces correct effect-set structural fact (derived from signature shape, not from tag lookup); redundant-read function fails compile; `reread`-using function compiles. **STOPs**: -- If audit (req 2) reveals a primitive performing side effects without an `OperationEffect` tag (a hidden hole in the closed-system invariant), STOP — that's a substrate gap that needs filling first. -- If the redundancy proof requires substrate primitives the lens can't read structurally (e.g., distinguishing pure from impure transforms inline), STOP — may need a `pure: Bool` fact or sibling carrier on Transform targets. -- If asymmetric-tightening at caller surfaces a structural-type-matching gap (caller can't actually pin effect-set constraints structurally today), STOP — that's its own substrate sub-lane. +- **OperationEffect retirement decision (path (i) vs (ii))** — if audit (req 2) finds the existence-proof for path (ii) (any primitive whose signature doesn't structurally reveal its effect), STOP and surface the retirement scope to Director. Substrate retirement (`OperationEffect` enum + `derive_op_effect` + `idempotency.dag` re-anchor) is its own dedicated sub-lane; this lane should not absorb it. If audit confirms path (i) (all primitives derive cleanly from signature shape), surface that finding for re-decision. +- **Redundancy proof needs a `pure: Bool` carrier** — if the lens can't distinguish pure from impure Transforms inline, STOP. May need a sibling carrier on Transform targets. (Note: the deeper closed-system framing is that "pure" should also be derivable from signature shape — pure functions don't return modified resources — so this STOP may itself dissolve under further design.) +- **Asymmetric-tightening structural gap** — if caller can't actually pin effect-set constraints structurally today (i.e., the type system doesn't yet express "I require callee body's signature-shape composition ⊆ {read-shaped}"), STOP — that's its own substrate sub-lane. +- **Q4.5 P1 (extdeps typed-primitive bypass) — surfaced via lens findings**: lens reports structural-coverage-gap on `dsl/extdeps/llm/openai.dag:92-110`, `anthropic.dag:104-124`, `github/auth.dag:13-24` (and any others the audit finds). NOT a STOP; this is the lens delivering its closed-system-foundation-gap-visibility value. Director routes P1 closure to a dedicated extdeps-typed-primitive-consumption lane. +- **Q4.5 P2 (ExecuteCommand)** — the lens itself doesn't depend on P2; only the TESTING.md `0-residual` claim does. NOT a STOP for this lane. P2 is independent. -**Acceptance**: 4 worked examples from this design doc compile (or fail-compile) per their stated outcomes; lens output observable via standard lens-output infrastructure; cargo + clippy + fmt clean; DB-8 fixed-point converges. +**Acceptance**: 4 worked examples from this design doc compile (or fail-compile) per their stated outcomes; lens output observable via standard lens-output infrastructure; lens reports structural-coverage-gap diagnostics on Q4.5 P1 bypass surfaces (gap becomes visible, not silent); audit produces existence-proof verdict (path (i) vs path (ii)) for Director re-decision on OperationEffect retirement; asymmetric-tightening worked example in PR body; cargo + clippy + fmt clean; DB-8 fixed-point converges. ## Capacity / sequencing impact @@ -251,7 +256,13 @@ Title: `feat(v3): T-ImpossibleBugs effects lens — closed-system structural der | `t-impossiblebugs-unenumerated-effects-fn-arrow-refactor-worker.md` (#805 brief; Fn→Arrow refactor) | **KEEP** — independent value (cleans `params + return_type` vestige); not effects-specific | | Bulk std/ annotation lane (was Lane D) | **DISSOLVES** — no annotations to add | -Net: 1 chain of 3 implementation lanes collapses to 1 implementation lane (effects lens) + 1 sub-lane (`reread` primitive in std/ if not already there) + 1 audit lane (tag std/ primitives with effect signatures). Smaller scope; stronger claim. +Net: 1 chain of 3 implementation lanes collapses to: +- 1 implementation lane (effects lens) — anchors on signature shape, not on tag lookup. +- 1 audit-as-existence-check lane (verify primitives' signature-shape coverage; NOT "tag every primitive") — produces the path (i) vs (ii) verdict on `OperationEffect` retention. +- 1 sub-lane (`reread` primitive in std/ if not already there) + 1 transactional-pattern lens. +- 2 prereq lanes named in Q4.5: P1 extdeps typed-primitive consumption; P2 `ExecuteCommand` materialization. Both pre-existing tracked-debt; surfaced explicitly so the lens's closed-system claim is honest end-to-end. + +Smaller scope; stronger claim. The taxonomy-retirement scope (substrate-side) is **not** in this lane — it's surfaced by audit and routed to dedicated retirement lane if path (ii) wins. ## Cross-manager note From 57a9b13183212ac4568b81676084e18c6d485450 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 14:05:43 -0400 Subject: [PATCH 42/52] =?UTF-8?q?docs(closed-system-effects):=20close=20BL?= =?UTF-8?q?OCKING=20=E2=80=94=20P2=20stale,=20ExecuteCommand=20landed=20vi?= =?UTF-8?q?a=20#792?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves codex inline BLOCKING at sha 191be310 on docs/briefs/t-impossiblebugs-unenumerated-effects-design.md:150. Real: my Q4.5 P2 framing described ExecuteCommand as still NotYetImplemented (M1.5 allowlist + Rust TestRunner returning NotYetImplemented), but PR #792 landed the PB-Runtime ExecuteCommand extension before this PR's authoring. TESTING.md:195 capability-state callout confirms: - Rust TestRunner + M1.5 testgen harness share one std::process path for arbitrary command + args + expect_exit_code. - M1.5 allowlist + fail-closed panic retired. - Distinguishable ClaimResult::Fail messages for spawn / timeout / policy / exit-mismatch. - Linux unshare(1) namespace isolation on host-allowing systems. - T-PB-B-1 boundary migration example landed. Fix: P2 section rewritten: - Header retitled "ExecuteCommand runner primitive: LANDED (PR #792); residual is bulk-migration." - Status update naming PR #792 + the post-#792 capability state (allowlist retired, etc.). - Honest acknowledgement: "My earlier P2 framing was stale." - Residual narrowed to bulk-migration of existing Rust Command::new boundary tests (tracked as ROADMAP residual, not lens prereq). - Sequencing reframed: P2 was always orthogonal to the effects lens itself; bulk migration proceeds at its own pace; lens not blocked. Q4.5 footer updated: - "P1 + P2 closure" → "P1 closure (P2 runner-primitive landed via #792; only consumer-side bulk migration remains)" - Worker-discretion-vs-Director-call P2 line updated: "runner primitive landed; only consumer-side bulk migration remains; tracked as ROADMAP residual, independent of the lens." Q6 STOP for P2 updated: - "the lens itself doesn't depend on P2; only TESTING.md's 0-residual claim does" → "runner primitive landed via PR #792 (post-Q4.5- authoring update). The lens itself never depended on P2; bulk consumer migration is residual ROADMAP work and remains independent of this lane." Brief now reflects live state. The closed-system claim's prereq landscape is honest: - P1 (extdeps typed-primitive consumption): real prereq, tracked debt at ROADMAP:153-154. - P2 (ExecuteCommand runner): satisfied via #792; bulk migration is consumer-side residual, not foundation work. Co-Authored-By: Claude Opus 4.7 (1M context) --- ...ossiblebugs-unenumerated-effects-design.md | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md index 60b8ccc3199..fb31afc73fb 100644 --- a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md +++ b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md @@ -145,26 +145,33 @@ The substrate must make it impossible for a service definition to declare `messa **Sequencing**: prereq for the lens's *coverage* claim. The lens itself can land first (Q6 implementation brief); it just won't cover the bypassed extdeps surfaces until P1 closes. The lens's acceptance must surface structural-coverage-gap diagnostics on those surfaces (i.e., the lens itself reports "this surface has a structural hole; effect-derivation can't proceed structurally"). That's how the gap becomes load-bearing visible rather than silent. -### P2 — `ExecuteCommand` fully materialized as a typed runner primitive +### P2 — `ExecuteCommand` runner primitive: LANDED (PR #792); residual is bulk-migration -Subprocess invocations need a typed primitive that derives "external-toolchain effect" structurally — analog of how `derive_op_effect` derives effects from HTTP method. Today the M1.5 testgen harness allowlists only `command == "true" && args.is_empty() && expect_exit == 0` and panics fail-closed on anything else; the Rust `TestRunner` returns `NotYetImplemented` for `ExecuteCommand` (see `TESTING.md:195` capability state callout). +**Status update 2026-04-25 (post-`f073aa95e` Q4.5 authoring)**: PR #792 has shipped the PB-Runtime `ExecuteCommand` extension. Per TESTING.md:195 capability-state callout (post-#792): +- Rust `TestRunner` + M1.5 testgen harness share one `std::process` path for arbitrary `command` + `args` + `expect_exit_code`. +- M1.5 allowlist + fail-closed panic for disallowed `ExecuteCommand` shapes **retired**. +- Distinguishable `ClaimResult::Fail` messages for spawn errors / wall-clock timeout / policy fails / exit mismatches. +- Linux: `unshare(1)`-based namespace isolation when host allows. +- T-PB-B-1 boundary migration example landed at `src/v3/compiler/tests/dag/t_pb_b_1_execute_command_boundary.dag`. -**Why load-bearing**: TESTING.md (post-#782 cascade) committed to `0-residual` framing — boundary tests migrate to `ExecuteCommand`-based `.dag` `TestClaim` declarations. **Until `ExecuteCommand` can execute equivalent `.dag` TestClaims, deleting Rust boundary tests creates a verification gap.** Same closed-system shape applied to test execution: the typed runner primitive IS the path; subprocess invocations have nowhere structural to live until then. +**My earlier P2 framing was stale** — described `ExecuteCommand` as `NotYetImplemented` when it's now fully materialized. **The typed-runner-primitive prerequisite is satisfied.** -**Sequencing**: pre-requisite for *any* Rust boundary-test deletion. Already named under PB-Runtime in Zero-Floor Manager's program scope; Director-signaled twice. Should be priority once Zero-Floor's authoring queue clears. +**Residual prereq (narrowed)**: bulk migration of existing Rust `Command::new("rustc" | "python3" | …)` boundary tests to `.dag` `TestClaim` declarations using `ExecuteCommand`. TESTING.md explicitly tracks this as residual: *"Residual bulk migration of older Rust `Command::new("rustc" | "python3" | …)` boundary tests to `.dag` remains its own work item on ROADMAP."* Until that bulk migration completes, deleting the existing Rust boundary tests creates a verification gap. **The prereq is no longer "build the runner primitive" — it's "migrate the consumers of the runner primitive."** + +**Sequencing**: not a structural prereq for the lens (P2 was always orthogonal to the effects lens itself; the design doc's framing of P2 was about TESTING.md's `0-residual` claim). Bulk migration proceeds at its own pace; lens implementation does not depend on it. Worker reading this doc treats P2 as **closed for runner-primitive purposes**; bulk migration is a tracked-residual ROADMAP item, not a load-bearing prereq for the lens. ### Why these belong in this design doc Both prereqs are load-bearing for the closed-system claim this doc commits to. Naming them in-doc surfaces the dependencies upfront rather than letting the implementation brief discover them as STOP-AND-ESCALATEs at dispatch time. Workers reading this doc see correctly that: - The lens at Q6 can land independently (worth the empirical receipt of structural-coverage diagnostics). -- The closed-system claim's *full coverage* requires P1 + P2 closure. +- The closed-system claim's *full coverage* requires P1 closure (P2 runner-primitive is already landed via PR #792; only bulk migration of consumers remains, which is independent of the lens). - Without P1: bypass surfaces visible only via the lens's own gap diagnostics (lens lands; reports holes). - Without P2: TESTING.md `0-residual` claim cannot be acted on (no Rust boundary-test deletion). Worker-discretion-vs-Director-call: - Lens implementation worker: dispatchable now; lens reports gaps as findings. - P1 closure: substantive substrate work touching extdeps; tracked debt at ROADMAP.md:153-154; should land via dedicated lane. -- P2 closure: PB-Runtime in Zero-Floor; signal pending. +- P2: runner primitive landed via PR #792. Only consumer-side bulk migration remains; tracked as ROADMAP residual, independent of the lens. ## Q5 — Asymmetric tightening (the only declaration-value exception) @@ -243,7 +250,7 @@ Title: `feat(v3): T-ImpossibleBugs effects lens — closed-system structural der - **Redundancy proof needs a `pure: Bool` carrier** — if the lens can't distinguish pure from impure Transforms inline, STOP. May need a sibling carrier on Transform targets. (Note: the deeper closed-system framing is that "pure" should also be derivable from signature shape — pure functions don't return modified resources — so this STOP may itself dissolve under further design.) - **Asymmetric-tightening structural gap** — if caller can't actually pin effect-set constraints structurally today (i.e., the type system doesn't yet express "I require callee body's signature-shape composition ⊆ {read-shaped}"), STOP — that's its own substrate sub-lane. - **Q4.5 P1 (extdeps typed-primitive bypass) — surfaced via lens findings**: lens reports structural-coverage-gap on `dsl/extdeps/llm/openai.dag:92-110`, `anthropic.dag:104-124`, `github/auth.dag:13-24` (and any others the audit finds). NOT a STOP; this is the lens delivering its closed-system-foundation-gap-visibility value. Director routes P1 closure to a dedicated extdeps-typed-primitive-consumption lane. -- **Q4.5 P2 (ExecuteCommand)** — the lens itself doesn't depend on P2; only the TESTING.md `0-residual` claim does. NOT a STOP for this lane. P2 is independent. +- **Q4.5 P2 (ExecuteCommand)** — runner primitive landed via PR #792 (post-Q4.5-authoring update). The lens itself never depended on P2; bulk consumer migration is residual ROADMAP work and remains independent of this lane. NOT a STOP. **Acceptance**: 4 worked examples from this design doc compile (or fail-compile) per their stated outcomes; lens output observable via standard lens-output infrastructure; lens reports structural-coverage-gap diagnostics on Q4.5 P1 bypass surfaces (gap becomes visible, not silent); audit produces existence-proof verdict (path (i) vs path (ii)) for Director re-decision on OperationEffect retirement; asymmetric-tightening worked example in PR body; cargo + clippy + fmt clean; DB-8 fixed-point converges. From ece964e95f6469c25808cd3bed22187db431c469 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 14:27:34 -0400 Subject: [PATCH 43/52] =?UTF-8?q?docs(closed-system-effects):=20close=20co?= =?UTF-8?q?dex=20non-blocking=20=E2=80=94=20capacity-table=20P2=20framing?= =?UTF-8?q?=20stale?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves codex non-blocking finding at sha bcac41bb on docs/briefs/t-impossiblebugs-unenumerated-effects-design.md:270. Real residual: capacity-table line still listed P2 as "`ExecuteCommand` materialization" prereq + framed both P1 and P2 as "pre-existing tracked-debt" — but my prior 57a9b1318 fix established that PR #792 already landed the runner primitive, so P2 is no longer a materialization prereq. Fix: capacity-table P2 line rewritten to distinguish P1 (real prereq) from P2 (residual, not prereq): - P1: extdeps typed-primitive consumption — pre-existing tracked debt at ROADMAP:153-154; load-bearing for the lens's full-coverage claim. - P2: ExecuteCommand runner primitive landed via PR #792; only consumer-side bulk migration of existing Rust Command::new boundary tests remains (tracked as ROADMAP residual, independent of the lens; not a materialization prereq). Brief now consistently treats P2 as bulk-migration-residual across: - §Q4.5 P2 section header (LANDED via PR #792; residual is bulk-migration). - §Q4.5 footer (P2: runner primitive landed; only consumer-side bulk migration remains). - Q6 STOP for P2 (runner primitive landed; bulk migration is residual ROADMAP work). - §Capacity / sequencing impact (P2 as residual, not prereq). Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/briefs/t-impossiblebugs-unenumerated-effects-design.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md index fb31afc73fb..d6e6308b773 100644 --- a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md +++ b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md @@ -267,7 +267,9 @@ Net: 1 chain of 3 implementation lanes collapses to: - 1 implementation lane (effects lens) — anchors on signature shape, not on tag lookup. - 1 audit-as-existence-check lane (verify primitives' signature-shape coverage; NOT "tag every primitive") — produces the path (i) vs (ii) verdict on `OperationEffect` retention. - 1 sub-lane (`reread` primitive in std/ if not already there) + 1 transactional-pattern lens. -- 2 prereq lanes named in Q4.5: P1 extdeps typed-primitive consumption; P2 `ExecuteCommand` materialization. Both pre-existing tracked-debt; surfaced explicitly so the lens's closed-system claim is honest end-to-end. +- 1 prereq lane + 1 residual lane named in Q4.5: + - **P1**: extdeps typed-primitive consumption — pre-existing tracked debt at ROADMAP:153-154; load-bearing for the lens's full-coverage claim. + - **P2**: `ExecuteCommand` runner primitive landed via PR #792; **only consumer-side bulk migration of existing Rust `Command::new` boundary tests remains** (tracked as ROADMAP residual, independent of the lens; not a materialization prereq). Smaller scope; stronger claim. The taxonomy-retirement scope (substrate-side) is **not** in this lane — it's surfaced by audit and routed to dedicated retirement lane if path (ii) wins. From 2552ca3b5c624fca8a9a59dfe0a613f600ae268e Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 14:47:09 -0400 Subject: [PATCH 44/52] =?UTF-8?q?docs(effects-design):=20fix=20stale=20ROA?= =?UTF-8?q?DMAP=20citations=20153-154=20=E2=86=92=20348-349?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex finding on PR #808 sha ece964e9: lines 153-154 are unrelated target-grounding prose; the matching extdeps typed-primitive bypass entries (LLM service flattening, GitHub auth model bypass) live at ROADMAP.md:348-349. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/briefs/t-impossiblebugs-unenumerated-effects-design.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md index d6e6308b773..d97422d59f3 100644 --- a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md +++ b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md @@ -136,7 +136,7 @@ The closed-system claim *"effects derive structurally from the composition of ty The substrate must make it impossible for a service definition to declare `messages: Json` instead of `messages: List`. Typed protocol carriers must be the ONLY path; raw Json / string-path extraction must have no structural home in service definitions. -**Today's tracked debt** (per ROADMAP.md:153-154): +**Today's tracked debt** (per ROADMAP.md:348-349): - `dsl/extdeps/llm/openai.dag:92-110` — `messages: Json` + string-path output extraction (bypass: typed `LlmMessage` + `ContentBlock` carriers exist but not consumed). - `dsl/extdeps/llm/anthropic.dag:104-124` — same pattern. - `dsl/extdeps/github/auth.dag:13-24` — `github_token() → { token: Secret }` discards modeled scopes + `expires_at` from `GitHubAuthToken`. @@ -170,7 +170,7 @@ Both prereqs are load-bearing for the closed-system claim this doc commits to. N Worker-discretion-vs-Director-call: - Lens implementation worker: dispatchable now; lens reports gaps as findings. -- P1 closure: substantive substrate work touching extdeps; tracked debt at ROADMAP.md:153-154; should land via dedicated lane. +- P1 closure: substantive substrate work touching extdeps; tracked debt at ROADMAP.md:348-349; should land via dedicated lane. - P2: runner primitive landed via PR #792. Only consumer-side bulk migration remains; tracked as ROADMAP residual, independent of the lens. ## Q5 — Asymmetric tightening (the only declaration-value exception) From 103a9cd5ee0d347451ee05f8ebfde05af5997680 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 15:01:16 -0400 Subject: [PATCH 45/52] docs(effects-design): fix third stale ROADMAP citation at line 271 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex follow-up on sha 2552ca3b: prior fix missed a third occurrence at line 271 in the §Q4.5 capacity table. Now consistent with lines 139 and 173 (ROADMAP.md:348-349). Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/briefs/t-impossiblebugs-unenumerated-effects-design.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md index d97422d59f3..219488229a6 100644 --- a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md +++ b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md @@ -268,7 +268,7 @@ Net: 1 chain of 3 implementation lanes collapses to: - 1 audit-as-existence-check lane (verify primitives' signature-shape coverage; NOT "tag every primitive") — produces the path (i) vs (ii) verdict on `OperationEffect` retention. - 1 sub-lane (`reread` primitive in std/ if not already there) + 1 transactional-pattern lens. - 1 prereq lane + 1 residual lane named in Q4.5: - - **P1**: extdeps typed-primitive consumption — pre-existing tracked debt at ROADMAP:153-154; load-bearing for the lens's full-coverage claim. + - **P1**: extdeps typed-primitive consumption — pre-existing tracked debt at ROADMAP.md:348-349; load-bearing for the lens's full-coverage claim. - **P2**: `ExecuteCommand` runner primitive landed via PR #792; **only consumer-side bulk migration of existing Rust `Command::new` boundary tests remains** (tracked as ROADMAP residual, independent of the lens; not a materialization prereq). Smaller scope; stronger claim. The taxonomy-retirement scope (substrate-side) is **not** in this lane — it's surfaced by audit and routed to dedicated retirement lane if path (ii) wins. From dac76942c48250550dcb20a46d85d64ef2a7f89d Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 15:05:07 -0400 Subject: [PATCH 46/52] docs(effects-design): clarify cross-manager note avoids 'tagging' ambiguity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex flagged 'Effect-signature tagging on std/ primitives' as potentially contradicting Q5.5/THESIS single-authority claim. Reqs 2 (lines 124/240) already explicitly say 'NOT tag every primitive' — but the cross-manager line used sloppy wording. Reworded to make explicit that the audit walks signature shape; no parallel tag added. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/briefs/t-impossiblebugs-unenumerated-effects-design.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md index 219488229a6..dd4b70d61d6 100644 --- a/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md +++ b/docs/briefs/t-impossiblebugs-unenumerated-effects-design.md @@ -275,7 +275,7 @@ Smaller scope; stronger claim. The taxonomy-retirement scope (substrate-side) is ## Cross-manager note -- **Zero-Floor Manager**: heads-up. Effect-signature tagging on std/ primitives may touch substrate-adjacent territory; coordinate at audit-phase if needed. +- **Zero-Floor Manager**: heads-up. The audit-as-existence-check (Req 2) walks signature shape on std/ primitives — no parallel tag is added; per Q5.5/THESIS the signature shape IS the effect. Coordinate at audit-phase if signature reshaping (e.g., resource-threading on logging primitives that today return Unit) touches substrate-adjacent territory. - **Grounding Manager**: no current overlap. - **PM**: synergy framing (5-behavior fold table) is the load-bearing reframe; the effects lens is positioned as the next instance of an established pattern (idempotency / termination / omni-emit are prior art) rather than novel substrate work. From 555183955f715e87d9ddcd7c0cc5189f7b4576a4 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 15:36:02 -0400 Subject: [PATCH 47/52] =?UTF-8?q?docs(briefs):=20author=20B1-B4=20per=20de?= =?UTF-8?q?bt-paydown=20synthesis=20#810=20=C2=A75?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - B1: Tier 0 Go UnknownVariant fabrication → EmitError::VariantParentNotFound - B2: Tier 0 lower_fn_body Arrow re-derive → fail-closed diagnostic + seed-phase root cause - B3: Tier 0 lens fold ambiguous fallback → require structural template-formal edge - B4: Tier 1 program brief — Identity-Carrier Substrate Pass (M; primary recommendation) B4 framed per feedback_groundedness_gates_lenses (revised 2026-04-25): language vocabulary is primitives + namespacing only; no escape syntax; the §0 sentinels are the compiler itself failing to use primitives + namespacing internally. Eight surface sites dissolve via four substrate carriers (DeclarationRef, structural fold-shape carrier, structural emit-helper carrier, structural extdeps-fixture-set carrier). B1-B3 are independent; dispatch in parallel. B4 is sequential program work; sub-brief dispatch (B4.1-B4.12) follows. Co-Authored-By: Claude Opus 4.7 (1M context) --- ...b1-go-unknownvariant-fail-closed-worker.md | 65 +++++++++ .../b2-lower-fn-body-arrow-rederive-worker.md | 67 +++++++++ .../b3-lens-fold-ambiguous-fallback-worker.md | 66 +++++++++ .../b4-identity-carrier-substrate-pass.md | 130 ++++++++++++++++++ 4 files changed, 328 insertions(+) create mode 100644 docs/briefs/b1-go-unknownvariant-fail-closed-worker.md create mode 100644 docs/briefs/b2-lower-fn-body-arrow-rederive-worker.md create mode 100644 docs/briefs/b3-lens-fold-ambiguous-fallback-worker.md create mode 100644 docs/briefs/b4-identity-carrier-substrate-pass.md diff --git a/docs/briefs/b1-go-unknownvariant-fail-closed-worker.md b/docs/briefs/b1-go-unknownvariant-fail-closed-worker.md new file mode 100644 index 00000000000..c5c362ae82a --- /dev/null +++ b/docs/briefs/b1-go-unknownvariant-fail-closed-worker.md @@ -0,0 +1,65 @@ +# B1 — Go `UnknownVariant` fabrication → `EmitError::VariantParentNotFound` `(S, Tier 0)` + +> **Worker brief.** Reports through Director (`zesty-bear-812`). +> Tier 0 fail-closed P3 fix per +> [`docs/briefs/debt-paydown-synthesis-2026-04-25.md`](debt-paydown-synthesis-2026-04-25.md) §3. +> Independent of B2/B3; dispatch in parallel. + +## Read first + +- **[`src/v3/compiler/src/emit.rs:1456-1464`](../../src/v3/compiler/src/emit.rs)** — the site. `variant_parent_info(self.dag, variant_id)` returns `Option<(String, String)>`; on `None` the code falls back to `declaration(variant_id).name`, then to the literal string `"UnknownVariant"`. Both fallbacks fabricate plausible Go output instead of failing closed when the variant has no resolvable parent enum. +- **[`src/v3/compiler/src/emit.rs:2989`](../../src/v3/compiler/src/emit.rs)** — `variant_parent_info` definition; returns `None` when `Disjunction` parent isn't found. Confirms the failure mode that today silently emits a bad identifier. +- **[`src/v3/compiler/src/emit.rs:1791`](../../src/v3/compiler/src/emit.rs)** + **[`src/v3/compiler/src/emit/rust_target.rs:4325`](../../src/v3/compiler/src/emit/rust_target.rs)** — sibling `variant_parent_info` callers; both already pattern-match `let Some(..) = .. else { … }` and fail explicitly. The Go path is the outlier. +- **[`src/v3/compiler/src/emit/rust_target.rs`](../../src/v3/compiler/src/emit/rust_target.rs)** `:54` — `EmitError` definition. Use the **existing fail-closed shape** (`MissingRealizationMeta`, `MissingTargetSyntax`, `MalformedRealization`); add a new variant `VariantParentNotFound { variant_id: DeclarationId }` (or equivalent — worker picks; surface choice in PR description). No parallel error taxonomy. +- **`feedback_fail_closed_discipline`** + **`feedback_compile_time_errors`**. + +## Frame + +This is **not a scaffold** — it's a fabrication leak. The Go emitter today, when a variant declaration has no `Disjunction` parent, silently emits the literal token `UnknownVariant` (or the variant's own name, which still doesn't compile against any real Go type). Downstream Go compilation fails opaquely; the bug surfaces as "Go output references undefined identifier" rather than "compiler couldn't find variant parent." + +The fix is one-site, structural, and parallels existing `variant_parent_info` callsites. Replace the `unwrap_or_else` chain with an explicit `Result` early return. + +## Slice + +1. Add `EmitError::VariantParentNotFound { variant_id: DeclarationId }` (or worker-equivalent shape) to the existing `EmitError` enum. Coproduct dissolution receipt only if the variant introduces a new top-level error class — likely **purely additive**, no receipt required. +2. At `emit.rs:1456-1464`, replace: + ```rust + let variant_name = variant_parent_info(self.dag, variant_id) + .map(|(_, variant_name)| variant_name) + .unwrap_or_else(|| { + self.dag.declaration(variant_id).name.clone() + .unwrap_or_else(|| "UnknownVariant".to_string()) + }); + ``` + with the `let Some(..) = .. else { return Err(..) }` shape used at `emit.rs:1791` and `rust_target.rs:4325`. The outer function's signature already returns `Result<_, EmitError>`. +3. Verify call-graph: every caller of the Go branch-emission path already propagates `Result`. No signature change needed. +4. Add a regression test: construct a `Dag` with a variant declaration that has no `Disjunction` parent; assert the Go emitter returns `EmitError::VariantParentNotFound`, not a `Ok(_)` with a bogus identifier. Hermetic per `TESTING.md`. + +## Acceptance + +- [ ] `EmitError::VariantParentNotFound` (or equivalent) added; existing `EmitError` shape preserved. +- [ ] `emit.rs:1456-1464` no longer falls back to a literal string; fails closed via `Result`. +- [ ] Regression test asserts the new error variant is returned for the missing-parent case. +- [ ] `cargo test --workspace --exclude v2-compiler-tests` passes. +- [ ] `cargo clippy --all-targets -- -D warnings` clean. +- [ ] `cargo fmt --all --check` clean. +- [ ] DB-8 fixed-point converges bit-identically (no Go-emit changes for well-formed inputs). + +## STOP-AND-ESCALATE + +- **Existing `EmitError` shape doesn't fit the new variant cleanly** (e.g., the variant requires carrying parent context beyond `DeclarationId`) — STOP. Surface design call. +- **Audit reveals additional fail-open string fallbacks in the Go emitter** — STOP. This brief covers only the `:1456-1464` site; sibling fallbacks are out of scope but should be reported for follow-up dispatch. +- **DB-8 drifts** — STOP immediately. +- **`variant_parent_info` returning `None` turns out to be a legitimate runtime case in any well-formed program** — STOP. The diagnosis says it's always a compiler bug; if execution refutes that, the brief's framing needs revision. + +## Non-goals + +- Not touching the sibling fallback in `declaration(variant_id).name` (the inner `unwrap_or_else`) unless the worker concludes it's part of the same fail-open class. Surface in PR description if so. +- Not refactoring `variant_parent_info`'s shape. +- Not addressing the file-suffix special case in `lens_apply.rs` (that's the §0 identity-carrier class — B4). + +## Reporting + +Single PR. Title: `fix(v3): B1 Go UnknownVariant fabrication → EmitError::VariantParentNotFound (Tier 0 fail-closed)`. Body cites this brief + names the dissolution: *"Go emitter no longer fabricates plausible identifiers when variant parent resolution fails."* + +On merge: signal Director. diff --git a/docs/briefs/b2-lower-fn-body-arrow-rederive-worker.md b/docs/briefs/b2-lower-fn-body-arrow-rederive-worker.md new file mode 100644 index 00000000000..8546a1e2559 --- /dev/null +++ b/docs/briefs/b2-lower-fn-body-arrow-rederive-worker.md @@ -0,0 +1,67 @@ +# B2 — `lower_fn_body_into_existing_decl` defensive Arrow re-derive → diagnostic + seed-phase root cause `(S, Tier 0)` + +> **Worker brief.** Reports through Director (`zesty-bear-812`). +> Tier 0 fail-closed P3 fix per +> [`docs/briefs/debt-paydown-synthesis-2026-04-25.md`](debt-paydown-synthesis-2026-04-25.md) §3. +> Independent of B1/B3; dispatch in parallel. + +## Read first + +- **[`src/v3/compiler/src/lower.rs:3585-3611`](../../src/v3/compiler/src/lower.rs)** — the site. The `match &dag.declaration(fn_decl_id).connective` arm reads the seeded `Arrow`; the `_ =>` defensive fallback re-derives parameter declarations + refinements when the connective is *not* an `Arrow`. Inline comment: *"Defensive fallback — should not occur because `seed_function_signatures_phase` runs unconditionally on every `Fn` item before bodies are lowered. If the connective is not an Arrow here, the seed phase was skipped or the declaration was clobbered; re-derive to keep the body-lowering pass going and surface the real issue upstream."* +- **[`src/v3/compiler/src/lower.rs:214`](../../src/v3/compiler/src/lower.rs)** — `seed_function_signatures_phase` invocation; runs unconditionally on every module pass. +- **[`src/v3/compiler/src/lower.rs:429`](../../src/v3/compiler/src/lower.rs)** — `seed_function_signatures_phase` definition. Verify: every `Fn` item gets an `Arrow` connective seeded. If a path skips it, that's the root cause. +- **[`src/v3/compiler/src/lower.rs:1697`](../../src/v3/compiler/src/lower.rs)** + **[`src/v3/compiler/src/lower.rs:2358`](../../src/v3/compiler/src/lower.rs)** — sibling sites that reference the seed phase as authority. Confirms the structural invariant the defensive fallback hedges against. +- **`feedback_construction_over_ratchets`** — *"Ratchets are an obtuse form of validation — the system already produced the wrong output and the ratchet notices retroactively."* The defensive fallback is exactly that shape. +- **`feedback_fail_closed_discipline`** (C-8) + **`feedback_compile_time_errors`**. + +## Frame + +The current code admits two states for a function declaration at body-lowering time: +1. The seeded `Arrow` connective is present (intended path). +2. The connective is something else; re-derive parameters from scratch. + +State (2) is documented as *"should not occur"* — it's a hedge against a bug elsewhere (seed phase skipped or declaration clobbered). The hedge masks the bug: when state (2) fires, lowering proceeds with re-derived parameters that **do not match** the seeded ones used by other phases (DB-11 refinement carriers, callsite resolution, etc.), producing structurally inconsistent DAGs that pass downstream checks until a much later phase blows up opaquely. + +Per `feedback_state_space_vs_behavioral_invariants` + `feedback_construction_over_ratchets`: the right shape is to **delete state (2) and fail closed** with a `Diagnostic`, then **fix the root cause** in seed phase. If seed phase already runs unconditionally on every `Fn`, the only way to reach state (2) is a bug — the diagnostic surfaces it; the seed-phase fix prevents it. + +## Slice — two coupled deliverables + +### Deliverable A — replace the defensive fallback with a fail-closed diagnostic + +- At `lower.rs:3585-3611`, replace the `_ =>` arm with a `Diagnostic` (per C-8 / `feedback_fail_closed_discipline`). The diagnostic should name the fn declaration, its observed connective, and the invariant violated (*"seed_function_signatures_phase did not produce an Arrow connective for this Fn"*). +- Use the existing diagnostic-emission path; don't introduce parallel error machinery. + +### Deliverable B — root-cause the seed-phase gap (if any) + +- Audit `seed_function_signatures_phase` (`lower.rs:429`) and every `Fn` item enumeration site. Verify: every `Fn` item that reaches `lower_fn_body_into_existing_decl` has had its declaration seeded with an `Arrow`. +- If the audit finds **no gap** (i.e., seed phase is already total over `Fn` items), Deliverable A alone is sufficient. The diagnostic becomes a structural assertion that converts the unreachable hedge into a fail-closed contract. +- If the audit finds **a gap** (a path where `Fn` items reach body-lowering without seeding), fix the seed-phase invocation to cover it. The fix must be at the seed phase, **not** at the body-lowering site (per `feedback_construction_over_ratchets`). + +## Acceptance + +- [ ] `lower.rs:3585-3611` defensive fallback removed; diagnostic-emit path in place. +- [ ] Seed-phase audit recorded in PR description: every `Fn`-item path verified to seed before body-lowering, OR root-cause fix landed. +- [ ] Existing tests pass; no test currently relies on the silent-rederive path (if any do, that's a test-discipline fix, not a brief expansion — surface in PR). +- [ ] `cargo test --workspace --exclude v2-compiler-tests` passes. +- [ ] `cargo clippy --all-targets -- -D warnings` clean. +- [ ] `cargo fmt --all --check` clean. +- [ ] DB-8 fixed-point converges bit-identically. + +## STOP-AND-ESCALATE + +- **Audit reveals a legitimate runtime path that produces non-`Arrow` connectives at this site** (e.g., a refinement layer or builtin `Fn`-but-not-`Arrow` case) — STOP. The framing of "should not occur" is wrong; brief needs revision. +- **Diagnostic-emission requires substrate work beyond C-8's existing shape** (e.g., a new diagnostic class) — STOP. Coordinate diagnostic taxonomy with Surface Manager. +- **Removing the fallback breaks v2-compiler-tests** (rather than v3 tests) — STOP. `v2-compiler-tests` may exercise the legacy hedge intentionally; surface for design call. +- **DB-8 drifts** — STOP immediately. + +## Non-goals + +- Not refactoring `seed_function_signatures_phase` beyond the minimum needed to close the gap (if any). +- Not touching DB-11 refinement carriers (`lower_parameter_refinement`) — they're consumed correctly by both branches; the issue is which branch fires. +- Not part of the §0 identity-carrier class (B4). + +## Reporting + +Single PR. Title: `fix(v3): B2 lower_fn_body Arrow re-derive → fail-closed diagnostic + seed-phase root cause (Tier 0)`. Body cites this brief + records the seed-phase audit outcome. + +On merge: signal Director. diff --git a/docs/briefs/b3-lens-fold-ambiguous-fallback-worker.md b/docs/briefs/b3-lens-fold-ambiguous-fallback-worker.md new file mode 100644 index 00000000000..40db2486899 --- /dev/null +++ b/docs/briefs/b3-lens-fold-ambiguous-fallback-worker.md @@ -0,0 +1,66 @@ +# B3 — Lens fold ambiguous unique-candidate fallback → require structural template-formal edge `(S, Tier 0)` + +> **Worker brief.** Reports through Director (`zesty-bear-812`). +> Tier 0 fail-closed P3 fix per +> [`docs/briefs/debt-paydown-synthesis-2026-04-25.md`](debt-paydown-synthesis-2026-04-25.md) §3. +> Independent of B1/B2; dispatch in parallel. **Note**: the file-suffix +> special case elsewhere in `lens_apply.rs` is part of the §0 +> identity-carrier class (B4); do not touch it here. + +## Read first + +- **[`src/v3/compiler/src/lens_apply.rs:132-148`](../../src/v3/compiler/src/lens_apply.rs)** — the site. After failing to find a `BindNode` whose argument's `parameter` is in `formals`, the code falls back to *"if exactly one unique callable bind candidate exists across all arguments, return it."* This is a heuristic: the **structural** fact (this argument's parameter is one of the fold-template's formals) is replaced by an **enumerative** fact (only one candidate exists, so it must be right). +- **[`src/v3/compiler/src/lens_apply.rs`](../../src/v3/compiler/src/lens_apply.rs)** `:118-131` — context: the fold-template + its formals are looked up, and each argument is walked. The `formals.contains(&arg.parameter)` check IS the structural invariant; the fallback admits arguments that don't match it. +- **`fold_template_callable_formals`** + **`monomorph_callable_bind_root`** — supporting helpers; verify they produce the right structural-edge data when called. +- **`feedback_lenses_not_passes`** — *"analyses are lenses over physics; zero heuristics; heuristic = missing physics."* The unique-candidate fallback is the heuristic shape; the structural template-formal edge is the missing physics. +- **`feedback_groundedness_gates_lenses`** — language has primitives + namespacing only; lenses apply by construction. If the fold lens needs a heuristic fallback to run on some programs, the design has a leak. +- **`feedback_fail_closed_discipline`** (C-8) + **`feedback_construction_over_ratchets`**. + +## Frame + +The fold lens today reasons about which `BindNode` represents the fold's callable step by walking template arguments and checking whether each argument's `parameter` is a fold-template formal. When that check fires, the answer is structurally certain. When the check **doesn't** fire on any argument, the current code shrugs and returns the unique callable bind candidate if there's only one. + +The unique-candidate fallback is wrong for two reasons: +1. **It's a heuristic.** Two distinct callables (fold step + an unrelated lambda passed in the same call) collapse to "one unique" in many cases; the heuristic gives a confident-but-wrong answer. +2. **It hides a missing structural edge.** If the formals walk doesn't identify the step, that's the lens detecting that the input program lacks the structural template-formal edge it needs. The right response is **fail closed with a diagnostic**, not "guess the unique candidate." + +Per `feedback_lenses_not_passes`: the fix is to require the structural fact (template-formal edge identification) and remove the heuristic. If the fact isn't present in the input DAG, the lens reports a structural-coverage diagnostic and the program is treated as out-of-scope for this lens — **not** silently fabricated through. + +## Slice + +1. **Confirm structural-fact availability.** Audit: when does `formals.contains(&arg.parameter)` legitimately fail to fire on any argument of a fold call? If it can fail in well-formed v3 programs, the structural edge is missing from the DAG — that's a substrate gap and STOP-AND-ESCALATE; this brief becomes contingent on substrate work. + - **Expected outcome of audit**: every well-formed fold call has at least one argument whose parameter is in the template's formals. If the audit confirms this, the fallback is dead code masking a bug. +2. **Replace the unique-candidate fallback** at `lens_apply.rs:132-148` with `None` (or a typed lens-coverage-gap diagnostic via `LensApplyError`, if the surrounding code supports it). The function already returns `Option<&BindNode>`; making the fallback `None` should be sufficient. +3. **Audit downstream consumers** of the `Option<&BindNode>` return value. They already handle `None`; the change makes the previously-`Some(unique)` paths now `None`, which means downstream produces a structural-coverage diagnostic (or whatever its existing `None` path does). **If a downstream consumer treats `None` as success, that's a separate fail-open bug — surface for follow-up.** +4. **Regression test**: construct a fold call where the formals-walk fails on every argument but a unique callable bind exists. Assert the lens now returns `None` (or the structural-coverage diagnostic), not the heuristic match. + +## Acceptance + +- [ ] Fallback removed; function returns `None` (or typed diagnostic) when no argument's parameter is in the template's formals. +- [ ] Audit recorded in PR description: every well-formed fold call structurally identifies the step via the formals edge (or substrate gap surfaced as STOP). +- [ ] Downstream-consumer audit recorded: every consumer of the function's `None` return path is fail-closed. +- [ ] Regression test asserts the new behavior. +- [ ] `cargo test --workspace --exclude v2-compiler-tests` passes. +- [ ] `cargo clippy --all-targets -- -D warnings` clean. +- [ ] `cargo fmt --all --check` clean. +- [ ] DB-8 fixed-point converges bit-identically. + +## STOP-AND-ESCALATE + +- **Audit finds well-formed fold calls where the formals walk legitimately fails** — STOP. Substrate gap; this brief reframes as "structural template-formal edge work." Director call. +- **A downstream consumer of the function's return treats `None` as success** — STOP. Fail-open class; surface for follow-up dispatch. +- **The fallback turns out to be load-bearing for some lens-evaluation case (existing tests fail when removed)** — STOP. Surface the case; revise framing. +- **Touching this file pulls in the file-suffix special case** elsewhere in `lens_apply.rs` — STOP. That's B4 territory; do not bundle. +- **DB-8 drifts** — STOP immediately. + +## Non-goals + +- Not addressing the `lens_apply.rs` file-suffix special case (§0 identity-carrier class — B4). +- Not refactoring `fold_template_callable_formals` or `monomorph_callable_bind_root`. +- Not introducing a new `LensApplyError` variant unless the existing `Option` shape proves inadequate. + +## Reporting + +Single PR. Title: `fix(v3): B3 lens fold ambiguous fallback → structural template-formal edge required (Tier 0)`. Body cites this brief + records the formals-walk audit outcome. + +On merge: signal Director. diff --git a/docs/briefs/b4-identity-carrier-substrate-pass.md b/docs/briefs/b4-identity-carrier-substrate-pass.md new file mode 100644 index 00000000000..273022be46a --- /dev/null +++ b/docs/briefs/b4-identity-carrier-substrate-pass.md @@ -0,0 +1,130 @@ +# B4 — Identity-Carrier Substrate Pass `(M; Tier 1; primary recommendation)` + +> **Program brief.** Director (`zesty-bear-812`) coordinates; sub-briefs +> dispatched as workers. Frames the §0 class from +> [`docs/briefs/debt-paydown-synthesis-2026-04-25.md`](debt-paydown-synthesis-2026-04-25.md) +> as **one M-scope substrate program**, not eight item-by-item paydowns. + +## Read first + +- **[`docs/briefs/debt-paydown-synthesis-2026-04-25.md`](debt-paydown-synthesis-2026-04-25.md) §0** — the headline finding: dominant scaffold pattern in 2026-04-25 analyses is a single class of identity-bridge sentinels with a shared upstream root cause. +- **`feedback_groundedness_gates_lenses` (revised 2026-04-25)** — *"the language has no vocabulary other than primitives + composition/namespacing; 'leaving the stack' means writing a different compiler, not an in-language feature; lenses apply to every program because there's no way to author one outside the kernel."* Load-bearing for this brief's framing. +- **`feedback_compiler_is_dag_processor`** — compiler knows only `Node / Conj / Disj / Cardinality / Bit`. +- **`feedback_lenses_not_passes`** — analyses are lenses over physics; zero heuristics. +- **`feedback_construction_over_ratchets`** — model first; violations dissolve. +- **`feedback_no_metadata_markers`** — no `__is_X` string markers; model concepts structurally in `std/`. +- **[`THESIS.md`](../../THESIS.md)** + **[`MODELING.md`](../../MODELING.md)** + **[`INVARIANTS.md`](../../INVARIANTS.md)**. + +## Frame — groundedness gates lenses (revised) + +The language vocabulary is **primitives + namespacing/composition only**: +- 5 behaviors (`Value | Transform | Branch | Loop | Bind`) +- typed substrate carriers +- 4 type connectives (`Conjunction | Disjunction | Cardinality | Bit`) + +There is no user-defined-primitive feature, no escape syntax, no annotation the compiler can't see through. **Consequence: there is no "ungrounded user program" category.** A user "leaving the stack" inside the language means composing primitives into named patterns (namespacing) — the compiler sees through; lenses apply for free. "Leaving the stack" outside the language means literally writing a different compiler — not our concern until they ground their outputs back into our primitives by emitting `.dag`. + +**The lens contract is: applies to every program by construction.** If a lens needs an ungrounded-output path for user programs, the design has a leak — there's no syntax for a user to author an ungrounded program. + +### Sharpened diagnosis of the §0 class + +The eight surface sentinels — `PROGRAM_INPUT_SENTINEL`, fixture-filename routing, `span.file ==` checks, `include_str!` lens side-channels, file-preference rank, `bind.span.file` emission special cases, `EXTDEPS_BOOTSTRAP_FIXTURES`, the `lens_apply.rs` `algebra.dag` fold-skip — are **NOT "ungrounded fallbacks the compiler labels"** (earlier framing). They are: + +> **The compiler itself failing to use the language's primitives + namespacing internally.** + +The compiler reaches for sentinel strings instead of structural carriers because the substrate doesn't yet carry the structural identity end-to-end through lowering. The fix is to **make the compiler hold itself to the language's own vocabulary**: where today it asks `bind.span.file == "match_emit_helper.v3"`, it should ask a structural question against a typed carrier (`DeclarationRef`, structural template-formal edge, explicit input-value carrier, structural emit-helper carrier). + +This is the **highest-leverage paydown in the entire 2026-04-25 inventory** because eight item-by-item PRs will fight the same upstream every quarter; one substrate pass dissolves the class. + +## Eight surface dissolution sites + +| # | Site | File:line | Today | Carrier needed | +|---|------|-----------|-------|----------------| +| §0.1 | `PROGRAM_INPUT_SENTINEL` (5 sites) | `test_runner.rs:1594, 1617, 1642, 1709, 1855` | sentinel-string `"r1_lens_output_input_from_program"` | `DeclarationRef` for the program-input-binding role | +| §0.2 | Fixture-filename → bind-name routing | `test_runner.rs:47-48` | filename string lookup | `DeclarationRef` (same carrier as §0.1) | +| §0.3 | `include_str!` canonical lens side-channel | `test_runner.rs:23, :33` | `include_str!("../lenses/named_function_count.dag")` | `DeclarationRef` to the canonical lens declaration | +| §0.4 | `span.file ends_with "std/algebra.dag"` fold-skip | `lens_apply.rs:38, :372-383` | path-suffix string check | structural fold-shape carrier | +| §0.5 | `span.file == "dsl/std/types.dag"` type-alias bridge | `lower.rs:836` | path-equality string check | structural type-alias carrier | +| §0.6 | `bind.span.file == "named_alias_emit_helper.v3"` / `"match_emit_helper.v3"` | `emit.rs:3181, 3206` | path-equality string check | structural emit-helper carrier (typed role marker on the binding) | +| §0.7 | `declaration_name_preference_rank(&span.file)` | `dag.rs:2735-2764` + `lower.rs:1451-1452, 1546-1547` | file-suffix preference table | structural declaration-source carrier | +| §0.8 | `EXTDEPS_BOOTSTRAP_FIXTURES` manual fixture list | `bootstrap.rs::std_fixtures()` | hardcoded list of fixture paths | structural extdeps-fixture-set carrier | + +Each site has its own dissolution comment today. **What's been missing is a single substrate pass that lands the carriers; the eight sites then dissolve as consumers of the new substrate.** + +## Program shape — substrate-first, sites-after + +This program is **not** "go fix eight files." That ordering would patch the symptoms while the substrate stays absent, leaking new sentinel-string sites in the next quarter. + +### Phase 1 — substrate carriers (M-scope, sequential) + +Land the typed carriers into `src/v3/std/` and lower them end-to-end: + +1. **`DeclarationRef`** — typed reference to a declaration by structural identity, not by name-string. Consumers: §0.1, §0.2, §0.3, §0.5, §0.7. Likely the largest sub-deliverable; substrate-port + lowering wiring + consumer migration. +2. **Structural fold-shape carrier** (template-formal edge) — typed carrier on fold-template instantiation that records which formal binds the step. Consumers: §0.4 + B3's underlying invariant. +3. **Structural emit-helper carrier** — typed role marker on `Bind` / `Branch` nodes that participate in match/named-alias emission, attached at lowering time, not inferred from `span.file`. Consumers: §0.6. +4. **Structural extdeps-fixture-set carrier** — typed extdeps-bootstrap-set declaration, consumed by `bootstrap.rs::std_fixtures()`. Consumers: §0.8. + +Each of these is a sub-brief. Author and dispatch sequentially or in parallel where dependencies allow (DeclarationRef likely first; emit-helper carrier likely second since it's a smaller targeted shape; fold-shape carrier independent; fixture-set carrier independent of the other three). + +### Phase 2 — site dissolution (S-scope each, parallel after Phase 1) + +Once each Phase 1 carrier lands, the corresponding sites dissolve mechanically: +- §0.1-§0.3, §0.5, §0.7 dissolve with `DeclarationRef`. +- §0.4 dissolves with the fold-shape carrier. +- §0.6 dissolves with the emit-helper carrier. +- §0.8 dissolves with the fixture-set carrier. + +These are mechanical follow-up PRs once substrate is in place; not the substantive work. + +### Phase 3 — discipline ratchet (one-time, after Phase 1) + +Add a per-PR gate (and CI lint, if structural): **no new `span.file ==` / `span.file.ends_with` / sentinel-string checks in `src/v3/compiler/src/`.** The `feedback_no_textual_enforcement_bridges` discipline says no grep enforcement of "be structural"; this gate is reviewer-side discipline + the PR-template-line addition from synthesis §5.4, not an automated regex check. The structural prevention is that the carriers exist and the right answer is structurally available; reviewers just need to refuse the sentinel-string path. + +## Acceptance — program-level + +- [ ] All four Phase 1 carriers land in `src/v3/std/` with substrate-port + lowering + consumer migration. +- [ ] All eight Phase 2 sites dissolve; sentinel strings deleted. +- [ ] Phase 3 reviewer-discipline addition lands (PR-template line, brief checklist line). +- [ ] DB-8 fixed-point converges bit-identically across every Phase 1 + Phase 2 PR. +- [ ] No new `span.file == "..."` / `span.file.ends_with("...")` / sentinel-string sites introduced anywhere in `src/v3/compiler/src/`. +- [ ] Lens contract holds: every program (well-formed + structurally complete) has lens output without sentinel-string fabrication. + +## Sub-brief dispatch order + +Director authors and dispatches per Phase 1 ordering: +1. **B4.1 — `DeclarationRef` carrier** (largest; most consumers; gate for §0.1, §0.2, §0.3, §0.5, §0.7). +2. **B4.2 — Structural fold-shape carrier** (independent; can run in parallel with B4.1). +3. **B4.3 — Structural emit-helper carrier** (independent; can run in parallel with B4.1). +4. **B4.4 — Structural extdeps-fixture-set carrier** (independent; can run in parallel with B4.1). +5. **B4.5–B4.12 — Eight Phase 2 site-dissolution PRs** (mechanical; dispatch as each Phase 1 carrier lands). + +Each sub-brief gets the substrate-principle audit per `feedback_substrate_principle_audit` before authoring. Each sub-brief lands SG-0 census deltas + REGEN_OUTPUTS partition updates + DB-8 fixed-point check. + +## STOP-AND-ESCALATE — program-level + +- **A Phase 1 carrier proves to require substrate work outside this program's scope** (e.g., DeclarationRef requires resolving an InternTable + node-name interaction beyond the carrier itself) — STOP. Surface for re-scoping. +- **A Phase 2 site refuses to dissolve cleanly with the landed carrier** (e.g., consumer needs information the carrier doesn't yet provide) — STOP. Indicates the carrier was under-specified; revise Phase 1 sub-brief. +- **A new sentinel-string site is introduced during Phase 1 work** (e.g., a workaround in the substrate landing PR itself) — STOP. The discipline is being violated by the dissolution work; surface for design call. +- **DB-8 drifts on any sub-PR** — STOP immediately. +- **A site turns out NOT to belong to the §0 class** (e.g., a sentinel that's actually correct boundary contract per `feedback_fail_closed_is_boundary`) — STOP. Re-classify; remove from Phase 2 list. + +## Non-goals + +- Not addressing P3 fail-closed leaks (B1, B2, B3 — Tier 0). +- Not addressing host-Rust mirrors of std `.dag` carriers (Tier 3 #10 — Zero-Floor + R2 Grounding territory). +- Not addressing lossy lens reflection (Tier 3 #8 — adjacent but distinct; defer behind this program). +- Not extending lens taxonomy. +- Not adding analyzer-local heuristics or whitelists (per `feedback_construction_over_ratchets`). + +## Cross-manager note + +- **Zero-Floor Manager (`stern-swift-335`)** — heads-up. Phase 1 carriers touch substrate-adjacent territory; coordinate at sub-brief authoring (especially B4.1 DeclarationRef interaction with InternTable / node-name work). +- **Grounding Manager (`crisp-seal-366`)** — heads-up. §0.7 file-preference rank and §0.8 extdeps-fixture-set may touch Grounding-adjacent territory; coordinate if needed. +- **PM** — synthesis framing (one program, not eight paydowns) is the load-bearing reframe; primary recommendation per `debt-paydown-synthesis-2026-04-25.md` §0. + +## Reporting + +Program-level brief; no single PR. Sub-briefs (B4.1 – B4.12) report individually as authored. + +On Phase 1 close: Director signals PM + cross-managers; Phase 2 dispatch begins. +On program close: SG-0 census reflects the dissolution; ROADMAP debt rows for the §0 class retire. From c150c8f05662122cdc008d5efe698e887662f6dc Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 15:41:29 -0400 Subject: [PATCH 48/52] =?UTF-8?q?docs(briefs):=20B1=20=E2=80=94=20drop=20i?= =?UTF-8?q?ncoherent=20inner-fallback=20non-goal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex P2: the non-goal line excluding the inner declaration().name unwrap_or_else fallback contradicted Slice step 2, which replaces the whole chain with let-Some-else-return. Both fallbacks are in scope by construction; remove the contradictory non-goal. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/briefs/b1-go-unknownvariant-fail-closed-worker.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/briefs/b1-go-unknownvariant-fail-closed-worker.md b/docs/briefs/b1-go-unknownvariant-fail-closed-worker.md index c5c362ae82a..0bb41bc6973 100644 --- a/docs/briefs/b1-go-unknownvariant-fail-closed-worker.md +++ b/docs/briefs/b1-go-unknownvariant-fail-closed-worker.md @@ -54,7 +54,6 @@ The fix is one-site, structural, and parallels existing `variant_parent_info` ca ## Non-goals -- Not touching the sibling fallback in `declaration(variant_id).name` (the inner `unwrap_or_else`) unless the worker concludes it's part of the same fail-open class. Surface in PR description if so. - Not refactoring `variant_parent_info`'s shape. - Not addressing the file-suffix special case in `lens_apply.rs` (that's the §0 identity-carrier class — B4). From 488f6c15d62c01f6ca6b20db0536507c397d4b06 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 15:42:07 -0400 Subject: [PATCH 49/52] =?UTF-8?q?docs(briefs):=20B4=20=E2=80=94=20fix=20?= =?UTF-8?q?=C2=A7Frame=20vocabulary=20enumeration=20to=20canonical=206=20c?= =?UTF-8?q?onnectives?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PM REQUEST_CHANGES: §Frame listed '4 type connectives (Conjunction | Disjunction | Cardinality | Bit)' which contradicted the canonical thesis source. Replaced with the canonical 6 (Atom | Conj | Disj | Arrow | Cardinality | Instantiation) per docs/thesis/the-substrate-two-coordinated-shapes.md §'The vocabulary closes here'. Also removed 'typed substrate carriers' from the vocabulary list — substrate carriers are defined using the vocabulary, not part of it. Added a clarifying note that B4's carriers (DeclarationRef, fold-shape, emit-helper, extdeps-fixture-set) are typed declarations composed from the vocabulary, not vocabulary extensions. Per feedback_verify_thesis_claims: brief framings citing thesis structure must ground in the canonical source. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/briefs/b4-identity-carrier-substrate-pass.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/briefs/b4-identity-carrier-substrate-pass.md b/docs/briefs/b4-identity-carrier-substrate-pass.md index 273022be46a..9d1ec790017 100644 --- a/docs/briefs/b4-identity-carrier-substrate-pass.md +++ b/docs/briefs/b4-identity-carrier-substrate-pass.md @@ -18,9 +18,10 @@ ## Frame — groundedness gates lenses (revised) The language vocabulary is **primitives + namespacing/composition only**: +- 6 type connectives (`Atom | Conj | Disj | Arrow | Cardinality | Instantiation`) — per [`docs/thesis/the-substrate-two-coordinated-shapes.md`](../thesis/the-substrate-two-coordinated-shapes.md) §"The vocabulary closes here". `Atom` carries payloads at the user-input boundary; the other five decompose. - 5 behaviors (`Value | Transform | Branch | Loop | Bind`) -- typed substrate carriers -- 4 type connectives (`Conjunction | Disjunction | Cardinality | Bit`) + +The carriers B4 lands (`DeclarationRef`, structural fold-shape carrier, structural emit-helper carrier, structural extdeps-fixture-set carrier) are **defined using** this vocabulary — they are typed declarations the substrate composes from connectives + behaviors, not extensions of the vocabulary. There is no user-defined-primitive feature, no escape syntax, no annotation the compiler can't see through. **Consequence: there is no "ungrounded user program" category.** A user "leaving the stack" inside the language means composing primitives into named patterns (namespacing) — the compiler sees through; lenses apply for free. "Leaving the stack" outside the language means literally writing a different compiler — not our concern until they ground their outputs back into our primitives by emitting `.dag`. From f52e2cea7e84df385015ad11edb2f6b7d9a2992d Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 15:45:29 -0400 Subject: [PATCH 50/52] =?UTF-8?q?docs(briefs):=20B4=20=E2=80=94=20reframe?= =?UTF-8?q?=20B4.1=20as=20consumer=20migration;=20cite=20live=20substrate?= =?UTF-8?q?=20authority?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex BLOCKING: B4 §Frame copied stale feedback vocabulary instead of naming the live substrate authority. Two coordinated fixes: 1. §Read first cites src/v3/std/substrate.dag (live .dag substrate authority) and src/v3/spec/v3_l1.dag:69 (DeclarationRef sentinel meta-type — already exists with consumers in verification.dag, emit_model.dag, python.dag). 2. Phase 1 #1 reframed: 'land DeclarationRef' → 'consume the existing DeclarationRef'. The work is consumer migration + any role-extension layer the audit reveals, NOT designing or landing the carrier. Phase 1 #2-#4 (fold-shape, emit-helper, extdeps-fixture-set carriers) keep their 'new' framing but explicitly require sub-briefs to grep src/v3/std/ + src/v3/spec/ for existing authority before authoring 'design and land' framing — per feedback_verify_thesis_claims + feedback_emitter_workaround_is_gap_symptom. Acceptance + sub-brief dispatch order updated to reflect B4.1's consumer-migration shape. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../b4-identity-carrier-substrate-pass.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/briefs/b4-identity-carrier-substrate-pass.md b/docs/briefs/b4-identity-carrier-substrate-pass.md index 9d1ec790017..61445b77203 100644 --- a/docs/briefs/b4-identity-carrier-substrate-pass.md +++ b/docs/briefs/b4-identity-carrier-substrate-pass.md @@ -13,6 +13,8 @@ - **`feedback_lenses_not_passes`** — analyses are lenses over physics; zero heuristics. - **`feedback_construction_over_ratchets`** — model first; violations dissolve. - **`feedback_no_metadata_markers`** — no `__is_X` string markers; model concepts structurally in `std/`. +- **[`src/v3/std/substrate.dag`](../../src/v3/std/substrate.dag)** — live substrate authority (the .dag source of truth for the connectives + behaviors enumerated in §Frame). +- **[`src/v3/spec/v3_l1.dag:69`](../../src/v3/spec/v3_l1.dag)** — **`DeclarationRef` already exists as live substrate authority**. Sentinel meta-type: *"a field declared `target: DeclarationRef` accepts an identifier value instead of a literal value at the data-body parse site, and that identifier is resolved to a DeclarationId during lowering. This is the structural alternative to passing declaration names as strings — the substrate carries the typed reference forward, no name-bridge lookup at consumption time."* B4.1 **consumes** this carrier; it does NOT design or land it. Existing consumers: `src/v3/std/verification.dag`, `src/v3/std/emit_model.dag`, `src/v3/spec/python.dag`. - **[`THESIS.md`](../../THESIS.md)** + **[`MODELING.md`](../../MODELING.md)** + **[`INVARIANTS.md`](../../INVARIANTS.md)**. ## Frame — groundedness gates lenses (revised) @@ -60,12 +62,12 @@ This program is **not** "go fix eight files." That ordering would patch the symp Land the typed carriers into `src/v3/std/` and lower them end-to-end: -1. **`DeclarationRef`** — typed reference to a declaration by structural identity, not by name-string. Consumers: §0.1, §0.2, §0.3, §0.5, §0.7. Likely the largest sub-deliverable; substrate-port + lowering wiring + consumer migration. -2. **Structural fold-shape carrier** (template-formal edge) — typed carrier on fold-template instantiation that records which formal binds the step. Consumers: §0.4 + B3's underlying invariant. -3. **Structural emit-helper carrier** — typed role marker on `Bind` / `Branch` nodes that participate in match/named-alias emission, attached at lowering time, not inferred from `span.file`. Consumers: §0.6. -4. **Structural extdeps-fixture-set carrier** — typed extdeps-bootstrap-set declaration, consumed by `bootstrap.rs::std_fixtures()`. Consumers: §0.8. +1. **Consume the existing `DeclarationRef`** at `src/v3/spec/v3_l1.dag:69` — already-landed substrate authority. The work is **not** to design or land the carrier; it's to (a) audit which §0 sites can route through `DeclarationRef` directly and (b) extend lowering/resolution where consumers need additional structural data (e.g., role-tagged references, input-binding refs) on top of the base sentinel meta-type. Consumers: §0.1, §0.2, §0.3, §0.5, §0.7. Likely the largest sub-deliverable; the work is consumer migration + any role-extension layer the audit reveals. +2. **Structural fold-shape carrier** (template-formal edge) — *new*: typed carrier on fold-template instantiation that records which formal binds the step. Consumers: §0.4 + B3's underlying invariant. Verify against current substrate before designing — search `src/v3/std/` for any existing fold-template-formal authority. +3. **Structural emit-helper carrier** — *new*: typed role marker on `Bind` / `Branch` nodes that participate in match/named-alias emission, attached at lowering time, not inferred from `span.file`. Consumers: §0.6. Verify against current substrate. +4. **Structural extdeps-fixture-set carrier** — *new*: typed extdeps-bootstrap-set declaration, consumed by `bootstrap.rs::std_fixtures()`. Consumers: §0.8. Verify against current substrate. -Each of these is a sub-brief. Author and dispatch sequentially or in parallel where dependencies allow (DeclarationRef likely first; emit-helper carrier likely second since it's a smaller targeted shape; fold-shape carrier independent; fixture-set carrier independent of the other three). +Each of these is a sub-brief. **Each sub-brief MUST grep `src/v3/std/` + `src/v3/spec/` for an existing authority before authoring "design and land" framing** (per `feedback_verify_thesis_claims` + `feedback_emitter_workaround_is_gap_symptom`). B4.1's audit already established the existing-authority case; B4.2/B4.3/B4.4 must repeat the discipline. Author and dispatch sequentially or in parallel where dependencies allow. ### Phase 2 — site dissolution (S-scope each, parallel after Phase 1) @@ -83,7 +85,8 @@ Add a per-PR gate (and CI lint, if structural): **no new `span.file ==` / `span. ## Acceptance — program-level -- [ ] All four Phase 1 carriers land in `src/v3/std/` with substrate-port + lowering + consumer migration. +- [ ] B4.1: `DeclarationRef` migration consumed across §0.1, §0.2, §0.3, §0.5, §0.7 (no carrier landing — consume existing `src/v3/spec/v3_l1.dag:69`). +- [ ] B4.2-B4.4: each new carrier (fold-shape, emit-helper, extdeps-fixture-set) lands in `src/v3/std/` with substrate-port + lowering + consumer migration, OR the sub-brief audit reveals an existing authority to consume. - [ ] All eight Phase 2 sites dissolve; sentinel strings deleted. - [ ] Phase 3 reviewer-discipline addition lands (PR-template line, brief checklist line). - [ ] DB-8 fixed-point converges bit-identically across every Phase 1 + Phase 2 PR. @@ -93,7 +96,7 @@ Add a per-PR gate (and CI lint, if structural): **no new `span.file ==` / `span. ## Sub-brief dispatch order Director authors and dispatches per Phase 1 ordering: -1. **B4.1 — `DeclarationRef` carrier** (largest; most consumers; gate for §0.1, §0.2, §0.3, §0.5, §0.7). +1. **B4.1 — `DeclarationRef` consumer migration** (largest; most consumers; gate for §0.1, §0.2, §0.3, §0.5, §0.7). NOT a carrier-landing brief — `DeclarationRef` already exists at `src/v3/spec/v3_l1.dag:69`. Audit + consumer migration + any role-extension layer needed. 2. **B4.2 — Structural fold-shape carrier** (independent; can run in parallel with B4.1). 3. **B4.3 — Structural emit-helper carrier** (independent; can run in parallel with B4.1). 4. **B4.4 — Structural extdeps-fixture-set carrier** (independent; can run in parallel with B4.1). From 12c7e8f20e3c9e660e82e2b30541db8e296db3b6 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 15:46:20 -0400 Subject: [PATCH 51/52] =?UTF-8?q?docs(briefs):=20B4=20=E2=80=94=20tighten?= =?UTF-8?q?=20Phase=201=20umbrella=20sentence?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The umbrella 'Land the typed carriers into src/v3/std/' framing was stale after f52e2cea7's reframe of #1 to consumer-migration. Replaced with audit-first wording that covers both the consume-existing case (#1) and the design-and-land case (#2-#4 if their audits show real gaps). Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/briefs/b4-identity-carrier-substrate-pass.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/briefs/b4-identity-carrier-substrate-pass.md b/docs/briefs/b4-identity-carrier-substrate-pass.md index 61445b77203..c7c9c23b2ee 100644 --- a/docs/briefs/b4-identity-carrier-substrate-pass.md +++ b/docs/briefs/b4-identity-carrier-substrate-pass.md @@ -60,7 +60,7 @@ This program is **not** "go fix eight files." That ordering would patch the symp ### Phase 1 — substrate carriers (M-scope, sequential) -Land the typed carriers into `src/v3/std/` and lower them end-to-end: +For each carrier: **first audit existing authorities in `src/v3/std/` + `src/v3/spec/`**; consume what's already landed; only design + land net-new substrate where the audit shows a real gap. Lower end-to-end so Phase 2 sites can dissolve mechanically. 1. **Consume the existing `DeclarationRef`** at `src/v3/spec/v3_l1.dag:69` — already-landed substrate authority. The work is **not** to design or land the carrier; it's to (a) audit which §0 sites can route through `DeclarationRef` directly and (b) extend lowering/resolution where consumers need additional structural data (e.g., role-tagged references, input-binding refs) on top of the base sentinel meta-type. Consumers: §0.1, §0.2, §0.3, §0.5, §0.7. Likely the largest sub-deliverable; the work is consumer migration + any role-extension layer the audit reveals. 2. **Structural fold-shape carrier** (template-formal edge) — *new*: typed carrier on fold-template instantiation that records which formal binds the step. Consumers: §0.4 + B3's underlying invariant. Verify against current substrate before designing — search `src/v3/std/` for any existing fold-template-formal authority. From 1aeaa9a78ceca5e9307c8630958cacc8e721e41c Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Sat, 25 Apr 2026 15:51:25 -0400 Subject: [PATCH 52/52] =?UTF-8?q?docs(briefs):=20B4=20=E2=80=94=20consiste?= =?UTF-8?q?ncy=20fix=20for=20'carriers=20B4=20lands'=20wording?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex APPROVE_WITH_COMMENTS: §Frame still said 'carriers B4 lands' which conflicted with the post-reframe reality that B4.1 consumes the existing DeclarationRef. Updated to 'consumes or lands' with explicit existing-authority citation and audit-pending caveat for B4.2-B4.4. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/briefs/b4-identity-carrier-substrate-pass.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/briefs/b4-identity-carrier-substrate-pass.md b/docs/briefs/b4-identity-carrier-substrate-pass.md index c7c9c23b2ee..8f6f8831e59 100644 --- a/docs/briefs/b4-identity-carrier-substrate-pass.md +++ b/docs/briefs/b4-identity-carrier-substrate-pass.md @@ -23,7 +23,7 @@ The language vocabulary is **primitives + namespacing/composition only**: - 6 type connectives (`Atom | Conj | Disj | Arrow | Cardinality | Instantiation`) — per [`docs/thesis/the-substrate-two-coordinated-shapes.md`](../thesis/the-substrate-two-coordinated-shapes.md) §"The vocabulary closes here". `Atom` carries payloads at the user-input boundary; the other five decompose. - 5 behaviors (`Value | Transform | Branch | Loop | Bind`) -The carriers B4 lands (`DeclarationRef`, structural fold-shape carrier, structural emit-helper carrier, structural extdeps-fixture-set carrier) are **defined using** this vocabulary — they are typed declarations the substrate composes from connectives + behaviors, not extensions of the vocabulary. +The carriers B4 consumes or lands (the existing `DeclarationRef` at `src/v3/spec/v3_l1.dag:69`, plus a structural fold-shape carrier, structural emit-helper carrier, structural extdeps-fixture-set carrier — each pending audit per Phase 1) are **defined using** this vocabulary — they are typed declarations the substrate composes from connectives + behaviors, not extensions of the vocabulary. There is no user-defined-primitive feature, no escape syntax, no annotation the compiler can't see through. **Consequence: there is no "ungrounded user program" category.** A user "leaving the stack" inside the language means composing primitives into named patterns (namespacing) — the compiler sees through; lenses apply for free. "Leaving the stack" outside the language means literally writing a different compiler — not our concern until they ground their outputs back into our primitives by emitting `.dag`.