diff --git a/src/v3/compiler/tests/fixtures/r1_pb_census_gates.dag b/src/v3/compiler/tests/fixtures/r1_pb_census_gates.dag new file mode 100644 index 00000000000..3feb81ddfa9 --- /dev/null +++ b/src/v3/compiler/tests/fixtures/r1_pb_census_gates.dag @@ -0,0 +1,157 @@ +// std.r1_pb_census_gates - R1C-D `.dag` TestClaim fixtures for the six +// PB census gates (T-PB-A ×4 + T-PB-B ×2). The Rust ratchets in +// `src/v3/compiler/tests/integration/sg0_census_test.rs` remain the +// drift-detection authority on the underlying lists; this file wires the +// release-gate `.dag` layer that R1 close evaluates, per the strict +// reading of `THESIS.md §"Tests are structural data"`. +// +// Predicate shapes consumed here (`CensusBoundCheck`, `CensusSubsetCount`, +// `FixedPointConverges`, `RatchetZero`, `GeneratedFromDag`) live at +// `src/v3/std/verification.dag`. Runner dispatch lives at +// `src/v3/compiler/src/test_runner.rs::run_claim` (the +// `eval_*_shape` family). +// +// **Today's evaluation state** (R1C-D acceptance: gate evaluates `Pass` +// or `Fail` against the live census, never `NotYetImplemented`): +// +// D.1 / D.6 — `CensusBoundCheck` against `EXPECTED_HAND_AUTHORED_*` +// at `bound = 0` is RED until cascade-promotion 0-floor +// (`docs/design-pure-bootstrap-zero.md`, LIVE 2026-04-25) +// retires the residual lists. Pacing owned by Pure +// Bootstrap to Zero program; surfaced cross-manager. +// D.2 — `CensusSubsetCount` lens-producer subset over the non-test +// census; same dissolution-pacing dependency as D.1. +// D.3 — `FixedPointConverges` runs DB-8 twice and compares snapshots. +// D.4 — `RatchetZero` checks the consolidation ratchet count. +// D.5 — `GeneratedFromDag` checks that the test census is empty +// (same dissolution gating as D.6) AND that the listed paths +// all live in the SG-0 generated-file manifest. +// +// Lives under `src/v3/compiler/tests/fixtures/` so it is **not** +// auto-staged into `Dag::new()` bootstrap (`src/v3/std/*.dag` is the +// build-script-enumerated tree). The runner test in +// `tests/integration/r1c_d_pb_census_gates_test.rs` lowers this file +// via `compile_to_dag` exactly like the sibling R1 gate fixtures. + +module std.r1_pb_census_gates + +import std.verification { + CensusBoundCheck, + CensusSubsetCount, + FixedPointConverges, + GeneratedFromDag, + RatchetZero, + TestClaim, + TestSuite, + compiler_std_positive_set_ratchet, + expected_hand_authored_non_test, + expected_hand_authored_test, + lens_producer_files_subset_predicate +} + +// Census-authority handle. The Rust runner's `resolve_census_authority_ref` +// only requires a `DeclarationRef` edge (it does not pin a name or type); +// the marker exists so fixtures point at a typed identity that names the +// underlying authority (`src/v3/compiler/tests/integration/sg0_census_test.rs`) +// rather than smuggling the path through fixture text. +type Sg0CensusAuthority {} + +data sg0_census_test_authority: Sg0CensusAuthority = {} + +// Stub source string repeated inline on each `TestClaim` below. The PB +// census `eval_*_shape` family does not consume `claim.source` — +// evaluation reads live census state via `sg0_census_list_*` helpers in +// `test_runner.rs`. The string is repeated rather than referenced through +// a shared `data` because `TestClaimValue::from_declaration` reads `source` +// as a `FieldValue::Literal(String)`; a `Reference(_)` edge falls back to +// the declaration name and breaks the structural `name` contract used by +// the runner test's claim-order assertion. +data pb_hand_rust_at_shim_floor_gate: TestClaim = { + name: "pb_hand_rust_at_shim_floor", + source: "// PB census predicates read external census state, not this source.\nlet _: Int = 0\n", + file_name: "r1_pb_hand_rust_at_shim_floor.v3", + predicate: CensusBoundCheck { + authority: sg0_census_test_authority, + list_constant: expected_hand_authored_non_test, + bound: 0 + }, + requires: [] +} + +data lens_producer_files_remaining_gate: TestClaim = { + name: "lens_producer_files_remaining", + source: "// PB census predicates read external census state, not this source.\nlet _: Int = 0\n", + file_name: "r1_lens_producer_files_remaining.v3", + predicate: CensusSubsetCount { + authority: sg0_census_test_authority, + list_constant: expected_hand_authored_non_test, + subset_predicate: lens_producer_files_subset_predicate + }, + requires: [] +} + +data pb_self_compile_fixed_point_gate: TestClaim = { + name: "pb_self_compile_fixed_point", + source: "// PB census predicates read external census state, not this source.\nlet _: Int = 0\n", + file_name: "r1_pb_self_compile_fixed_point.v3", + predicate: FixedPointConverges { + compile_target: "default_fixed_point_source", + expected: "pipeline_stage_snapshots" + }, + requires: [] +} + +data pb_compiler_std_ratchet_zero_gate: TestClaim = { + name: "pb_compiler_std_ratchet_zero", + source: "// PB census predicates read external census state, not this source.\nlet _: Int = 0\n", + file_name: "r1_pb_compiler_std_ratchet_zero.v3", + predicate: RatchetZero { + authority: sg0_census_test_authority, + ratchet_kind: compiler_std_positive_set_ratchet + }, + requires: [] +} + +// `generated_paths` enumerates a representative subset of the SG-0 +// generated-file manifest (`src/v3/compiler/src/lib.rs::generated_files`, +// emitted by `build.rs::REGEN_OUTPUTS`). The runner validates each entry +// is in `GENERATED_FILES`; the gate's load-bearing check is that the +// `EXPECTED_HAND_AUTHORED_TEST` census is empty. +data pb_test_file_generated_from_dag_gate: TestClaim = { + name: "pb_test_file_generated_from_dag", + source: "// PB census predicates read external census state, not this source.\nlet _: Int = 0\n", + file_name: "r1_pb_test_file_generated_from_dag.v3", + predicate: GeneratedFromDag { + authority: sg0_census_test_authority, + generated_paths: [ + "src/v3/compiler/src/parse_generated.rs", + "src/v3/compiler/src/tokenize_generated.rs", + "src/v3/compiler/src/types_generated.rs" + ] + }, + requires: [] +} + +data pb_rust_tests_outside_residual_zero_gate: TestClaim = { + name: "pb_rust_tests_outside_residual_zero", + source: "// PB census predicates read external census state, not this source.\nlet _: Int = 0\n", + file_name: "r1_pb_rust_tests_outside_residual_zero.v3", + predicate: CensusBoundCheck { + authority: sg0_census_test_authority, + list_constant: expected_hand_authored_test, + bound: 0 + }, + requires: [] +} + +data r1_pb_census_gates_suite: TestSuite = { + name: "r1_pb_census_gates_suite", + claims: [ + pb_hand_rust_at_shim_floor_gate, + lens_producer_files_remaining_gate, + pb_self_compile_fixed_point_gate, + pb_compiler_std_ratchet_zero_gate, + pb_test_file_generated_from_dag_gate, + pb_rust_tests_outside_residual_zero_gate + ] +} diff --git a/src/v3/compiler/tests/integration.rs b/src/v3/compiler/tests/integration.rs index 73231df6e0a..8750f426208 100644 --- a/src/v3/compiler/tests/integration.rs +++ b/src/v3/compiler/tests/integration.rs @@ -117,6 +117,8 @@ mod p0_std_render_repeat_string_test; mod pb1_bootstrap_full_snapshot_test; #[path = "integration/pipe_desugar.rs"] mod pipe_desugar; +#[path = "integration/r1c_d_pb_census_gates_test.rs"] +mod r1c_d_pb_census_gates_test; #[path = "integration/r1c_e_emit_gates_dag_test.rs"] mod r1c_e_emit_gates_dag_test; #[path = "integration/r1c_e_emit_gates_omni_dag_test.rs"] diff --git a/src/v3/compiler/tests/integration/r1c_d_pb_census_gates_test.rs b/src/v3/compiler/tests/integration/r1c_d_pb_census_gates_test.rs new file mode 100644 index 00000000000..f2686f0dac0 --- /dev/null +++ b/src/v3/compiler/tests/integration/r1c_d_pb_census_gates_test.rs @@ -0,0 +1,96 @@ +//! **Layer:** integration +//! +//! R1C-D — runner-side receipt that the six PB census `.dag` `TestClaim` +//! fixtures in `tests/fixtures/r1_pb_census_gates.dag` lower cleanly and +//! evaluate through `TestRunner` against the live SG-0 census authority. +//! +//! The acceptance shape (per `docs/briefs/r1c-d-t-pb-census-as-dag-worker.md` +//! §Acceptance) is **not** "every claim Pass" — three of the six gates +//! (`pb_hand_rust_at_shim_floor`, `pb_test_file_generated_from_dag`, +//! `pb_rust_tests_outside_residual_zero`) are RED today and stay RED until +//! cascade-promotion 0-floor work in the Pure Bootstrap to Zero program +//! retires the residual hand-Rust census lists. The receipt this test +//! carries is: +//! +//! 1. The fixture compiles cleanly through `compile_to_dag`. +//! 2. `TestRunner::run_suite` returns six results in declared order. +//! 3. **No** result is `ClaimResult::NotYetImplemented(_)` — proving +//! every PB census predicate's `eval_*_shape` slice is wired in +//! `test_runner.rs` (R1C-D Acceptance line: "Runner dispatches each +//! fixture cleanly"). +//! 4. Each result is `Pass` or `Fail` against current census state, never +//! an evaluation error from a missing dispatch arm. +//! +//! The Rust ratchets in `tests/integration/sg0_census_test.rs` remain the +//! drift-detection authority on the underlying lists. RED `.dag` gates are +//! surfaced to the R1 Closure Manager inbox as dissolution-work-pending +//! cross-manager queue entries; pacing is the Pure Bootstrap to Zero +//! program's, not this test's. + +use v3_compiler::compile_to_dag; +use v3_compiler::test_runner::{ClaimResult, TestRunner}; +use v3_compiler::CompileError; + +const FIXTURE_SOURCE: &str = include_str!("../fixtures/r1_pb_census_gates.dag"); +const FIXTURE_PATH: &str = "src/v3/compiler/tests/fixtures/r1_pb_census_gates.dag"; +const SUITE_NAME: &str = "r1_pb_census_gates_suite"; + +const EXPECTED_CLAIM_NAMES: &[&str] = &[ + "pb_hand_rust_at_shim_floor", + "lens_producer_files_remaining", + "pb_self_compile_fixed_point", + "pb_compiler_std_ratchet_zero", + "pb_test_file_generated_from_dag", + "pb_rust_tests_outside_residual_zero", +]; + +#[test] +fn r1c_d_pb_census_gates_suite_evaluates_through_runner() { + let dag = match compile_to_dag(FIXTURE_SOURCE, FIXTURE_PATH) { + Ok(dag) => { + assert!( + dag.diagnostics().is_empty(), + "{FIXTURE_PATH}: expected empty module diagnostics, got {:?}", + dag.diagnostics().iter().collect::>() + ); + dag + } + Err(CompileError::Semantic(dag)) => panic!( + "{FIXTURE_PATH} should lower without module diagnostics. Got `Err(Semantic)`: {:?}", + dag.diagnostics().iter().collect::>() + ), + Err(other) => panic!("unexpected compile error for {FIXTURE_PATH}: {other:?}"), + }; + + let results = TestRunner::new(&dag).run_suite(SUITE_NAME); + let actual_names: Vec<&str> = results.iter().map(|r| r.claim_name.as_str()).collect(); + assert_eq!( + actual_names, EXPECTED_CLAIM_NAMES, + "suite `{SUITE_NAME}`: claim order must match the declared deliverable list" + ); + + // Brief acceptance line: "Runner dispatches each fixture cleanly (no + // `NotYetImplemented` returns)." A `NotYetImplemented` here would mean + // a PB census `eval_*_shape` slice regressed to a stub — that is the + // exact regression this test is designed to catch. + let unimplemented: Vec<_> = results + .iter() + .filter(|r| matches!(r.result, ClaimResult::NotYetImplemented(_))) + .collect(); + assert!( + unimplemented.is_empty(), + "PB census predicates must dispatch to wired evaluators, not `NotYetImplemented`. Offenders:\n{unimplemented:#?}" + ); + + // Everything else should be a structural Pass/Fail outcome — never an + // evaluation error from a missing dispatch arm or malformed payload. + for result in &results { + match &result.result { + ClaimResult::Pass | ClaimResult::Fail(_) => {} + other => panic!( + "PB census claim `{}` must evaluate to Pass or Fail, got {:?}", + result.claim_name, other + ), + } + } +} diff --git a/src/v3/compiler/tests/integration/sg0_census_test.rs b/src/v3/compiler/tests/integration/sg0_census_test.rs index f2febb57d9a..f2b1a0929d0 100644 --- a/src/v3/compiler/tests/integration/sg0_census_test.rs +++ b/src/v3/compiler/tests/integration/sg0_census_test.rs @@ -278,6 +278,15 @@ const EXPECTED_HAND_AUTHORED_TEST: &[&str] = &[ "src/v3/compiler/tests/integration/p0_std_render_repeat_string_test.rs", "src/v3/compiler/tests/integration/pb1_bootstrap_full_snapshot_test.rs", "src/v3/compiler/tests/integration/pipe_desugar.rs", + // R1C-D (PB census `.dag` `TestClaim` wrappers): runner-side receipt + // for the six PB census gates in `tests/fixtures/r1_pb_census_gates.dag`. + // Asserts `TestRunner` dispatches each PB census predicate to a wired + // `eval_*_shape` slice (no `NotYetImplemented`) and that results are + // structural `Pass`/`Fail` against the live SG-0 census authority. + // Same residual class as the R1C-E driver below — paired hand-Rust + // shim until R1 close dissolves the wrappers (D.5 / cascade-promotion + // 0-floor work in the Pure Bootstrap to Zero program). + "src/v3/compiler/tests/integration/r1c_d_pb_census_gates_test.rs", // R1C-E (T-Emit `.dag` `TestClaim` wrappers): integration-test driver // that splices `env!("CARGO_BIN_EXE_r1c_e_emit_gates")` into the // `tests/dag/r1c_e_emit_gates.template.dag` source and runs the suite