diff --git a/ROADMAP.md b/ROADMAP.md index ab63bdb0098..2aea3ca5477 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,6 +1,6 @@ # gunbc — Roadmap -`DESIGN.md` is the authority for why. This file projects the remaining committed deliverables and their dependency order from `dag/gunbc/roadmap/roadmap_authority.dag`. The authority declares every node and records a typed acceptance receipt per accepted node; the active set is derived as declared minus validly accepted, so acceptance never deletes a row and this projection stays active-only. It carries no mutable pull-request, CI, session, or attempt state. Implementation evidence does not equal acceptance; a merged but unaccepted deliverable remains active. +`DESIGN.md` is the authority for why. This file projects the remaining committed deliverables and their dependency order from `dag/gunbc/roadmap/roadmap_authority.dag`. The authority declares every node and records a typed acceptance receipt per accepted node; the active set is derived as declared minus validly accepted minus withheld (revoked receipts whose disposition keeps a superseded node off the frontier), so acceptance never deletes a row and this projection stays active-only. It carries no mutable pull-request, CI, session, or attempt state. Implementation evidence does not equal acceptance; a merged but unaccepted deliverable remains active. Indented rows depend on the row above them. Some deliverables have additional cross-chain prerequisites represented by `RoadmapEdge` in the authority. Every active row requires explicit manual acceptance. Automatic admission from this refreshed authority is future work; the existing manual dispatch path remains live and outside this model slice. Ready may schedule only after every dependency is accepted; it never overrides a dependency or refusal. Parked plans remain reachable through the documentation graph but are not active roadmap rows. @@ -10,7 +10,7 @@ Parked context (non-dispatchable): [compiler algorithm survey](docs/plans/compil The graph has sixteen lanes: SCM compatibility · namespace · P-derive · observation · placement · compute · CI cost · CI control · generated artefacts · v1 exit (four finish lines: compiler fixed point, interpreter deleted, products v1-free, zero hand-maintained Rust) · shell · roadmap runtime · fleet/hygiene · judgment · hermetic toolchain · compiler-guarantee (the DESIGN §4b ladder climbs; rung STATE lives in the guarantee claims carrier and is emitted, never restated in tickets — [gap analysis](docs/plans/compiler-guarantee-recovery-gap-analysis.md)). The three independent SCM R0 models, the separate P−1 evidence carrier, R1 compatibility-shape extraction, and P0 user-contract/landing spine are accepted; the operator-authored P1 proof-kernel node is active and fail-closed pending its first discriminating closing validation, while P2 and later product lanes remain parked. The toolchain pin model is an independent root. The P-derive receipt feeds the emitter fixed point, so the v1 chain nests under it. Compute owns the one contract everything else asks for work through — an exact subject in, a typed ending and the outputs it promised back out — and it sits ABOVE CI rather than inside it, because owning CI, converging the fleet, serving models and eventually judging changes are four consumers of one fabric, not four execution systems. It grounds on the signed realization spine rather than minting a second scheduler beside it. CI control owns who starts, queues and hands out required work and how its result reaches GitHub; CI cost owns how much computation that work performs. Fleet owns whether a merge to main becomes applied machine state and whether that question has one answer. Node fields define boundary, first slice, RED control, exclusions, owner, and handback. -**Focused view — the compute fabric + the infrastructure stabilisation lanes + fleet convergence from main + the harness, roadmap workflow and dashboard lanes.** 125 active deliverable(s) in other lanes are declared in the authority and hidden here; nothing is deleted or parked by focusing. Clear `roadmap_focus_selection` in `dag/gunbc/roadmap/roadmap_authority.dag` to restore the full page. 11 of the rows below are NOT lane deliverables — they are prerequisites pulled in from other lanes because lane work is blocked on them: commit-writer-admission, shell-gate-migration, shell-effectplan-to-bash, shell-typed-invocation, placement-compile-pool-envelope, placement-live-roster-preflight, observation-scoped-run-consumer, observation-scoped-run-seed-growth-justification, observation-scoped-run-seed-growth-justification-closing-contract, fleet-spark-host-enrollment, confidence-semantic-impact-query. Hidden lanes remain readable through their carriers: [docs/plans/dag-scm-design.md](docs/plans/dag-scm-design.md) · [docs/plans/namespace-unique-on-chain-operational-plan.md](docs/plans/namespace-unique-on-chain-operational-plan.md) · [docs/plans/v2-self-hosting.md](docs/plans/v2-self-hosting.md) · [src/v2/compiler/05_emit.dag](src/v2/compiler/05_emit.dag) · [docs/plans/progress-observation-design.md](docs/plans/progress-observation-design.md) · [src/v2/compiler/self_host/candidate_generation.dag](src/v2/compiler/self_host/candidate_generation.dag) · [src/v2/compiler/self_host/stage0_production_target.dag](src/v2/compiler/self_host/stage0_production_target.dag) · [src/v2/compiler/self_host/wet_receipt_enrollment.dag](src/v2/compiler/self_host/wet_receipt_enrollment.dag) · [src/v2/workflow/rust_crate_partition.dag](src/v2/workflow/rust_crate_partition.dag) · [src/v2/compiler/self_host/v2_emitter_direct_rust_door_contract.dag](src/v2/compiler/self_host/v2_emitter_direct_rust_door_contract.dag) · [dag/gunbc/v1/v1_deletion_plan.dag](dag/gunbc/v1/v1_deletion_plan.dag) · [dag/gunbc/stage0/stage0_rust_host_observation.dag](dag/gunbc/stage0/stage0_rust_host_observation.dag) · [docs/plans/witness-realization-plan.md](docs/plans/witness-realization-plan.md) · [src/v1/05_emit_rust.dag](src/v1/05_emit_rust.dag) · [dag/gunbc/v1/v1_interpreter_primitive_surface.dag](dag/gunbc/v1/v1_interpreter_primitive_surface.dag) · [docs/plans/shell-to-dag-residual-census-and-arc-completion.md](docs/plans/shell-to-dag-residual-census-and-arc-completion.md) · [docs/plans/roadmap-workspace-ux-plan.md](docs/plans/roadmap-workspace-ux-plan.md) · [docs/plans/hermetic-tool-provisioning-design.md](docs/plans/hermetic-tool-provisioning-design.md) · [dag/gunbc/capability_binding.dag](dag/gunbc/capability_binding.dag) · [dag/gunbc/roadmap/roadmap_component.dag](dag/gunbc/roadmap/roadmap_component.dag) · [dag/gunbc/design_document.dag](dag/gunbc/design_document.dag) · [docs/plans/compiler-guarantee-recovery-gap-analysis.md](docs/plans/compiler-guarantee-recovery-gap-analysis.md) · [docs/plans/cardinality-refinement.md](docs/plans/cardinality-refinement.md) · [dag/gunbc/roadmap/roadmap_authority.dag](dag/gunbc/roadmap/roadmap_authority.dag) · [dag/test/claim/closing/namespace_cross_file_provenance_closing_contract_witness_test.dag](dag/test/claim/closing/namespace_cross_file_provenance_closing_contract_witness_test.dag) · [dag/test/claim/closing/v1_materialization_kernel_closing_contract_witness_test.dag](dag/test/claim/closing/v1_materialization_kernel_closing_contract_witness_test.dag) · [dag/test/claim/closing/toolchain_pin_model_closing_contract_witness_test.dag](dag/test/claim/closing/toolchain_pin_model_closing_contract_witness_test.dag) · [dag/test/claim/closing/instrument_motion_physical_qualification_closing_contract_witness_test.dag](dag/test/claim/closing/instrument_motion_physical_qualification_closing_contract_witness_test.dag) · [dag/test/claim/closing/instrument_rendered_control_coverage_closing_contract_witness_test.dag](dag/test/claim/closing/instrument_rendered_control_coverage_closing_contract_witness_test.dag) · [dag/test/claim/closing/discarded_bool_result_wall_closing_contract_witness_test.dag](dag/test/claim/closing/discarded_bool_result_wall_closing_contract_witness_test.dag) · [dag/test/claim/closing/ladder_probe_corpus_closing_contract_witness_test.dag](dag/test/claim/closing/ladder_probe_corpus_closing_contract_witness_test.dag) · [dag/test/claim/closing/method_established_surface_wall_closing_contract_witness_test.dag](dag/test/claim/closing/method_established_surface_wall_closing_contract_witness_test.dag) · [dag/test/claim/closing/call_label_and_surplus_wall_closing_contract_witness_test.dag](dag/test/claim/closing/call_label_and_surplus_wall_closing_contract_witness_test.dag) · [dag/test/claim/closing/declared_conformance_ground_fragment_closing_contract_witness_test.dag](dag/test/claim/closing/declared_conformance_ground_fragment_closing_contract_witness_test.dag) · [dag/test/claim/closing/v2_self_grounding_frontier_closing_contract_witness_test.dag](dag/test/claim/closing/v2_self_grounding_frontier_closing_contract_witness_test.dag) · [dag/test/claim/closing/interpreter_primitive_roster_closing_contract_witness_test.dag](dag/test/claim/closing/interpreter_primitive_roster_closing_contract_witness_test.dag) · [dag/test/claim/closing/unforgeable_construction_capability_closing_contract_witness_test.dag](dag/test/claim/closing/unforgeable_construction_capability_closing_contract_witness_test.dag). +**Focused view — the compute fabric + the infrastructure stabilisation lanes + fleet convergence from main + the harness, roadmap workflow and dashboard lanes.** 124 active deliverable(s) in other lanes are declared in the authority and hidden here; nothing is deleted or parked by focusing. Clear `roadmap_focus_selection` in `dag/gunbc/roadmap/roadmap_authority.dag` to restore the full page. 11 of the rows below are NOT lane deliverables — they are prerequisites pulled in from other lanes because lane work is blocked on them: commit-writer-admission, shell-gate-migration, shell-effectplan-to-bash, shell-typed-invocation, placement-compile-pool-envelope, placement-live-roster-preflight, observation-scoped-run-consumer, observation-scoped-run-seed-growth-justification, observation-scoped-run-seed-growth-justification-closing-contract, fleet-spark-host-enrollment, confidence-semantic-impact-query. Hidden lanes remain readable through their carriers: [docs/plans/dag-scm-design.md](docs/plans/dag-scm-design.md) · [docs/plans/namespace-unique-on-chain-operational-plan.md](docs/plans/namespace-unique-on-chain-operational-plan.md) · [docs/plans/v2-self-hosting.md](docs/plans/v2-self-hosting.md) · [src/v2/compiler/05_emit.dag](src/v2/compiler/05_emit.dag) · [docs/plans/progress-observation-design.md](docs/plans/progress-observation-design.md) · [src/v2/compiler/self_host/candidate_generation.dag](src/v2/compiler/self_host/candidate_generation.dag) · [src/v2/compiler/self_host/stage0_production_target.dag](src/v2/compiler/self_host/stage0_production_target.dag) · [src/v2/compiler/self_host/wet_receipt_enrollment.dag](src/v2/compiler/self_host/wet_receipt_enrollment.dag) · [src/v2/workflow/rust_crate_partition.dag](src/v2/workflow/rust_crate_partition.dag) · [src/v2/compiler/self_host/v2_emitter_direct_rust_door_contract.dag](src/v2/compiler/self_host/v2_emitter_direct_rust_door_contract.dag) · [dag/gunbc/v1/v1_deletion_plan.dag](dag/gunbc/v1/v1_deletion_plan.dag) · [dag/gunbc/stage0/stage0_rust_host_observation.dag](dag/gunbc/stage0/stage0_rust_host_observation.dag) · [docs/plans/witness-realization-plan.md](docs/plans/witness-realization-plan.md) · [src/v1/05_emit_rust.dag](src/v1/05_emit_rust.dag) · [dag/gunbc/v1/v1_interpreter_primitive_surface.dag](dag/gunbc/v1/v1_interpreter_primitive_surface.dag) · [docs/plans/shell-to-dag-residual-census-and-arc-completion.md](docs/plans/shell-to-dag-residual-census-and-arc-completion.md) · [docs/plans/roadmap-workspace-ux-plan.md](docs/plans/roadmap-workspace-ux-plan.md) · [docs/plans/hermetic-tool-provisioning-design.md](docs/plans/hermetic-tool-provisioning-design.md) · [dag/gunbc/capability_binding.dag](dag/gunbc/capability_binding.dag) · [dag/gunbc/roadmap/roadmap_component.dag](dag/gunbc/roadmap/roadmap_component.dag) · [dag/gunbc/design_document.dag](dag/gunbc/design_document.dag) · [docs/plans/compiler-guarantee-recovery-gap-analysis.md](docs/plans/compiler-guarantee-recovery-gap-analysis.md) · [docs/plans/cardinality-refinement.md](docs/plans/cardinality-refinement.md) · [dag/gunbc/roadmap/roadmap_authority.dag](dag/gunbc/roadmap/roadmap_authority.dag) · [dag/test/claim/closing/namespace_cross_file_provenance_closing_contract_witness_test.dag](dag/test/claim/closing/namespace_cross_file_provenance_closing_contract_witness_test.dag) · [dag/test/claim/closing/v1_materialization_kernel_closing_contract_witness_test.dag](dag/test/claim/closing/v1_materialization_kernel_closing_contract_witness_test.dag) · [dag/test/claim/closing/toolchain_pin_model_closing_contract_witness_test.dag](dag/test/claim/closing/toolchain_pin_model_closing_contract_witness_test.dag) · [dag/test/claim/closing/instrument_motion_physical_qualification_closing_contract_witness_test.dag](dag/test/claim/closing/instrument_motion_physical_qualification_closing_contract_witness_test.dag) · [dag/test/claim/closing/instrument_rendered_control_coverage_closing_contract_witness_test.dag](dag/test/claim/closing/instrument_rendered_control_coverage_closing_contract_witness_test.dag) · [dag/test/claim/closing/discarded_bool_result_wall_closing_contract_witness_test.dag](dag/test/claim/closing/discarded_bool_result_wall_closing_contract_witness_test.dag) · [dag/test/claim/closing/ladder_probe_corpus_closing_contract_witness_test.dag](dag/test/claim/closing/ladder_probe_corpus_closing_contract_witness_test.dag) · [dag/test/claim/closing/method_established_surface_wall_closing_contract_witness_test.dag](dag/test/claim/closing/method_established_surface_wall_closing_contract_witness_test.dag) · [dag/test/claim/closing/call_label_and_surplus_wall_closing_contract_witness_test.dag](dag/test/claim/closing/call_label_and_surplus_wall_closing_contract_witness_test.dag) · [dag/test/claim/closing/declared_conformance_ground_fragment_closing_contract_witness_test.dag](dag/test/claim/closing/declared_conformance_ground_fragment_closing_contract_witness_test.dag) · [dag/test/claim/closing/v2_self_grounding_frontier_closing_contract_witness_test.dag](dag/test/claim/closing/v2_self_grounding_frontier_closing_contract_witness_test.dag) · [dag/test/claim/closing/interpreter_primitive_roster_closing_contract_witness_test.dag](dag/test/claim/closing/interpreter_primitive_roster_closing_contract_witness_test.dag) · [dag/test/claim/closing/unforgeable_construction_capability_closing_contract_witness_test.dag](dag/test/claim/closing/unforgeable_construction_capability_closing_contract_witness_test.dag). - [x] **Run the worker on DeepSeek V4 Flash with thinking on, straight at the engines, from briefs it can finish** — The harness posts to the Spark vLLM engines directly on the chat-completions shape with Think Max as the request switch, decodes inline reasoning client-side, replays it, and derives its deadline from the engine's own decode rate. A write brief names files small enough to hold whole and the decisions already made. Why: A day of runs with 0 files changed: briefs naming one file when the change spans its importers, a co-tenanted router killing every long step, a deadline that could not cover max_tokens, and agents deliberating modeling decisions a brief should have made. [authority](dag/gunbc/harness/harness_cli.dag) — ✓ signed off: operator curation 2026-09-06 (session 019iXPtAqzPaNBZbaaM5rxrY) - [x] **The roadmap commits, verifies, and opens the pull request itself once verification passes** — After the provider completes, the belt commits the attempt worktree, verifies the committed head in a detached checkout, admits publication only on a ValidationPassed receipt for that exact head, and the token-holding helper pushes the branch and opens the pull request, then answers with what GitHub shows. Why: Verification was checking out an uncommitted worktree's head, publication never consulted the verdict, and no operation existed to push or create a pull request, so every attempt stalled in the Agent segment and a human harvested by hand. [authority](dag/gunbc/roadmap/roadmap_publish_admission.dag) — ✓ signed off: operator curation 2026-09-06 (session 019iXPtAqzPaNBZbaaM5rxrY) diff --git a/dag/gunbc/roadmap/roadmap_acceptance_event_history.jsonl b/dag/gunbc/roadmap/roadmap_acceptance_event_history.jsonl index 69b1017b714..bd8c04a04af 100644 --- a/dag/gunbc/roadmap/roadmap_acceptance_event_history.jsonl +++ b/dag/gunbc/roadmap/roadmap_acceptance_event_history.jsonl @@ -14,3 +14,4 @@ {"variant":"acceptance_recorded","receipt":{"node":"ladder-measurement-schema","criteria_digest":"74da4d8be7125c81","red_control":{"variant":"red_control_executed","witness_module":"test.claim.guarantee_measurement_witness_test","witness_fn":"duplicate_class_id_reds_uniqueness","executed_on":"2026-08-01"},"handback":{"variant":"handback_delivered","first_artifact":"dag/gunbc/guarantee_measurement.dag","further_artifacts":["dag/test/claim/guarantee_measurement_witness_test.dag"]},"accepted_by":"operator","accepted_on":"2026-08-01"}} {"variant":"acceptance_recorded","receipt":{"node":"v2-emitter-producer-provenance","criteria_digest":"f1c76111c83a0a60","red_control":{"variant":"red_control_executed","witness_module":"v2.test.claim.self_host.emitter_producer_provenance_witness_test","witness_fn":"witness_restored_binding_without_executed_receipt_does_not_authorize_reds","executed_on":"2026-08-02"},"handback":{"variant":"handback_delivered","first_artifact":"src/v2/compiler/self_host/frontier.dag","further_artifacts":["src/v2/test/claim/self_host/emitter_producer_provenance_witness_test.dag"]},"accepted_by":"operator","accepted_on":"2026-08-02"}} {"variant":"acceptance_recorded","receipt":{"node":"v1-seed-honesty-decision","criteria_digest":"1717cfe258d9afe1","red_control":{"variant":"red_control_executed","witness_module":"test.claim.seed_honesty_discharge_unavailable_test","witness_fn":"seed_honesty_undecided_would_keep_closing_contract_red","executed_on":"2026-08-02"},"handback":{"variant":"handback_delivered","first_artifact":"src/v2/workflow/bootstrap.dag","further_artifacts":["dag/test/claim/seed_honesty_discharge_unavailable_test.dag","dag/gunbc/ci/ci_layer_roots.dag"]},"accepted_by":"operator","accepted_on":"2026-08-02"}} +{"variant":"acceptance_revoked","exact_prior_receipt":{"node":"entry-graph-union-construction","criteria_digest":"3502539e920d9e40","red_control":{"variant":"red_control_executed","witness_module":"v1-compiler-tests.union_resolve_receipts_test","witness_fn":"shared_typecheck_distinct_compute_count_is_order_invariant","executed_on":"2026-08-01"},"handback":{"variant":"handback_delivered","first_artifact":"docs/plans/entry-graph-union-slice2-typecheck-attribution.md","further_artifacts":["docs/plans/receipts/entry-graph-union-slice2/receipt-broad-disjoint.json","docs/plans/receipts/entry-graph-union-slice2/receipt-post-merge-representative-50.json","docs/plans/per-entry-assembly-decomposition-measurement.md","src/v1/tests/src/union_resolve_receipts_test.rs"]},"accepted_by":"operator","accepted_on":"2026-08-01"},"disposition":{"variant":"acceptance_node_remains_superseded"},"reason":"The floor cut retired this work's subject; remaining cost work lives on the successor. The recorded acceptance is retained as history.","revoked_by":"operator","revoked_on":"2026-09-13"} diff --git a/dag/gunbc/roadmap/roadmap_authority.dag b/dag/gunbc/roadmap/roadmap_authority.dag index 143db11f323..6e5c3422ead 100644 --- a/dag/gunbc/roadmap/roadmap_authority.dag +++ b/dag/gunbc/roadmap/roadmap_authority.dag @@ -19,8 +19,21 @@ import gunbc.roadmap_model { AcceptanceRecorded, AcceptanceRevoked, AcceptanceNodeReopensActiveFrontier, + node_ids_held_off_active_frontier, + remains_superseded_revocations_join, + RemainsSupersededRevocationsJoined, + RemainsSupersededRevocationOnNonSupersededNode, + RemainsSupersededRevocationOnUndeclaredNode, + RemainsSupersededRevocationOnAmbiguousDeclaredNode, + live_receipts_join_declared_nodes, + LiveReceiptsJoinDeclared, + LiveReceiptJoinsSupersededLine, + LiveReceiptDoesNotMatchDeclaredNode, + LiveReceiptJoinsUndeclaredNode, + LiveReceiptJoinsAmbiguousDeclaredNode, node_accepted, project_live_acceptance_receipts, + replay_acceptance_history, acceptance_history_integrity_holds, AcceptanceHistoryIntegrityVerdict, AcceptanceHistoryIntegrityHolds, @@ -3028,7 +3041,9 @@ fn roadmap_acceptance_event_history_load() -> RoadmapAcceptanceEventHistoryLoad // dag/gunbc/roadmap/roadmap_acceptance_event_history.jsonl (append-only JSONL carrier). // roadmap_acceptance_receipts projects the live receipt set by replaying recorded and revoked // events only — never a second editable receipt list; LoadRefused is a typed -// RoadmapAcceptanceReceiptsProjectionRefused, never an empty receipt list. New acceptance appends +// RoadmapAcceptanceReceiptsProjectionRefused, never an empty receipt list. Withheld node ids +// from the same carrier refuse the same way: LoadRefused is WithheldNodeIdsProjectionRefused, +// never [] (empty withheld would widen the active frontier). New acceptance appends // AcceptanceRecorded to the carrier; withdrawal appends AcceptanceRevoked naming the exact prior // receipt, a disposition, and audit fields. Authored seal count/digest are deleted: prefix law is // enforced by gunbc.roadmap_acceptance_history_observation parsing merge-base carrier content via @@ -3151,51 +3166,110 @@ fn roadmap_acceptance_history_integrity_holds() -> Bool { // load-bearing: weaken the decision arm so an undecided value satisfies the contract and the // contract stays green while only the control reds. -type AcceptedRoadmapNodesProjection - = AcceptedRoadmapNodesProjected { nodes: List } - | AcceptedRoadmapNodesProjectionRefused { detail: String } - -type AcceptedRoadmapNodeIdsProjection - = AcceptedRoadmapNodeIdsProjected { ids: List } - | AcceptedRoadmapNodeIdsProjectionRefused { detail: String } - type RoadmapAuthorityProjection - = RoadmapAuthorityProjected { doc: RoadmapDocument, accepted: List } + = RoadmapAuthorityProjected { + doc: RoadmapDocument, + accepted: List, + withheld: List, + } | RoadmapAuthorityProjectionRefused { detail: String } -fn accepted_roadmap_nodes_projection() -> AcceptedRoadmapNodesProjection { - match roadmap_acceptance_receipts() { - RoadmapAcceptanceReceiptsProjected { receipts: receipts } => - AcceptedRoadmapNodesProjected { - nodes: declared_roadmap_nodes() |> filter(n => node_accepted(receipts: receipts, rn: n)), +// One load of the carrier produces both frontier halves. Callers that need accepted AND withheld +// consume this, never a pair of independent live projections. FrontierSetsProjected is admitted +// only after replay succeeds and every live receipt joins the current declaration authority. +type FrontierSetsProjection + = FrontierSetsProjected { accepted: List, withheld: List } + | FrontierSetsProjectionRefused { detail: String } + +fn frontier_sets_from_events(events: List) -> FrontierSetsProjection { + match remains_superseded_revocations_join(history: events, nodes: declared_roadmap_nodes()) { + RemainsSupersededRevocationOnNonSupersededNode { node: node } => + FrontierSetsProjectionRefused { + detail: join(["remains-superseded-revocation-on-non-superseded-node:", node as String], ""), + } + RemainsSupersededRevocationOnUndeclaredNode { node: node } => + FrontierSetsProjectionRefused { + detail: join(["remains-superseded-revocation-on-undeclared-node:", node as String], ""), + } + RemainsSupersededRevocationOnAmbiguousDeclaredNode { node: node } => + FrontierSetsProjectionRefused { + detail: join(["remains-superseded-revocation-on-ambiguous-declared-node:", node as String], ""), + } + RemainsSupersededRevocationsJoined => + match replay_acceptance_history(events: events) { + Absent => + FrontierSetsProjectionRefused { detail: "acceptance-history-unreplayable" } + Present { value: state } => + match live_receipts_join_declared_nodes(receipts: state.live, nodes: declared_roadmap_nodes()) { + LiveReceiptJoinsSupersededLine { node: node } => + FrontierSetsProjectionRefused { + detail: join(["live-receipt-on-superseded-line:", node as String], ""), + } + LiveReceiptDoesNotMatchDeclaredNode { node: node } => + FrontierSetsProjectionRefused { + detail: join(["live-receipt-does-not-match-declared-node:", node as String], ""), + } + LiveReceiptJoinsUndeclaredNode { node: node } => + FrontierSetsProjectionRefused { + detail: join(["live-receipt-on-undeclared-node:", node as String], ""), + } + LiveReceiptJoinsAmbiguousDeclaredNode { node: node } => + FrontierSetsProjectionRefused { + detail: join(["live-receipt-on-ambiguous-declared-node:", node as String], ""), + } + LiveReceiptsJoinDeclared => + FrontierSetsProjected { + accepted: accepted_node_ids_from_receipts(receipts: state.live), + withheld: node_ids_held_off_active_frontier(history: events), + } + } } - RoadmapAcceptanceReceiptsProjectionRefused { detail: detail } => - AcceptedRoadmapNodesProjectionRefused { detail: detail } } } -fn accepted_roadmap_node_ids_projection_from_carrier_text(text: String) -> AcceptedRoadmapNodeIdsProjection { - match roadmap_acceptance_receipts_from_carrier_text(text: text) { - RoadmapAcceptanceReceiptsProjected { receipts: receipts } => - AcceptedRoadmapNodeIdsProjected { - ids: accepted_node_ids_from_receipts(receipts: receipts), - } - RoadmapAcceptanceReceiptsProjectionRefused { detail: detail } => - AcceptedRoadmapNodeIdsProjectionRefused { detail: detail } +fn frontier_sets_from_live_history() -> FrontierSetsProjection { + match roadmap_acceptance_event_history_load() { + RoadmapAcceptanceEventHistoryLoadRefused { detail: detail } => + FrontierSetsProjectionRefused { detail: detail } + RoadmapAcceptanceEventHistoryLoaded { events: events } => + frontier_sets_from_events(events: events) } } -fn accepted_roadmap_node_ids_projection() -> AcceptedRoadmapNodeIdsProjection { - match accepted_roadmap_nodes_projection() { - AcceptedRoadmapNodesProjected { nodes: nodes } => - AcceptedRoadmapNodeIdsProjected { ids: nodes |> map(n => n.node) } - AcceptedRoadmapNodesProjectionRefused { detail: detail } => - AcceptedRoadmapNodeIdsProjectionRefused { detail: detail } +type WithheldNodeIdsProjection + = WithheldNodeIdsProjected { ids: List } + | WithheldNodeIdsProjectionRefused { detail: String } + +fn withheld_node_ids_from_live_history() -> WithheldNodeIdsProjection { + match frontier_sets_from_live_history() { + FrontierSetsProjected { accepted: _, withheld: withheld } => + WithheldNodeIdsProjected { ids: withheld } + FrontierSetsProjectionRefused { detail: detail } => + WithheldNodeIdsProjectionRefused { detail: detail } } } -fn active_roadmap_nodes_for_accepted(accepted: List) -> List { - declared_roadmap_nodes() |> filter(n => !(accepted |> any(a => a == n.node))) +fn withheld_node_ids_from_carrier_text(text: String) -> WithheldNodeIdsProjection { + match load_roadmap_acceptance_event_history_from_carrier_text(text: text) { + RoadmapAcceptanceEventHistoryLoadRefused { detail: detail } => + WithheldNodeIdsProjectionRefused { detail: detail } + RoadmapAcceptanceEventHistoryLoaded { events: events } => + match frontier_sets_from_events(events: events) { + FrontierSetsProjected { accepted: _, withheld: withheld } => + WithheldNodeIdsProjected { ids: withheld } + FrontierSetsProjectionRefused { detail: detail } => + WithheldNodeIdsProjectionRefused { detail: detail } + } + } +} + +fn active_roadmap_nodes_for_accepted( + accepted: List, + withheld: List, +) -> List { + declared_roadmap_nodes() |> filter(n => + !(accepted |> any(a => a == n.node)) && !(withheld |> any(w => w == n.node)) + ) } type ActiveRoadmapNodesProjection @@ -3207,24 +3281,24 @@ type ActiveRoadmapEdgesProjection | ActiveRoadmapEdgesProjectionRefused { detail: String } fn active_roadmap_nodes_projection() -> ActiveRoadmapNodesProjection { - match accepted_roadmap_node_ids_projection() { - AcceptedRoadmapNodeIdsProjected { ids: accepted } => + match frontier_sets_from_live_history() { + FrontierSetsProjectionRefused { detail: detail } => + ActiveRoadmapNodesProjectionRefused { detail: detail } + FrontierSetsProjected { accepted: accepted, withheld: withheld } => ActiveRoadmapNodesProjected { - nodes: active_roadmap_nodes_for_accepted(accepted: accepted), + nodes: active_roadmap_nodes_for_accepted(accepted: accepted, withheld: withheld), } - AcceptedRoadmapNodeIdsProjectionRefused { detail: detail } => - ActiveRoadmapNodesProjectionRefused { detail: detail } } } fn active_roadmap_edges_projection() -> ActiveRoadmapEdgesProjection { - match accepted_roadmap_node_ids_projection() { - AcceptedRoadmapNodeIdsProjected { ids: accepted } => + match frontier_sets_from_live_history() { + FrontierSetsProjectionRefused { detail: detail } => + ActiveRoadmapEdgesProjectionRefused { detail: detail } + FrontierSetsProjected { accepted: accepted, withheld: withheld } => ActiveRoadmapEdgesProjected { - edges: active_roadmap_edges_for_accepted(accepted: accepted), + edges: active_roadmap_edges_for_accepted(accepted: accepted, withheld: withheld), } - AcceptedRoadmapNodeIdsProjectionRefused { detail: detail } => - ActiveRoadmapEdgesProjectionRefused { detail: detail } } } @@ -3356,9 +3430,13 @@ fn node_sizing_is_declared(n: RoadmapNode) -> Bool { // closing check. Before this filter a ticket_row (Unsized) still minted a Sized closing-contract task // that sat in Ready, so parking a node by unsizing it moved the node out of Ready and put a task // for it straight back in (operator observation, 2026-09-04). -fn startable_nodes_missing_closing_contract_for_accepted(accepted: List) -> List { +fn startable_nodes_missing_closing_contract_for_accepted( + accepted: List, + withheld: List, +) -> List { declared_roadmap_nodes() |> filter(n => !(accepted |> any(a => a == n.node))) + |> filter(n => !(withheld |> any(w => w == n.node))) |> filter(n => node_sizing_is_declared(n: n)) |> filter(n => node_lacks_closing_validation(n: n)) |> filter(n => node_is_startable_for_accepted(n: n, accepted: accepted)) @@ -3458,8 +3536,11 @@ type ClosingContractTaskEdgesProjection = ClosingContractTaskEdgesProjected { edges: List } | ClosingContractTaskEdgesProjectionRefused { detail: String } -fn closing_contract_task_pairs_for_accepted(accepted: List) -> List { - startable_nodes_missing_closing_contract_for_accepted(accepted: accepted) +fn closing_contract_task_pairs_for_accepted( + accepted: List, + withheld: List, +) -> List { + startable_nodes_missing_closing_contract_for_accepted(accepted: accepted, withheld: withheld) |> map(n => ClosingContractTaskPair { task: closing_contract_task_for(n: n), subject: ticket_headline_of(n: n), @@ -3467,23 +3548,23 @@ fn closing_contract_task_pairs_for_accepted(accepted: List) -> Li } fn closing_contract_task_pairs_projection() -> ClosingContractTaskPairsProjection { - match accepted_roadmap_node_ids_projection() { - AcceptedRoadmapNodeIdsProjectionRefused { detail: detail } => + match frontier_sets_from_live_history() { + FrontierSetsProjectionRefused { detail: detail } => ClosingContractTaskPairsProjectionRefused { detail: detail } - AcceptedRoadmapNodeIdsProjected { ids: accepted } => + FrontierSetsProjected { accepted: accepted, withheld: withheld } => ClosingContractTaskPairsProjected { - pairs: closing_contract_task_pairs_for_accepted(accepted: accepted), + pairs: closing_contract_task_pairs_for_accepted(accepted: accepted, withheld: withheld), } } } fn closing_contract_task_edges_projection() -> ClosingContractTaskEdgesProjection { - match accepted_roadmap_node_ids_projection() { - AcceptedRoadmapNodeIdsProjectionRefused { detail: detail } => + match frontier_sets_from_live_history() { + FrontierSetsProjectionRefused { detail: detail } => ClosingContractTaskEdgesProjectionRefused { detail: detail } - AcceptedRoadmapNodeIdsProjected { ids: accepted } => + FrontierSetsProjected { accepted: accepted, withheld: withheld } => ClosingContractTaskEdgesProjected { - edges: closing_contract_task_edges_for_accepted(accepted: accepted), + edges: closing_contract_task_edges_for_accepted(accepted: accepted, withheld: withheld), } } } @@ -3498,33 +3579,42 @@ type ProjectedRoadmapDependencyEdgesProjection // dependencies that the authority derives from acceptance state. fn projected_roadmap_dependency_edges_projection() -> ProjectedRoadmapDependencyEdgesProjection { - match accepted_roadmap_node_ids_projection() { - AcceptedRoadmapNodeIdsProjectionRefused { detail: detail } => + match frontier_sets_from_live_history() { + FrontierSetsProjectionRefused { detail: detail } => ProjectedRoadmapDependencyEdgesProjectionRefused { detail: detail } - AcceptedRoadmapNodeIdsProjected { ids: accepted } => + FrontierSetsProjected { accepted: accepted, withheld: withheld } => ProjectedRoadmapDependencyEdgesProjected { - edges: projected_roadmap_edges_for_accepted(accepted: accepted), + edges: projected_roadmap_edges_for_accepted(accepted: accepted, withheld: withheld), } } } -fn closing_contract_task_edges_for_accepted(accepted: List) -> List { - startable_nodes_missing_closing_contract_for_accepted(accepted: accepted) +fn closing_contract_task_edges_for_accepted( + accepted: List, + withheld: List, +) -> List { + startable_nodes_missing_closing_contract_for_accepted(accepted: accepted, withheld: withheld) |> map(n => RoadmapEdge { child: n.node, parent: concat(n.node as String, "-closing-contract") as RoadmapNodeId, }) } -fn active_roadmap_edges_for_accepted(accepted: List) -> List { +fn active_roadmap_edges_for_accepted( + accepted: List, + withheld: List, +) -> List { declared_roadmap_edges() |> filter(e => - !(accepted |> any(a => a == e.child)) && !(accepted |> any(a => a == e.parent))) + !(accepted |> any(a => a == e.child)) + && !(accepted |> any(a => a == e.parent)) + && !(withheld |> any(w => w == e.child)) + && !(withheld |> any(w => w == e.parent))) } fn preamble() -> List { [ HeadingBlock { level: H1, inlines: [TextInline { text: "gunbc — Roadmap" }] }, - ParagraphBlock { inlines: [TextInline { text: "`DESIGN.md` is the authority for why. This file projects the remaining committed deliverables and their dependency order from `dag/gunbc/roadmap/roadmap_authority.dag`. The authority declares every node and records a typed acceptance receipt per accepted node; the active set is derived as declared minus validly accepted, so acceptance never deletes a row and this projection stays active-only. It carries no mutable pull-request, CI, session, or attempt state. Implementation evidence does not equal acceptance; a merged but unaccepted deliverable remains active." }] }, + ParagraphBlock { inlines: [TextInline { text: "`DESIGN.md` is the authority for why. This file projects the remaining committed deliverables and their dependency order from `dag/gunbc/roadmap/roadmap_authority.dag`. The authority declares every node and records a typed acceptance receipt per accepted node; the active set is derived as declared minus validly accepted minus withheld (revoked receipts whose disposition keeps a superseded node off the frontier), so acceptance never deletes a row and this projection stays active-only. It carries no mutable pull-request, CI, session, or attempt state. Implementation evidence does not equal acceptance; a merged but unaccepted deliverable remains active." }] }, ParagraphBlock { inlines: [TextInline { text: "Indented rows depend on the row above them. Some deliverables have additional cross-chain prerequisites represented by `RoadmapEdge` in the authority. Every active row requires explicit manual acceptance. Automatic admission from this refreshed authority is future work; the existing manual dispatch path remains live and outside this model slice. Ready may schedule only after every dependency is accepted; it never overrides a dependency or refusal. Parked plans remain reachable through the documentation graph but are not active roadmap rows." }] }, ParagraphBlock { inlines: [TextInline { text: "Parked context (non-dispatchable): [compiler algorithm survey](docs/plans/compiler-algorithm-survey-2026-07-04.md) · [dispatch maintain CC](docs/plans/dispatch-maintain-cc.md) · [eval bind proposal](docs/plans/eval-bind-node-eval-propose.md) · [interpreter memory chronicle](docs/plans/interpreter-memory-chronicle.md) · [node/subtree visibility grants](docs/plans/node-subtree-visibility-grants.md) · [non-fold residue catalogue](docs/plans/non-fold-irreducible-residue-catalogue.md) · [post-engine roadmap](docs/plans/post-engine-pr-roadmap.md) · [post-zero regen placement](docs/plans/post-zero-regen-gate-placement.md) · [syntactic sample audit](docs/plans/real-debt-syntactic-sample-audit.md) · [regen 31/32 reconciliation](docs/plans/regen-divergence-31-vs-32-reconciliation.md) · [roadmap spawner](docs/plans/roadmap-spawner.md) · [seed honesty discharge](docs/plans/seed-honesty-discharge-design.md) · [space lens minimal project](docs/plans/space-lens-minimal-project.md)." }] }, ] @@ -3574,24 +3664,34 @@ data roadmap_focus_selection: RoadmapFocus = FocusOnOwners { owners: ["compute", "fleet", "ci-placement", "ci-control", "generated-artifact", "ci-cost", "confidence", "harness", "roadmap", "dashboard"], } -fn projected_roadmap_nodes_for_accepted(accepted: List) -> List { +fn projected_roadmap_nodes_for_accepted( + accepted: List, + withheld: List, +) -> List { concat( - active_roadmap_nodes_for_accepted(accepted: accepted), - startable_nodes_missing_closing_contract_for_accepted(accepted: accepted) + active_roadmap_nodes_for_accepted(accepted: accepted, withheld: withheld), + startable_nodes_missing_closing_contract_for_accepted(accepted: accepted, withheld: withheld) |> map(n => closing_contract_task_for(n: n)), ) } -fn projected_roadmap_edges_for_accepted(accepted: List) -> List { +fn projected_roadmap_edges_for_accepted( + accepted: List, + withheld: List, +) -> List { concat( - active_roadmap_edges_for_accepted(accepted: accepted), - closing_contract_task_edges_for_accepted(accepted: accepted), + active_roadmap_edges_for_accepted(accepted: accepted, withheld: withheld), + closing_contract_task_edges_for_accepted(accepted: accepted, withheld: withheld), ) } -fn active_section_for_acceptance(focus: RoadmapFocus, accepted: List) -> RoadmapSection { - let nodes = projected_roadmap_nodes_for_accepted(accepted: accepted) - let edges = projected_roadmap_edges_for_accepted(accepted: accepted) +fn active_section_for_acceptance( + focus: RoadmapFocus, + accepted: List, + withheld: List, +) -> RoadmapSection { + let nodes = projected_roadmap_nodes_for_accepted(accepted: accepted, withheld: withheld) + let edges = projected_roadmap_edges_for_accepted(accepted: accepted, withheld: withheld) RoadmapSection { title: "Active deliverables — dependency order", elements: concat( @@ -3635,38 +3735,50 @@ fn accepted_node_ids_from_receipts(receipts: List) -> } fn roadmap_authority_projection_from_carrier_text(text: String) -> RoadmapAuthorityProjection { - match roadmap_acceptance_receipts_from_carrier_text(text: text) { - RoadmapAcceptanceReceiptsProjected { receipts: receipts } => - RoadmapAuthorityProjected { - doc: RoadmapDocument { - preamble: preamble(), - lead_lanes: [], - sections: [ - active_section_for_acceptance( - focus: roadmap_focus_selection, - accepted: accepted_node_ids_from_receipts(receipts: receipts), - ), - ], - }, - accepted: accepted_node_ids_from_receipts(receipts: receipts), - } - RoadmapAcceptanceReceiptsProjectionRefused { detail: detail } => + match load_roadmap_acceptance_event_history_from_carrier_text(text: text) { + RoadmapAcceptanceEventHistoryLoadRefused { detail: detail } => RoadmapAuthorityProjectionRefused { detail: detail } + RoadmapAcceptanceEventHistoryLoaded { events: events } => + match frontier_sets_from_events(events: events) { + FrontierSetsProjectionRefused { detail: detail } => + RoadmapAuthorityProjectionRefused { detail: detail } + FrontierSetsProjected { accepted: accepted, withheld: withheld } => + RoadmapAuthorityProjected { + doc: RoadmapDocument { + preamble: preamble(), + lead_lanes: [], + sections: [ + active_section_for_acceptance( + focus: roadmap_focus_selection, + accepted: accepted, + withheld: withheld, + ), + ], + }, + accepted: accepted, + withheld: withheld, + } + } } } fn roadmap_authority_projection() -> RoadmapAuthorityProjection { - match accepted_roadmap_node_ids_projection() { - AcceptedRoadmapNodeIdsProjectionRefused { detail: detail } => + match frontier_sets_from_live_history() { + FrontierSetsProjectionRefused { detail: detail } => RoadmapAuthorityProjectionRefused { detail: detail } - AcceptedRoadmapNodeIdsProjected { ids: accepted } => + FrontierSetsProjected { accepted: accepted, withheld: withheld } => RoadmapAuthorityProjected { doc: RoadmapDocument { preamble: preamble(), lead_lanes: [], - sections: [active_section_for_acceptance(focus: roadmap_focus_selection, accepted: accepted)], + sections: [active_section_for_acceptance( + focus: roadmap_focus_selection, + accepted: accepted, + withheld: withheld, + )], }, accepted: accepted, + withheld: withheld, } } } @@ -3700,8 +3812,12 @@ fn active_section_for(focus: RoadmapFocus) -> RoadmapSection { section_prose(content: concat("roadmap acceptance projection refused: ", detail)), ], } - RoadmapAuthorityProjected { doc: _, accepted: accepted } => - active_section_for_acceptance(focus: focus, accepted: accepted) + RoadmapAuthorityProjected { doc: _, accepted: accepted, withheld: withheld } => + active_section_for_acceptance( + focus: focus, + accepted: accepted, + withheld: withheld, + ) } } @@ -4448,7 +4564,7 @@ fn roadmap_authority_refusal_document(detail: String) -> RoadmapDocument { fn roadmap_authority() -> RoadmapDocument { match roadmap_authority_projection() { - RoadmapAuthorityProjected { doc: doc, accepted: _ } => doc + RoadmapAuthorityProjected { doc: doc, accepted: _, withheld: _ } => doc RoadmapAuthorityProjectionRefused { detail: detail } => roadmap_authority_refusal_document(detail: detail) } @@ -4460,7 +4576,7 @@ fn expected_roadmap_md_for_projection(proj: RoadmapAuthorityProjection) -> Strin match proj { RoadmapAuthorityProjectionRefused { detail: detail } => concat("# roadmap unavailable\n\n", concat(detail, "\n")) - RoadmapAuthorityProjected { doc: doc, accepted: _ } => + RoadmapAuthorityProjected { doc: doc, accepted: _, withheld: _ } => serialize_markdown_source( doc: project_roadmap_to_markdown( doc: doc, diff --git a/dag/gunbc/roadmap/roadmap_belt_actuate.dag b/dag/gunbc/roadmap/roadmap_belt_actuate.dag index e0faf9fab8b..1e74f19309d 100644 --- a/dag/gunbc/roadmap/roadmap_belt_actuate.dag +++ b/dag/gunbc/roadmap/roadmap_belt_actuate.dag @@ -3404,7 +3404,7 @@ fn belt_run_once_in( audit_outcomes: audit_outcomes, } } - RoadmapAuthorityProjected { doc: doc, accepted: _ } => + RoadmapAuthorityProjected { doc: doc, accepted: _, withheld: _ } => belt_tick_for_instance( instance: instance, state: roadmap_belt_production_spawn_mode, @@ -6030,7 +6030,7 @@ fn belt_lookup_node(node_id: String) -> BeltNodeLookup { match roadmap_authority_projection() { RoadmapAuthorityProjectionRefused { detail: detail } => AuthorityProjectionRefused { detail: detail } - RoadmapAuthorityProjected { doc: doc, accepted: _ } => + RoadmapAuthorityProjected { doc: doc, accepted: _, withheld: _ } => belt_find_node_in(nodes: doc_all_nodes(doc: doc), node_id: node_id) } } @@ -6244,7 +6244,7 @@ fn belt_launch_host_standing_for_page_over( let pre = belt_launch_host_standing(instance: instance) match plan { RoadmapAuthorityProjectionRefused { detail: _ } => pre - RoadmapAuthorityProjected { doc, accepted: _ } => { + RoadmapAuthorityProjected { doc, accepted: _, withheld: _ } => { let graph = launch_graph_of_document(doc: doc) let merged = authored_merged_prs() match belt_page_sessions_need(standing: pre, graph: graph, merged: merged, nodes: doc_all_nodes(doc: doc)) { diff --git a/dag/gunbc/roadmap/roadmap_forecast.dag b/dag/gunbc/roadmap/roadmap_forecast.dag index da0bbdcc2f1..c3bc0dcbb9c 100644 --- a/dag/gunbc/roadmap/roadmap_forecast.dag +++ b/dag/gunbc/roadmap/roadmap_forecast.dag @@ -859,9 +859,9 @@ fn schedule_forecast( } } } -// THE FORECAST'S PLAN IS A PARAMETER. The accepted set is carried BY the projection -- it is the -// field roadmap_authority_projection fills from accepted_roadmap_node_ids_projection -- so the fold -// reads it from the plan it was handed rather than re-deriving it from the public carrier. That is +// THE FORECAST'S PLAN IS A PARAMETER. The accepted set and the withheld set are carried BY the +// projection -- fields the authority fills from one history load -- so the fold reads both from +// the plan it was handed rather than re-deriving them from the public carrier. That is // what makes a caller-supplied plan forecastable at all: a second read would have answered about // the public roadmap while the nodes came from the caller's. fn roadmap_schedule_forecast_over( @@ -872,11 +872,11 @@ fn roadmap_schedule_forecast_over( match plan { RoadmapAuthorityProjectionRefused { detail: detail } => ScheduleForecastRefused { refusals: [ForecastRoadmapAuthorityRefused { detail: detail }] } - RoadmapAuthorityProjected { doc: _, accepted: accepted } => + RoadmapAuthorityProjected { doc: _, accepted: accepted, withheld: withheld } => let builds = roadmap_cycle_time_observation_builds() schedule_forecast( - nodes: active_roadmap_nodes_for_accepted(accepted: accepted), - edges: active_roadmap_edges_for_accepted(accepted: accepted), + nodes: active_roadmap_nodes_for_accepted(accepted: accepted, withheld: withheld), + edges: active_roadmap_edges_for_accepted(accepted: accepted, withheld: withheld), observations: accepted_cycle_time_observations(builds: builds), history_refusals: cycle_time_history_refusals(builds: builds), population_exclusions: cycle_time_population_exclusions(builds: builds), diff --git a/dag/gunbc/roadmap/roadmap_launch_admission.dag b/dag/gunbc/roadmap/roadmap_launch_admission.dag index 057ba8462fc..bc3d8402437 100644 --- a/dag/gunbc/roadmap/roadmap_launch_admission.dag +++ b/dag/gunbc/roadmap/roadmap_launch_admission.dag @@ -474,7 +474,7 @@ fn launch_graph_of_document(doc: RoadmapDocument) -> LaunchGraphStanding { fn launch_graph_of_projection(proj: RoadmapAuthorityProjection) -> LaunchGraphStanding { match proj { RoadmapAuthorityProjectionRefused { detail } => LaunchGraphUnobserved { detail: detail } - RoadmapAuthorityProjected { doc, accepted: _ } => launch_graph_of_document(doc: doc) + RoadmapAuthorityProjected { doc, accepted: _, withheld: _ } => launch_graph_of_document(doc: doc) } } diff --git a/dag/gunbc/roadmap/roadmap_model.dag b/dag/gunbc/roadmap/roadmap_model.dag index 4a099cc4a19..419d8596897 100644 --- a/dag/gunbc/roadmap/roadmap_model.dag +++ b/dag/gunbc/roadmap/roadmap_model.dag @@ -6,6 +6,7 @@ import std.content_hash { content_hash_atom, content_hash_combine_structural, co import gunbc.roadmap_status { RoadmapItem, DriftVerdict, Signoff, signoff_accepts, signoff_drift, TicketFields, line_ticket, + DerivableLine, AuthoredLine, PlainLine, SupersededLine, TicketLine, RedControlEvidence, HandbackEvidence, RedControlNotRun, RedControlExecuted, HandbackNotDelivered, HandbackDelivered, @@ -162,6 +163,33 @@ fn receipt_matches_node(r: RoadmapAcceptanceReceipt, rn: RoadmapNode) -> Bool { } } +type ReceiptNodeMatchVerdict + = ReceiptMatchesNode + | LiveReceiptOnSupersededLine { node: RoadmapNodeId } + | ReceiptDoesNotMatchNode + +fn node_line_is_superseded(rn: RoadmapNode) -> Bool { + match rn.line { + DerivableLine { prs: _, title: _, description: _ } => false + AuthoredLine { done: _, content: _ } => false + PlainLine { content: _ } => false + SupersededLine { by: _, content: _ } => true + TicketLine { done: _, ticket: _ } => false + } +} + +fn receipt_node_match_verdict(r: RoadmapAcceptanceReceipt, rn: RoadmapNode) -> ReceiptNodeMatchVerdict { + if !(r.node == rn.node) { + ReceiptDoesNotMatchNode + } else { + if node_line_is_superseded(rn: rn) { + LiveReceiptOnSupersededLine { node: rn.node } + } else { + if receipt_matches_node(r: r, rn: rn) { ReceiptMatchesNode } else { ReceiptDoesNotMatchNode } + } + } +} + fn receipts_for_node(receipts: List, id: RoadmapNodeId) -> List { receipts |> filter(r => r.node == id) } @@ -186,8 +214,38 @@ fn node_accepted(receipts: List, rn: RoadmapNode) -> B // arms. type AcceptanceNodeReopensActiveFrontier {} +type AcceptanceNodeRemainsSuperseded {} + +// The revocation disposition names the FRONTIER CONSEQUENCE, not the supersession fact. +// SupersededLine already owns terminal standing and `by`. AcceptanceNodeRemainsSuperseded is +// deliberately payload-free: it says the revoked receipt stays off the active frontier because the +// referenced node remains superseded. The join to that node's existing SupersededLine is the +// wall; `by` is read from the line, never re-authored on the event. +type AcceptanceRevocationDisposition + = AcceptanceNodeReopensActiveFrontier + | AcceptanceNodeRemainsSuperseded + +fn revocation_reopens_active_frontier(disposition: AcceptanceRevocationDisposition) -> Bool { + match disposition { + AcceptanceNodeReopensActiveFrontier {} => true + AcceptanceNodeRemainsSuperseded {} => false + } +} -type AcceptanceRevocationDisposition = AcceptanceNodeReopensActiveFrontier +fn revocation_disposition_eq(a: AcceptanceRevocationDisposition, b: AcceptanceRevocationDisposition) -> Bool { + match a { + AcceptanceNodeReopensActiveFrontier {} => + match b { + AcceptanceNodeReopensActiveFrontier {} => true + AcceptanceNodeRemainsSuperseded {} => false + } + AcceptanceNodeRemainsSuperseded {} => + match b { + AcceptanceNodeReopensActiveFrontier {} => false + AcceptanceNodeRemainsSuperseded {} => true + } + } +} type RoadmapAcceptanceEvent = AcceptanceRecorded { receipt: RoadmapAcceptanceReceipt } @@ -305,12 +363,7 @@ fn acceptance_event_eq(a: RoadmapAcceptanceEvent, b: RoadmapAcceptanceEvent) -> AcceptanceRecorded { receipt: _ } => false AcceptanceRevoked { exact_prior_receipt: bpr, disposition: bd, reason: br, revoked_by: bb, revoked_on: bo } => acceptance_receipt_eq(a: apr, b: bpr) - && match ad { - AcceptanceNodeReopensActiveFrontier {} => - match bd { - AcceptanceNodeReopensActiveFrontier {} => true - } - } + && revocation_disposition_eq(a: ad, b: bd) && ar == br && ab == bb && ao == bo @@ -422,6 +475,11 @@ fn acceptance_revocation_disposition_digest( tag: "roadmap-acceptance-reopens-active-frontier-v1", payload: content_hash_atom(value: "AcceptanceNodeReopensActiveFrontier" as NonEmptyStr), ) + AcceptanceNodeRemainsSuperseded {} => + content_hash_tagged_structural( + tag: "roadmap-acceptance-remains-superseded-v1", + payload: content_hash_atom(value: "AcceptanceNodeRemainsSuperseded" as NonEmptyStr), + ) } } @@ -583,6 +641,63 @@ fn ever_recorded_receipt_accounted_for( || receipt_present_exact(receipts: revoked, receipt: receipt) } +type LiveReceiptDeclarationJoin + = LiveReceiptsJoinDeclared + | LiveReceiptJoinsSupersededLine { node: RoadmapNodeId } + | LiveReceiptDoesNotMatchDeclaredNode { node: RoadmapNodeId } + | LiveReceiptJoinsUndeclaredNode { node: RoadmapNodeId } + | LiveReceiptJoinsAmbiguousDeclaredNode { node: RoadmapNodeId } + +fn live_receipt_join_declared_node( + r: RoadmapAcceptanceReceipt, + nodes: List, +) -> LiveReceiptDeclarationJoin { + let found = nodes |> filter(n => n.node == r.node) + if count(found) == 0 { + LiveReceiptJoinsUndeclaredNode { node: r.node } + } else { + if count(found) > 1 { + LiveReceiptJoinsAmbiguousDeclaredNode { node: r.node } + } else { + match first(found) { + Absent => LiveReceiptJoinsUndeclaredNode { node: r.node } + Present { value: rn } => + match receipt_node_match_verdict(r: r, rn: rn) { + ReceiptMatchesNode => LiveReceiptsJoinDeclared + LiveReceiptOnSupersededLine { node: node } => + LiveReceiptJoinsSupersededLine { node: node } + ReceiptDoesNotMatchNode => + LiveReceiptDoesNotMatchDeclaredNode { node: r.node } + } + } + } + } +} + +fn live_receipts_join_declared_nodes( + receipts: List, + nodes: List, +) -> LiveReceiptDeclarationJoin { + fold( + receipts, + init: LiveReceiptsJoinDeclared, + f: fn(acc, r) { + match acc { + LiveReceiptJoinsSupersededLine { node: n } => + LiveReceiptJoinsSupersededLine { node: n } + LiveReceiptDoesNotMatchDeclaredNode { node: n } => + LiveReceiptDoesNotMatchDeclaredNode { node: n } + LiveReceiptJoinsUndeclaredNode { node: n } => + LiveReceiptJoinsUndeclaredNode { node: n } + LiveReceiptJoinsAmbiguousDeclaredNode { node: n } => + LiveReceiptJoinsAmbiguousDeclaredNode { node: n } + LiveReceiptsJoinDeclared => + live_receipt_join_declared_node(r: r, nodes: nodes) + } + }, + ) +} + fn project_live_acceptance_receipts(history: List) -> List { match replay_acceptance_history(events: history) { Present { value: state } => state.live @@ -590,6 +705,98 @@ fn project_live_acceptance_receipts(history: List) -> Li } } +type RemainsSupersededRevocationJoin + = RemainsSupersededRevocationsJoined + | RemainsSupersededRevocationOnNonSupersededNode { node: RoadmapNodeId } + | RemainsSupersededRevocationOnUndeclaredNode { node: RoadmapNodeId } + | RemainsSupersededRevocationOnAmbiguousDeclaredNode { node: RoadmapNodeId } + +fn join_remains_superseded_to_declared_line( + node: RoadmapNodeId, + nodes: List, +) -> RemainsSupersededRevocationJoin { + let found = nodes |> filter(n => n.node == node) + if count(found) == 0 { + RemainsSupersededRevocationOnUndeclaredNode { node: node } + } else { + if count(found) > 1 { + RemainsSupersededRevocationOnAmbiguousDeclaredNode { node: node } + } else { + match first(found) { + Absent => RemainsSupersededRevocationOnUndeclaredNode { node: node } + Present { value: rn } => + if node_line_is_superseded(rn: rn) { + RemainsSupersededRevocationsJoined + } else { + RemainsSupersededRevocationOnNonSupersededNode { node: node } + } + } + } + } +} + +fn remains_superseded_revocation_event_join( + event: RoadmapAcceptanceEvent, + nodes: List, +) -> RemainsSupersededRevocationJoin { + match event { + AcceptanceRecorded { receipt: _ } => RemainsSupersededRevocationsJoined + AcceptanceRevoked { exact_prior_receipt, disposition, reason: _, revoked_by: _, revoked_on: _ } => + match disposition { + AcceptanceNodeReopensActiveFrontier {} => RemainsSupersededRevocationsJoined + AcceptanceNodeRemainsSuperseded {} => + join_remains_superseded_to_declared_line(node: exact_prior_receipt.node, nodes: nodes) + } + } +} + +fn remains_superseded_revocations_join( + history: List, + nodes: List, +) -> RemainsSupersededRevocationJoin { + fold( + history, + init: RemainsSupersededRevocationsJoined, + f: fn(acc, event) { + match acc { + RemainsSupersededRevocationOnNonSupersededNode { node: n } => + RemainsSupersededRevocationOnNonSupersededNode { node: n } + RemainsSupersededRevocationOnUndeclaredNode { node: n } => + RemainsSupersededRevocationOnUndeclaredNode { node: n } + RemainsSupersededRevocationOnAmbiguousDeclaredNode { node: n } => + RemainsSupersededRevocationOnAmbiguousDeclaredNode { node: n } + RemainsSupersededRevocationsJoined => + remains_superseded_revocation_event_join(event: event, nodes: nodes) + } + }, + ) +} + +// Consequence fold only. Callers that admit a withheld set MUST first +// remains_superseded_revocations_join against the declared nodes; a RemainsSuperseded arm that +// does not join a SupersededLine is a projection refusal, not an empty withheld list. +fn node_ids_held_off_active_frontier(history: List) -> List { + fold( + history, + init: [] as List, + f: fn(acc, event) { + match event { + AcceptanceRecorded { receipt } => + acc |> filter(id => !(id == receipt.node)) + AcceptanceRevoked { exact_prior_receipt, disposition, reason: _, revoked_by: _, revoked_on: _ } => + if revocation_reopens_active_frontier(disposition: disposition) { + acc |> filter(id => !(id == exact_prior_receipt.node)) + } else { + concat( + acc |> filter(id => !(id == exact_prior_receipt.node)), + [exact_prior_receipt.node], + ) + } + } + }, + ) +} + fn acceptance_history_integrity_verdict( history: List, prior_history: List, diff --git a/dag/gunbc/roadmap/roadmap_page.dag b/dag/gunbc/roadmap/roadmap_page.dag index 83d8801d057..bcaf90357c1 100644 --- a/dag/gunbc/roadmap/roadmap_page.dag +++ b/dag/gunbc/roadmap/roadmap_page.dag @@ -26,8 +26,8 @@ import gunbc.roadmap_authority { roadmap_authority_projection, RoadmapAuthorityProjection, RoadmapAuthorityProjected, RoadmapAuthorityProjectionRefused, - accepted_roadmap_node_ids_projection, - AcceptedRoadmapNodeIdsProjected, AcceptedRoadmapNodeIdsProjectionRefused, + frontier_sets_from_live_history, + FrontierSetsProjected, FrontierSetsProjectionRefused, declared_roadmap_nodes, ClosingContractTaskPair, closing_contract_task_pairs_for_accepted, closing_contract_family_claim, } @@ -131,15 +131,15 @@ fn finish_line_progress_markup_for_accepted(accepted_ids: List) - } fn finish_line_progress_markup() -> Fragment { - match accepted_roadmap_node_ids_projection() { - AcceptedRoadmapNodeIdsProjectionRefused { detail: detail } => + match frontier_sets_from_live_history() { + FrontierSetsProjectionRefused { detail: detail } => el_class("section", "finish-line-progress", [ el("h2", [ txt("v1 exit: four finish lines") ]), el_class("p", "finish-line-refused", [ txt(concat("acceptance carrier refused: ", detail)), ]), ]) - AcceptedRoadmapNodeIdsProjected { ids: accepted_ids } => + FrontierSetsProjected { accepted: accepted_ids, withheld: _ } => finish_line_progress_markup_for_accepted(accepted_ids: accepted_ids) } } @@ -1034,8 +1034,11 @@ fn live_work_family_decls() -> List { [ WorkFamilyDecl { id: closing_contract_family_id(), claim: closing_contract_family_claim } ] } -fn live_work_family_members_for_accepted(accepted: List) -> List { - closing_contract_task_pairs_for_accepted(accepted: accepted) |> map(p => WorkFamilyMemberFact { +fn live_work_family_members_for_accepted( + accepted: List, + withheld: List, +) -> List { + closing_contract_task_pairs_for_accepted(accepted: accepted, withheld: withheld) |> map(p => WorkFamilyMemberFact { family_id: closing_contract_family_id(), task_node: p.task.node as String, subject: p.subject, @@ -1050,6 +1053,7 @@ fn daily_workspace_view_of_for_accepted( doc: RoadmapDocument, merged: List, accepted_ids: List, + withheld: List, attempts: List, attempts_refused: String?, standings: RoadmapStandings, @@ -1073,13 +1077,14 @@ fn daily_workspace_view_of_for_accepted( program: Present { value: v1_exit_program_progress_view_for_accepted(accepted_ids: accepted_ids, ready_count: ready_count) }, observation: observation, families: live_work_family_decls(), - members: live_work_family_members_for_accepted(accepted: accepted_ids)) + members: live_work_family_members_for_accepted(accepted: accepted_ids, withheld: withheld)) } fn roadmap_daily_workspace_page_impl_for_accepted( doc: RoadmapDocument, merged: List, accepted_ids: List, + withheld: List, main_prefix: List, attempts: List, attempts_refused: String?, @@ -1090,6 +1095,7 @@ fn roadmap_daily_workspace_page_impl_for_accepted( doc: doc, merged: merged, accepted_ids: accepted_ids, + withheld: withheld, attempts: attempts, attempts_refused: attempts_refused, standings: standings, launch: launch, @@ -1245,7 +1251,7 @@ fn roadmap_page_for_projection_launch(proj: RoadmapAuthorityProjection, launch: ], launch: launch, ) - RoadmapAuthorityProjected { doc: doc, accepted: accepted } => + RoadmapAuthorityProjected { doc: doc, accepted: accepted, withheld: _ } => roadmap_page_impl( doc: doc, merged: authored_merged_prs(), @@ -1274,11 +1280,11 @@ fn roadmap_page_for_projection_launch(proj: RoadmapAuthorityProjection, launch: // own "the event carrier is not consulted" already claimed and did not deliver. fn roadmap_daily_workspace_page(doc: RoadmapDocument, merged: List) -> Fragment { - roadmap_daily_workspace_page_impl_for_accepted(doc: doc, merged: merged, accepted_ids: [], main_prefix: [], attempts: [], attempts_refused: none, standings: StandingsUnobserved { reason: "static render: the event carrier is not consulted" }, launch: launch_host_unobserved_static_render()) + roadmap_daily_workspace_page_impl_for_accepted(doc: doc, merged: merged, accepted_ids: [], withheld: [], main_prefix: [], attempts: [], attempts_refused: none, standings: StandingsUnobserved { reason: "static render: the event carrier is not consulted" }, launch: launch_host_unobserved_static_render()) } fn roadmap_daily_workspace_page_launch(doc: RoadmapDocument, merged: List, launch: LaunchHostStanding) -> Fragment { - roadmap_daily_workspace_page_impl_for_accepted(doc: doc, merged: merged, accepted_ids: [], main_prefix: [], attempts: [], attempts_refused: none, standings: StandingsUnobserved { reason: "static render: the event carrier is not consulted" }, launch: launch) + roadmap_daily_workspace_page_impl_for_accepted(doc: doc, merged: merged, accepted_ids: [], withheld: [], main_prefix: [], attempts: [], attempts_refused: none, standings: StandingsUnobserved { reason: "static render: the event carrier is not consulted" }, launch: launch) } // The served daily workspace consumes the OBSERVED attempt evidence at render (the tick decomposes the belt observation and passes progress rows or the located refusal), so the active band and every server-rendered activity region are real facts, not placeholders — the same decided views the /workflow.json wire carries, giving the client poll an identical starting DOM (the parity obligation's server half). The plan is a parameter because the caller that renders it is the caller that chose it. @@ -1295,6 +1301,7 @@ fn roadmap_daily_workspace_page_for_projection_observed( doc: RoadmapDocument { preamble: [], lead_lanes: [], sections: [] }, merged: [], accepted_ids: [], + withheld: [], main_prefix: [ dashboard_instance_banner(), roadmap_authority_refusal_markup(detail: detail), @@ -1304,11 +1311,12 @@ fn roadmap_daily_workspace_page_for_projection_observed( standings: standings, launch: launch, ) - RoadmapAuthorityProjected { doc: doc, accepted: accepted } => + RoadmapAuthorityProjected { doc: doc, accepted: accepted, withheld: withheld } => roadmap_daily_workspace_page_impl_for_accepted( doc: doc, merged: authored_merged_prs(), accepted_ids: accepted, + withheld: withheld, main_prefix: [ dashboard_instance_banner(), ], diff --git a/dag/gunbc/roadmap/roadmap_site_surface_observe.dag b/dag/gunbc/roadmap/roadmap_site_surface_observe.dag index 9b540f72cdf..6459bfc1d74 100644 --- a/dag/gunbc/roadmap/roadmap_site_surface_observe.dag +++ b/dag/gunbc/roadmap/roadmap_site_surface_observe.dag @@ -60,7 +60,7 @@ fn subject_identity_for_projection(proj: RoadmapAuthorityProjection) -> Fnv1a64S tag: "roadmap-site-surface-subject-refused/v1" as NonEmptyStr, payload: content_hash_atom(value: detail as NonEmptyStr), ) - RoadmapAuthorityProjected { doc: _, accepted: accepted } => + RoadmapAuthorityProjected { doc: _, accepted: accepted, withheld: _ } => content_hash_combine_structural( left: acceptance_identity_from_accepted(accepted: accepted), right: content_hash_combine_structural( diff --git a/dag/gunbc/roadmap/roadmap_spawner.dag b/dag/gunbc/roadmap/roadmap_spawner.dag index 395f9cad515..3568029c9a9 100644 --- a/dag/gunbc/roadmap/roadmap_spawner.dag +++ b/dag/gunbc/roadmap/roadmap_spawner.dag @@ -425,7 +425,7 @@ fn roadmap_dispatch_file_content_for_projection(proj: RoadmapAuthorityProjection json_kv(key: "refused", value: json_bool(b: true)), json_kv(key: "detail", value: json_string(s: detail)), ])) - RoadmapAuthorityProjected { doc: doc, accepted: _ } => + RoadmapAuthorityProjected { doc: doc, accepted: _, withheld: _ } => serialize_json(v: json_object(members: [ json_kv(key: "schema", value: json_string(s: "roadmap-dispatch-file/v1")), json_kv(key: "brief_template", value: json_string(s: dispatch_brief_template)), diff --git a/dag/test/claim/roadmap/roadmap_authority_test.dag b/dag/test/claim/roadmap/roadmap_authority_test.dag index cbfa31b86c1..fc09c27a3ba 100644 --- a/dag/test/claim/roadmap/roadmap_authority_test.dag +++ b/dag/test/claim/roadmap/roadmap_authority_test.dag @@ -15,9 +15,15 @@ import gunbc.roadmap_authority { RoadmapAcceptanceEventHistoryLoadRefused, RoadmapAcceptanceReceiptsProjected, RoadmapAcceptanceReceiptsProjectionRefused, - accepted_roadmap_node_ids_projection, - AcceptedRoadmapNodeIdsProjected, - AcceptedRoadmapNodeIdsProjectionRefused, + withheld_node_ids_from_live_history, + WithheldNodeIdsProjected, + WithheldNodeIdsProjectionRefused, + active_roadmap_nodes_projection, + ActiveRoadmapNodesProjected, + ActiveRoadmapNodesProjectionRefused, + active_roadmap_edges_projection, + ActiveRoadmapEdgesProjected, + ActiveRoadmapEdgesProjectionRefused, roadmap_authority, authored_merged_prs, observation_scoped_run_seed_growth_justification, @@ -27,6 +33,11 @@ import gunbc.roadmap_authority { projected_roadmap_dependency_edges_projection, ProjectedRoadmapDependencyEdgesProjected, ProjectedRoadmapDependencyEdgesProjectionRefused, + startable_nodes_missing_closing_contract_for_accepted, + frontier_sets_from_events, + frontier_sets_from_live_history, + FrontierSetsProjected, + FrontierSetsProjectionRefused, } import gunbc.roadmap_spawner { roadmap_rendered_ghost_count, @@ -66,6 +77,18 @@ import gunbc.roadmap_model { AcceptanceRecorded, AcceptanceRevoked, AcceptanceNodeReopensActiveFrontier, + AcceptanceNodeRemainsSuperseded, + remains_superseded_revocations_join, + join_remains_superseded_to_declared_line, + RemainsSupersededRevocationsJoined, + RemainsSupersededRevocationOnNonSupersededNode, + RemainsSupersededRevocationOnUndeclaredNode, + RemainsSupersededRevocationOnAmbiguousDeclaredNode, + receipt_node_match_verdict, + ReceiptMatchesNode, + LiveReceiptOnSupersededLine, + ReceiptDoesNotMatchNode, + node_ids_held_off_active_frontier, node_accepted, receipt_matches_node, node_criteria_digest, @@ -77,6 +100,7 @@ import gunbc.roadmap_model { roadmap_parent_ids, is_top_level, Pointer, + RoadmapNodeIdentity, IntricacyLow, IntricacyMedium, IntricacyHigh, @@ -116,22 +140,29 @@ data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly fn nodes() -> List { declared_roadmap_nodes() } fn edges() -> List { declared_roadmap_edges() } fn active_nodes() -> List { - match live_accepted_node_ids() { - Present { value: accepted } => active_roadmap_nodes_for_accepted(accepted: accepted) - Absent => [] + match active_roadmap_nodes_projection() { + ActiveRoadmapNodesProjectionRefused { detail: _ } => [] + ActiveRoadmapNodesProjected { nodes: nodes } => nodes } } fn active_edges() -> List { - match live_accepted_node_ids() { - Present { value: accepted } => active_roadmap_edges_for_accepted(accepted: accepted) - Absent => [] + match active_roadmap_edges_projection() { + ActiveRoadmapEdgesProjectionRefused { detail: _ } => [] + ActiveRoadmapEdgesProjected { edges: edges } => edges } } fn live_accepted_node_ids() -> List? { - match accepted_roadmap_node_ids_projection() { - AcceptedRoadmapNodeIdsProjected { ids: ids } => Present { value: ids } - AcceptedRoadmapNodeIdsProjectionRefused { detail: _ } => Absent + match frontier_sets_from_live_history() { + FrontierSetsProjected { accepted: ids, withheld: _ } => Present { value: ids } + FrontierSetsProjectionRefused { detail: _ } => Absent + } +} + +fn live_withheld_node_ids() -> List? { + match withheld_node_ids_from_live_history() { + WithheldNodeIdsProjected { ids: ids } => Present { value: ids } + WithheldNodeIdsProjectionRefused { detail: _ } => Absent } } @@ -329,8 +360,13 @@ test fn witness_active_set_is_declared_minus_accepted() -> Bool { && (accepted |> any(a => a == "2-claim-indexed-evidence")) && (accepted |> any(a => a == "2-scm-compatibility-shape")) && (accepted |> any(a => a == "2-scm-p0-landing-spine")) - && count(active_nodes()) == count(nodes()) - count(accepted) - && all(active_nodes(), n => !(accepted |> any(a => a == n.node))) + && match live_withheld_node_ids() { + Absent => false + Present { value: withheld } => + count(active_nodes()) == count(nodes()) - count(accepted) - count(withheld) + && all(active_nodes(), n => !(accepted |> any(a => a == n.node))) + && all(active_nodes(), n => !(withheld |> any(w => w == n.node))) + } && all(accepted, a => id_exists(id: a)) } } @@ -342,7 +378,212 @@ test fn witness_acceptance_receipts_are_valid_and_unique() -> Bool { count(receipts) > 0 && all(receipts, r => count(receipts |> filter(x => x.node == r.node)) == 1) && all(receipts, r => id_exists(id: r.node)) - && all(receipts, r => all(declared_node(id: r.node as String), n => receipt_matches_node(r: r, rn: n))) + && all(receipts, r => all(declared_node(id: r.node as String), n => + match receipt_node_match_verdict(r: r, rn: n) { + ReceiptMatchesNode => true + LiveReceiptOnSupersededLine { node: _ } => false + ReceiptDoesNotMatchNode => false + } + )) + } +} + +test fn witness_live_receipt_on_superseded_line_refuses_with_typed_cause() -> Bool { + let victims = declared_node(id: "entry-graph-union-construction") + count(victims) == 1 + && all(victims, n => + match receipt_node_match_verdict( + r: receipt_fixture(node: "entry-graph-union-construction", digest: tchash(s: "3502539e920d9e40")), + rn: n, + ) { + LiveReceiptOnSupersededLine { node } => node == n.node + ReceiptMatchesNode => false + ReceiptDoesNotMatchNode => false + } + ) +} + +test fn witness_superseded_revocation_does_not_reopen_active_frontier() -> Bool { + !active_id_exists(id: tnid(s: "entry-graph-union-construction")) + && match live_withheld_node_ids() { + Absent => false + Present { value: withheld } => + withheld |> any(w => w == tnid(s: "entry-graph-union-construction")) + } +} + +test fn witness_reopen_revocation_returns_node_to_active_frontier() -> Bool { + let prior = live_acceptance_event_history() + let receipt = first( + project_live_acceptance_receipts(history: prior) + |> filter(r => r.node == tnid(s: "namespace-occurrence-transport")), + ) + let reopened = concat(prior, [ + AcceptanceRevoked { + exact_prior_receipt: receipt, + disposition: AcceptanceNodeReopensActiveFrontier {}, + reason: "fixture reopen revocation still returns the node to the active frontier" as NonEmptyStr, + revoked_by: "operator" as NonEmptyStr, + revoked_on: "2026-09-13" as NonEmptyStr, + }, + ]) + let accepted = declared_roadmap_nodes() + |> filter(n => node_accepted(receipts: project_live_acceptance_receipts(history: reopened), rn: n)) + |> map(n => n.node) + let withheld = node_ids_held_off_active_frontier(history: reopened) + active_roadmap_nodes_for_accepted(accepted: accepted, withheld: withheld) + |> any(n => n.node == tnid(s: "namespace-occurrence-transport")) +} + +test fn witness_revocation_frontier_disposition_discriminates() -> Bool { + witness_superseded_revocation_does_not_reopen_active_frontier() + && witness_reopen_revocation_returns_node_to_active_frontier() +} + +test fn witness_live_remains_superseded_revocations_join_superseded_lines() -> Bool { + match remains_superseded_revocations_join( + history: live_acceptance_event_history(), + nodes: declared_roadmap_nodes(), + ) { + RemainsSupersededRevocationsJoined => + all( + declared_node(id: "entry-graph-union-construction"), + n => match n.line { + SupersededLine { by: _, content: _ } => true + TicketLine { done: _, ticket: _ } => false + AuthoredLine { done: _, content: _ } => false + PlainLine { content: _ } => false + DerivableLine { prs: _, title: _, description: _ } => false + }, + ) + RemainsSupersededRevocationOnNonSupersededNode { node: _ } => false + RemainsSupersededRevocationOnUndeclaredNode { node: _ } => false + RemainsSupersededRevocationOnAmbiguousDeclaredNode { node: _ } => false + } +} + +test fn witness_remains_superseded_revocation_on_ticket_line_refuses() -> Bool { + let victims = declared_node(id: "namespace-occurrence-transport") + let prior = live_acceptance_event_history() + let receipt = first( + project_live_acceptance_receipts(history: prior) + |> filter(r => r.node == tnid(s: "namespace-occurrence-transport")), + ) + count(victims) == 1 + && all(victims, n => + match n.line { + TicketLine { done: _, ticket: _ } => true + SupersededLine { by: _, content: _ } => false + AuthoredLine { done: _, content: _ } => false + PlainLine { content: _ } => false + DerivableLine { prs: _, title: _, description: _ } => false + } + ) + && match remains_superseded_revocations_join( + history: concat(prior, [ + AcceptanceRevoked { + exact_prior_receipt: receipt, + disposition: AcceptanceNodeRemainsSuperseded {}, + reason: "fixture remains-superseded on a live ticket line must refuse" as NonEmptyStr, + revoked_by: "operator" as NonEmptyStr, + revoked_on: "2026-09-13" as NonEmptyStr, + }, + ]), + nodes: declared_roadmap_nodes(), + ) { + RemainsSupersededRevocationOnNonSupersededNode { node } => + node == tnid(s: "namespace-occurrence-transport") + RemainsSupersededRevocationsJoined => false + RemainsSupersededRevocationOnUndeclaredNode { node: _ } => false + RemainsSupersededRevocationOnAmbiguousDeclaredNode { node: _ } => false + } +} + +test fn witness_remains_superseded_revocation_on_undeclared_node_refuses() -> Bool { + match remains_superseded_revocations_join( + history: [ + AcceptanceRevoked { + exact_prior_receipt: receipt_fixture( + node: "not-a-declared-roadmap-node-for-join-red", + digest: tchash(s: "0123456789abcdef"), + ), + disposition: AcceptanceNodeRemainsSuperseded {}, + reason: "fixture remains-superseded on an undeclared node must refuse" as NonEmptyStr, + revoked_by: "operator" as NonEmptyStr, + revoked_on: "2026-09-13" as NonEmptyStr, + }, + ], + nodes: declared_roadmap_nodes(), + ) { + RemainsSupersededRevocationOnUndeclaredNode { node } => + node == tnid(s: "not-a-declared-roadmap-node-for-join-red") + RemainsSupersededRevocationsJoined => false + RemainsSupersededRevocationOnNonSupersededNode { node: _ } => false + RemainsSupersededRevocationOnAmbiguousDeclaredNode { node: _ } => false + } +} + +test fn witness_ambiguous_declared_node_refuses_remains_superseded_join() -> Bool { + match join_remains_superseded_to_declared_line( + node: tnid(s: "red-fixture"), + nodes: [ + red_fixture(line: red_ticket(done: false), signoff: Unsigned), + red_fixture(line: SupersededLine { by: "successor", content: "fixture" }, signoff: Unsigned), + ], + ) { + RemainsSupersededRevocationOnAmbiguousDeclaredNode { node } => + node == tnid(s: "red-fixture") + RemainsSupersededRevocationsJoined => false + RemainsSupersededRevocationOnNonSupersededNode { node: _ } => false + RemainsSupersededRevocationOnUndeclaredNode { node: _ } => false + } +} + +test fn witness_orphan_reopen_revocation_refuses_frontier_sets() -> Bool { + match frontier_sets_from_events(events: [ + AcceptanceRevoked { + exact_prior_receipt: receipt_fixture( + node: "namespace-occurrence-transport", + digest: tchash(s: "0123456789abcdef"), + ), + disposition: AcceptanceNodeReopensActiveFrontier {}, + reason: "fixture orphan reopen revocation must refuse the frontier projection" as NonEmptyStr, + revoked_by: "operator" as NonEmptyStr, + revoked_on: "2026-09-13" as NonEmptyStr, + }, + ]) { + FrontierSetsProjectionRefused { detail } => + detail == "acceptance-history-unreplayable" + FrontierSetsProjected { accepted: _, withheld: _ } => false + } +} + +test fn witness_record_after_remains_superseded_on_superseded_line_refuses_frontier_sets() -> Bool { + let prior = live_acceptance_event_history() + match first( + prior |> filter(e => + match e { + AcceptanceRecorded { receipt: r } => + r.node == tnid(s: "entry-graph-union-construction") + AcceptanceRevoked { exact_prior_receipt: _, disposition: _, reason: _, revoked_by: _, revoked_on: _ } => + false + } + ), + ) { + Absent => false + Present { value: recorded } => + match recorded { + AcceptanceRevoked { exact_prior_receipt: _, disposition: _, reason: _, revoked_by: _, revoked_on: _ } => + false + AcceptanceRecorded { receipt } => + match frontier_sets_from_events(events: concat(prior, [ + AcceptanceRecorded { receipt: receipt }, + ])) { + FrontierSetsProjectionRefused { detail } => + detail == concat("live-receipt-on-superseded-line:", "entry-graph-union-construction") + FrontierSetsProjected { accepted: _, withheld: _ } => false + } + } } } @@ -877,15 +1118,39 @@ test fn witness_fleet_state_frontier_authority_is_host_converge_carrier() -> Boo } test fn witness_projected_dependency_edges_include_active_edges() -> Bool { - match accepted_roadmap_node_ids_projection() { - AcceptedRoadmapNodeIdsProjected { ids: accepted } => + match frontier_sets_from_live_history() { + FrontierSetsProjected { accepted: accepted, withheld: withheld } => match projected_roadmap_dependency_edges_projection() { ProjectedRoadmapDependencyEdgesProjected { edges: projected } => - fold(active_roadmap_edges_for_accepted(accepted: accepted), init: true, f: fn(acc, edge) { - acc && projected |> any(p => p.child == edge.child && p.parent == edge.parent) - }) + fold( + active_roadmap_edges_for_accepted(accepted: accepted, withheld: withheld), + init: true, + f: fn(acc, edge) { + acc && projected |> any(p => p.child == edge.child && p.parent == edge.parent) + } + ) ProjectedRoadmapDependencyEdgesProjectionRefused { detail: _ } => false } - AcceptedRoadmapNodeIdsProjectionRefused { detail: _ } => false + FrontierSetsProjectionRefused { detail: _ } => false + } +} + +test fn witness_withheld_sized_subject_does_not_mint_closing_contract_task() -> Bool { + match live_accepted_node_ids() { + Absent => false + Present { value: accepted } => + let unfiltered = startable_nodes_missing_closing_contract_for_accepted( + accepted: accepted, + withheld: [], + ) + if count(unfiltered) == 0 { + false + } else { + let victim = first(unfiltered) + !(startable_nodes_missing_closing_contract_for_accepted( + accepted: accepted, + withheld: [victim.node], + ) |> any(x => x.node == victim.node)) + } } } diff --git a/dag/test/claim/roadmap/roadmap_closing_contract_task_witness_test.dag b/dag/test/claim/roadmap/roadmap_closing_contract_task_witness_test.dag index 68aaf1f1312..ca888ca986f 100644 --- a/dag/test/claim/roadmap/roadmap_closing_contract_task_witness_test.dag +++ b/dag/test/claim/roadmap/roadmap_closing_contract_task_witness_test.dag @@ -6,7 +6,7 @@ import gunbc.roadmap_spawner { node_is_sized } import gunbc.roadmap_model { RoadmapNode } test fn an_unsized_node_mints_no_closing_contract_task() -> Bool { - let candidates = startable_nodes_missing_closing_contract_for_accepted(accepted: []) + let candidates = startable_nodes_missing_closing_contract_for_accepted(accepted: [], withheld: []) let has_unsized_declared = any(declared_roadmap_nodes(), n => !node_is_sized(n: n)) has_unsized_declared && all(candidates, n => node_is_sized(n: n)) } diff --git a/dag/test/claim/roadmap/roadmap_focus_witness_test.dag b/dag/test/claim/roadmap/roadmap_focus_witness_test.dag index e8373549398..87eb03be4d7 100644 --- a/dag/test/claim/roadmap/roadmap_focus_witness_test.dag +++ b/dag/test/claim/roadmap/roadmap_focus_witness_test.dag @@ -9,11 +9,12 @@ import gunbc.roadmap_status { TicketLine, TicketFields, Unsigned } import gunbc.roadmap_execution_contract { ExecutionContractUnspecified } import gunbc.roadmap_authority { - active_roadmap_nodes_for_accepted, - active_roadmap_edges_for_accepted, - accepted_roadmap_node_ids_projection, - AcceptedRoadmapNodeIdsProjected, - AcceptedRoadmapNodeIdsProjectionRefused, + active_roadmap_nodes_projection, + ActiveRoadmapNodesProjected, + ActiveRoadmapNodesProjectionRefused, + active_roadmap_edges_projection, + ActiveRoadmapEdgesProjected, + ActiveRoadmapEdgesProjectionRefused, roadmap_focus_selection, } import gunbc.roadmap_focus { @@ -47,18 +48,16 @@ data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly // check and still look correct on the focused page. fn all_nodes() -> List { - match accepted_roadmap_node_ids_projection() { - AcceptedRoadmapNodeIdsProjected { ids: accepted } => - active_roadmap_nodes_for_accepted(accepted: accepted) - AcceptedRoadmapNodeIdsProjectionRefused { detail: _ } => [] + match active_roadmap_nodes_projection() { + ActiveRoadmapNodesProjectionRefused { detail: _ } => [] + ActiveRoadmapNodesProjected { nodes: nodes } => nodes } } fn active_roadmap_edges() -> List { - match accepted_roadmap_node_ids_projection() { - AcceptedRoadmapNodeIdsProjected { ids: accepted } => - active_roadmap_edges_for_accepted(accepted: accepted) - AcceptedRoadmapNodeIdsProjectionRefused { detail: _ } => [] + match active_roadmap_edges_projection() { + ActiveRoadmapEdgesProjectionRefused { detail: _ } => [] + ActiveRoadmapEdgesProjected { edges: edges } => edges } } diff --git a/dag/test/claim/roadmap/roadmap_receipt_continuity_acceptance_fixture.dag b/dag/test/claim/roadmap/roadmap_receipt_continuity_acceptance_fixture.dag index e543793667f..1ff70905673 100644 --- a/dag/test/claim/roadmap/roadmap_receipt_continuity_acceptance_fixture.dag +++ b/dag/test/claim/roadmap/roadmap_receipt_continuity_acceptance_fixture.dag @@ -1,3 +1,3 @@ module test.claim.roadmap_receipt_continuity_acceptance_fixture -data receipt_continuity_acceptance_carrier_fixture_text: String = "{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"2-scm-git-upstream-model\",\"criteria_digest\":\"b3747b95baf099cc\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.manual.git_upstream_model_execution\",\"witness_fn\":\"witness_git_cli_fixture_hashes_projects_and_independently_reads_back\",\"executed_on\":\"2026-07-29\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/extdeps/git/object_store.dag\",\"further_artifacts\":[\"dag/test/claim/git_upstream_model_witness_test.dag\",\"dag/test/manual/git_upstream_model_execution_test.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-07-29\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"2-scm-mercurial-upstream-model\",\"criteria_digest\":\"c43b17d5134b111d\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.manual.mercurial_upstream_model_execution\",\"witness_fn\":\"witness_mercurial_cli_fixture_projects_and_independently_reads_back\",\"executed_on\":\"2026-07-29\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/extdeps/mercurial.dag\",\"further_artifacts\":[\"dag/test/claim/mercurial_upstream_model_witness_test.dag\",\"dag/test/manual/mercurial_upstream_model_execution_test.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-07-29\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"2-scm-pijul-upstream-model\",\"criteria_digest\":\"098c989bdc87dac7\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.manual.pijul_upstream_model_execution\",\"witness_fn\":\"witness_pijul_cli_fixture_reads_channel_sets_and_retained_conflict\",\"executed_on\":\"2026-07-29\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/extdeps/pijul.dag\",\"further_artifacts\":[\"dag/test/claim/pijul_upstream_model_witness_test.dag\",\"dag/test/manual/pijul_upstream_model_execution_test.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-07-29\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"2-claim-indexed-evidence\",\"criteria_digest\":\"2b81ac6aacf6a190\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.claim.claim_indexed_evidence_witness\",\"witness_fn\":\"witness_claim_evidence_roles_are_externally_grounded\",\"executed_on\":\"2026-07-29\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/std/claim_evidence.dag\",\"further_artifacts\":[\"dag/gunbc/provider_readiness_claim_evidence.dag\",\"dag/gunbc/os_install_claim_evidence.dag\",\"dag/gunbc/source_integration_claim_evidence.dag\",\"dag/test/claim/claim_indexed_evidence_witness_test.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-07-29\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"2-scm-compatibility-shape\",\"criteria_digest\":\"f023bb4e862d9e27\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.claim.scm_compatibility_shape_witness\",\"witness_fn\":\"witness_r1_acceptance_contract_holds\",\"executed_on\":\"2026-07-29\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/gunbc/scm_compatibility_shape.dag\",\"further_artifacts\":[\"dag/gunbc/scm_compatibility/git.dag\",\"dag/gunbc/scm_compatibility/mercurial.dag\",\"dag/gunbc/scm_compatibility/pijul.dag\",\"dag/test/claim/scm/scm_compatibility_shape_witness_test.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-07-29\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"2-scm-p0-landing-spine\",\"criteria_digest\":\"9d3aa951e0f5ffa3\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.claim.source_integration_landing_spine_witness\",\"witness_fn\":\"witness_p0_roadmap_acceptance_contract_holds\",\"executed_on\":\"2026-08-01\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/gunbc/source_integration_landing_spine.dag\",\"further_artifacts\":[\"dag/gunbc/native_scm_interaction_contract.dag\",\"dag/test/claim/source_integration_landing_spine_witness_test.dag\",\"dag/test/claim/native_scm_interaction_contract_witness_test.dag\",\"dag/gunbc/scm_compatibility_shape.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-08-01\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"namespace-occurrence-transport\",\"criteria_digest\":\"d76cf14b12dbf4bf\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.claim.namespace_occurrence_transport_test\",\"witness_fn\":\"namespace_occurrence_equal_text_mints_distinct_ids_holds\",\"executed_on\":\"2026-07-28\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/std/occurrence_identity.dag\",\"further_artifacts\":[\"dag/test/claim/namespace_occurrence_transport_test.dag\",\"src/v1/tests/claim/pattern_binder_declaration_node_test.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-07-28\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"namespace-binding-kernel\",\"criteria_digest\":\"2eba4715cdef42eb\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.claim.occurrence_binding_resolve_witness_test\",\"witness_fn\":\"occurrence_binding_resolve_malformed_transport_refuses_holds\",\"executed_on\":\"2026-08-01\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/std/occurrence_binding_resolve.dag\",\"further_artifacts\":[\"dag/test/claim/occurrence_binding_resolve_witness_test.dag\",\"src/v1/04_occurrence_binding.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-08-01\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"entry-graph-union-construction\",\"criteria_digest\":\"3502539e920d9e40\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"v1-compiler-tests.union_resolve_receipts_test\",\"witness_fn\":\"shared_typecheck_distinct_compute_count_is_order_invariant\",\"executed_on\":\"2026-08-01\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"docs/plans/entry-graph-union-slice2-typecheck-attribution.md\",\"further_artifacts\":[\"docs/plans/receipts/entry-graph-union-slice2/receipt-broad-disjoint.json\",\"docs/plans/receipts/entry-graph-union-slice2/receipt-post-merge-representative-50.json\",\"docs/plans/per-entry-assembly-decomposition-measurement.md\",\"src/v1/tests/src/union_resolve_receipts_test.rs\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-08-01\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"pderive-typesafe-nullary-reflection\",\"criteria_digest\":\"dac83172a613e659\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"v2.test.manual.coproduct_reflection_conformance\",\"witness_fn\":\"witness_nullary_reflection_rejects_requested_a_with_context_b\",\"executed_on\":\"2026-07-28\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"src/v2/std/node_query.dag\",\"further_artifacts\":[\"src/v2/test/claim/manual/coproduct_reflection_conformance_test.dag\",\"src/v1/stage0/src/coproduct_reflection.rs\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-07-28\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"pderive-static-supplemental-contract\",\"criteria_digest\":\"fa6378dabdb12432\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"v2.test.claim.emit.trait_derive_supplemental_generic_bound_contract\",\"witness_fn\":\"nested_generic_swap_red_rejects_swapped_slot_requirements\",\"executed_on\":\"2026-07-29\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/std/trait_derive_shape.dag\",\"further_artifacts\":[\"dag/extdeps/languages/rust/derive_contracts.dag\",\"src/v2/test/claim/emit/trait_derive_supplemental_generic_bound_contract_test.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-07-29\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"v1-test-hygiene-producer-retirement\",\"criteria_digest\":\"8f77a4b2e0ee3387\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.claim.test_module_hygiene_hand_rust_equivalence_witness\",\"witness_fn\":\"test_module_hygiene_equivalence_unparsable_refuse_discriminator_holds\",\"executed_on\":\"2026-07-29\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/gunbc/test_module_hygiene.dag\",\"further_artifacts\":[\"dag/test/claim/test_module_hygiene_hand_rust_equivalence_witness_test.dag\",\"src/v1/stage0/src/cli_run/test_module_hygiene_bridge.rs\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-07-29\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"v1-interpreter-primitive-roster\",\"criteria_digest\":\"581758f45921b40a\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.claim.v1_interpreter_primitive_surface_witness_test\",\"witness_fn\":\"shadow_detector_catches_a_planted_duplicate\",\"executed_on\":\"2026-08-02\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/gunbc/v1/v1_interpreter_primitive_surface.dag\",\"further_artifacts\":[\"dag/test/claim/v1_interpreter_primitive_surface_witness_test.dag\",\"dag/test/claim/primitive_identity_join_witness_test.dag\",\"src/v1/stage0/src/v1_interpreter.rs\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-08-02\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"ladder-measurement-schema\",\"criteria_digest\":\"74da4d8be7125c81\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.claim.guarantee_measurement_witness_test\",\"witness_fn\":\"duplicate_class_id_reds_uniqueness\",\"executed_on\":\"2026-08-01\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/gunbc/guarantee_measurement.dag\",\"further_artifacts\":[\"dag/test/claim/guarantee_measurement_witness_test.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-08-01\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"v2-emitter-producer-provenance\",\"criteria_digest\":\"f1c76111c83a0a60\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"v2.test.claim.self_host.emitter_producer_provenance_witness_test\",\"witness_fn\":\"witness_restored_binding_without_executed_receipt_does_not_authorize_reds\",\"executed_on\":\"2026-08-02\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"src/v2/compiler/self_host/frontier.dag\",\"further_artifacts\":[\"src/v2/test/claim/self_host/emitter_producer_provenance_witness_test.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-08-02\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"v1-seed-honesty-decision\",\"criteria_digest\":\"1717cfe258d9afe1\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.claim.seed_honesty_discharge_unavailable_test\",\"witness_fn\":\"seed_honesty_undecided_would_keep_closing_contract_red\",\"executed_on\":\"2026-08-02\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"src/v2/workflow/bootstrap.dag\",\"further_artifacts\":[\"dag/test/claim/seed_honesty_discharge_unavailable_test.dag\",\"dag/gunbc/ci/ci_layer_roots.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-08-02\"}}\n" +data receipt_continuity_acceptance_carrier_fixture_text: String = "{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"2-scm-git-upstream-model\",\"criteria_digest\":\"b3747b95baf099cc\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.manual.git_upstream_model_execution\",\"witness_fn\":\"witness_git_cli_fixture_hashes_projects_and_independently_reads_back\",\"executed_on\":\"2026-07-29\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/extdeps/git/object_store.dag\",\"further_artifacts\":[\"dag/test/claim/git_upstream_model_witness_test.dag\",\"dag/test/manual/git_upstream_model_execution_test.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-07-29\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"2-scm-mercurial-upstream-model\",\"criteria_digest\":\"c43b17d5134b111d\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.manual.mercurial_upstream_model_execution\",\"witness_fn\":\"witness_mercurial_cli_fixture_projects_and_independently_reads_back\",\"executed_on\":\"2026-07-29\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/extdeps/mercurial.dag\",\"further_artifacts\":[\"dag/test/claim/mercurial_upstream_model_witness_test.dag\",\"dag/test/manual/mercurial_upstream_model_execution_test.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-07-29\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"2-scm-pijul-upstream-model\",\"criteria_digest\":\"098c989bdc87dac7\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.manual.pijul_upstream_model_execution\",\"witness_fn\":\"witness_pijul_cli_fixture_reads_channel_sets_and_retained_conflict\",\"executed_on\":\"2026-07-29\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/extdeps/pijul.dag\",\"further_artifacts\":[\"dag/test/claim/pijul_upstream_model_witness_test.dag\",\"dag/test/manual/pijul_upstream_model_execution_test.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-07-29\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"2-claim-indexed-evidence\",\"criteria_digest\":\"2b81ac6aacf6a190\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.claim.claim_indexed_evidence_witness\",\"witness_fn\":\"witness_claim_evidence_roles_are_externally_grounded\",\"executed_on\":\"2026-07-29\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/std/claim_evidence.dag\",\"further_artifacts\":[\"dag/gunbc/provider_readiness_claim_evidence.dag\",\"dag/gunbc/os_install_claim_evidence.dag\",\"dag/gunbc/source_integration_claim_evidence.dag\",\"dag/test/claim/claim_indexed_evidence_witness_test.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-07-29\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"2-scm-compatibility-shape\",\"criteria_digest\":\"f023bb4e862d9e27\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.claim.scm_compatibility_shape_witness\",\"witness_fn\":\"witness_r1_acceptance_contract_holds\",\"executed_on\":\"2026-07-29\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/gunbc/scm_compatibility_shape.dag\",\"further_artifacts\":[\"dag/gunbc/scm_compatibility/git.dag\",\"dag/gunbc/scm_compatibility/mercurial.dag\",\"dag/gunbc/scm_compatibility/pijul.dag\",\"dag/test/claim/scm/scm_compatibility_shape_witness_test.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-07-29\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"2-scm-p0-landing-spine\",\"criteria_digest\":\"9d3aa951e0f5ffa3\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.claim.source_integration_landing_spine_witness\",\"witness_fn\":\"witness_p0_roadmap_acceptance_contract_holds\",\"executed_on\":\"2026-08-01\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/gunbc/source_integration_landing_spine.dag\",\"further_artifacts\":[\"dag/gunbc/native_scm_interaction_contract.dag\",\"dag/test/claim/source_integration_landing_spine_witness_test.dag\",\"dag/test/claim/native_scm_interaction_contract_witness_test.dag\",\"dag/gunbc/scm_compatibility_shape.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-08-01\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"namespace-occurrence-transport\",\"criteria_digest\":\"d76cf14b12dbf4bf\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.claim.namespace_occurrence_transport_test\",\"witness_fn\":\"namespace_occurrence_equal_text_mints_distinct_ids_holds\",\"executed_on\":\"2026-07-28\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/std/occurrence_identity.dag\",\"further_artifacts\":[\"dag/test/claim/namespace_occurrence_transport_test.dag\",\"src/v1/tests/claim/pattern_binder_declaration_node_test.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-07-28\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"namespace-binding-kernel\",\"criteria_digest\":\"2eba4715cdef42eb\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.claim.occurrence_binding_resolve_witness_test\",\"witness_fn\":\"occurrence_binding_resolve_malformed_transport_refuses_holds\",\"executed_on\":\"2026-08-01\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/std/occurrence_binding_resolve.dag\",\"further_artifacts\":[\"dag/test/claim/occurrence_binding_resolve_witness_test.dag\",\"src/v1/04_occurrence_binding.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-08-01\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"entry-graph-union-construction\",\"criteria_digest\":\"3502539e920d9e40\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"v1-compiler-tests.union_resolve_receipts_test\",\"witness_fn\":\"shared_typecheck_distinct_compute_count_is_order_invariant\",\"executed_on\":\"2026-08-01\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"docs/plans/entry-graph-union-slice2-typecheck-attribution.md\",\"further_artifacts\":[\"docs/plans/receipts/entry-graph-union-slice2/receipt-broad-disjoint.json\",\"docs/plans/receipts/entry-graph-union-slice2/receipt-post-merge-representative-50.json\",\"docs/plans/per-entry-assembly-decomposition-measurement.md\",\"src/v1/tests/src/union_resolve_receipts_test.rs\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-08-01\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"pderive-typesafe-nullary-reflection\",\"criteria_digest\":\"dac83172a613e659\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"v2.test.manual.coproduct_reflection_conformance\",\"witness_fn\":\"witness_nullary_reflection_rejects_requested_a_with_context_b\",\"executed_on\":\"2026-07-28\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"src/v2/std/node_query.dag\",\"further_artifacts\":[\"src/v2/test/claim/manual/coproduct_reflection_conformance_test.dag\",\"src/v1/stage0/src/coproduct_reflection.rs\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-07-28\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"pderive-static-supplemental-contract\",\"criteria_digest\":\"fa6378dabdb12432\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"v2.test.claim.emit.trait_derive_supplemental_generic_bound_contract\",\"witness_fn\":\"nested_generic_swap_red_rejects_swapped_slot_requirements\",\"executed_on\":\"2026-07-29\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/std/trait_derive_shape.dag\",\"further_artifacts\":[\"dag/extdeps/languages/rust/derive_contracts.dag\",\"src/v2/test/claim/emit/trait_derive_supplemental_generic_bound_contract_test.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-07-29\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"v1-test-hygiene-producer-retirement\",\"criteria_digest\":\"8f77a4b2e0ee3387\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.claim.test_module_hygiene_hand_rust_equivalence_witness\",\"witness_fn\":\"test_module_hygiene_equivalence_unparsable_refuse_discriminator_holds\",\"executed_on\":\"2026-07-29\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/gunbc/test_module_hygiene.dag\",\"further_artifacts\":[\"dag/test/claim/test_module_hygiene_hand_rust_equivalence_witness_test.dag\",\"src/v1/stage0/src/cli_run/test_module_hygiene_bridge.rs\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-07-29\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"v1-interpreter-primitive-roster\",\"criteria_digest\":\"581758f45921b40a\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.claim.v1_interpreter_primitive_surface_witness_test\",\"witness_fn\":\"shadow_detector_catches_a_planted_duplicate\",\"executed_on\":\"2026-08-02\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/gunbc/v1/v1_interpreter_primitive_surface.dag\",\"further_artifacts\":[\"dag/test/claim/v1_interpreter_primitive_surface_witness_test.dag\",\"dag/test/claim/primitive_identity_join_witness_test.dag\",\"src/v1/stage0/src/v1_interpreter.rs\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-08-02\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"ladder-measurement-schema\",\"criteria_digest\":\"74da4d8be7125c81\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.claim.guarantee_measurement_witness_test\",\"witness_fn\":\"duplicate_class_id_reds_uniqueness\",\"executed_on\":\"2026-08-01\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"dag/gunbc/guarantee_measurement.dag\",\"further_artifacts\":[\"dag/test/claim/guarantee_measurement_witness_test.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-08-01\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"v2-emitter-producer-provenance\",\"criteria_digest\":\"f1c76111c83a0a60\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"v2.test.claim.self_host.emitter_producer_provenance_witness_test\",\"witness_fn\":\"witness_restored_binding_without_executed_receipt_does_not_authorize_reds\",\"executed_on\":\"2026-08-02\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"src/v2/compiler/self_host/frontier.dag\",\"further_artifacts\":[\"src/v2/test/claim/self_host/emitter_producer_provenance_witness_test.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-08-02\"}}\n{\"variant\":\"acceptance_recorded\",\"receipt\":{\"node\":\"v1-seed-honesty-decision\",\"criteria_digest\":\"1717cfe258d9afe1\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"test.claim.seed_honesty_discharge_unavailable_test\",\"witness_fn\":\"seed_honesty_undecided_would_keep_closing_contract_red\",\"executed_on\":\"2026-08-02\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"src/v2/workflow/bootstrap.dag\",\"further_artifacts\":[\"dag/test/claim/seed_honesty_discharge_unavailable_test.dag\",\"dag/gunbc/ci/ci_layer_roots.dag\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-08-02\"}}\n{\"variant\":\"acceptance_revoked\",\"exact_prior_receipt\":{\"node\":\"entry-graph-union-construction\",\"criteria_digest\":\"3502539e920d9e40\",\"red_control\":{\"variant\":\"red_control_executed\",\"witness_module\":\"v1-compiler-tests.union_resolve_receipts_test\",\"witness_fn\":\"shared_typecheck_distinct_compute_count_is_order_invariant\",\"executed_on\":\"2026-08-01\"},\"handback\":{\"variant\":\"handback_delivered\",\"first_artifact\":\"docs/plans/entry-graph-union-slice2-typecheck-attribution.md\",\"further_artifacts\":[\"docs/plans/receipts/entry-graph-union-slice2/receipt-broad-disjoint.json\",\"docs/plans/receipts/entry-graph-union-slice2/receipt-post-merge-representative-50.json\",\"docs/plans/per-entry-assembly-decomposition-measurement.md\",\"src/v1/tests/src/union_resolve_receipts_test.rs\"]},\"accepted_by\":\"operator\",\"accepted_on\":\"2026-08-01\"},\"disposition\":{\"variant\":\"acceptance_node_remains_superseded\"},\"reason\":\"The floor cut retired this work's subject; remaining cost work lives on the successor. The recorded acceptance is retained as history.\",\"revoked_by\":\"operator\",\"revoked_on\":\"2026-09-13\"}" diff --git a/dag/test/claim/roadmap/roadmap_receipt_continuity_acceptance_test.dag b/dag/test/claim/roadmap/roadmap_receipt_continuity_acceptance_test.dag index 588b53cfe26..bc5234d27a3 100644 --- a/dag/test/claim/roadmap/roadmap_receipt_continuity_acceptance_test.dag +++ b/dag/test/claim/roadmap/roadmap_receipt_continuity_acceptance_test.dag @@ -8,9 +8,9 @@ import gunbc.roadmap_authority { roadmap_acceptance_receipts_from_carrier_text, RoadmapAcceptanceReceiptsProjected, RoadmapAcceptanceReceiptsProjectionRefused, - accepted_roadmap_node_ids_projection_from_carrier_text, - AcceptedRoadmapNodeIdsProjected, - AcceptedRoadmapNodeIdsProjectionRefused, + withheld_node_ids_from_carrier_text, + WithheldNodeIdsProjected, + WithheldNodeIdsProjectionRefused, roadmap_authority_projection_from_carrier_text, RoadmapAuthorityProjected, RoadmapAuthorityProjectionRefused, @@ -130,8 +130,9 @@ test fn roadmap_receipt_continuity_acceptance_contract_holds() -> Bool { && witness_non_empty_prior_prefix_law_catches_deletion_without_seal_coedit() && witness_changed_history_empty_prior_bypass_admits_deletion_observed_prior_refuses() && witness_digest_field_mutation_without_revocation_refuses_prefix() - && witness_accepted_node_ids_projection_refuses_when_receipts_projection_refuses() + && witness_authority_projection_refuses_when_receipts_projection_refuses() && witness_receipts_projection_refuses_when_history_load_refuses() + && witness_withheld_projection_refuses_when_history_load_refuses() && witness_unreadable_carrier_text_refuses_load_with_line_parse_detail() && witness_unreadable_merge_base_carrier_parse_refuses_prior_observation() && witness_missing_carrier_prevents_silent_empty_authority_projection() @@ -294,6 +295,19 @@ test fn witness_digest_field_mutation_without_revocation_refuses_prefix() -> Boo && !acceptance_history_integrity_holds(history: current, prior_history: prior) } +test fn witness_withheld_projection_refuses_when_history_load_refuses() -> Bool { + match load_roadmap_acceptance_event_history_from_carrier_text(text: unreadable_carrier_text_fixture) { + RoadmapAcceptanceEventHistoryLoaded { events: _ } => false + RoadmapAcceptanceEventHistoryLoadRefused { detail: history_detail } => + match withheld_node_ids_from_carrier_text(text: unreadable_carrier_text_fixture) { + WithheldNodeIdsProjected { ids: _ } => false + WithheldNodeIdsProjectionRefused { detail: withheld_detail } => + withheld_detail == history_detail + && string_contains(s: history_detail, pattern: "line 1:") + } + } +} + test fn witness_receipts_projection_refuses_when_history_load_refuses() -> Bool { match load_roadmap_acceptance_event_history_from_carrier_text(text: unreadable_carrier_text_fixture) { RoadmapAcceptanceEventHistoryLoaded { events: _ } => false @@ -315,15 +329,15 @@ test fn witness_unreadable_carrier_text_refuses_load_with_line_parse_detail() -> } } -test fn witness_accepted_node_ids_projection_refuses_when_receipts_projection_refuses() -> Bool { +test fn witness_authority_projection_refuses_when_receipts_projection_refuses() -> Bool { match roadmap_acceptance_receipts_from_carrier_text(text: unreadable_carrier_text_fixture) { RoadmapAcceptanceReceiptsProjected { receipts: _ } => false RoadmapAcceptanceReceiptsProjectionRefused { detail: receipt_detail } => - match accepted_roadmap_node_ids_projection_from_carrier_text(text: unreadable_carrier_text_fixture) { - AcceptedRoadmapNodeIdsProjected { ids: _ } => false - AcceptedRoadmapNodeIdsProjectionRefused { detail: node_detail } => - node_detail == receipt_detail - && string_contains(s: node_detail, pattern: "line 1:") + match roadmap_authority_projection_from_carrier_text(text: unreadable_carrier_text_fixture) { + RoadmapAuthorityProjected { doc: _, accepted: _, withheld: _ } => false + RoadmapAuthorityProjectionRefused { detail: authority_detail } => + authority_detail == receipt_detail + && string_contains(s: authority_detail, pattern: "line 1:") } } } @@ -340,12 +354,12 @@ test fn witness_missing_carrier_prevents_silent_empty_authority_projection() -> match roadmap_authority_projection_from_carrier_text(text: unreadable_carrier_text_fixture) { RoadmapAuthorityProjectionRefused { detail: detail } => string_contains(s: detail, pattern: "line 1:") - RoadmapAuthorityProjected { doc: doc, accepted: _ } => count(doc_all_nodes(doc: doc)) == 0 + RoadmapAuthorityProjected { doc: doc, accepted: _, withheld: _ } => count(doc_all_nodes(doc: doc)) == 0 } && match roadmap_authority_projection_from_carrier_text( text: receipt_continuity_acceptance_carrier_fixture_text, ) { - RoadmapAuthorityProjected { doc: doc, accepted: _ } => count(doc_all_nodes(doc: doc)) > 0 + RoadmapAuthorityProjected { doc: doc, accepted: _, withheld: _ } => count(doc_all_nodes(doc: doc)) > 0 RoadmapAuthorityProjectionRefused { detail: _ } => false } } @@ -360,7 +374,7 @@ test fn witness_dispatch_never_presents_empty_frontier_on_authority_refusal() -> && string_contains(s: refused_dispatch, pattern: "\"refused\": true") && !string_contains(s: refused_dispatch, pattern: "\"brief_template\": ") && match projected { - RoadmapAuthorityProjected { doc: _, accepted: _ } => { + RoadmapAuthorityProjected { doc: _, accepted: _, withheld: _ } => { let dispatch = roadmap_dispatch_file_content_for_projection(proj: projected) string_contains(s: dispatch, pattern: "\"brief_template\": ") && string_contains(s: dispatch, pattern: "\"dispatch\": ") diff --git a/dag/test/claim/roadmap/roadmap_serve_witness_test.dag b/dag/test/claim/roadmap/roadmap_serve_witness_test.dag index 6b7f8ac5700..8cd2ac5c16c 100644 --- a/dag/test/claim/roadmap/roadmap_serve_witness_test.dag +++ b/dag/test/claim/roadmap/roadmap_serve_witness_test.dag @@ -429,6 +429,7 @@ fn caller_supplied_plan_fixture() -> RoadmapAuthorityProjection { ], }, accepted: [], + withheld: [], } } diff --git a/src/v1/stage0/src/cli_run/roadmap_acceptance_history_carrier.rs b/src/v1/stage0/src/cli_run/roadmap_acceptance_history_carrier.rs index 8c6e66b8a5a..a419846e717 100644 --- a/src/v1/stage0/src/cli_run/roadmap_acceptance_history_carrier.rs +++ b/src/v1/stage0/src/cli_run/roadmap_acceptance_history_carrier.rs @@ -66,6 +66,7 @@ enum JsonEvent { #[serde(tag = "variant", rename_all = "snake_case", deny_unknown_fields)] enum JsonAcceptanceRevocationDisposition { AcceptanceNodeReopensActiveFrontier, + AcceptanceNodeRemainsSuperseded, } #[derive(Debug, Deserialize, Serialize)] @@ -221,6 +222,13 @@ fn event_value(event: JsonEvent, ctx: &InterpContext) -> Result { fields: Rc::new(Vec::new()), } } + JsonAcceptanceRevocationDisposition::AcceptanceNodeRemainsSuperseded => { + Value::Variant { + type_name: ctx.sym("AcceptanceRevocationDisposition"), + variant_name: ctx.sym("AcceptanceNodeRemainsSuperseded"), + fields: Rc::new(Vec::new()), + } + } }; Value::Variant { type_name: ctx.sym("RoadmapAcceptanceEvent"), @@ -365,6 +373,9 @@ fn event_to_json(value: &Value, ctx: &InterpContext) -> Result { JsonAcceptanceRevocationDisposition::AcceptanceNodeReopensActiveFrontier } + "AcceptanceNodeRemainsSuperseded" => { + JsonAcceptanceRevocationDisposition::AcceptanceNodeRemainsSuperseded + } name => { return Err(format!( "unknown AcceptanceRevocationDisposition variant `{name}`" @@ -515,4 +526,30 @@ mod tests { RoadmapAcceptanceEventHistoryParse::Parsed { .. } => panic!("expected refusal"), } } + + #[test] + fn remains_superseded_disposition_parses() { + let ctx = empty_ctx(); + let jsonl = r#"{"variant":"acceptance_revoked","exact_prior_receipt":{"node":"n","criteria_digest":"0123456789abcdef","red_control":{"variant":"red_control_not_run"},"handback":{"variant":"handback_not_delivered"},"accepted_by":"op","accepted_on":"2026-01-01"},"disposition":{"variant":"acceptance_node_remains_superseded"},"reason":"rationale","revoked_by":"operator","revoked_on":"2026-09-13"}"#; + match parse_roadmap_acceptance_event_history_jsonl(jsonl, &ctx) { + RoadmapAcceptanceEventHistoryParse::Parsed { events } => assert_eq!(events.len(), 1), + RoadmapAcceptanceEventHistoryParse::Refused { detail } => { + panic!("unexpected refusal: {detail}") + } + } + } + + #[test] + fn payload_bearing_superseded_disposition_refuses() { + let ctx = empty_ctx(); + let jsonl = r#"{"variant":"acceptance_revoked","exact_prior_receipt":{"node":"n","criteria_digest":"0123456789abcdef","red_control":{"variant":"red_control_not_run"},"handback":{"variant":"handback_not_delivered"},"accepted_by":"op","accepted_on":"2026-01-01"},"disposition":{"variant":"acceptance_node_superseded","by":"successor"},"reason":"rationale","revoked_by":"operator","revoked_on":"2026-09-13"}"#; + match parse_roadmap_acceptance_event_history_jsonl(jsonl, &ctx) { + RoadmapAcceptanceEventHistoryParse::Refused { detail } => { + assert!(detail.starts_with("line 1:")); + } + RoadmapAcceptanceEventHistoryParse::Parsed { .. } => { + panic!("expected refusal of payload-bearing superseded disposition") + } + } + } }