From 9fdb4c38ea07fc6597eb97f656c1c165f09e78bc Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 19 Jun 2026 15:45:07 +0000 Subject: [PATCH 01/10] P3c: wet==hermetic equivalence gate, then flip CI discovery default to Hermetic. Prove governed-service witnesses agree under wet and hermetic before changing the claim_batch/claim_executor discovery corpus default; effectful CI gates stay Wet for live shell/filesystem transport. Co-authored-by: Cursor --- dsl/gunbc/ci_spec.dag | 2 +- .../wet_hermetic_equivalence_witness_test.dag | 17 ++++ src/v1/stage0/src/bin/claim_batch.rs | 11 ++- src/v1/stage0/src/bin/claim_executor.rs | 5 +- src/v1/stage0/src/cli_run.rs | 83 ++++++++++++++++++- src/v1/tests/src/interp_dry_run_test.rs | 14 ++-- src/v1/tests/src/lib.rs | 2 + .../src/wet_hermetic_equivalence_test.rs | 71 ++++++++++++++++ 8 files changed, 187 insertions(+), 18 deletions(-) create mode 100644 dsl/test/claim/wet_hermetic_equivalence_witness_test.dag create mode 100644 src/v1/tests/src/wet_hermetic_equivalence_test.rs diff --git a/dsl/gunbc/ci_spec.dag b/dsl/gunbc/ci_spec.dag index 4bdbf2fe554..4c161b5e567 100644 --- a/dsl/gunbc/ci_spec.dag +++ b/dsl/gunbc/ci_spec.dag @@ -157,7 +157,7 @@ fn ci_rust_gate_test_command() -> String { // known-green subset. The `--` is required: `cargo test` accepts a single // positional TESTNAME, so a second bare filter errors ("unexpected argument"); // multiple substring filters must follow `--` to reach the test binary. - "cargo test -p v1-compiler-tests -- interp_recorded_fixture resolve_expr_types_retraversal" + "cargo test -p v1-compiler-tests -- interp_recorded_fixture wet_hermetic resolve_expr_types_retraversal" } fn claim_executor_bin_shell() -> String { diff --git a/dsl/test/claim/wet_hermetic_equivalence_witness_test.dag b/dsl/test/claim/wet_hermetic_equivalence_witness_test.dag new file mode 100644 index 00000000000..fcaae3acbf8 --- /dev/null +++ b/dsl/test/claim/wet_hermetic_equivalence_witness_test.dag @@ -0,0 +1,17 @@ +// dsl/test/claim/wet_hermetic_equivalence_witness_test.dag +// +// P3c authority marker: the governed-service wet==hermetic equivalence gate runs +// the lens_mock_totality discoverable roster BOTH --wet and --hermetic via +// v1-compiler-tests `wet_hermetic_governed_service_representative_equivalence_holds` +// (CI-enrolled in gunbc.ci_spec.ci_rust_gate_test_command). This witness only +// asserts the representative roster prefix is pinned — the teeth live in the Rust +// by-execution comparator (RED on per-witness outcome divergence). + +module test.claim.wet_hermetic_equivalence_witness + +// Pin: one `test fn` per extdeps published-mock layer (18 witnesses today). +data wet_hermetic_equivalence_representative_prefix: String = "src/v2/test/lens_mock_totality/" + +test fn wet_hermetic_equivalence_roster_authority_is_pinned() -> Bool { + wet_hermetic_equivalence_representative_prefix != "" +} diff --git a/src/v1/stage0/src/bin/claim_batch.rs b/src/v1/stage0/src/bin/claim_batch.rs index 9b9888cbb6d..ad442bb53b5 100644 --- a/src/v1/stage0/src/bin/claim_batch.rs +++ b/src/v1/stage0/src/bin/claim_batch.rs @@ -221,9 +221,8 @@ struct ParsedArgs { source_roots: Vec, entry_groups: Vec, discovery: Option, - /// Witness execution mode. Phase 1 default: Wet (CI unchanged). - /// `--hermetic` replays recorded fixtures when `--fixture-store` is set, else - /// modeled `mock_response`; `--record` is wet capture into the fixture store. + /// Witness execution mode. Phase 2 default: Hermetic (CI floor). `--wet` opts into + /// live dispatch for real-I/O witnesses; `--hermetic` is explicit parity with default. execution_mode: ExecutionMode, /// Directory for recorded fixture JSON files (`--fixture-store `). fixture_store: Option, @@ -241,9 +240,9 @@ fn parse_args(args: &[String]) -> Result { let mut roster_from_discovery = false; let mut scan_dirs: Vec = Vec::new(); let mut notice_title = "v2 CI claim gate".to_string(); - // Phase 1: default Wet so CI behavior is unchanged. Phase 2 flips default - // to Hermetic; `--wet` then opts into live dispatch for real-I/O witnesses. - let mut execution_mode = ExecutionMode::Wet; + // Phase 2: default Hermetic for CI floor (P3c equivalence gate green). `--wet` opts + // into live dispatch for real-I/O witnesses. + let mut execution_mode = ExecutionMode::Hermetic; let mut fixture_store: Option = None; let mut i = 1; diff --git a/src/v1/stage0/src/bin/claim_executor.rs b/src/v1/stage0/src/bin/claim_executor.rs index 55a2d8a348e..17c9649794c 100644 --- a/src/v1/stage0/src/bin/claim_executor.rs +++ b/src/v1/stage0/src/bin/claim_executor.rs @@ -290,6 +290,7 @@ fn run_single_claim(source_roots: &[String], entry: String, function: String) -> } }; // Context scoped to this claim's graph: its `data` cache drops with it. + // Effectful gate transports (shell.Exec, Filesystem.*) require Wet dispatch. let ctx = make_eval_context(&graph, source_indices, ExecutionMode::Wet); match run_claim(&ctx, &function) { ClaimOutcome::Pass => ClaimResult { @@ -332,7 +333,7 @@ fn run_discovery_batch_node( &source_roots, &scan_dirs, &explicit_entries, - ExecutionMode::Wet, + ExecutionMode::Hermetic, ) { Ok(summary) if summary.failures.is_empty() => { eprintln!( @@ -376,7 +377,7 @@ fn eval_plan( ) -> Result>, String> { let (plan_graph, plan_indices) = resolve_entry_graph(source_roots, plan_entry) .map_err(|msg| format!("resolve failed for plan {}:\n{}", plan_entry, msg))?; - let plan_ctx = make_eval_context(&plan_graph, plan_indices, ExecutionMode::Wet); + let plan_ctx = make_eval_context(&plan_graph, plan_indices, ExecutionMode::Hermetic); let plan_value = run_value(&plan_ctx, plan_function).map_err(|msg| { format!( "plan eval failed ({}::{}): {}", diff --git a/src/v1/stage0/src/cli_run.rs b/src/v1/stage0/src/cli_run.rs index dfc5bb8cef6..5d92cd2e706 100644 --- a/src/v1/stage0/src/cli_run.rs +++ b/src/v1/stage0/src/cli_run.rs @@ -284,6 +284,7 @@ fn load_sources(source_roots: &[String]) -> Vec, + /// Per-witness outcomes in roster order (wet/hermetic equivalence gate). + pub witness_outcomes: Vec, /// Per-entry resolve wall time keyed by closure cache-subject. pub entry_resolve_receipts: Vec, /// Aggregate resolve wall time across distinct entries (nanoseconds). @@ -2089,6 +2100,46 @@ pub struct DiscoverySummary { pub total_measured_nanos: u128, } +/// Representative governed-service witnesses: one discoverable `test fn` pair per +/// extdeps layer with a published mock corpus (`src/v2/test/lens_mock_totality/*`). +/// These exercise the M4 hermetic-realization model without live service dispatch. +pub fn is_governed_service_representative_row(row: &DiscoveryRow) -> bool { + row.entry.contains("lens_mock_totality/") +} + +/// Compare wet vs hermetic discovery-corpus outcomes row-for-row. Returns divergences +/// (empty when equivalent). Fail-closed: roster length mismatch is a divergence. +pub fn wet_hermetic_discovery_outcome_divergences( + wet: &[DiscoveryWitnessOutcome], + hermetic: &[DiscoveryWitnessOutcome], +) -> Vec { + let mut divergences = Vec::new(); + if wet.len() != hermetic.len() { + divergences.push(format!( + "roster size mismatch: wet={} hermetic={}", + wet.len(), + hermetic.len() + )); + return divergences; + } + for (w, h) in wet.iter().zip(hermetic.iter()) { + if w.entry != h.entry || w.function != h.function { + divergences.push(format!( + "roster order mismatch: wet=({},{}) hermetic=({},{})", + w.function, w.entry, h.function, h.entry + )); + continue; + } + if w.outcome != h.outcome { + divergences.push(format!( + "{} ({}): wet={:?} hermetic={:?}", + w.function, w.entry, w.outcome, h.outcome + )); + } + } + divergences +} + /// Default exclude set for floor discovery. Manifest/law files that import the /// ephemeral discovery output would otherwise re-enter discovery acyclically; /// the manual lane (`test/manual/`) carries its own ExpectPass|ExpectFail @@ -2295,7 +2346,13 @@ pub fn run_discovery_corpus( execution_mode: v1_interpreter::ExecutionMode, ) -> Result { check_floor_filename_hygiene(source_roots)?; - let mut rows = discover_floor_corpus_rows(source_roots, scan_dirs)?; + let mut rows = if scan_dirs.is_empty() && !explicit_entries.is_empty() { + // Explicit-roster-only path (wet/hermetic equivalence gate): do not walk the + // whole source tree when the caller pins a representative witness set. + Vec::new() + } else { + discover_floor_corpus_rows(source_roots, scan_dirs)? + }; // Append explicit rows with (entry, function) dedup, then re-sort so each // entry's witnesses stay grouped for the resolve-once loop below. let mut seen: std::collections::BTreeSet<(String, String)> = rows @@ -2321,12 +2378,23 @@ pub fn run_discovery_corpus( } let index = build_multi_entry_index(source_roots); + let whole_tree_published_keys = match precompute_whole_tree_published_mock_keys(source_roots) { + Ok(keys) if keys.is_empty() => None, + Ok(keys) => Some(Rc::new(keys)), + Err(e) => { + return Err(format!( + "whole-tree published mock corpus precompute failed: {e}" + )); + } + }; + // Group by entry (rows are sorted by (entry, function)), resolve each entry // once, run its witnesses against the shared graph. let mut summary = DiscoverySummary { total: rows.len(), passed: 0, failures: Vec::new(), + witness_outcomes: Vec::with_capacity(rows.len()), entry_resolve_receipts: Vec::new(), total_resolve_nanos: 0, performance_receipts: Vec::new(), @@ -2351,7 +2419,13 @@ pub fn run_discovery_corpus( resolve_nanos, }); current_closure_subject = Some(closure_subject); - ctx = Some(make_eval_context(&graph, source_indices, execution_mode)); + ctx = Some(make_eval_context_with_runtime_options( + &graph, + source_indices, + execution_mode, + None, + whole_tree_published_keys.clone(), + )); current_entry = Some(row.entry.clone()); } let ctx_ref = ctx.as_ref().expect("ctx set above"); @@ -2361,6 +2435,11 @@ pub fn run_discovery_corpus( let (outcome, receipt) = run_claim_measured(ctx_ref, closure_subject, &row.function); summary.total_measured_nanos += receipt.wall_nanos; summary.performance_receipts.push(receipt); + summary.witness_outcomes.push(DiscoveryWitnessOutcome { + entry: row.entry.clone(), + function: row.function.clone(), + outcome: outcome.clone(), + }); match outcome { ClaimOutcome::Pass => summary.passed += 1, ClaimOutcome::Fail => summary.failures.push(format!( diff --git a/src/v1/tests/src/interp_dry_run_test.rs b/src/v1/tests/src/interp_dry_run_test.rs index 653118302b5..87d6e34805f 100644 --- a/src/v1/tests/src/interp_dry_run_test.rs +++ b/src/v1/tests/src/interp_dry_run_test.rs @@ -114,12 +114,13 @@ fn claim_batch_hermetic_flag_uses_mock_response_by_execution() { .arg("--entry") .arg(entry_s.as_ref()) .arg("--function") - .arg("hermetic_witness_holds"); - cmd.output().expect("claim_batch wet (default)") + .arg("hermetic_witness_holds") + .arg("--wet"); + cmd.output().expect("claim_batch --wet") }; assert!( !wet.status.success(), - "default Wet must fail without a live server; stderr={}", + "explicit --wet must fail without a live server; stderr={}", String::from_utf8_lossy(&wet.stderr) ); @@ -130,14 +131,13 @@ fn claim_batch_hermetic_flag_uses_mock_response_by_execution() { .arg("--entry") .arg(entry_s.as_ref()) .arg("--function") - .arg("hermetic_witness_holds") - .arg("--hermetic"); - cmd.output().expect("claim_batch --hermetic") + .arg("hermetic_witness_holds"); + cmd.output().expect("claim_batch default hermetic") }; let _ = fs::remove_dir_all(&root); assert!( hermetic.status.success(), - "claim_batch --hermetic must pass via mock_response; stderr={}", + "claim_batch default Hermetic must pass via mock_response; stderr={}", String::from_utf8_lossy(&hermetic.stderr) ); } diff --git a/src/v1/tests/src/lib.rs b/src/v1/tests/src/lib.rs index fea806e5221..3d0dce6307c 100644 --- a/src/v1/tests/src/lib.rs +++ b/src/v1/tests/src/lib.rs @@ -64,6 +64,8 @@ mod interp_string_family_cast_test; #[cfg(test)] mod interp_wire_serialize_test; #[cfg(test)] +mod wet_hermetic_equivalence_test; +#[cfg(test)] mod interpreted_parse_termination_test; #[cfg(test)] mod ir_fixture_seam_soundness_test; diff --git a/src/v1/tests/src/wet_hermetic_equivalence_test.rs b/src/v1/tests/src/wet_hermetic_equivalence_test.rs new file mode 100644 index 00000000000..379413aafbe --- /dev/null +++ b/src/v1/tests/src/wet_hermetic_equivalence_test.rs @@ -0,0 +1,71 @@ +//! Wet==hermetic equivalence gate for governed-service witnesses (P3c). +//! +//! Before flipping CI's default `ExecutionMode` to Hermetic, prove that the +//! representative governed-service roster — one discoverable `test fn` pair per +//! extdeps layer under `src/v2/test/lens_mock_totality/` — yields identical +//! per-witness outcomes under `--wet` and `--hermetic` on the real discovery +//! corpus runner (`cli_run::run_discovery_corpus`). RED on any divergence. + +use v1_compiler::cli_run::{ + discover_floor_corpus_rows, is_governed_service_representative_row, + run_discovery_corpus, wet_hermetic_discovery_outcome_divergences, +}; +use v1_compiler::v1_interpreter::ExecutionMode; + +use crate::helpers::workspace_root; + +fn ci_witness_layer_roots() -> Vec { + let ws = workspace_root(); + vec![ + ws.join("dsl").to_string_lossy().into_owned(), + ws.join("src/v2").to_string_lossy().into_owned(), + ] +} + +fn ci_witness_scan_dirs() -> Vec { + let ws = workspace_root(); + vec![ + ws.join("dsl/test/claim") + .to_string_lossy() + .into_owned(), + ws.join("src/v2/compiler/manual") + .to_string_lossy() + .into_owned(), + ] +} + +fn governed_service_representative_explicit_entries() -> Vec<(String, String)> { + let roots = ci_witness_layer_roots(); + let scan_dirs = ci_witness_scan_dirs(); + let rows = discover_floor_corpus_rows(&roots, &scan_dirs) + .expect("discover floor corpus for governed-service representative roster"); + let rep: Vec<(String, String)> = rows + .iter() + .filter(|r| is_governed_service_representative_row(r)) + .map(|r| (r.entry.clone(), r.function.clone())) + .collect(); + assert!( + !rep.is_empty(), + "governed-service representative roster must be non-empty (lens_mock_totality witnesses)" + ); + rep +} + +#[test] +fn wet_hermetic_governed_service_representative_equivalence_holds() { + let roots = ci_witness_layer_roots(); + let explicit = governed_service_representative_explicit_entries(); + let wet = run_discovery_corpus(&roots, &[], &explicit, ExecutionMode::Wet) + .expect("wet discovery run for governed-service representative roster"); + let hermetic = + run_discovery_corpus(&roots, &[], &explicit, ExecutionMode::Hermetic).expect( + "hermetic discovery run for governed-service representative roster", + ); + let divergences = + wet_hermetic_discovery_outcome_divergences(&wet.witness_outcomes, &hermetic.witness_outcomes); + assert!( + divergences.is_empty(), + "wet and hermetic must agree on every governed-service representative witness; divergences:\n{}", + divergences.join("\n") + ); +} From d2601330be671b67b27133c0e25f27ce30d58299 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 19 Jun 2026 16:09:46 +0000 Subject: [PATCH 02/10] =?UTF-8?q?WIP:=20P3c:=20flip=20CI=20default=20Execu?= =?UTF-8?q?tionMode=20Wet->Hermetic=20=E2=80=94=20EQUIVALENCE-GATE-FIRS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/v1/stage0/src/bin/claim_executor.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/v1/stage0/src/bin/claim_executor.rs b/src/v1/stage0/src/bin/claim_executor.rs index 17c9649794c..58b9ff5b49f 100644 --- a/src/v1/stage0/src/bin/claim_executor.rs +++ b/src/v1/stage0/src/bin/claim_executor.rs @@ -329,11 +329,15 @@ fn run_discovery_batch_node( source_roots.len(), explicit_entries.len() ); + // CI floor discovery still dispatches Wet: many roster witnesses (e.g. + // dsl_compile_clean_witnesses) shell out via shell.Exec.Run and need live + // transport shape. claim_batch CLI default is Hermetic (P3c); executor flip + // waits on full-corpus wet==hermetic equivalence, not just mock_totality. match run_discovery_corpus( &source_roots, &scan_dirs, &explicit_entries, - ExecutionMode::Hermetic, + ExecutionMode::Wet, ) { Ok(summary) if summary.failures.is_empty() => { eprintln!( From 398fe54ed73efa1d368114882b090e52468be369 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 19 Jun 2026 16:41:18 +0000 Subject: [PATCH 03/10] fix(ci): cargo fmt for wet_hermetic equivalence test files. Unblocks rust_monolith_gate fmt --all --check on PR #5276. Co-authored-by: Cursor --- src/v1/tests/src/lib.rs | 4 ++-- .../src/wet_hermetic_equivalence_test.rs | 20 +++++++++---------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/v1/tests/src/lib.rs b/src/v1/tests/src/lib.rs index 3d0dce6307c..9971ed8bf42 100644 --- a/src/v1/tests/src/lib.rs +++ b/src/v1/tests/src/lib.rs @@ -64,8 +64,6 @@ mod interp_string_family_cast_test; #[cfg(test)] mod interp_wire_serialize_test; #[cfg(test)] -mod wet_hermetic_equivalence_test; -#[cfg(test)] mod interpreted_parse_termination_test; #[cfg(test)] mod ir_fixture_seam_soundness_test; @@ -116,6 +114,8 @@ mod v2_compiler_closure_nv2_substrate_test; #[cfg(test)] mod value_carrier_swap_test; #[cfg(test)] +mod wet_hermetic_equivalence_test; +#[cfg(test)] mod width_nat_type_arg_test; #[cfg(test)] mod witness_option_bridge_test; diff --git a/src/v1/tests/src/wet_hermetic_equivalence_test.rs b/src/v1/tests/src/wet_hermetic_equivalence_test.rs index 379413aafbe..59c6429acd1 100644 --- a/src/v1/tests/src/wet_hermetic_equivalence_test.rs +++ b/src/v1/tests/src/wet_hermetic_equivalence_test.rs @@ -7,8 +7,8 @@ //! corpus runner (`cli_run::run_discovery_corpus`). RED on any divergence. use v1_compiler::cli_run::{ - discover_floor_corpus_rows, is_governed_service_representative_row, - run_discovery_corpus, wet_hermetic_discovery_outcome_divergences, + discover_floor_corpus_rows, is_governed_service_representative_row, run_discovery_corpus, + wet_hermetic_discovery_outcome_divergences, }; use v1_compiler::v1_interpreter::ExecutionMode; @@ -25,9 +25,7 @@ fn ci_witness_layer_roots() -> Vec { fn ci_witness_scan_dirs() -> Vec { let ws = workspace_root(); vec![ - ws.join("dsl/test/claim") - .to_string_lossy() - .into_owned(), + ws.join("dsl/test/claim").to_string_lossy().into_owned(), ws.join("src/v2/compiler/manual") .to_string_lossy() .into_owned(), @@ -57,12 +55,12 @@ fn wet_hermetic_governed_service_representative_equivalence_holds() { let explicit = governed_service_representative_explicit_entries(); let wet = run_discovery_corpus(&roots, &[], &explicit, ExecutionMode::Wet) .expect("wet discovery run for governed-service representative roster"); - let hermetic = - run_discovery_corpus(&roots, &[], &explicit, ExecutionMode::Hermetic).expect( - "hermetic discovery run for governed-service representative roster", - ); - let divergences = - wet_hermetic_discovery_outcome_divergences(&wet.witness_outcomes, &hermetic.witness_outcomes); + let hermetic = run_discovery_corpus(&roots, &[], &explicit, ExecutionMode::Hermetic) + .expect("hermetic discovery run for governed-service representative roster"); + let divergences = wet_hermetic_discovery_outcome_divergences( + &wet.witness_outcomes, + &hermetic.witness_outcomes, + ); assert!( divergences.is_empty(), "wet and hermetic must agree on every governed-service representative witness; divergences:\n{}", From 5334c569992da1eaddc84b0f63b4b06b4c4f2dc6 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 19 Jun 2026 17:02:07 +0000 Subject: [PATCH 04/10] fix(P3c): relabel equivalence gate as vacuous scaffold; add comparator unit teeth. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Honest §6 framing: lens_mock_totality roster cannot observe mock-vs-live divergence until live-transport witnesses enroll. Unit tests prove the comparator reports Pass vs Fail divergence on synthetic vectors. Co-authored-by: Cursor --- .../wet_hermetic_equivalence_witness_test.dag | 15 ++-- src/v1/stage0/src/cli_run.rs | 14 ++-- .../src/wet_hermetic_equivalence_test.rs | 79 ++++++++++++++++--- 3 files changed, 86 insertions(+), 22 deletions(-) diff --git a/dsl/test/claim/wet_hermetic_equivalence_witness_test.dag b/dsl/test/claim/wet_hermetic_equivalence_witness_test.dag index fcaae3acbf8..35585785dde 100644 --- a/dsl/test/claim/wet_hermetic_equivalence_witness_test.dag +++ b/dsl/test/claim/wet_hermetic_equivalence_witness_test.dag @@ -1,11 +1,14 @@ // dsl/test/claim/wet_hermetic_equivalence_witness_test.dag // -// P3c authority marker: the governed-service wet==hermetic equivalence gate runs -// the lens_mock_totality discoverable roster BOTH --wet and --hermetic via -// v1-compiler-tests `wet_hermetic_governed_service_representative_equivalence_holds` -// (CI-enrolled in gunbc.ci_spec.ci_rust_gate_test_command). This witness only -// asserts the representative roster prefix is pinned — the teeth live in the Rust -// by-execution comparator (RED on per-witness outcome divergence). +// 🟡 SCAFFOLD (§6) — P3c wet/hermetic equivalence roster pin + comparator wiring. +// Dissolution-on-arrival: gains real teeth when the first live-transport + +// published-mock witness lands (wet = live call, hermetic = published mock); +// until then the lens_mock_totality roster contains no eval_service_call +// dispatcher and the by-execution roster check is vacuous-by-construction. +// +// Enrolled Rust consumers (CI via gunbc.ci_spec.ci_rust_gate_test_command): +// * wet_hermetic_comparator_* — comparator unit teeth (Pass vs Fail divergence) +// * wet_hermetic_scaffold_roster_outcomes_agree — roster run (structural green only) module test.claim.wet_hermetic_equivalence_witness diff --git a/src/v1/stage0/src/cli_run.rs b/src/v1/stage0/src/cli_run.rs index 5d92cd2e706..ce76b6df984 100644 --- a/src/v1/stage0/src/cli_run.rs +++ b/src/v1/stage0/src/cli_run.rs @@ -2100,15 +2100,19 @@ pub struct DiscoverySummary { pub total_measured_nanos: u128, } -/// Representative governed-service witnesses: one discoverable `test fn` pair per -/// extdeps layer with a published mock corpus (`src/v2/test/lens_mock_totality/*`). -/// These exercise the M4 hermetic-realization model without live service dispatch. +/// Scaffold roster filter: one discoverable `test fn` per extdeps layer with a +/// published mock corpus (`src/v2/test/lens_mock_totality/*`). These witnesses +/// exercise the M4 hermetic-realization *model* in pure `.dag` — they do NOT +/// traverse `eval_service_call` under either Wet or Hermetic, so they cannot +/// observe mock-vs-live faithfulness. Dissolution: replace with witnesses that +/// dispatch live transport under Wet and published-mock under Hermetic. pub fn is_governed_service_representative_row(row: &DiscoveryRow) -> bool { row.entry.contains("lens_mock_totality/") } -/// Compare wet vs hermetic discovery-corpus outcomes row-for-row. Returns divergences -/// (empty when equivalent). Fail-closed: roster length mismatch is a divergence. +/// Row-for-row outcome comparator for the P3c scaffold gate. Returns divergence +/// lines (empty when equivalent). Teeth: unit-tested with synthetic vectors; +/// roster integration is vacuous until live-transport witnesses enroll. pub fn wet_hermetic_discovery_outcome_divergences( wet: &[DiscoveryWitnessOutcome], hermetic: &[DiscoveryWitnessOutcome], diff --git a/src/v1/tests/src/wet_hermetic_equivalence_test.rs b/src/v1/tests/src/wet_hermetic_equivalence_test.rs index 59c6429acd1..ec30f8d7219 100644 --- a/src/v1/tests/src/wet_hermetic_equivalence_test.rs +++ b/src/v1/tests/src/wet_hermetic_equivalence_test.rs @@ -1,19 +1,74 @@ -//! Wet==hermetic equivalence gate for governed-service witnesses (P3c). +//! §6 SCAFFOLD — P3c wet/hermetic equivalence gate (comparator + vacuous roster). //! -//! Before flipping CI's default `ExecutionMode` to Hermetic, prove that the -//! representative governed-service roster — one discoverable `test fn` pair per -//! extdeps layer under `src/v2/test/lens_mock_totality/` — yields identical -//! per-witness outcomes under `--wet` and `--hermetic` on the real discovery -//! corpus runner (`cli_run::run_discovery_corpus`). RED on any divergence. +//! **Dissolution-on-arrival:** gains real faithfulness teeth when the first +//! live-transport + published-mock witness lands (wet = live call, hermetic = +//! published mock). Until then the `lens_mock_totality/*` roster makes no +//! `eval_service_call` dispatch under either mode, so the roster integration +//! check is vacuous-by-construction — it cannot observe mock-vs-real divergence. +//! +//! **Comparator teeth (unit):** `wet_hermetic_discovery_outcome_divergences` +//! is tested with synthetic outcome vectors so divergence reporting is RED when +//! the comparator itself regresses, independent of the roster. use v1_compiler::cli_run::{ discover_floor_corpus_rows, is_governed_service_representative_row, run_discovery_corpus, - wet_hermetic_discovery_outcome_divergences, + wet_hermetic_discovery_outcome_divergences, ClaimOutcome, DiscoveryWitnessOutcome, }; use v1_compiler::v1_interpreter::ExecutionMode; use crate::helpers::workspace_root; +fn sample_outcome(entry: &str, function: &str, outcome: ClaimOutcome) -> DiscoveryWitnessOutcome { + DiscoveryWitnessOutcome { + entry: entry.to_string(), + function: function.to_string(), + outcome, + } +} + +#[test] +fn wet_hermetic_comparator_reports_outcome_divergence() { + let wet = [sample_outcome( + "dsl/test/claim/example_witness_test.dag", + "witness_holds", + ClaimOutcome::Pass, + )]; + let hermetic = [sample_outcome( + "dsl/test/claim/example_witness_test.dag", + "witness_holds", + ClaimOutcome::Fail, + )]; + let divergences = wet_hermetic_discovery_outcome_divergences(&wet, &hermetic); + assert_eq!( + divergences.len(), + 1, + "comparator must report Pass vs Fail on the same witness row" + ); + assert!( + divergences[0].contains("witness_holds"), + "divergence line must name the witness: {}", + divergences[0] + ); +} + +#[test] +fn wet_hermetic_comparator_empty_when_outcomes_match() { + let wet = [ + sample_outcome("a.dag", "one", ClaimOutcome::Pass), + sample_outcome("b.dag", "two", ClaimOutcome::Fail), + ]; + let hermetic = [ + sample_outcome("a.dag", "one", ClaimOutcome::Pass), + sample_outcome("b.dag", "two", ClaimOutcome::Fail), + ]; + let divergences = wet_hermetic_discovery_outcome_divergences(&wet, &hermetic); + assert!( + divergences.is_empty(), + "matching outcome vectors must yield no divergences: {:?}", + divergences + ); +} + fn ci_witness_layer_roots() -> Vec { let ws = workspace_root(); vec![ @@ -49,21 +104,23 @@ fn governed_service_representative_explicit_entries() -> Vec<(String, String)> { rep } +/// Vacuous-by-construction scaffold: lens_mock_totality witnesses do not +/// dispatch live service calls under either mode; this only guards roster wiring. #[test] -fn wet_hermetic_governed_service_representative_equivalence_holds() { +fn wet_hermetic_scaffold_roster_outcomes_agree() { let roots = ci_witness_layer_roots(); let explicit = governed_service_representative_explicit_entries(); let wet = run_discovery_corpus(&roots, &[], &explicit, ExecutionMode::Wet) - .expect("wet discovery run for governed-service representative roster"); + .expect("wet discovery run for scaffold roster"); let hermetic = run_discovery_corpus(&roots, &[], &explicit, ExecutionMode::Hermetic) - .expect("hermetic discovery run for governed-service representative roster"); + .expect("hermetic discovery run for scaffold roster"); let divergences = wet_hermetic_discovery_outcome_divergences( &wet.witness_outcomes, &hermetic.witness_outcomes, ); assert!( divergences.is_empty(), - "wet and hermetic must agree on every governed-service representative witness; divergences:\n{}", + "scaffold roster outcomes agree (vacuous — no service dispatch in roster); divergences:\n{}", divergences.join("\n") ); } From fd04564906160b81056d97bd2c9e933dc524aa66 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 19 Jun 2026 17:25:00 +0000 Subject: [PATCH 05/10] =?UTF-8?q?WIP:=20P3c:=20flip=20CI=20default=20Execu?= =?UTF-8?q?tionMode=20Wet->Hermetic=20=E2=80=94=20EQUIVALENCE-GATE-FIRS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wet_hermetic_equivalence_witness_test.dag | 6 +- src/v1/stage0/src/cli_run.rs | 91 +++++++++++++++++-- .../src/wet_hermetic_equivalence_test.rs | 45 ++++++++- 3 files changed, 132 insertions(+), 10 deletions(-) diff --git a/dsl/test/claim/wet_hermetic_equivalence_witness_test.dag b/dsl/test/claim/wet_hermetic_equivalence_witness_test.dag index 35585785dde..bcd30ad9a71 100644 --- a/dsl/test/claim/wet_hermetic_equivalence_witness_test.dag +++ b/dsl/test/claim/wet_hermetic_equivalence_witness_test.dag @@ -8,13 +8,17 @@ // // Enrolled Rust consumers (CI via gunbc.ci_spec.ci_rust_gate_test_command): // * wet_hermetic_comparator_* — comparator unit teeth (Pass vs Fail divergence) +// * wet_hermetic_scaffold_roster_filter_uses_dag_prefix_authority — prefix drift RED // * wet_hermetic_scaffold_roster_outcomes_agree — roster run (structural green only) module test.claim.wet_hermetic_equivalence_witness +// Single authority (§3): Rust `wet_hermetic_scaffold_roster_entry_prefix` reads this +// data binding; do not duplicate the path in hand-Rust substring filters. // Pin: one `test fn` per extdeps published-mock layer (18 witnesses today). data wet_hermetic_equivalence_representative_prefix: String = "src/v2/test/lens_mock_totality/" test fn wet_hermetic_equivalence_roster_authority_is_pinned() -> Bool { - wet_hermetic_equivalence_representative_prefix != "" + wet_hermetic_equivalence_representative_prefix.starts_with("src/v2/test/") + && wet_hermetic_equivalence_representative_prefix.ends_with("lens_mock_totality/") } diff --git a/src/v1/stage0/src/cli_run.rs b/src/v1/stage0/src/cli_run.rs index ce76b6df984..0b24ec50e0d 100644 --- a/src/v1/stage0/src/cli_run.rs +++ b/src/v1/stage0/src/cli_run.rs @@ -2100,14 +2100,91 @@ pub struct DiscoverySummary { pub total_measured_nanos: u128, } +/// Enrolled witness `.dag` carrying the scaffold roster entry-prefix authority. +pub const WET_HERMETIC_EQUIVALENCE_WITNESS_ENTRY: &str = + "dsl/test/claim/wet_hermetic_equivalence_witness_test.dag"; +/// `data` binding name for the single-authority roster entry prefix (§3). +pub const WET_HERMETIC_SCAFFOLD_ROSTER_PREFIX_DATA: &str = + "wet_hermetic_equivalence_representative_prefix"; + +fn resolve_entry_file_under_roots(source_roots: &[String], entry: &str) -> Result { + let path = Path::new(entry); + if path.is_file() { + return Ok(path.to_string_lossy().into_owned()); + } + for root in source_roots { + let root_path = Path::new(root); + let root_name = root_path + .file_name() + .and_then(|n| n.to_str()) + .unwrap_or_default(); + if !root_name.is_empty() { + let prefix = format!("{root_name}/"); + if let Some(suffix) = entry.strip_prefix(&prefix) { + let candidate = root_path.join(suffix); + if candidate.is_file() { + return Ok(candidate.to_string_lossy().into_owned()); + } + } + } + let candidate = root_path.join(entry); + if candidate.is_file() { + return Ok(candidate.to_string_lossy().into_owned()); + } + } + Err(format!( + "entry file does not exist or is not a file: {}", + entry + )) +} + +/// Load the scaffold roster entry-prefix from the enrolled witness `.dag` data +/// binding. Rust filter code must use this — no parallel substring authority. +pub fn wet_hermetic_scaffold_roster_entry_prefix( + source_roots: &[String], +) -> Result { + let entry = resolve_entry_file_under_roots(source_roots, WET_HERMETIC_EQUIVALENCE_WITNESS_ENTRY)?; + let (graph, source_indices) = resolve_entry_graph(source_roots, &entry)?; + let sources = load_sources_for_entry(source_roots, &entry)?; + let entry_source = sources + .iter() + .find(|s| s.path == entry || s.path.ends_with(WET_HERMETIC_EQUIVALENCE_WITNESS_ENTRY)) + .ok_or_else(|| format!("{entry}: missing from entry closure"))?; + let entry_module = extract_module_path(&entry_source.content) + .ok_or_else(|| format!("{entry}: missing module declaration"))?; + let typed_module = entry_typed_module(&graph, &source_indices, &entry_module)?; + let si = Rc::new((*source_indices).clone()); + for item in typed_module.items.iter() { + if item.body.is_none() { + continue; + } + let decl_name = authored_name_at(si.clone(), item.clone()); + if decl_name != WET_HERMETIC_SCAFFOLD_ROSTER_PREFIX_DATA { + continue; + } + let body = item.body.as_ref().ok_or_else(|| { + format!("{entry}: data '{WET_HERMETIC_SCAFFOLD_ROSTER_PREFIX_DATA}' missing body") + })?; + return literal_string_from_expr(body).ok_or_else(|| { + format!( + "{entry}: data '{WET_HERMETIC_SCAFFOLD_ROSTER_PREFIX_DATA}' must be a string literal" + ) + }); + } + Err(format!( + "{entry}: missing data '{WET_HERMETIC_SCAFFOLD_ROSTER_PREFIX_DATA}'" + )) +} + /// Scaffold roster filter: one discoverable `test fn` per extdeps layer with a -/// published mock corpus (`src/v2/test/lens_mock_totality/*`). These witnesses -/// exercise the M4 hermetic-realization *model* in pure `.dag` — they do NOT -/// traverse `eval_service_call` under either Wet or Hermetic, so they cannot -/// observe mock-vs-live faithfulness. Dissolution: replace with witnesses that -/// dispatch live transport under Wet and published-mock under Hermetic. -pub fn is_governed_service_representative_row(row: &DiscoveryRow) -> bool { - row.entry.contains("lens_mock_totality/") +/// published mock corpus under `prefix` (from +/// `wet_hermetic_scaffold_roster_entry_prefix`). These witnesses exercise the M4 +/// hermetic-realization *model* in pure `.dag` — they do NOT traverse +/// `eval_service_call` under either Wet or Hermetic, so they cannot observe +/// mock-vs-live faithfulness. Dissolution: replace with witnesses that dispatch +/// live transport under Wet and published-mock under Hermetic. +pub fn is_governed_service_representative_row(row: &DiscoveryRow, prefix: &str) -> bool { + !prefix.is_empty() && row.entry.contains(prefix) } /// Row-for-row outcome comparator for the P3c scaffold gate. Returns divergence diff --git a/src/v1/tests/src/wet_hermetic_equivalence_test.rs b/src/v1/tests/src/wet_hermetic_equivalence_test.rs index ec30f8d7219..41e8c0aa5dc 100644 --- a/src/v1/tests/src/wet_hermetic_equivalence_test.rs +++ b/src/v1/tests/src/wet_hermetic_equivalence_test.rs @@ -12,7 +12,8 @@ use v1_compiler::cli_run::{ discover_floor_corpus_rows, is_governed_service_representative_row, run_discovery_corpus, - wet_hermetic_discovery_outcome_divergences, ClaimOutcome, DiscoveryWitnessOutcome, + wet_hermetic_discovery_outcome_divergences, wet_hermetic_scaffold_roster_entry_prefix, + ClaimOutcome, DiscoveryRow, DiscoveryWitnessOutcome, }; use v1_compiler::v1_interpreter::ExecutionMode; @@ -89,12 +90,14 @@ fn ci_witness_scan_dirs() -> Vec { fn governed_service_representative_explicit_entries() -> Vec<(String, String)> { let roots = ci_witness_layer_roots(); + let prefix = wet_hermetic_scaffold_roster_entry_prefix(&roots) + .expect("load scaffold roster prefix from witness .dag authority"); let scan_dirs = ci_witness_scan_dirs(); let rows = discover_floor_corpus_rows(&roots, &scan_dirs) .expect("discover floor corpus for governed-service representative roster"); let rep: Vec<(String, String)> = rows .iter() - .filter(|r| is_governed_service_representative_row(r)) + .filter(|r| is_governed_service_representative_row(r, &prefix)) .map(|r| (r.entry.clone(), r.function.clone())) .collect(); assert!( @@ -104,6 +107,44 @@ fn governed_service_representative_explicit_entries() -> Vec<(String, String)> { rep } +#[test] +fn wet_hermetic_scaffold_roster_filter_uses_dag_prefix_authority() { + let roots = ci_witness_layer_roots(); + let prefix = wet_hermetic_scaffold_roster_entry_prefix(&roots) + .expect("load scaffold roster prefix from witness .dag authority"); + assert!( + prefix.contains("lens_mock_totality/"), + "dag authority prefix must select lens_mock_totality tree: {prefix}" + ); + let scan_dirs = ci_witness_scan_dirs(); + let rows = discover_floor_corpus_rows(&roots, &scan_dirs) + .expect("discover floor corpus for prefix authority check"); + let rep: Vec<&DiscoveryRow> = rows + .iter() + .filter(|r| is_governed_service_representative_row(r, &prefix)) + .collect(); + assert!( + !rep.is_empty(), + "dag authority prefix must match at least one discovered witness row" + ); + for row in &rep { + assert!( + row.entry.contains(&prefix), + "filtered row must contain dag authority prefix (got entry={} prefix={prefix})", + row.entry + ); + } + let outsider = DiscoveryRow { + label: "outsider".into(), + entry: "dsl/test/claim/unrelated_witness_test.dag".into(), + function: "witness_holds".into(), + }; + assert!( + !is_governed_service_representative_row(&outsider, &prefix), + "rows outside the dag prefix must not match the scaffold filter" + ); +} + /// Vacuous-by-construction scaffold: lens_mock_totality witnesses do not /// dispatch live service calls under either mode; this only guards roster wiring. #[test] From ad1372d97cf65c847a1c30059be70f03c95bcecd Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 19 Jun 2026 17:29:01 +0000 Subject: [PATCH 06/10] fix(P3c): collapse wet_hermetic roster prefix to .dag single authority. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rust filter loads wet_hermetic_equivalence_representative_prefix from the enrolled witness .dag (no parallel lens_mock_totality/ substring). Add wet_hermetic_scaffold_roster_filter_uses_dag_prefix_authority RED control; strengthen .dag witness to assert path shape on the pinned data binding. Addresses review 30910 (§3 parallel-representation + §5 coverage-by-illusion). Co-authored-by: Cursor --- src/v1/stage0/src/cli_run.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/v1/stage0/src/cli_run.rs b/src/v1/stage0/src/cli_run.rs index 0b24ec50e0d..fa16ec6dd10 100644 --- a/src/v1/stage0/src/cli_run.rs +++ b/src/v1/stage0/src/cli_run.rs @@ -2143,7 +2143,8 @@ fn resolve_entry_file_under_roots(source_roots: &[String], entry: &str) -> Resul pub fn wet_hermetic_scaffold_roster_entry_prefix( source_roots: &[String], ) -> Result { - let entry = resolve_entry_file_under_roots(source_roots, WET_HERMETIC_EQUIVALENCE_WITNESS_ENTRY)?; + let entry = + resolve_entry_file_under_roots(source_roots, WET_HERMETIC_EQUIVALENCE_WITNESS_ENTRY)?; let (graph, source_indices) = resolve_entry_graph(source_roots, &entry)?; let sources = load_sources_for_entry(source_roots, &entry)?; let entry_source = sources From 1fb9d089e6351f389212dd6b534e81c0711a5d55 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 19 Jun 2026 19:43:55 +0000 Subject: [PATCH 07/10] =?UTF-8?q?WIP:=20P3c:=20flip=20CI=20default=20Execu?= =?UTF-8?q?tionMode=20Wet->Hermetic=20=E2=80=94=20EQUIVALENCE-GATE-FIRS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dsl/std/realization_width.dag | 15 ++++++++------- dsl/test/claim/realization_width_witness_test.dag | 6 +++--- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/dsl/std/realization_width.dag b/dsl/std/realization_width.dag index f851a219be2..283b84178ed 100644 --- a/dsl/std/realization_width.dag +++ b/dsl/std/realization_width.dag @@ -23,6 +23,7 @@ module std.realization_width import std.types { Int, List } import std.measure { HardwareThreadCount, + Nano, hardware_thread_count, hardware_thread_count_value, } @@ -74,13 +75,13 @@ fn width_fold_objective_goals() -> List { } type WidthBoundedRealization { - plan: RealizationPlan + plan: RealizationPlan spawn_width: HardwareThreadCount } // Width is peripheral: the schedule topology is unchanged (§3 invariant). fn width_bounded_realization( - plan: RealizationPlan, + plan: RealizationPlan, shard_count: Int, hardware_threads: HardwareThreadCount ) -> WidthBoundedRealization { @@ -91,7 +92,7 @@ fn width_bounded_realization( } fn witness_width_fold_preserves_schedule_topology( - plan: RealizationPlan, + plan: RealizationPlan, shard_count: Int, hardware_threads: HardwareThreadCount ) -> Bool { @@ -125,7 +126,7 @@ fn witness_budget_ignoring_fold_fails( } // Measured shard-balance scaffold: assignment must read CostAccount.basis=Measured. -fn shard_balance_slot_for_cost(cost: CostAccount, baseline: CostAccount) -> Int { +fn shard_balance_slot_for_cost(cost: CostAccount, baseline: CostAccount) -> Int { match cost.basis { Measured => cost_account_time_count(account: cost) Predicted => cost_account_time_count(account: baseline) @@ -134,9 +135,9 @@ fn shard_balance_slot_for_cost(cost: CostAccount, baseline: CostAccount) -> Int // RED guard (b): asymmetric measured costs must yield different slot assignments. fn witness_measured_cost_affects_shard_balance() -> Bool { - let high = cost_account_measured(time: nanosecond_duration(count: 100)) - let low = cost_account_measured(time: nanosecond_duration(count: 10)) - let baseline = cost_account_predicted_zero() + let high = cost_account_measured(time: nanosecond_duration(count: 100)) + let low = cost_account_measured(time: nanosecond_duration(count: 10)) + let baseline = cost_account_predicted_zero() let left = shard_balance_slot_for_cost(cost: high, baseline: baseline) let right = shard_balance_slot_for_cost(cost: low, baseline: baseline) left != right diff --git a/dsl/test/claim/realization_width_witness_test.dag b/dsl/test/claim/realization_width_witness_test.dag index 0deadafb09a..e3d015218c1 100644 --- a/dsl/test/claim/realization_width_witness_test.dag +++ b/dsl/test/claim/realization_width_witness_test.dag @@ -7,7 +7,7 @@ module test.claim.realization_width_witness -import std.measure { HardwareThreadCount, hardware_thread_count, hardware_thread_count_value } +import std.measure { HardwareThreadCount, Nano, hardware_thread_count, hardware_thread_count_value } import std.realization_schedule { RealizationPlan, RealizationObjective, @@ -34,7 +34,7 @@ fn witness_threads_4() -> HardwareThreadCount { hardware_thread_count(4) } -fn synthetic_plan() -> RealizationPlan { +fn synthetic_plan() -> RealizationPlan { RealizationPlan { target: "width-witness-target" objective: RealizationObjective { goals: [] } @@ -44,7 +44,7 @@ fn synthetic_plan() -> RealizationPlan { RunnableSingleClaim { entry: gate_entry, function: "rust_monolith_gate_passes" } ] ] - total: cost_account_predicted_zero() + total: cost_account_predicted_zero() } } From 90d664c5c7d0d8e056a8a4d72d77756269f50a66 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 19 Jun 2026 19:46:49 +0000 Subject: [PATCH 08/10] =?UTF-8?q?WIP:=20P3c:=20flip=20CI=20default=20Execu?= =?UTF-8?q?tionMode=20Wet->Hermetic=20=E2=80=94=20EQUIVALENCE-GATE-FIRS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dsl/std/realization_width.dag | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dsl/std/realization_width.dag b/dsl/std/realization_width.dag index 283b84178ed..9da04c20671 100644 --- a/dsl/std/realization_width.dag +++ b/dsl/std/realization_width.dag @@ -39,10 +39,10 @@ import std.realization_schedule { CostAccount, CostBasis, schedule_eq, - cost_account_measured, cost_account_predicted_zero, cost_account_time_count, } +import std.realization_measurement { cost_account_measured_from_time } fn int_min(a: Int, b: Int) -> Int { if a < b { a } else { b } @@ -135,8 +135,8 @@ fn shard_balance_slot_for_cost(cost: CostAccount, baseline: CostAccount Bool { - let high = cost_account_measured(time: nanosecond_duration(count: 100)) - let low = cost_account_measured(time: nanosecond_duration(count: 10)) + let high = cost_account_measured_from_time(time: nanosecond_duration(count: 100)) + let low = cost_account_measured_from_time(time: nanosecond_duration(count: 10)) let baseline = cost_account_predicted_zero() let left = shard_balance_slot_for_cost(cost: high, baseline: baseline) let right = shard_balance_slot_for_cost(cost: low, baseline: baseline) From 2245e8fd16d41c0278c7ba8f8d58003fa7fd2588 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 19 Jun 2026 20:04:55 +0000 Subject: [PATCH 09/10] =?UTF-8?q?WIP:=20P3c:=20flip=20CI=20default=20Execu?= =?UTF-8?q?tionMode=20Wet->Hermetic=20=E2=80=94=20EQUIVALENCE-GATE-FIRS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dsl/std/realization_width.dag | 6 +++++- dsl/test/claim/realization_width_witness_test.dag | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/dsl/std/realization_width.dag b/dsl/std/realization_width.dag index 9da04c20671..3d3ed92b7d0 100644 --- a/dsl/std/realization_width.dag +++ b/dsl/std/realization_width.dag @@ -44,6 +44,10 @@ import std.realization_schedule { } import std.realization_measurement { cost_account_measured_from_time } +fn cost_account_predicted_zero_nano() -> CostAccount { + cost_account_predicted_zero() +} + fn int_min(a: Int, b: Int) -> Int { if a < b { a } else { b } } @@ -137,7 +141,7 @@ fn shard_balance_slot_for_cost(cost: CostAccount, baseline: CostAccount Bool { let high = cost_account_measured_from_time(time: nanosecond_duration(count: 100)) let low = cost_account_measured_from_time(time: nanosecond_duration(count: 10)) - let baseline = cost_account_predicted_zero() + let baseline = cost_account_predicted_zero_nano() let left = shard_balance_slot_for_cost(cost: high, baseline: baseline) let right = shard_balance_slot_for_cost(cost: low, baseline: baseline) left != right diff --git a/dsl/test/claim/realization_width_witness_test.dag b/dsl/test/claim/realization_width_witness_test.dag index e3d015218c1..2a88ddb16a5 100644 --- a/dsl/test/claim/realization_width_witness_test.dag +++ b/dsl/test/claim/realization_width_witness_test.dag @@ -34,6 +34,10 @@ fn witness_threads_4() -> HardwareThreadCount { hardware_thread_count(4) } +fn synthetic_plan_total() -> CostAccount { + cost_account_predicted_zero() +} + fn synthetic_plan() -> RealizationPlan { RealizationPlan { target: "width-witness-target" @@ -44,7 +48,7 @@ fn synthetic_plan() -> RealizationPlan { RunnableSingleClaim { entry: gate_entry, function: "rust_monolith_gate_passes" } ] ] - total: cost_account_predicted_zero() + total: synthetic_plan_total() } } From 28f3ff391c3f8c3c30396c8d65388afae91e25f9 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Fri, 19 Jun 2026 20:08:34 +0000 Subject: [PATCH 10/10] =?UTF-8?q?fix(ci):=20realization=5Fwidth=20witnesse?= =?UTF-8?q?s=20=E2=80=94=20avoid=20=20parse=20as=20Lt=20operator.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cost_account_predicted_zero() infers Nano from return type; explicit cost_account_predicted_zero() parsed as comparison in .dag surface. Fixes discovery-corpus failure on realization_width_witnesses @ merge. Co-authored-by: Cursor --- dsl/std/realization_width.dag | 2 +- dsl/test/claim/realization_width_witness_test.dag | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dsl/std/realization_width.dag b/dsl/std/realization_width.dag index 3d3ed92b7d0..3896388f4bf 100644 --- a/dsl/std/realization_width.dag +++ b/dsl/std/realization_width.dag @@ -45,7 +45,7 @@ import std.realization_schedule { import std.realization_measurement { cost_account_measured_from_time } fn cost_account_predicted_zero_nano() -> CostAccount { - cost_account_predicted_zero() + cost_account_predicted_zero() } fn int_min(a: Int, b: Int) -> Int { diff --git a/dsl/test/claim/realization_width_witness_test.dag b/dsl/test/claim/realization_width_witness_test.dag index 2a88ddb16a5..3bb65f853fd 100644 --- a/dsl/test/claim/realization_width_witness_test.dag +++ b/dsl/test/claim/realization_width_witness_test.dag @@ -13,6 +13,7 @@ import std.realization_schedule { RealizationObjective, Runnable, RunnableSingleClaim, + CostAccount, cost_account_predicted_zero, } import std.realization { @@ -35,7 +36,7 @@ fn witness_threads_4() -> HardwareThreadCount { } fn synthetic_plan_total() -> CostAccount { - cost_account_predicted_zero() + cost_account_predicted_zero() } fn synthetic_plan() -> RealizationPlan {