From 518568f941601f5668aa74e80cdfabcc2dadd639 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Mon, 29 Jun 2026 21:20:37 +0000 Subject: [PATCH 1/4] WIP: roadmap discussion --- dsl/gunbc/roadmap_model.dag | 10 ++++++++-- dsl/gunbc/roadmap_status.dag | 29 +++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/dsl/gunbc/roadmap_model.dag b/dsl/gunbc/roadmap_model.dag index d4a9a62ac04..1c0502bbb7a 100644 --- a/dsl/gunbc/roadmap_model.dag +++ b/dsl/gunbc/roadmap_model.dag @@ -1,7 +1,7 @@ module gunbc.roadmap_model import ctrl.process_algebra { ProcessNodeId } -import gunbc.roadmap_status { RoadmapItem, DriftVerdict, status_drift } +import gunbc.roadmap_status { RoadmapItem, DriftVerdict, status_drift, Signoff, Unsigned, signoff_accepts, signoff_drift } type Pointer { label: String, path: String } @@ -28,6 +28,8 @@ type RoadmapNode { line: RoadmapItem carriers: List sizing: NodeSizing + owner: String + signoff: Signoff } type RoadmapEdge { @@ -81,5 +83,9 @@ fn node_carrier_clean(rn: RoadmapNode, existing_docs: List) -> Bool { } fn node_status_drift(rn: RoadmapNode, committed_box: Bool, merged: List) -> DriftVerdict { - status_drift(item: rn.line, committed_box: committed_box, merged: merged) + signoff_drift(s: rn.signoff, committed_box: committed_box) +} + +fn node_closed(rn: RoadmapNode) -> Bool { + signoff_accepts(s: rn.signoff) } diff --git a/dsl/gunbc/roadmap_status.dag b/dsl/gunbc/roadmap_status.dag index fcb305d0612..103b16f14f9 100644 --- a/dsl/gunbc/roadmap_status.dag +++ b/dsl/gunbc/roadmap_status.dag @@ -10,6 +10,31 @@ type RoadmapItem | PlainLine { content: String } +type Signoff + = Unsigned + | SignedOff { by: String, works: Bool, scope_equivalent: Bool, as_expected: Bool } + +fn signoff_accepts(s: Signoff) -> Bool { + match s { + Unsigned => false + SignedOff { by: _, works, scope_equivalent, as_expected } => works && scope_equivalent && as_expected + } +} + +fn signoff_is_present(s: Signoff) -> Bool { + match s { + Unsigned => false + SignedOff { by: _, works: _, scope_equivalent: _, as_expected: _ } => true + } +} + +fn signoff_by(s: Signoff) -> String { + match s { + Unsigned => "" + SignedOff { by, works: _, scope_equivalent: _, as_expected: _ } => by + } +} + fn pr_merged(pr: PullRequest) -> Bool { match pr.merged_at { Present { value: _ } => true @@ -35,6 +60,10 @@ fn item_is_done(item: RoadmapItem, merged: List) -> Bool { type DriftVerdict = Drifted | Clean | Underivable +fn signoff_drift(s: Signoff, committed_box: Bool) -> DriftVerdict { + if committed_box == signoff_accepts(s: s) { Clean } else { Drifted } +} + fn status_drift(item: RoadmapItem, committed_box: Bool, merged: List) -> DriftVerdict { match item { AuthoredLine { done: _, content: _ } => Underivable From dc78201b31439888f1f937f490cc58b54f8cdc4d Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Mon, 29 Jun 2026 21:25:07 +0000 Subject: [PATCH 2/4] Roadmap sign-off convergence model (mechanism): box [x] requires PM/TPM sign-off, not PR-merge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add Signoff{Unsigned|SignedOff{by,works,scope_equivalent,as_expected}} to the roadmap authority. A node closes ([x]) only when signed off on all three criteria; a merged-but- unsigned node renders '⏳ awaiting sign-off' (the operator's ticket queue). PR-merge is evidence, not closure — the plan-layer fail-closed against the DESIGN §5 fabricated-green trap. Drift gate flips from box==PRs-merged to box==signed-off. Mechanism only (status/model/authority-helpers/emit). Gate-witness rework, 4 test-file RoadmapNode literals, regen of ROADMAP.md, and the content rework (owners + sign-offs + stale->landed corrections + new lanes) follow. Co-Authored-By: Claude Opus 4.8 (1M context) --- dsl/gunbc/roadmap_authority.dag | 34 +++++++++++++++++++++++++-------- dsl/gunbc/roadmap_emit.dag | 20 +++++++++++++++++-- dsl/gunbc/roadmap_model.dag | 2 +- 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/dsl/gunbc/roadmap_authority.dag b/dsl/gunbc/roadmap_authority.dag index 07f79e1f864..dd5ebd3aa1c 100644 --- a/dsl/gunbc/roadmap_authority.dag +++ b/dsl/gunbc/roadmap_authority.dag @@ -9,7 +9,7 @@ import gunbc.roadmap_model { NodeSizing, Unsized, Sized, SectionElement, section_prose, section_group, } -import gunbc.roadmap_status { RoadmapItem, DerivableLine, AuthoredLine, PlainLine } +import gunbc.roadmap_status { RoadmapItem, DerivableLine, AuthoredLine, PlainLine, Signoff, Unsigned, SignedOff } import ctrl.process_algebra { ProcessNodeId } import std.markdown { MarkdownBlock, HeadingBlock, ParagraphBlock, TextInline, H1 } import extdeps.languages.markdown { serialize_markdown_source } @@ -19,30 +19,36 @@ fn nid(s: String) -> ProcessNodeId { s } fn ptr(label: String, path: String) -> Pointer { Pointer { label: label, path: path } } fn plan_ptr(path: String) -> List { [Pointer { label: "plan", path: path }] } +fn unsigned() -> Signoff { Unsigned } + +fn signed(by: String, works: Bool, scope_equivalent: Bool, as_expected: Bool) -> Signoff { + SignedOff { by: by, works: works, scope_equivalent: scope_equivalent, as_expected: as_expected } +} + fn authored(id: String, done: Bool, content: String) -> RoadmapNode { - RoadmapNode { node: nid(s: id), line: AuthoredLine { done: done, content: content }, carriers: [], sizing: Unsized } + RoadmapNode { node: nid(s: id), line: AuthoredLine { done: done, content: content }, carriers: [], sizing: Unsized, owner: "", signoff: Unsigned } } fn authored_doc(id: String, done: Bool, content: String, path: String) -> RoadmapNode { - RoadmapNode { node: nid(s: id), line: AuthoredLine { done: done, content: content }, carriers: plan_ptr(path: path), sizing: Unsized } + RoadmapNode { node: nid(s: id), line: AuthoredLine { done: done, content: content }, carriers: plan_ptr(path: path), sizing: Unsized, owner: "", signoff: Unsigned } } fn authored_pp(id: String, done: Bool, content: String, carriers: List) -> RoadmapNode { - RoadmapNode { node: nid(s: id), line: AuthoredLine { done: done, content: content }, carriers: carriers, sizing: Unsized } + RoadmapNode { node: nid(s: id), line: AuthoredLine { done: done, content: content }, carriers: carriers, sizing: Unsized, owner: "", signoff: Unsigned } } fn plain(id: String, content: String) -> RoadmapNode { - RoadmapNode { node: nid(s: id), line: PlainLine { content: content }, carriers: [], sizing: Unsized } + RoadmapNode { node: nid(s: id), line: PlainLine { content: content }, carriers: [], sizing: Unsized, owner: "", signoff: Unsigned } } fn derivable(id: String, prs: List, title: String, description: String) -> RoadmapNode { - RoadmapNode { node: nid(s: id), line: DerivableLine { prs: prs, title: title, description: description }, carriers: [], sizing: Unsized } + RoadmapNode { node: nid(s: id), line: DerivableLine { prs: prs, title: title, description: description }, carriers: [], sizing: Unsized, owner: "", signoff: Unsigned } } fn derivable_doc(id: String, prs: List, title: String, description: String, path: String) -> RoadmapNode { - RoadmapNode { node: nid(s: id), line: DerivableLine { prs: prs, title: title, description: description }, carriers: plan_ptr(path: path), sizing: Unsized } + RoadmapNode { node: nid(s: id), line: DerivableLine { prs: prs, title: title, description: description }, carriers: plan_ptr(path: path), sizing: Unsized, owner: "", signoff: Unsigned } } fn derivable_pp(id: String, prs: List, title: String, description: String, carriers: List) -> RoadmapNode { - RoadmapNode { node: nid(s: id), line: DerivableLine { prs: prs, title: title, description: description }, carriers: carriers, sizing: Unsized } + RoadmapNode { node: nid(s: id), line: DerivableLine { prs: prs, title: title, description: description }, carriers: carriers, sizing: Unsized, owner: "", signoff: Unsigned } } fn derivable_wi(id: String, prs: List, title: String, description: String, intricacy: Intricacy, volume: Volume, repo: String) -> RoadmapNode { @@ -51,6 +57,8 @@ fn derivable_wi(id: String, prs: List, title: String, description: String, line: DerivableLine { prs: prs, title: title, description: description }, carriers: [], sizing: Sized { intricacy: intricacy, volume: volume, repo: repo, acceptance: PrsMerged }, + owner: "", + signoff: Unsigned, } } @@ -60,9 +68,19 @@ fn authored_wi(id: String, done: Bool, content: String, intricacy: Intricacy, vo line: AuthoredLine { done: done, content: content }, carriers: [], sizing: Sized { intricacy: intricacy, volume: volume, repo: repo, acceptance: ManualAcceptance }, + owner: "", + signoff: Unsigned, } } +fn owned(rn: RoadmapNode, owner: String) -> RoadmapNode { + RoadmapNode { node: rn.node, line: rn.line, carriers: rn.carriers, sizing: rn.sizing, owner: owner, signoff: rn.signoff } +} + +fn sign(rn: RoadmapNode, s: Signoff) -> RoadmapNode { + RoadmapNode { node: rn.node, line: rn.line, carriers: rn.carriers, sizing: rn.sizing, owner: rn.owner, signoff: s } +} + fn preamble() -> List { [ HeadingBlock { level: H1, inlines: [TextInline { text: "gunbc — Roadmap" }] }, diff --git a/dsl/gunbc/roadmap_emit.dag b/dsl/gunbc/roadmap_emit.dag index e6e9aeadb47..3fcf5891153 100644 --- a/dsl/gunbc/roadmap_emit.dag +++ b/dsl/gunbc/roadmap_emit.dag @@ -11,15 +11,31 @@ import gunbc.roadmap_model { SectionElement, Prose, Group, SectionProse, SectionGroup, } -import gunbc.roadmap_status { RoadmapItem, DerivableLine, AuthoredLine, PlainLine, item_is_done } +import gunbc.roadmap_status { RoadmapItem, DerivableLine, AuthoredLine, PlainLine, item_is_done, signoff_accepts, signoff_by } import ctrl.process_algebra { ProcessNodeId } fn roadmap_max_depth() -> Int { 8 } fn node_is_done(rn: RoadmapNode, merged: List) -> Bool { + signoff_accepts(s: rn.signoff) +} + +fn node_evidence_present(rn: RoadmapNode, merged: List) -> Bool { item_is_done(item: rn.line, merged: merged) } +fn signoff_suffix_inlines(rn: RoadmapNode, merged: List) -> List { + if signoff_accepts(s: rn.signoff) { + [TextInline { text: concat(" — ✓ signed off: ", signoff_by(s: rn.signoff)) }] + } else { + if node_evidence_present(rn: rn, merged: merged) { + [TextInline { text: " — ⏳ awaiting sign-off" }] + } else { + [] + } + } +} + fn pointer_inlines(p: Pointer) -> List { [ TextInline { text: " " }, @@ -90,7 +106,7 @@ fn plain_item_for(rn: RoadmapNode) -> MarkdownListItem { } fn task_item_for(rn: RoadmapNode, nodes: List, edges: List, merged: List, fuel: Int) -> MarkdownTaskItem { - let para = ParagraphBlock { inlines: node_inlines(rn: rn) } + let para = ParagraphBlock { inlines: concat(node_inlines(rn: rn), signoff_suffix_inlines(rn: rn, merged: merged)) } let kids = if fuel > 0 { children_of(nodes: nodes, edges: edges, parent: rn.node) } else { [] } let blocks = if count(kids) > 0 { concat([para], nodes_to_blocks(items: kids, nodes: nodes, edges: edges, merged: merged, fuel: fuel - 1)) diff --git a/dsl/gunbc/roadmap_model.dag b/dsl/gunbc/roadmap_model.dag index 1c0502bbb7a..fcb61cb49a2 100644 --- a/dsl/gunbc/roadmap_model.dag +++ b/dsl/gunbc/roadmap_model.dag @@ -1,7 +1,7 @@ module gunbc.roadmap_model import ctrl.process_algebra { ProcessNodeId } -import gunbc.roadmap_status { RoadmapItem, DriftVerdict, status_drift, Signoff, Unsigned, signoff_accepts, signoff_drift } +import gunbc.roadmap_status { RoadmapItem, DriftVerdict, Signoff, signoff_accepts, signoff_drift } type Pointer { label: String, path: String } From c00197752b11a11df2aae601ae967028fc3b35c1 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Mon, 29 Jun 2026 21:38:41 +0000 Subject: [PATCH 3/4] WIP: Take roadmap sign-off PR #5968 mechanism to green --- ROADMAP.md | 70 +++++++++---------- dsl/test/claim/roadmap_document_test.dag | 33 ++++++--- dsl/test/claim/roadmap_emit_test.dag | 46 ++++++++++-- dsl/test/claim/roadmap_gate_test.dag | 68 +++++++++++++----- dsl/test/claim/roadmap_model_test.dag | 23 ++++-- .../claim/roadmap_spawner_witness_test.dag | 6 +- 6 files changed, 170 insertions(+), 76 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 6513863388b..2d0394b53fa 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -44,18 +44,18 @@ This window = a few days of STABILITY — shrink the fail-open surface, don't "l **Audits (done):** -- [x] lens/gate wiring — most analytical lenses inert (authored, no discovered gate) -- [x] fail-open code — cache lossy-digest · under-keyed memos · `unwrap_or_default` infer -- [x] **model↔realization fork — ROOT CONFIRMED** — one seam (~13 bridges); sub-roots = numeric tower + `Value::Null` [plan](docs/plans/model-realization-fork.md) +- [ ] lens/gate wiring — most analytical lenses inert (authored, no discovered gate) — ⏳ awaiting sign-off +- [ ] fail-open code — cache lossy-digest · under-keyed memos · `unwrap_or_default` infer — ⏳ awaiting sign-off +- [ ] **model↔realization fork — ROOT CONFIRMED** — one seam (~13 bridges); sub-roots = numeric tower + `Value::Null` [plan](docs/plans/model-realization-fork.md) — ⏳ awaiting sign-off - [ ] remaining: coercion/equality straddles · inference fail-open · cache-purity · CI-coverage-completeness [detail](docs/plans/fail-closed-lockdown.md) **In-scope this window:** -- [x] **numeric-tower grounding** (#5428) — `Int=GroupCompletion`; `==` straddle guard now dead-in-corpus [plan](docs/plans/model-realization-fork.md) +- [ ] **numeric-tower grounding** (#5428) — `Int=GroupCompletion`; `==` straddle guard now dead-in-corpus [plan](docs/plans/model-realization-fork.md) — ⏳ awaiting sign-off - [ ] **cache trustworthy** — authoritative home is §2 F2/F3/P1; ship the warm==cold oracle as a detective now - [ ] **rust-gate coverage** (shared §1) — **▸ run-all at nextest speed ✓ CI-green-proven (#5427, in queue): full v1 coverage every `.rs` PR ~6m (was ~42m), no coverage-vs-speed tradeoff**; `.dag`→rust coverage wall = edge-(b), SCOPED / pending operator greenlight *(quick-ant-298)* [cause table](docs/plans/ci-selection-vs-scheduling.md) [edge-(b) brief](docs/plans/edge-b-rust-dag-provenance-brief.md) - [ ] **promote-or-delete inert lenses · de-vacuum gates** — EmitHostGate de-vacuumed ✓ (#5477); 4 advisory lenses widened+bounded, whole-corpus deferred to `.dag` structural-reflection (also unlocks coverage/testgen) *(silent-wren-739)* -- [x] **realization-vocabulary containment guard** (#5445/#5453) — target-AST importable only at the realization edge (fail-closed, shrinking-roster); dissolve-on: bash-sidecar arc empties the roster → pure wall → `program.dag` deletable [plan](docs/plans/emission-ingestion-inverse.md) +- [ ] **realization-vocabulary containment guard** (#5445/#5453) — target-AST importable only at the realization edge (fail-closed, shrinking-roster); dissolve-on: bash-sidecar arc empties the roster → pure wall → `program.dag` deletable [plan](docs/plans/emission-ingestion-inverse.md) — ⏳ awaiting sign-off - [ ] **stage0 clone-census inert + seed regressed** to 21540 (~1138 over) — resolve by clone-reduction / substrate-migration, NEVER a cap-bump; #5427 `#[ignore]` is the interim *(fierce-hawk-540 via quick-ant-298)* - [ ] **`Disposition` carrier** *(un-parked, operator GO)* — slice-1 prove-by-use active *(adhoc-0a633bef-bb9 / fierce-crane-13 under neat-dove-397)*: model `Disposition`+`ConstructionMechanism` in std → migrate one region (the post-#5579 `data:String` marker fleet) → fail-closed redundancy lens. Single-authority convergence home for scaffold/rationale/dissolution marks; substrate-mandatory #1 is the end-state, not this slice. [plan](docs/plans/disposition-carrier.md) @@ -63,16 +63,16 @@ This window = a few days of STABILITY — shrink the fail-open surface, don't "l - [ ] **split `Value::Null`** (None/Absent/miss/Violates → own carriers) — ~131-site substrate change, the deeper root; own runway - [ ] **self-host purity gate** — a §5 deliverable, not §0 (avoids the §0↔§5 cycle) -- [x] **cross-tree import activation** (§5) (#5473) — LANDED; the §0↔§5 escalate item is now closed +- [ ] **cross-tree import activation** (§5) (#5473) — LANDED; the §0↔§5 escalate item is now closed — ⏳ awaiting sign-off - [ ] complexity-budget whole-codebase (§3) · cache-redundancy completeness (§2 P3) — residue, after construction - [ ] **cardinality refinement** — illegal cardinalities (wrong length · empty · overflow) unwritable by construction; the *decidable* refinement axis (linear arithmetic over counts), fold-propagated. MVP-1 (`Byte` via `Length<8>`) + P4 (fold homomorphism · uint8 overflow → typed `Rejected`) proven (#5512); P1 (`where` lowering) / P2 (construction-enforced) behind this lane; P5 (phantom-width reflection) substrate-blocked. [plan](docs/plans/cardinality-refinement.md) [P1](docs/plans/p1-where-clause-lowering.md) **Meta — lock down the reasoning (§7 recursion):** -- [x] **inert-lens hygiene backstop** (#5433) — every `lens/*.dag` wired or deleted; runs over the corpus +- [ ] **inert-lens hygiene backstop** (#5433) — every `lens/*.dag` wired or deleted; runs over the corpus — ⏳ awaiting sign-off - [ ] **reachability-completeness lens** — every declared node (code carrier · doc · lens) reachable from a run-root, rostered, or deleted; generalizes #5433 to carriers + docs [plan](docs/plans/inert-layer-lens.md) - [ ] **gate-hygiene: a floor-enrolled gate must be green-on-main at merge** — roster-completeness assertion promoted to should-land ([plan](docs/plans/emission-ingestion-inverse.md) §2; [merge-freshness decision record](docs/plans/ci-merge-freshness.md)) *(quick-ant-298)* -- [x] **construction-justification rule** (#5476) (authoring-time) — justify why a class can't be construction before adding a lens *(silent-wren-739)* [plan](docs/plans/construction-justification-rule.md) [DESIGN §6](DESIGN.md) +- [ ] **construction-justification rule** (#5476) (authoring-time) — justify why a class can't be construction before adding a lens *(silent-wren-739)* [plan](docs/plans/construction-justification-rule.md) [DESIGN §6](DESIGN.md) — ⏳ awaiting sign-off - [ ] **expressibility frontier** — partition each modeling discipline into wall / lens-residue / undecidable-review *before* gating [plan](docs/plans/expressibility-frontier.md) - [ ] **confront the skipped modeling decisions** — the `🟡` comment backlog *+ the post-#5579 `data:String` marker fleet* (the comment-wall moved marks comments→rows, growing the §3-migrate surface); converges on the `Disposition` carrier (single authority, `0-disposition`) [Disposition plan](docs/plans/disposition-carrier.md) - [ ] **reference grounding** — migrate stringly-typed *references* (a symbol/module/fn/url written as free text where a typed edge belongs) to typed carriers (`DeclarationRef`/`QualifiedName`/`Uri`); the carrier half of the groundedness effort (detector half = `v2.lens.grounding` EXTRACT). Splits the coincidence into REFERENCE (independent entity → `DeclarationRef`) vs ROLE (genitive/ownership of the enclosing concept → an EdgeLabel/FieldRef tag, EARNED from an adjudication ledger, not guessed). Follow-on to `0-construction-rule`'s prose deletion *(tidy-badger-45)* [plan](docs/plans/reference-grounding-migration.md) [construction rule](docs/plans/construction-justification-rule.md) @@ -97,8 +97,8 @@ A flaky or green-but-broken floor means no gate protects anything — so CI is u - [ ] **resolve is not affected-set-pruned** — discovery is deliberately tree-wide (fail-closed enrol), but EXECUTION still **resolves all 870** every run; #5427 selection shrinks compile/test, not the 518s resolve. The lever: extend the affected-set across discovery→resolve so unchanged witnesses skip (the floor-selection items below, applied to the resolve phase). [plan](docs/plans/ci-selection-vs-scheduling.md) - [ ] **kill the within-run double-resolve** — the corpus resolves once for discovery and again for execution (~275s second pass); execution should piggyback the discovery resolve. Pure within-run win, no cross-run cache needed. - [ ] **profile the 518s resolve** — ~0.6s/witness average, but a known machine-independent resolver bug resolves `budget_roster` ~450x its structural twin; a few pathological witnesses likely dominate the 518s. Profile which, fix the resolver. -- [x] **fractal Gantt profiling receipt (#5757 baseline)** — per-claim timing tap (`GUNBC_FLOOR_GANTT=1`) + Batch 1/2/3 breakdown; hot spots: rust gate ~530s (host-effect, architectural sep), discovery eval ~229s (interpreter, `width=3`), cold resolve ~50s (resolve-cache lever). [plan](docs/plans/ci-floor-fractal-gantt.md) -- [x] **interpreter memory chronicle (post-#5910)** — execution-grounded floor RSS receipt (width=1 @ 8 GiB: ~5.12 GiB self-RSS, ~5.31 GiB cgroup) + per-shard/per-resolve probes vs the 14.2→5.5→5.1 GiB arc; phase-0 measurement scaffold toward `PerformanceReceipt`. [plan](docs/plans/interpreter-memory-chronicle.md) +- [ ] **fractal Gantt profiling receipt (#5757 baseline)** — per-claim timing tap (`GUNBC_FLOOR_GANTT=1`) + Batch 1/2/3 breakdown; hot spots: rust gate ~530s (host-effect, architectural sep), discovery eval ~229s (interpreter, `width=3`), cold resolve ~50s (resolve-cache lever). [plan](docs/plans/ci-floor-fractal-gantt.md) — ⏳ awaiting sign-off +- [ ] **interpreter memory chronicle (post-#5910)** — execution-grounded floor RSS receipt (width=1 @ 8 GiB: ~5.12 GiB self-RSS, ~5.31 GiB cgroup) + per-shard/per-resolve probes vs the 14.2→5.5→5.1 GiB arc; phase-0 measurement scaffold toward `PerformanceReceipt`. [plan](docs/plans/interpreter-memory-chronicle.md) — ⏳ awaiting sign-off **The <1min lever is resolve-phase incrementality, NOT cross-run resolve-cache** — CI is cold-dominated (the exe-hash re-colds on every code change), so §2 P3 resolve-cache is the *warm* ~18% lever and was measured net-negative as the cold-CI path. Incrementality (don't resolve what didn't change) is upstream of caching (memoize what repeats); the <1min target rides the former. **This re-frames the §2 "core ask" — operator review.** @@ -108,9 +108,9 @@ A flaky or green-but-broken floor means no gate protects anything — so CI is u **What's on `.dag` today (the gap map — detail in the charter §2/§4):** -- [x] **execution = a dependency-graph walk** — `claim_executor` interprets `ci_floor_plan.dag`; one fold, batches from dependency edges (the realest layer) -- [x] **scheduling: width axis** (#5444) — `memory_aware_spawn_width` consumes the measured envelope; single-host -- [x] **Section 1 spawn-width foundation — std.measure expressibility** (#5470/#5478) — the FLOOR family (measure_scale_fraction_floor + measure_fit_count_floor) and the demand-CEIL family completing the ceil-not-equal-floor money-pair landed, dissolving the measure unwrap→raw-arith→rewrap §3 fork. Authority: the expressibility-frontier spec #5467 [plan](docs/plans/expressibility-frontier.md) +- [ ] **execution = a dependency-graph walk** — `claim_executor` interprets `ci_floor_plan.dag`; one fold, batches from dependency edges (the realest layer) — ⏳ awaiting sign-off +- [ ] **scheduling: width axis** (#5444) — `memory_aware_spawn_width` consumes the measured envelope; single-host — ⏳ awaiting sign-off +- [ ] **Section 1 spawn-width foundation — std.measure expressibility** (#5470/#5478) — the FLOOR family (measure_scale_fraction_floor + measure_fit_count_floor) and the demand-CEIL family completing the ceil-not-equal-floor money-pair landed, dissolving the measure unwrap→raw-arith→rewrap §3 fork. Authority: the expressibility-frontier spec #5467 [plan](docs/plans/expressibility-frontier.md) — ⏳ awaiting sign-off - [ ] **scheduling: placement + materialization inert** — `Placement`/`Materialization` modeled + witness-passing, **no live consumer** (same band as the host-ops gap, substrate side) - [ ] **scheduling: resource-aware (larger allocation → larger throughput)** — `spawn_width` is a side-channel derived from a static data row (`gunbc_ci_floor_measured_peak`, coarse whole_run÷concurrency estimate); goal: width derived from per-`Runnable` cost in the plan itself, self-calibrating from measured per-shard RSS. Four nodes: (A) measurement plumbing — claim_batch emits `[measurement] per-shard-peak-rss`, claim_executor collects max *(dispatched adhoc-97532cd3-dfe)*; (B) `CostEstimate.space` on `Runnable` in std; (C) scheduler reads cost → derives width, side-channel deleted; (D) calibration loop retires static data rows. Construction invariant: host memory increase → higher width → more throughput, no `.dag` edits required. [plan](docs/plans/resource-aware-scheduler.md) - [ ] **caching forked** — sccache live · resolve-cache **opt-in (`GUNBC_RESOLVED_GRAPH_CACHE_DIR`; #5789 always-on default reverted — its whole-file JSON read/write OOMs the floor, must stream before it can default on)** · ParseTable memo live · RecordedFixture · BuildBuddy opt-in → converge on `realize(subject)` (§2 P2) @@ -133,7 +133,7 @@ A flaky or green-but-broken floor means no gate protects anything — so CI is u - [ ] **interpreter terminal-output de-fork** — the seed interpreter's CLI rendering (`v1_interpreter.rs` sgr/color_enabled/cli_verbosity/render_shell_trace, `claim_executor.rs` result lines) is a hand-Rust realization of three `.dag` authorities it does not yet consume: `extdeps.render.ansi.ansi_mappings` (SGR codes), `extdeps.render.terminal_capability.detect_capability` (NO_COLOR/CI/TTY to color), and `gunbc.output_policy` (resolve_verbosity precedence, channel_decision, env_var_for dispatch, shell_trace_summary_max_columns cap). §3 single-authority: the parallel representation can drift until the interpreter reads these tables. Dissolve-on: interpreter consumes the .dag render/output-policy tables at runtime (same class as CI inline-shell de-fork — seed forks the modeled authority; one home each). [plan](dsl/gunbc/output_policy.dag) - [ ] **G5 rust-gate selection** — rust fmt/clippy/run-all is all-or-nothing on `.rs` PRs; no affected-set (the `.dag` floor already has one) [plan](docs/plans/ci-selection-vs-scheduling.md) - [ ] **floor runs the right things** — SELECTION (what changed) vs SCHEDULING (by cost); cost never drives selection [plan](docs/plans/ci-selection-vs-scheduling.md) - - [x] opt-level=3 restores Pop-A to per-PR (#5456) — merged + - [ ] opt-level=3 restores Pop-A to per-PR (#5456) — merged — ⏳ awaiting sign-off - [ ] per-PR = #5427 run-all sound baseline, shrunk to the affected set (#5427) - [ ] nightly = full-corpus selector-backstop + non-hermetic residue (#5447 stood down; ⚠ CI-gen load-bearing) *(quick-ant-298)* - [ ] **tree-scoped builtin registry** (fail-closed) — global seed registry leaks intrinsics into the substrate compile; instance fix #5452, class fix (partition) open *(quick-ant-298)* [force-check plan](docs/plans/compile-clean-forcecheck.md) @@ -148,7 +148,7 @@ A flaky or green-but-broken floor means no gate protects anything — so CI is u **Downstream / parked:** -- [x] privacy (compute fabric) +- [ ] privacy (compute fabric) — ⏳ awaiting sign-off - [ ] repo model (internal repo) on compute fabric - [ ] **gunbhub** — own the Git/CI engine (closes G6, the irreducible GitHub boundary); not pressing - [ ] *(downstream)* compute fabric as a sellable infra piece @@ -159,9 +159,9 @@ Gate: uncached non-redundant work is an ERROR, not "slow". The cache-key-from-in **◆ Milestones:** key-by-construction ✓ (#5425) → **▸ warm==cold purity proven (616/616, #5429)** → resolve-cache ON — ~18% floor cut *(core ask)* → native `content(T)` *(gated B2)* -- [x] F1 scheduler gives heavy nodes budgeted width (#5421) -- [x] F2/F3 `resolved_graph` key derived from declared `inputs_considered` (#5425) — construction, not a lens - - [x] P1 honest keys by construction — warm==cold purity oracle **LANDED (#5429)** +- [ ] F1 scheduler gives heavy nodes budgeted width (#5421) — ⏳ awaiting sign-off +- [ ] F2/F3 `resolved_graph` key derived from declared `inputs_considered` (#5425) — construction, not a lens — ⏳ awaiting sign-off + - [ ] P1 honest keys by construction — warm==cold purity oracle **LANDED (#5429)** — ⏳ awaiting sign-off - [ ] P2 one door: `realize(subject)` sole API — kernel inhabits `cache_interface.dag` (#5446); ParseTable dissolution is downstream of the dsl→v2 de-fork (§5) - hermetic fixtures feed P2: [x] M4.1 universal hermetic corpus governance (#5236, [plan](docs/plans/m4-universal-hermetic-corpus.md)); [ ] M5 fixture-store onto one Realization kernel ([plan](docs/plans/m5-fixture-store-consolidation.md)) - [ ] P3 **resolve-cache enable** — purity proven (616/616); cache is correct but **opt-in** (`GUNBC_RESOLVED_GRAPH_CACHE_DIR`): #5789's always-on `$TMPDIR` default was reverted because the whole-file JSON read (hit) and write (miss) buffer ~11x the packed graph in memory and OOM the concurrent-shard floor. Re-enabling by default is gated on a streaming IO realization (binary + `deserialize_from`/`serialize_into`, no whole-file `Vec`) @@ -176,8 +176,8 @@ Operator decision (2026-06-21): budget-gate validation is the in-window tool; th **◆ Milestones:** budget-gate non-toothless ✓ (#5437) → complexity gates the whole codebase *(gated on §5 fn-body reflection)* -- [x] complexity lens total over the kernel (cost.dag U2); the gate runs a curated subject roster -- [x] cost-lens zero-absorption fix — budgets non-toothless (#5437) +- [ ] complexity lens total over the kernel (cost.dag U2); the gate runs a curated subject roster — ⏳ awaiting sign-off +- [ ] cost-lens zero-absorption fix — budgets non-toothless (#5437) — ⏳ awaiting sign-off - [ ] a subject-producer for every fn (#5437 helper; whole-corpus needs fn-body reflection) - [ ] complexity budget gates the whole codebase (gated on fn-body reflection) - [ ] synthesis stays advisory (by Rice, optimality is a ratchet not a wall — DESIGN §5) @@ -192,14 +192,14 @@ Prevent the next class, not the last instance: generate witnesses from declared Motivating instance: a prod rotation 401'd `CREDENTIALS_MISSING` because `auth_input: access_token` was modeled (§3-correct) but the interpreter REST realization (`resolve_auth`) only realizes the env-var path — a declared input wired into nothing, typechecking but dead, and the only "auth tests" were `.contains("Bearer")` greps on emitted source (§5 spec-without-execution). The general class is **wiring-liveness**: a declared input must influence the output it feeds — the cache-purity oracle read backwards (purity: *same* in ⇒ *same* out; liveness: *different* in ⇒ *different* out — one perturbation kernel, two readings). → [audit + design](docs/plans/wiring-liveness-preflight.md) -- [x] gate the generated output (#5434) — floor-discover `generated/` (or regen==committed drift gate) -- [x] CoproductExhaustiveness made structural (#5441) — over every declared coproduct, not a hand-roster -- [x] cross-representation-equality category (#5449) — straddle witness per coproduct × native realization -- [x] **the oracle method (retro)** (#5471) — bug-class→mechanism map (generator/lens/wall); testgen owns A + B-routing only, rest are lenses/walls ([map](docs/plans/testgen-oracle.md) §2) -- [x] affected-set = the completeness half (#5430) — model the full repo-process universe — frontier now has a paying consumer: the wiring residue-preflight (below) +- [ ] gate the generated output (#5434) — floor-discover `generated/` (or regen==committed drift gate) — ⏳ awaiting sign-off +- [ ] CoproductExhaustiveness made structural (#5441) — over every declared coproduct, not a hand-roster — ⏳ awaiting sign-off +- [ ] cross-representation-equality category (#5449) — straddle witness per coproduct × native realization — ⏳ awaiting sign-off +- [ ] **the oracle method (retro)** (#5471) — bug-class→mechanism map (generator/lens/wall); testgen owns A + B-routing only, rest are lenses/walls ([map](docs/plans/testgen-oracle.md) §2) — ⏳ awaiting sign-off +- [ ] affected-set = the completeness half (#5430) — model the full repo-process universe — frontier now has a paying consumer: the wiring residue-preflight (below) — ⏳ awaiting sign-off - [ ] *anemia lens?* (parked, DESIGN §2 leaf-side) — likely advisory, not a hard gate; decide whether to elevate - [ ] **wiring-liveness oracle** — a declared input must influence its output; the cache-purity oracle read backwards (perturbation-response, one kernel two readings). Decidability split (§5): static dataflow reachability over the Node DAG is the **compile-time wall** (declared input with no path to an output = unwired → fail compilation, no runtime gate); perturbation/fuzz is the runtime **confirmation** for the opaque-seed residue (`resolve_auth` is Rust, invisible to `.dag` reflection today). [plan](docs/plans/wiring-liveness-preflight.md) - - [x] **pre-send fail-closed guard** (narrowest seam) — declared-auth-but-no-token ⇒ typed `AuthDeclaredButUnwired` refusal before send. **LANDED (#5683)** — fail-closed typed error before the request leaves `dispatch_rest`, never a remote 401; perturb-confirmed (drop the token → typed error) + - [ ] **pre-send fail-closed guard** (narrowest seam) — declared-auth-but-no-token ⇒ typed `AuthDeclaredButUnwired` refusal before send. **LANDED (#5683)** — fail-closed typed error before the request leaves `dispatch_rest`, never a remote 401; perturb-confirmed (drop the token → typed error) — ⏳ awaiting sign-off - [ ] **wiring lens — static reachability, compile-time** — over `.dag`-modeled input→output relations; fails compilation on a dead wire. **Wave-1 LANDED (#5679): reachability kernel + wired floor witness.** Primary mechanism; grows to subsume the seed realizations as they self-host (§5/§7) - [ ] **wiring witness — opaque-realization generator** — perturbation witness over declared service input→request relations; RED when an input is dropped (the execution-grounded generalization of the auth case, for realizations the compile-time lens can't see) - [ ] **runtime preflight — residue only** — run the wiring check over the `affected_set` `ReExecFrontier` (the about-to-run slice) before execution; `FailClosed` on a dead wire. Needed only for opaque realizations; dissolves into the compile-time lens as they self-host @@ -215,16 +215,16 @@ Adjacent lane — algorithmic-cost rewrite engine (the §3 construction design; - [ ] rewrite suboptimal patterns to the cheaper equivalent (`O(n²)→O(n)` …) — published finite catalog, bulletproof where it fires - [ ] `Unknown` dissolved over time as an anemic atom (reuse the `Disposition` carrier) - [ ] `O(n^x)→O(n log n)` substitution as per-idiom rules (candidate shared framing: **redundant intent** — the anti-unification generalization measures `spec − minimal`; see §0 self-applying lenses) -- [x] front-end (parse / resolve / infer) over the whole tree -- [x] emit whole tree `--target rust` (well-typed under CI gate) +- [ ] front-end (parse / resolve / infer) over the whole tree — ⏳ awaiting sign-off +- [ ] emit whole tree `--target rust` (well-typed under CI gate) — ⏳ awaiting sign-off - [ ] de-fork dsl ↔ v2 (one std authority) — **grounding cluster UNPARKED: operator ruled FreeMonoid/algebra single authority** (coproduct = structural authority; dsl record-surface derived-from-inhabitance; grounded-realization wins) → de-fork + self-host fused into one grounding lane ([brief](docs/plans/dsl-v2-defork-audit.md) §3b) - - [x] turn on cross-tree import — Step 1 **LANDED** (#5473) - - [x] **Root A — emit-seam grounding ✓ LANDED (#5734)**: String/`FreeMonoid`→host `Vec` via the #5428 `RustCorpusRepr` seam; drove HostNative cargo-green *(jolly-cat)* + - [ ] turn on cross-tree import — Step 1 **LANDED** (#5473) — ⏳ awaiting sign-off + - [ ] **Root A — emit-seam grounding ✓ LANDED (#5734)**: String/`FreeMonoid`→host `Vec` via the #5428 `RustCorpusRepr` seam; drove HostNative cargo-green *(jolly-cat)* — ⏳ awaiting sign-off - [ ] **Root B — generic-inference keystone ✓ MERGED (#5552)** → def-unification (coproduct authority + aliases) → repoints (algebra/nat/integer/float/logic/effects/verification) → 🟡-marker dissolution *(bright-deer-111)* - [ ] v1-coupled `coercion`/`node` renames — deferred to v1-delete -- [x] **emitted crate `cargo build`s green (Route-A last mile) ✓ LANDED (#5777/#5873)** — execution-grounded **re-census CONFIRMED 0 TOTAL errors** (cool-hawk-908: `regen_stage0 --emit-fresh` → `cargo build` debug+release, 2026-06-28). **REFUTED** the stale 'residual 2 = E0091×2' hypothesis: #5777 cleared E0599/E0624 **and** E0091 (`alias_unused_param_names` → `PhantomData` for unused type-alias params; `type_alias_phantom_param_test` witnesses). Trajectory: 647 E0308 → 0 (#5716/#5718/#5717) → ~32 other-family → 5 TOTAL → **0 TOTAL** (#5777). #5873: two-generation regen cutover + `regen --verify` CI gate. Compose emits `PhantomData<(Algebra, MachineConstraint)>`. Model hole stays flagged: pipe-first `OptionalOf` unwrap follow-up owed upstream (`Value::Null` runway). *(jolly-cat #5705/#5716/#5718 + cool-hawk-908 re-census)* +- [ ] **emitted crate `cargo build`s green (Route-A last mile) ✓ LANDED (#5777/#5873)** — execution-grounded **re-census CONFIRMED 0 TOTAL errors** (cool-hawk-908: `regen_stage0 --emit-fresh` → `cargo build` debug+release, 2026-06-28). **REFUTED** the stale 'residual 2 = E0091×2' hypothesis: #5777 cleared E0599/E0624 **and** E0091 (`alias_unused_param_names` → `PhantomData` for unused type-alias params; `type_alias_phantom_param_test` witnesses). Trajectory: 647 E0308 → 0 (#5716/#5718/#5717) → ~32 other-family → 5 TOTAL → **0 TOTAL** (#5777). #5873: two-generation regen cutover + `regen --verify` CI gate. Compose emits `PhantomData<(Algebra, MachineConstraint)>`. Model hole stays flagged: pipe-first `OptionalOf` unwrap follow-up owed upstream (`Value::Null` runway). *(jolly-cat #5705/#5716/#5718 + cool-hawk-908 re-census)* — ⏳ awaiting sign-off - [ ] real fixed point: `content_hash` stage1==stage2 (dissolve placeholder hashes) - - [x] wire `regen_stage0 --verify` lockstep gate into CI — enforces no hand-edits to **generated** stage0 files (`GENERATED_STAGE0_FILES`); `HAND_MAINTAINED_STAGE0_FILES` are copied through, excluded by design ← **keystone** + - [ ] wire `regen_stage0 --verify` lockstep gate into CI — enforces no hand-edits to **generated** stage0 files (`GENERATED_STAGE0_FILES`); `HAND_MAINTAINED_STAGE0_FILES` are copied through, excluded by design ← **keystone** — ⏳ awaiting sign-off - [ ] dissolve seed hand-patches (`patch_*` / `HAND_MAINTAINED_STAGE0_FILES`) — the `emit_rust` hand-sync caveat the gate reproduces (the required-facts plan is dissolved into the executable `RegenVerifyGate`) - [ ] **TypeScript self-host (own lane)** — emit the compiler ITSELF as TypeScript and reproduce a per-realization merkle fixed point (the Rust `regen --verify` gate, mirrored for the TS realization). This is what makes "language design collapses to a row" real at full scale — §7 medium-agnostic proof, emit Rust *and* TypeScript, fixed point *per realization*. `5-ts-first-class` is the emit seed; this is the self-host. Gated on the Rust fixed point. - [ ] TypeScript to first-class (beyond the `add` slice) — the emit SEED. **In progress: Char atom-realization + green typed-fn emit (#5695), FieldAccess + RecordConstruct + `tsc --noEmit` oracle (#5701), operators by inhabitance (#5704)** @@ -237,8 +237,8 @@ A program is a canonical `Node` (the *idea*); ingest / emit / eval across many m **◆ Milestones:** medium axis ✓ → language axis: English ingest round-trip → cross-media first-class (JSON/react/diagram) → invert hand-maintained: ROADMAP emitted + drift-gated -- [x] **medium axis** — `Medium` + `DecodeFidelity`; `LanguageModel` unified (13 forks dissolved); `compile(Eval) → EvalResult{value: Medium}` -- [x] **round-trip law (ingest∘emit = id, DecodeFidelity-bounded)** (#5525/#5527) — established across two structurally-different media: markdown (block-document) and GHA-expr (recursive-expression). v2-TargetModel convergence is the deferred single-authority destination; per-medium round-trips are v1-seed interim. Authority for the law: the round-trip oracle #5513 §5.2 [plan](docs/plans/emission-ingestion-inverse.md) +- [ ] **medium axis** — `Medium` + `DecodeFidelity`; `LanguageModel` unified (13 forks dissolved); `compile(Eval) → EvalResult{value: Medium}` — ⏳ awaiting sign-off +- [ ] **round-trip law (ingest∘emit = id, DecodeFidelity-bounded)** (#5525/#5527) — established across two structurally-different media: markdown (block-document) and GHA-expr (recursive-expression). v2-TargetModel convergence is the deferred single-authority destination; per-medium round-trips are v1-seed interim. Authority for the law: the round-trip oracle #5513 §5.2 [plan](docs/plans/emission-ingestion-inverse.md) — ⏳ awaiting sign-off - [ ] **ingestion as a first-class direction** — fold foreign surface INTO the node tree (the inverse of emit): `Lossless` where decidable, fail-closed `DecodeFidelity` where not, and **emit = ingest⁻¹ over ONE `GrammarRelation`** (§4: one grammar read both directions; the §7 "any language with a typed honesty boundary" payoff). Emission is well-covered (round-trip law, language axis); ingest *at large* — beyond the per-medium round-trips — has no lane. (the comment parser-wall #5579 is one corner of the construction direction; ingest-at-large needs an owner.) [plan](docs/plans/emission-ingestion-inverse.md) - [ ] **language axis** — 15+ targets wave-1; English emit proven - [ ] English vocabulary closure → fail-closed English ingest (today's catch-all is fail-open; also §0) @@ -249,7 +249,7 @@ A program is a canonical `Node` (the *idea*); ingest / emit / eval across many m - [ ] `FidelityDisposition` compose-up → medium-level `DecodeFidelity` - [ ] eval runtime generalization (wave-1 literal pins → `wave1_model_core` primitives) - [ ] **invert hand-maintained artifacts** — emit each (ROADMAP flagship · doc indexes) from its `.dag` authority + drift-gate it (the ci.yml pattern) [plan](docs/plans/invert-hand-maintained.md) - - [x] **PR→checkbox status + section-emit + projection layer** (#5491/#5508/#5520) — box derived from an explicit *completes-iff-PR* binding (not mere mention), drift-gated; slice-1 status derivation + slice-2 section-emit + step-3a whole-document projection landed; #5513 medium-as-Node operative as the acceptance test [plan](docs/plans/invert-hand-maintained.md) + - [ ] **PR→checkbox status + section-emit + projection layer** (#5491/#5508/#5520) — box derived from an explicit *completes-iff-PR* binding (not mere mention), drift-gated; slice-1 status derivation + slice-2 section-emit + step-3a whole-document projection landed; #5513 medium-as-Node operative as the acceptance test [plan](docs/plans/invert-hand-maintained.md) — ⏳ awaiting sign-off ## 7. HTML / React rendering (expansion — the "website" sellable piece) diff --git a/dsl/test/claim/roadmap_document_test.dag b/dsl/test/claim/roadmap_document_test.dag index cc5508cec05..73c61e3f93e 100644 --- a/dsl/test/claim/roadmap_document_test.dag +++ b/dsl/test/claim/roadmap_document_test.dag @@ -2,8 +2,8 @@ module test.claim.roadmap_document import extdeps.languages.markdown { serialize_markdown_source } import gunbc.roadmap_document { RoadmapDocument, RoadmapSection, project_roadmap_to_markdown } -import gunbc.roadmap_model { RoadmapNode, RoadmapEdge, Pointer, SectionElement, section_group } -import gunbc.roadmap_status { RoadmapItem, DerivableLine, AuthoredLine } +import gunbc.roadmap_model { RoadmapNode, RoadmapEdge, Pointer, NodeSizing, Unsized, SectionElement, section_group } +import gunbc.roadmap_status { RoadmapItem, DerivableLine, AuthoredLine, Signoff, Unsigned, SignedOff } import std.markdown { MarkdownBlock, HeadingBlock, ParagraphBlock, TextInline, H1 } import ctrl.process_algebra { ProcessNodeId } @@ -16,6 +16,9 @@ fn audit_node() -> RoadmapNode { node: audit_id, line: AuthoredLine { done: true, content: "**fail-open audit**" }, carriers: [Pointer { label: "plan", path: "docs/plans/fail-closed-lockdown.md" }], + sizing: Unsized, + owner: "", + signoff: Unsigned, } } @@ -24,6 +27,9 @@ fn status_node() -> RoadmapNode { node: status_id, line: DerivableLine { prs: [5491], title: "**PR-checkbox status**", description: "" }, carriers: [], + sizing: Unsized, + owner: "", + signoff: Unsigned, } } fn child_node() -> RoadmapNode { @@ -31,6 +37,9 @@ fn child_node() -> RoadmapNode { node: child_id, line: AuthoredLine { done: false, content: "**host-fed status bridge**" }, carriers: [], + sizing: Unsized, + owner: "", + signoff: Unsigned, } } @@ -78,14 +87,18 @@ fn witness_both_sections() -> Bool { && string_contains(s: out, pattern: "## 6. Expansion") } -fn witness_authored_box_and_link() -> Bool { +fn witness_authored_evidence_awaiting_signoff() -> Bool { let out = emit(merged: [5491]) - string_contains(s: out, pattern: "[x] **fail-open audit**") + string_contains(s: out, pattern: "[ ] **fail-open audit**") && string_contains(s: out, pattern: "[plan](docs/plans/fail-closed-lockdown.md)") + && string_contains(s: out, pattern: "⏳ awaiting sign-off") } -fn witness_derived_checked_when_merged() -> Bool { - string_contains(s: emit(merged: [5491]), pattern: "[x] **PR-checkbox status**") +fn witness_derived_merged_awaiting_signoff() -> Bool { + let out = emit(merged: [5491]) + string_contains(s: out, pattern: "[ ] **PR-checkbox status**") + && string_contains(s: out, pattern: "⏳ awaiting sign-off") + && !string_contains(s: out, pattern: "[x] **PR-checkbox status**") } fn witness_derived_unchecked_when_unmerged() -> Bool { @@ -102,11 +115,11 @@ fn expected_roadmap() -> String { "\n", "## 0. Fail-closed lock-down\n", "\n", - "- [x] **fail-open audit** [plan](docs/plans/fail-closed-lockdown.md)\n", + "- [ ] **fail-open audit** [plan](docs/plans/fail-closed-lockdown.md) — ⏳ awaiting sign-off\n", "\n", "## 6. Expansion\n", "\n", - "- [x] **PR-checkbox status** (#5491)\n", + "- [ ] **PR-checkbox status** (#5491) — ⏳ awaiting sign-off\n", " - [ ] **host-fed status bridge**\n" ], "") } @@ -123,8 +136,8 @@ fn witness_drift_receipt() -> Bool { test fn roadmap_document_witnesses() -> Bool { witness_preamble_first() && witness_both_sections() - && witness_authored_box_and_link() - && witness_derived_checked_when_merged() + && witness_authored_evidence_awaiting_signoff() + && witness_derived_merged_awaiting_signoff() && witness_derived_unchecked_when_unmerged() && witness_exact_bytes() && witness_drift_receipt() diff --git a/dsl/test/claim/roadmap_emit_test.dag b/dsl/test/claim/roadmap_emit_test.dag index cfc54109c15..39a7d482bdd 100644 --- a/dsl/test/claim/roadmap_emit_test.dag +++ b/dsl/test/claim/roadmap_emit_test.dag @@ -2,8 +2,8 @@ module test.claim.roadmap_emit import extdeps.languages.markdown { serialize_markdown_source } import gunbc.roadmap_emit { project_roadmap_section } -import gunbc.roadmap_model { RoadmapNode, RoadmapEdge, Pointer, SectionElement, section_group } -import gunbc.roadmap_status { RoadmapItem, DerivableLine, AuthoredLine } +import gunbc.roadmap_model { RoadmapNode, RoadmapEdge, Pointer, NodeSizing, Unsized, SectionElement, section_group } +import gunbc.roadmap_status { RoadmapItem, DerivableLine, AuthoredLine, Signoff, Unsigned, SignedOff } import ctrl.process_algebra { ProcessNodeId } data parent_id: ProcessNodeId = "invert-hand-maintained" @@ -14,6 +14,9 @@ fn parent_node() -> RoadmapNode { node: parent_id, line: AuthoredLine { done: false, content: "**invert hand-maintained**" }, carriers: [Pointer { label: "plan", path: "docs/plans/invert-hand-maintained.md" }], + sizing: Unsized, + owner: "", + signoff: Unsigned, } } @@ -22,6 +25,20 @@ fn child_node() -> RoadmapNode { node: child_id, line: DerivableLine { prs: [5491], title: "**PR-checkbox status**", description: "" }, carriers: [], + sizing: Unsized, + owner: "", + signoff: Unsigned, + } +} + +fn signed_child_node() -> RoadmapNode { + RoadmapNode { + node: child_id, + line: DerivableLine { prs: [5491], title: "**PR-checkbox status**", description: "" }, + carriers: [], + sizing: Unsized, + owner: "", + signoff: SignedOff { by: "operator", works: true, scope_equivalent: true, as_expected: true }, } } @@ -30,12 +47,16 @@ fn edges() -> List { [RoadmapEdge { child: child_id, parent: parent fn elements() -> List { [section_group(label: "", nodes: nodes(), edges: edges())] } -fn emit(merged: List) -> String { +fn emit_nodes(nodes: List, merged: List) -> String { serialize_markdown_source(doc: project_roadmap_section( - title: "6. Expansion", elements: elements(), merged: merged, + title: "6. Expansion", elements: [section_group(label: "", nodes: nodes, edges: edges())], merged: merged, )) } +fn emit(merged: List) -> String { + emit_nodes(nodes: nodes(), merged: merged) +} + fn witness_heading() -> Bool { string_contains(s: emit(merged: [5491]), pattern: "## 6. Expansion") } @@ -46,19 +67,30 @@ fn witness_parent_authored_box_and_link() -> Bool { && string_contains(s: out, pattern: "[plan](docs/plans/invert-hand-maintained.md)") } -fn witness_child_derived_checked_when_merged() -> Bool { - string_contains(s: emit(merged: [5491]), pattern: "[x] **PR-checkbox status**") +fn witness_child_merged_unsigned_awaiting_signoff() -> Bool { + let out = emit(merged: [5491]) + string_contains(s: out, pattern: "[ ] **PR-checkbox status**") + && string_contains(s: out, pattern: "⏳ awaiting sign-off") + && !string_contains(s: out, pattern: "[x] **PR-checkbox status**") +} + +fn witness_child_signed_checked() -> Bool { + let out = emit_nodes(nodes: [parent_node(), signed_child_node()], merged: []) + string_contains(s: out, pattern: "[x] **PR-checkbox status**") + && string_contains(s: out, pattern: "✓ signed off: operator") } fn witness_child_derived_unchecked_when_unmerged() -> Bool { let out = emit(merged: []) string_contains(s: out, pattern: "[ ] **PR-checkbox status**") && !string_contains(s: out, pattern: "[x] **PR-checkbox status**") + && !string_contains(s: out, pattern: "⏳ awaiting sign-off") } test fn roadmap_emit_witnesses() -> Bool { witness_heading() && witness_parent_authored_box_and_link() - && witness_child_derived_checked_when_merged() + && witness_child_merged_unsigned_awaiting_signoff() + && witness_child_signed_checked() && witness_child_derived_unchecked_when_unmerged() } diff --git a/dsl/test/claim/roadmap_gate_test.dag b/dsl/test/claim/roadmap_gate_test.dag index 74c96cbf72c..6a2fa40734b 100644 --- a/dsl/test/claim/roadmap_gate_test.dag +++ b/dsl/test/claim/roadmap_gate_test.dag @@ -1,41 +1,71 @@ module test.claim.roadmap_gate import extdeps.languages.markdown { serialize_markdown_source } -import gunbc.roadmap_document { project_roadmap_to_markdown } +import gunbc.roadmap_document { RoadmapDocument, RoadmapSection, project_roadmap_to_markdown } +import gunbc.roadmap_model { RoadmapNode, SectionElement, section_group } import gunbc.roadmap_authority { - roadmap_authority, authored_merged_prs, expected_roadmap_md, roadmap_drifted, + expected_roadmap_md, roadmap_drifted, + derivable, sign, signed, } -fn emit_dropping_measure() -> String { - let perturbed = [5428, 5445, 5453, 5433, 5476, 5473, 5456, 5421, 5425, 5236, - 5437, 5434, 5441, 5449, 5471, 5430, 5481, 5491, 5508, 5520, 5525, 5527, 5444] - serialize_markdown_source(doc: project_roadmap_to_markdown(doc: roadmap_authority(), merged: perturbed)) +fn mini_doc(node: RoadmapNode) -> RoadmapDocument { + RoadmapDocument { + preamble: [], + lead_lanes: [], + sections: [RoadmapSection { + title: "Sign-off gate", + elements: [section_group(label: "", nodes: [node], edges: [])], + }], + } } -fn witness_clean_not_drift() -> Bool { - !roadmap_drifted(committed: expected_roadmap_md()) +fn emit_node(node: RoadmapNode, merged: List) -> String { + serialize_markdown_source(doc: project_roadmap_to_markdown(doc: mini_doc(node: node), merged: merged)) } -fn witness_set_perturbation_drifts() -> Bool { - let dropped = emit_dropping_measure() - roadmap_drifted(committed: dropped) - && string_contains(s: dropped, pattern: "- [ ] **Section 1 spawn-width foundation — std.measure expressibility** (#5470/#5478)") - && !string_contains(s: dropped, pattern: "- [x] **Section 1 spawn-width foundation — std.measure expressibility** (#5470/#5478)") - && string_contains(s: expected_roadmap_md(), pattern: "- [x] **Section 1 spawn-width foundation — std.measure expressibility** (#5470/#5478)") +fn witness_clean_not_drift() -> Bool { + !roadmap_drifted(committed: expected_roadmap_md()) } fn witness_hand_edit_drifts() -> Bool { roadmap_drifted(committed: concat(expected_roadmap_md(), "\n- [x] **a hand-added line**")) } -fn witness_authored_set_nonvacuous() -> Bool { - count(authored_merged_prs()) > 0 - && string_contains(s: expected_roadmap_md(), pattern: "- [x] **numeric-tower grounding** (#5428)") +fn witness_signed_emits_checked() -> Bool { + let node = sign( + rn: derivable(id: "signoff-witness", prs: [5491], title: "**signoff witness**", description: ""), + s: signed(by: "operator", works: true, scope_equivalent: true, as_expected: true), + ) + let out = emit_node(node: node, merged: []) + string_contains(s: out, pattern: "[x] **signoff witness**") + && string_contains(s: out, pattern: "✓ signed off: operator") +} + +fn witness_unsigned_with_evidence_awaiting() -> Bool { + let node = derivable(id: "signoff-witness", prs: [5491], title: "**signoff witness**", description: "") + let out = emit_node(node: node, merged: [5491]) + string_contains(s: out, pattern: "[ ] **signoff witness**") + && string_contains(s: out, pattern: "⏳ awaiting sign-off") + && !string_contains(s: out, pattern: "[x] **signoff witness**") +} + +fn witness_merge_perturb_does_not_flip_box() -> Bool { + let signed_node = sign( + rn: derivable(id: "signoff-witness", prs: [5491], title: "**signoff witness**", description: ""), + s: signed(by: "operator", works: true, scope_equivalent: true, as_expected: true), + ) + let unsigned_node = derivable(id: "signoff-witness", prs: [5491], title: "**signoff witness**", description: "") + let signed_stays_checked = string_contains(s: emit_node(node: signed_node, merged: []), pattern: "[x] **signoff witness**") + && string_contains(s: emit_node(node: signed_node, merged: [5491]), pattern: "[x] **signoff witness**") + let unsigned_stays_unchecked = string_contains(s: emit_node(node: unsigned_node, merged: []), pattern: "[ ] **signoff witness**") + && string_contains(s: emit_node(node: unsigned_node, merged: [5491]), pattern: "[ ] **signoff witness**") + signed_stays_checked && unsigned_stays_unchecked } test fn roadmap_gate_witnesses() -> Bool { witness_clean_not_drift() - && witness_set_perturbation_drifts() && witness_hand_edit_drifts() - && witness_authored_set_nonvacuous() + && witness_signed_emits_checked() + && witness_unsigned_with_evidence_awaiting() + && witness_merge_perturb_does_not_flip_box() } diff --git a/dsl/test/claim/roadmap_model_test.dag b/dsl/test/claim/roadmap_model_test.dag index fa0a9e1f3e2..421450efb30 100644 --- a/dsl/test/claim/roadmap_model_test.dag +++ b/dsl/test/claim/roadmap_model_test.dag @@ -9,10 +9,12 @@ import gunbc.roadmap_model { Pointer, RoadmapNode, RoadmapEdge, RoadmapParent, TopLevel, UnderParent, + NodeSizing, Unsized, roadmap_parent, is_top_level, node_carrier_clean, node_status_drift, } +import gunbc.roadmap_status { Signoff, Unsigned } data parent_node: ProcessNodeId = "invert-hand-maintained" data child_node: ProcessNodeId = "pr-checkbox-status" @@ -54,6 +56,9 @@ fn node_with_carriers(cs: List) -> RoadmapNode { node: child_node, line: AuthoredLine { done: false, content: "PR→checkbox status" }, carriers: cs, + sizing: Unsized, + owner: "", + signoff: Unsigned, } } @@ -80,17 +85,27 @@ fn witness_node_status_drifts() -> Bool { node: child_node, line: DerivableLine { prs: [5491], title: "stale", description: "" }, carriers: [], + sizing: Unsized, + owner: "", + signoff: Unsigned, } - verdict_is_drifted(v: node_status_drift(rn: rn, committed_box: false, merged: [5491])) + verdict_is_drifted(v: node_status_drift(rn: rn, committed_box: true, merged: [5491])) } -fn witness_node_authored_underivable() -> Bool { +fn witness_node_unsigned_box_clean() -> Bool { let rn = RoadmapNode { node: child_node, line: AuthoredLine { done: false, content: "partial evidence" }, carriers: [], + sizing: Unsized, + owner: "", + signoff: Unsigned, + } + match node_status_drift(rn: rn, committed_box: false, merged: [5491]) { + Clean => true + Drifted => false + Underivable => false } - verdict_is_underivable(v: node_status_drift(rn: rn, committed_box: false, merged: [5491])) } test fn roadmap_model_witnesses() -> Bool { @@ -101,5 +116,5 @@ test fn roadmap_model_witnesses() -> Bool { && witness_dangling_carrier_caught() && witness_no_carrier_clean() && witness_node_status_drifts() - && witness_node_authored_underivable() + && witness_node_unsigned_box_clean() } diff --git a/dsl/test/claim/roadmap_spawner_witness_test.dag b/dsl/test/claim/roadmap_spawner_witness_test.dag index 032b3da6e54..ac15937e7a5 100644 --- a/dsl/test/claim/roadmap_spawner_witness_test.dag +++ b/dsl/test/claim/roadmap_spawner_witness_test.dag @@ -8,7 +8,7 @@ import gunbc.roadmap_model { NodeSizing, Unsized, Sized, SectionElement, Group, SectionGroup, } -import gunbc.roadmap_status { DerivableLine, AuthoredLine } +import gunbc.roadmap_status { DerivableLine, AuthoredLine, Signoff, Unsigned } import gunbc.roadmap_document { RoadmapDocument, RoadmapSection } import gunbc.roadmap_spawner { next_spawnable, roadmap_spawn_request_json } @@ -20,6 +20,8 @@ fn sized_derivable(id: String, prs: List, title: String) -> RoadmapNode { line: DerivableLine { prs: prs, title: title, description: "" }, carriers: [], sizing: Sized { intricacy: IntricacyHigh, volume: VolumeMedium, repo: "gunbc", acceptance: PrsMerged }, + owner: "", + signoff: Unsigned, } } @@ -29,6 +31,8 @@ fn unsized_derivable(id: String, prs: List, title: String) -> RoadmapNode { line: DerivableLine { prs: prs, title: title, description: "" }, carriers: [], sizing: Unsized, + owner: "", + signoff: Unsigned, } } From c55f0e607e34a9e70567453d28d075c2ef936946 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Mon, 29 Jun 2026 21:52:20 +0000 Subject: [PATCH 4/4] fix(roadmap): align authority witnesses with signoff-driven closure Update roadmap_authority_test for the sign-off mechanism: landed items render [ ] + awaiting sign-off, and perturbing the merged PR set no longer flips checkboxes (merge is evidence, not closure). Co-authored-by: Cursor --- dsl/test/claim/roadmap_authority_test.dag | 25 +++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/dsl/test/claim/roadmap_authority_test.dag b/dsl/test/claim/roadmap_authority_test.dag index 36e810f6011..ea2a7f024d2 100644 --- a/dsl/test/claim/roadmap_authority_test.dag +++ b/dsl/test/claim/roadmap_authority_test.dag @@ -41,19 +41,22 @@ fn witness_emit_refs_from_binding() -> Bool { fn witness_c1_measure_rows() -> Bool { string_contains(s: out(), - pattern: "- [x] **Section 1 spawn-width foundation — std.measure expressibility** (#5470/#5478)") + pattern: "- [ ] **Section 1 spawn-width foundation — std.measure expressibility** (#5470/#5478)") + && string_contains(s: out(), pattern: "⏳ awaiting sign-off") } fn witness_c2_roundtrip_law() -> Bool { let o = out() - string_contains(s: o, pattern: "- [x] **round-trip law (ingest∘emit = id, DecodeFidelity-bounded)** (#5525/#5527)") - && string_contains(s: o, pattern: "- [x] **medium axis** —") + string_contains(s: o, pattern: "- [ ] **round-trip law (ingest∘emit = id, DecodeFidelity-bounded)** (#5525/#5527)") + && string_contains(s: o, pattern: "- [ ] **medium axis** —") && string_contains(s: o, pattern: "per-medium round-trips are v1-seed interim") + && string_contains(s: o, pattern: "⏳ awaiting sign-off") } fn witness_c3_inversion_subrows() -> Bool { string_contains(s: out(), - pattern: "- [x] **PR→checkbox status + section-emit + projection layer** (#5491/#5508/#5520)") + pattern: "- [ ] **PR→checkbox status + section-emit + projection layer** (#5491/#5508/#5520)") + && string_contains(s: out(), pattern: "⏳ awaiting sign-off") } fn witness_c4_selfhost_no_overclaim() -> Bool { @@ -65,7 +68,8 @@ fn witness_c4_selfhost_no_overclaim() -> Bool { fn witness_c4_cargo_green_landed() -> Bool { string_contains(s: out(), - pattern: "- [x] **emitted crate `cargo build`s green (Route-A last mile) ✓ LANDED (#5777/#5873)**") + pattern: "- [ ] **emitted crate `cargo build`s green (Route-A last mile) ✓ LANDED (#5777/#5873)**") + && string_contains(s: out(), pattern: "⏳ awaiting sign-off") } fn witness_c5_rust_gate_not_greenlit() -> Bool { @@ -89,10 +93,13 @@ fn witness_b_order_discriminator() -> Bool { !string_contains(s: out(), pattern: "**Audits (done):**\n\nThis window = a few days of STABILITY") } -fn witness_derivation_has_teeth() -> Bool { +fn witness_merge_perturb_does_not_flip_boxes() -> Bool { + let full = out() let dropped = emit_with(m: [5445, 5453, 5433, 5476, 5473, 5456, 5421, 5425]) - string_contains(s: dropped, pattern: "- [ ] **numeric-tower grounding** (#5428)") - && string_contains(s: dropped, pattern: "- [ ] **Section 1 spawn-width foundation — std.measure expressibility** (#5470/#5478)") + let pat = "- [ ] **numeric-tower grounding** (#5428)" + string_contains(s: full, pattern: pat) + && string_contains(s: dropped, pattern: pat) + && !string_contains(s: full, pattern: "- [x] **numeric-tower grounding** (#5428)") && !string_contains(s: dropped, pattern: "- [x] **numeric-tower grounding** (#5428)") } @@ -109,5 +116,5 @@ test fn roadmap_authority_witnesses() -> Bool { && witness_a_prose_verbatim() && witness_b_ordered_interleaving() && witness_b_order_discriminator() - && witness_derivation_has_teeth() + && witness_merge_perturb_does_not_flip_boxes() }