From 29785d3d181adc4dcae4c26f05c25f9985ba5850 Mon Sep 17 00:00:00 2001 From: AdaWorldAPI Date: Tue, 6 Oct 2026 07:24:22 +0200 Subject: [PATCH 1/6] probe: wire DAV EWA frontier through revision --- .../examples/dav_active_observation_probe.rs | 344 ++++++++++++++++++ 1 file changed, 344 insertions(+) create mode 100644 crates/jc/examples/dav_active_observation_probe.rs diff --git a/crates/jc/examples/dav_active_observation_probe.rs b/crates/jc/examples/dav_active_observation_probe.rs new file mode 100644 index 000000000..f2da12e8b --- /dev/null +++ b/crates/jc/examples/dav_active_observation_probe.rs @@ -0,0 +1,344 @@ +//! DAV × EWA × Revision — first end-to-end active-observation wiring. +//! +//! This is a diagnostic probe, NOT a JC pillar and NOT a production policy. +//! +//! It asks one deliberately small question: +//! +//! > Can an EWA-bounded candidate frontier plus deterministic multi-route +//! > disagreement choose a useful withheld observation, feed it through the +//! > real revision contract as a new independent root, and then show that the +//! > selected epistemic hole collapses on replay? +//! +//! Existing pieces only: +//! +//! - EWA transport: `lance_graph_contract::sigma_propagation::ewa_sandwich` +//! - disagreement normalization: `jc::quorum::max_u8_variance` +//! - write-back court of appeal: `lance_graph_contract::revision::GadamerRevision` +//! +//! No diffusion model, LPIPS, new 0..63 ordinal, new fold primitive, or +//! production write path is introduced here. +//! +//! Run: +//! +//! ```text +//! cargo run --manifest-path crates/jc/Cargo.toml --example dav_active_observation_probe +//! ``` + +use jc::quorum::max_u8_variance; +use lance_graph_contract::revision::{ + BasisView, CodebookId, EncounterEvidence, EvidentialEffect, GadamerRevision, GrammarId, + HorizonId, InterpretiveHorizon, LanguageId, LensId, QuestionId, RevisionKind, RevisionPolicy, +}; +use lance_graph_contract::sigma_propagation::{ewa_sandwich, Spd2}; + +const N: usize = 21; +const SEED: usize = 0; +const TARGET: usize = 10; + +// This is intentionally a probe threshold, not a substrate constant. +// It makes a=0.55's isotropic EWA field just reach hop 10: +// 0.55^10 ~= 0.002533. +const MIN_EWA_WEIGHT: f64 = 0.0025; +const APERTURES: [f64; 5] = [0.45, 0.50, 0.55, 0.60, 0.65]; + +#[derive(Clone, Copy, Debug)] +struct Candidate { + idx: usize, + disagreement: f64, + ewa_weight: f64, + score: f64, +} + +fn truth(idx: usize) -> bool { + // One planted regime change at TARGET, then a second one farther right. + // TARGET is the useful withheld fact the probe should discover. + (TARGET..16).contains(&idx) +} + +fn initial_observations() -> Vec> { + let mut observed: Vec> = (0..N).map(|idx| Some(truth(idx))).collect(); + + // Four withheld facts. Only TARGET sits on a regime boundary and therefore + // makes the deterministic completion routes disagree. + for idx in [6usize, TARGET, 13, 18] { + observed[idx] = None; + } + observed +} + +fn nearest_left(observed: &[Option], idx: usize) -> bool { + (0..idx) + .rev() + .find_map(|j| observed[j]) + .unwrap_or(false) +} + +fn nearest_right(observed: &[Option], idx: usize) -> bool { + ((idx + 1)..observed.len()) + .find_map(|j| observed[j]) + .unwrap_or(false) +} + +fn local_majority(observed: &[Option], idx: usize, radius: usize) -> bool { + let lo = idx.saturating_sub(radius); + let hi = (idx + radius + 1).min(observed.len()); + let mut yes = 0usize; + let mut no = 0usize; + + for value in observed[lo..hi].iter().flatten() { + if *value { + yes += 1; + } else { + no += 1; + } + } + + // Stable tie-break: false. The physical storage / iteration order cannot + // decide a semantic tie. + yes > no +} + +fn route_votes(observed: &[Option], idx: usize) -> [u8; 3] { + if let Some(v) = observed[idx] { + let x = if v { 255 } else { 0 }; + return [x, x, x]; + } + + [ + if nearest_left(observed, idx) { 255 } else { 0 }, + if nearest_right(observed, idx) { 255 } else { 0 }, + if local_majority(observed, idx, 3) { 255 } else { 0 }, + ] +} + +/// Complement of the quorum agreement normalization: +/// +/// disagreement = sqrt(var(votes) / max_attainable_var(k)) +/// +/// 0 = all routes coincide, 1 = maximally split for this k. +fn route_disagreement(observed: &[Option], idx: usize) -> f64 { + let votes = route_votes(observed, idx); + let mean = votes.iter().map(|&v| f64::from(v)).sum::() / votes.len() as f64; + let var = votes + .iter() + .map(|&v| { + let d = f64::from(v) - mean; + d * d + }) + .sum::() + / votes.len() as f64; + + let max_var = max_u8_variance(votes.len()); + if max_var == 0.0 { + 0.0 + } else { + (var / max_var).sqrt().clamp(0.0, 1.0) + } +} + +/// Isotropic special case of the real EWA sandwich. +/// +/// M = sqrt(a) I, Sigma_0 = I +/// Sigma_h = M Sigma_(h-1) M^T = a^h I +/// +/// Reading the mean diagonal therefore gives the aperture field weight at +/// exactly `hops` hops while still executing the certified ABI kernel. +fn ewa_aperture_weight(aperture: f64, hops: usize) -> f64 { + assert!((0.0..=1.0).contains(&aperture)); + let root = aperture.sqrt(); + let m = Spd2 { + a: root, + b: 0.0, + c: root, + }; + let mut sigma = Spd2::I; + for _ in 0..hops { + sigma = ewa_sandwich(&m, &sigma); + } + assert!(sigma.is_spd(1e-15)); + 0.5 * (sigma.a + sigma.c) +} + +fn rank_candidates(observed: &[Option], aperture: f64) -> Vec { + let mut candidates: Vec = observed + .iter() + .enumerate() + .filter_map(|(idx, value)| { + if value.is_some() { + return None; + } + + let hops = idx.abs_diff(SEED); + let ewa_weight = ewa_aperture_weight(aperture, hops); + if ewa_weight < MIN_EWA_WEIGHT { + return None; + } + + let disagreement = route_disagreement(observed, idx); + Some(Candidate { + idx, + disagreement, + ewa_weight, + score: disagreement * ewa_weight, + }) + }) + .collect(); + + candidates.sort_by(|a, b| { + b.score + .total_cmp(&a.score) + .then_with(|| a.idx.cmp(&b.idx)) + }); + candidates +} + +fn prior_horizon() -> InterpretiveHorizon { + InterpretiveHorizon { + id: HorizonId(1), + awareness: 0, + question: QuestionId(1), + language: LanguageId(1), + grammar: GrammarId(1), + codebook: CodebookId(1), + lens: LensId(1), + projected_claims: 0, + independent_roots: 0, + inherited_roots: 0, + unresolved_tension: 0, + revision_index: 0, + } +} + +fn revise_with_observation(idx: usize, value: bool) { + let bit = 1u64 << idx; + let prior = prior_horizon(); + let proposed_claims = if value { bit } else { 0 }; + + let encounter = EncounterEvidence { + proposed_claims, + independent_roots: bit, + inherited_roots: 0, + resistance: bit, + contradictions: 0, + affected_parts: bit, + }; + let ancestry = BasisView { + ancestry_independent_roots: 0, + ancestry_derived_roots: 0, + ancestor_claims: 0, + closes_cycle: false, + }; + + let delta = GadamerRevision.revise(&prior, &encounter, &ancestry); + + assert_eq!( + delta.kind, + RevisionKind::HorizonExpansion, + "a newly observed true boundary fact should expand the horizon" + ); + assert_eq!( + delta.evidential_effect, + EvidentialEffect::IncreaseEligible, + "the observation is a genuinely new independent root" + ); + assert_eq!(delta.new_independent_roots, bit); + assert_eq!(delta.resulting.independent_roots, bit); + assert_eq!(delta.resulting.projected_claims, bit); +} + +fn main() { + let mut observed = initial_observations(); + + println!("DAV x EWA x Revision active-observation probe"); + println!("seed={SEED}, planted useful withheld target={TARGET}"); + println!("frontier floor={MIN_EWA_WEIGHT:.6}"); + println!(); + + let mut best_efficiency = (0.0f64, 0.0f64); + + for aperture in APERTURES { + let ranked = rank_candidates(&observed, aperture); + let touched = ranked.len(); + let top = ranked.first().copied(); + let hit = top.is_some_and(|c| c.idx == TARGET); + let efficiency = if touched == 0 { + 0.0 + } else { + f64::from(hit) / touched as f64 + }; + + if efficiency > best_efficiency.1 { + best_efficiency = (aperture, efficiency); + } + + println!( + "a={aperture:.2} hop10={:.6} touched={touched} top={:?} hit={} efficiency={efficiency:.3}", + ewa_aperture_weight(aperture, 10), + top.map(|c| (c.idx, c.disagreement, c.ewa_weight, c.score)), + hit + ); + } + + // Synthetic falsifier shape: + // .45 cannot reach hop 10 at this frontier floor. + assert!( + rank_candidates(&observed, 0.45) + .first() + .is_none_or(|c| c.idx != TARGET), + "narrow aperture unexpectedly reached the planted hop-10 target" + ); + + // .55 is the first sweep point whose EWA field reaches hop 10 and the + // disagreement rank should put that useful fact first. + let ranked_055 = rank_candidates(&observed, 0.55); + let selected = ranked_055 + .first() + .copied() + .expect("a=0.55 should expose at least one candidate"); + assert_eq!( + selected.idx, TARGET, + "DAV ranking failed to choose the planted useful observation" + ); + assert!( + selected.disagreement > 0.0, + "selected target must be epistemically unresolved before observation" + ); + + // Deterministic-random baseline = lowest candidate ordinal. At this exact + // frontier it touches node 6 first, so k=1 misses the useful target. + let mut ordinal_baseline: Vec = ranked_055.iter().map(|c| c.idx).collect(); + ordinal_baseline.sort_unstable(); + assert_eq!(ordinal_baseline.first().copied(), Some(6)); + assert_ne!(ordinal_baseline[0], TARGET); + + // Observation is the only place where hidden truth enters. + let revealed = truth(selected.idx); + assert!(revealed, "the planted boundary target is a true fact"); + + // Existing revision.rs is the court of appeal. A physical observation is + // presented as a new independent root; DAV itself never mints evidence. + revise_with_observation(selected.idx, revealed); + + // Replay with the observation present. All three deterministic routes now + // read the same observed value at the selected site, so the epistemic hole + // must collapse. + observed[selected.idx] = Some(revealed); + let after = route_disagreement(&observed, selected.idx); + assert_eq!( + after, 0.0, + "observation + revision did not collapse the selected disagreement" + ); + + println!(); + println!( + "selected hop-{} target with a=.55: disagreement {:.3} -> {:.3} after observation", + TARGET.abs_diff(SEED), + selected.disagreement, + after + ); + println!( + "best synthetic recovered-fact/touched-candidate efficiency in sweep: a={:.2} ({:.3})", + best_efficiency.0, best_efficiency.1 + ); + println!("PASS: EWA frontier -> DAV disagreement -> observation -> revision -> replay collapse"); +} From 507ce849353b3c572413f10f37a862613a84c654 Mon Sep 17 00:00:00 2001 From: AdaWorldAPI Date: Tue, 6 Oct 2026 07:24:35 +0200 Subject: [PATCH 2/6] probe: register DAV active observation example --- crates/jc/Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/jc/Cargo.toml b/crates/jc/Cargo.toml index 8657b4d21..f83d761b3 100644 --- a/crates/jc/Cargo.toml +++ b/crates/jc/Cargo.toml @@ -55,6 +55,9 @@ name = "sigma_probe" [[example]] name = "probe_p1" +[[example]] +name = "dav_active_observation_probe" + [[example]] name = "osint_edge_traversal" From d3c437dabe41b8df89f0e08c4f98f1fa5066ea2c Mon Sep 17 00:00:00 2001 From: AdaWorldAPI Date: Tue, 6 Oct 2026 07:24:55 +0200 Subject: [PATCH 3/6] fix: keep DAV probe compatibility explicit --- crates/jc/examples/dav_active_observation_probe.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/jc/examples/dav_active_observation_probe.rs b/crates/jc/examples/dav_active_observation_probe.rs index f2da12e8b..36bf1b72c 100644 --- a/crates/jc/examples/dav_active_observation_probe.rs +++ b/crates/jc/examples/dav_active_observation_probe.rs @@ -264,7 +264,7 @@ fn main() { let efficiency = if touched == 0 { 0.0 } else { - f64::from(hit) / touched as f64 + (if hit { 1.0 } else { 0.0 }) / touched as f64 }; if efficiency > best_efficiency.1 { @@ -284,7 +284,7 @@ fn main() { assert!( rank_candidates(&observed, 0.45) .first() - .is_none_or(|c| c.idx != TARGET), + .map_or(true, |c| c.idx != TARGET), "narrow aperture unexpectedly reached the planted hop-10 target" ); From ccd83baa7c0b3b271a9dba5a56539b1ad5891522 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 6 Oct 2026 05:34:16 +0000 Subject: [PATCH 4/6] fix(jc): rustfmt and clippy for the DAV probe Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01DgxrCafsJuAahpBs7oC14R --- .../examples/dav_active_observation_probe.rs | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/crates/jc/examples/dav_active_observation_probe.rs b/crates/jc/examples/dav_active_observation_probe.rs index 36bf1b72c..26874636b 100644 --- a/crates/jc/examples/dav_active_observation_probe.rs +++ b/crates/jc/examples/dav_active_observation_probe.rs @@ -67,10 +67,7 @@ fn initial_observations() -> Vec> { } fn nearest_left(observed: &[Option], idx: usize) -> bool { - (0..idx) - .rev() - .find_map(|j| observed[j]) - .unwrap_or(false) + (0..idx).rev().find_map(|j| observed[j]).unwrap_or(false) } fn nearest_right(observed: &[Option], idx: usize) -> bool { @@ -107,7 +104,11 @@ fn route_votes(observed: &[Option], idx: usize) -> [u8; 3] { [ if nearest_left(observed, idx) { 255 } else { 0 }, if nearest_right(observed, idx) { 255 } else { 0 }, - if local_majority(observed, idx, 3) { 255 } else { 0 }, + if local_majority(observed, idx, 3) { + 255 + } else { + 0 + }, ] } @@ -184,11 +185,7 @@ fn rank_candidates(observed: &[Option], aperture: f64) -> Vec { }) .collect(); - candidates.sort_by(|a, b| { - b.score - .total_cmp(&a.score) - .then_with(|| a.idx.cmp(&b.idx)) - }); + candidates.sort_by(|a, b| b.score.total_cmp(&a.score).then_with(|| a.idx.cmp(&b.idx))); candidates } @@ -284,7 +281,7 @@ fn main() { assert!( rank_candidates(&observed, 0.45) .first() - .map_or(true, |c| c.idx != TARGET), + .is_none_or(|c| c.idx != TARGET), "narrow aperture unexpectedly reached the planted hop-10 target" ); @@ -340,5 +337,7 @@ fn main() { "best synthetic recovered-fact/touched-candidate efficiency in sweep: a={:.2} ({:.3})", best_efficiency.0, best_efficiency.1 ); - println!("PASS: EWA frontier -> DAV disagreement -> observation -> revision -> replay collapse"); + println!( + "PASS: EWA frontier -> DAV disagreement -> observation -> revision -> replay collapse" + ); } From 44987a00d07512c2c38ca22242276b9dc7bae618 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 6 Oct 2026 05:36:08 +0000 Subject: [PATCH 5/6] probe(jc): route the DAV loop through revision and quorum for real The belief state is now the revision horizon: routes read it, a revealed observation changes it only when GadamerRevision admits it as a new independent root, and replay reads delta.resulting. Before this, the revision call was asserted on and discarded, and deleting it left the probe green. Disagreement now comes from jc::quorum::pairwise_agreement_u8 instead of a local copy of its formula. Adds the anti-laundering negative (route consensus as an inherited root is refused and changes nothing), the enumeration-order check over a real score tie, the ordinal k=1 baseline by residual disagreement, and the reach rule a^h >= floor at every aperture in place of the hand-picked 0.45/0.55 asserts. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01DgxrCafsJuAahpBs7oC14R --- .../examples/dav_active_observation_probe.rs | 480 ++++++++++-------- 1 file changed, 282 insertions(+), 198 deletions(-) diff --git a/crates/jc/examples/dav_active_observation_probe.rs b/crates/jc/examples/dav_active_observation_probe.rs index 26874636b..e65d72ad1 100644 --- a/crates/jc/examples/dav_active_observation_probe.rs +++ b/crates/jc/examples/dav_active_observation_probe.rs @@ -12,9 +12,23 @@ //! Existing pieces only: //! //! - EWA transport: `lance_graph_contract::sigma_propagation::ewa_sandwich` -//! - disagreement normalization: `jc::quorum::max_u8_variance` +//! - disagreement: `jc::quorum::pairwise_agreement_u8`, the quorum dispersion +//! `1 − σ/σ_max(k)`, read as its complement //! - write-back court of appeal: `lance_graph_contract::revision::GadamerRevision` //! +//! # The belief state is the revision horizon +//! +//! What the probe believes is an `InterpretiveHorizon`: bit `i` of +//! `independent_roots` says site `i` has been observed, and bit `i` of +//! `projected_claims` says what was observed there. The routes read that +//! horizon and nothing else. A revealed observation changes the belief state +//! only by being presented to `GadamerRevision` and adopted when the revision +//! returns `EvidentialEffect::IncreaseEligible`; replay then reads +//! `delta.resulting`. Remove the revision call and the hole cannot close. +//! +//! The counterfactual docket (`RevisionVerdict::is_acceptable`) is NOT walked: +//! this updates the probe's working horizon, not actual-world state. +//! //! No diffusion model, LPIPS, new 0..63 ordinal, new fold primitive, or //! production write path is introduced here. //! @@ -24,46 +38,78 @@ //! cargo run --manifest-path crates/jc/Cargo.toml --example dav_active_observation_probe //! ``` -use jc::quorum::max_u8_variance; +use jc::quorum::pairwise_agreement_u8; use lance_graph_contract::revision::{ BasisView, CodebookId, EncounterEvidence, EvidentialEffect, GadamerRevision, GrammarId, - HorizonId, InterpretiveHorizon, LanguageId, LensId, QuestionId, RevisionKind, RevisionPolicy, + HorizonId, InterpretiveHorizon, LanguageId, LensId, QuestionId, RevisionDelta, RevisionPolicy, }; use lance_graph_contract::sigma_propagation::{ewa_sandwich, Spd2}; +type Horizon = InterpretiveHorizon; + const N: usize = 21; const SEED: usize = 0; const TARGET: usize = 10; +const WITHHELD: [usize; 4] = [6, TARGET, 13, 18]; -// This is intentionally a probe threshold, not a substrate constant. -// It makes a=0.55's isotropic EWA field just reach hop 10: -// 0.55^10 ~= 0.002533. +// A probe threshold, not a substrate constant. It places the reach boundary +// for hop 10 between apertures 0.50 and 0.55 (0.50^10 ~= 0.000977, +// 0.55^10 ~= 0.002533). The sweep therefore demonstrates the reach rule +// `a^h >= floor`; it is not evidence that 0.55 is special. const MIN_EWA_WEIGHT: f64 = 0.0025; const APERTURES: [f64; 5] = [0.45, 0.50, 0.55, 0.60, 0.65]; -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq)] struct Candidate { idx: usize, - disagreement: f64, + /// `0` = the routes coincide, `255` = maximally split. + disagreement: u8, ewa_weight: f64, score: f64, } +/// The hidden world. Read only by `initial_horizon` (for the prior evidence) +/// and by the reveal step; ranking never sees it. fn truth(idx: usize) -> bool { // One planted regime change at TARGET, then a second one farther right. - // TARGET is the useful withheld fact the probe should discover. (TARGET..16).contains(&idx) } -fn initial_observations() -> Vec> { - let mut observed: Vec> = (0..N).map(|idx| Some(truth(idx))).collect(); +fn bit(idx: usize) -> u64 { + 1u64 << idx +} - // Four withheld facts. Only TARGET sits on a regime boundary and therefore - // makes the deterministic completion routes disagree. - for idx in [6usize, TARGET, 13, 18] { - observed[idx] = None; +/// Prior evidence: every site except `WITHHELD` was observed independently. +fn initial_horizon() -> Horizon { + let mut roots = 0u64; + let mut claims = 0u64; + for idx in (0..N).filter(|i| !WITHHELD.contains(i)) { + roots |= bit(idx); + if truth(idx) { + claims |= bit(idx); + } } - observed + InterpretiveHorizon { + id: HorizonId(1), + awareness: 0, + question: QuestionId(1), + language: LanguageId(1), + grammar: GrammarId(1), + codebook: CodebookId(1), + lens: LensId(1), + projected_claims: claims, + independent_roots: roots, + inherited_roots: 0, + unresolved_tension: 0, + revision_index: 0, + } +} + +/// The read the routes are allowed: what the horizon says was observed. +fn observations(h: &Horizon) -> [Option; N] { + core::array::from_fn(|idx| { + (h.independent_roots & bit(idx) != 0).then_some(h.projected_claims & bit(idx) != 0) + }) } fn nearest_left(observed: &[Option], idx: usize) -> bool { @@ -79,9 +125,7 @@ fn nearest_right(observed: &[Option], idx: usize) -> bool { fn local_majority(observed: &[Option], idx: usize, radius: usize) -> bool { let lo = idx.saturating_sub(radius); let hi = (idx + radius + 1).min(observed.len()); - let mut yes = 0usize; - let mut no = 0usize; - + let (mut yes, mut no) = (0usize, 0usize); for value in observed[lo..hi].iter().flatten() { if *value { yes += 1; @@ -89,61 +133,45 @@ fn local_majority(observed: &[Option], idx: usize, radius: usize) -> bool no += 1; } } - - // Stable tie-break: false. The physical storage / iteration order cannot - // decide a semantic tie. + // Stable tie-break: false. Iteration order cannot decide a semantic tie. yes > no } +fn vote(v: bool) -> u8 { + if v { + 255 + } else { + 0 + } +} + fn route_votes(observed: &[Option], idx: usize) -> [u8; 3] { if let Some(v) = observed[idx] { - let x = if v { 255 } else { 0 }; - return [x, x, x]; + return [vote(v); 3]; } - [ - if nearest_left(observed, idx) { 255 } else { 0 }, - if nearest_right(observed, idx) { 255 } else { 0 }, - if local_majority(observed, idx, 3) { - 255 - } else { - 0 - }, + vote(nearest_left(observed, idx)), + vote(nearest_right(observed, idx)), + vote(local_majority(observed, idx, 3)), ] } -/// Complement of the quorum agreement normalization: -/// -/// disagreement = sqrt(var(votes) / max_attainable_var(k)) +/// Route disagreement at one site, through jc's quorum dispersion. /// -/// 0 = all routes coincide, 1 = maximally split for this k. -fn route_disagreement(observed: &[Option], idx: usize) -> f64 { - let votes = route_votes(observed, idx); - let mean = votes.iter().map(|&v| f64::from(v)).sum::() / votes.len() as f64; - let var = votes - .iter() - .map(|&v| { - let d = f64::from(v) - mean; - d * d - }) - .sum::() - / votes.len() as f64; - - let max_var = max_u8_variance(votes.len()); - if max_var == 0.0 { - 0.0 - } else { - (var / max_var).sqrt().clamp(0.0, 1.0) - } +/// `pairwise_agreement_u8` scores the pairs of `k` square tables. Each route +/// contributes a 2×2 table whose single off-diagonal pair holds its vote, so +/// cell `[0][1]` is exactly the quorum score of the three votes. +fn route_disagreement(observed: &[Option], idx: usize) -> u8 { + let tables = route_votes(observed, idx).map(|v| [255u8, v, v, 255]); + let refs: [&[u8]; 3] = [&tables[0], &tables[1], &tables[2]]; + let agreement = pairwise_agreement_u8(&refs, 2).expect("three 2x2 tables"); + 255 - agreement[1] } /// Isotropic special case of the real EWA sandwich. /// -/// M = sqrt(a) I, Sigma_0 = I -/// Sigma_h = M Sigma_(h-1) M^T = a^h I -/// -/// Reading the mean diagonal therefore gives the aperture field weight at -/// exactly `hops` hops while still executing the certified ABI kernel. +/// M = sqrt(a) I, Sigma_0 = I, so Sigma_h = a^h I. The mean diagonal is the +/// aperture field weight at `hops` hops, computed by the contract kernel. fn ewa_aperture_weight(aperture: f64, hops: usize) -> f64 { assert!((0.0..=1.0).contains(&aperture)); let root = aperture.sqrt(); @@ -160,184 +188,240 @@ fn ewa_aperture_weight(aperture: f64, hops: usize) -> f64 { 0.5 * (sigma.a + sigma.c) } -fn rank_candidates(observed: &[Option], aperture: f64) -> Vec { - let mut candidates: Vec = observed - .iter() - .enumerate() - .filter_map(|(idx, value)| { - if value.is_some() { - return None; - } - - let hops = idx.abs_diff(SEED); - let ewa_weight = ewa_aperture_weight(aperture, hops); - if ewa_weight < MIN_EWA_WEIGHT { - return None; - } - - let disagreement = route_disagreement(observed, idx); - Some(Candidate { - idx, - disagreement, - ewa_weight, - score: disagreement * ewa_weight, +/// Rank the unobserved sites inside the EWA frontier, enumerating them in +/// `order`. The result must not depend on `order`. +fn rank_in( + observed: &[Option], + aperture: f64, + order: impl Iterator, +) -> Vec { + let mut candidates: Vec = order + .filter(|&idx| observed[idx].is_none()) + .filter_map(|idx| { + let ewa_weight = ewa_aperture_weight(aperture, idx.abs_diff(SEED)); + (ewa_weight >= MIN_EWA_WEIGHT).then(|| { + let disagreement = route_disagreement(observed, idx); + Candidate { + idx, + disagreement, + ewa_weight, + score: f64::from(disagreement) / 255.0 * ewa_weight, + } }) }) .collect(); - + // Explicit, total order: higher score first, then the semantic site + // ordinal. Enumeration order never decides. candidates.sort_by(|a, b| b.score.total_cmp(&a.score).then_with(|| a.idx.cmp(&b.idx))); candidates } -fn prior_horizon() -> InterpretiveHorizon { - InterpretiveHorizon { - id: HorizonId(1), - awareness: 0, - question: QuestionId(1), - language: LanguageId(1), - grammar: GrammarId(1), - codebook: CodebookId(1), - lens: LensId(1), - projected_claims: 0, - independent_roots: 0, - inherited_roots: 0, - unresolved_tension: 0, - revision_index: 0, - } +fn rank(observed: &[Option], aperture: f64) -> Vec { + rank_in(observed, aperture, 0..N) } -fn revise_with_observation(idx: usize, value: bool) { - let bit = 1u64 << idx; - let prior = prior_horizon(); - let proposed_claims = if value { bit } else { 0 }; - - let encounter = EncounterEvidence { - proposed_claims, - independent_roots: bit, - inherited_roots: 0, - resistance: bit, - contradictions: 0, - affected_parts: bit, - }; +/// Present an encounter to `GadamerRevision`, with the prior horizon as the +/// ancestry, and adopt the result only if it is eligible to increase support. +fn revise( + prior: &Horizon, + encounter: &EncounterEvidence, +) -> (Horizon, RevisionDelta) { let ancestry = BasisView { - ancestry_independent_roots: 0, - ancestry_derived_roots: 0, - ancestor_claims: 0, + ancestry_independent_roots: prior.independent_roots, + ancestry_derived_roots: prior.inherited_roots, + ancestor_claims: prior.projected_claims, closes_cycle: false, }; + let delta = GadamerRevision.revise(prior, encounter, &ancestry); + let next = if delta.evidential_effect == EvidentialEffect::IncreaseEligible { + delta.resulting.clone() + } else { + prior.clone() + }; + (next, delta) +} - let delta = GadamerRevision.revise(&prior, &encounter, &ancestry); +fn claims_with(prior: &Horizon, idx: usize, value: bool) -> u64 { + if value { + prior.projected_claims | bit(idx) + } else { + prior.projected_claims & !bit(idx) + } +} - assert_eq!( - delta.kind, - RevisionKind::HorizonExpansion, - "a newly observed true boundary fact should expand the horizon" - ); +/// The reveal step: the only place hidden truth enters after the prior. The +/// physical observation is a new independent root. +fn observe(prior: &Horizon, idx: usize) -> (Horizon, RevisionDelta) { + let value = truth(idx); + revise( + prior, + &EncounterEvidence { + proposed_claims: claims_with(prior, idx, value), + independent_roots: bit(idx), + inherited_roots: 0, + resistance: 0, + contradictions: 0, + affected_parts: bit(idx), + }, + ) +} + +/// What DAV must NOT be able to do: turn its own route consensus into +/// evidence. The consensus is a derived interpretation, so it arrives as an +/// inherited root, never an independent one. +fn adopt_route_consensus(prior: &Horizon, idx: usize) -> (Horizon, RevisionDelta) { + let votes = route_votes(&observations(prior), idx); + let value = votes.iter().filter(|&&v| v == 255).count() * 2 > votes.len(); + revise( + prior, + &EncounterEvidence { + proposed_claims: claims_with(prior, idx, value), + independent_roots: 0, + inherited_roots: bit(idx), + resistance: 0, + contradictions: 0, + affected_parts: bit(idx), + }, + ) +} + +/// Total route disagreement over every still-withheld site. +fn residual_disagreement(h: &Horizon) -> u32 { + let observed = observations(h); + (0..N) + .filter(|&i| observed[i].is_none()) + .map(|i| u32::from(route_disagreement(&observed, i))) + .sum() +} + +#[derive(Debug, PartialEq)] +struct Cycle { + selected: usize, + before: u8, + after: u8, + residual_after: u32, + resulting: Horizon, +} + +/// One closed loop: observe `selected`, revise, replay from the horizon. +fn run_cycle(prior: &Horizon, selected: usize) -> Cycle { + let before = route_disagreement(&observations(prior), selected); + let (next, delta) = observe(prior, selected); assert_eq!( delta.evidential_effect, EvidentialEffect::IncreaseEligible, - "the observation is a genuinely new independent root" + "a revealed observation must enter as a new independent root" ); - assert_eq!(delta.new_independent_roots, bit); - assert_eq!(delta.resulting.independent_roots, bit); - assert_eq!(delta.resulting.projected_claims, bit); + assert_eq!(delta.new_independent_roots, bit(selected)); + let after = route_disagreement(&observations(&next), selected); + Cycle { + selected, + before, + after, + residual_after: residual_disagreement(&next), + resulting: next, + } } fn main() { - let mut observed = initial_observations(); + let prior = initial_horizon(); + let observed = observations(&prior); println!("DAV x EWA x Revision active-observation probe"); - println!("seed={SEED}, planted useful withheld target={TARGET}"); - println!("frontier floor={MIN_EWA_WEIGHT:.6}"); + println!("seed={SEED}, planted useful withheld target={TARGET}, withheld={WITHHELD:?}"); + println!("frontier floor={MIN_EWA_WEIGHT:.6} (probe threshold, not a constant)"); println!(); - let mut best_efficiency = (0.0f64, 0.0f64); - + // The frontier follows the reach rule, at every aperture. `powi` is an + // independent computation of a^h, not the kernel under test. for aperture in APERTURES { - let ranked = rank_candidates(&observed, aperture); - let touched = ranked.len(); + let ranked = rank(&observed, aperture); + let reaches_target = aperture.powi(TARGET as i32) >= MIN_EWA_WEIGHT; let top = ranked.first().copied(); - let hit = top.is_some_and(|c| c.idx == TARGET); - let efficiency = if touched == 0 { - 0.0 - } else { - (if hit { 1.0 } else { 0.0 }) / touched as f64 - }; - - if efficiency > best_efficiency.1 { - best_efficiency = (aperture, efficiency); - } - println!( - "a={aperture:.2} hop10={:.6} touched={touched} top={:?} hit={} efficiency={efficiency:.3}", - ewa_aperture_weight(aperture, 10), - top.map(|c| (c.idx, c.disagreement, c.ewa_weight, c.score)), - hit + "a={aperture:.2} hop10={:.6} frontier={:?} top={:?}", + ewa_aperture_weight(aperture, TARGET), + ranked.iter().map(|c| c.idx).collect::>(), + top.map(|c| (c.idx, c.disagreement)) + ); + assert_eq!( + ranked.iter().any(|c| c.idx == TARGET), + reaches_target, + "a={aperture}: the EWA frontier disagrees with a^h >= floor" + ); + assert_eq!( + top.is_some_and(|c| c.idx == TARGET), + reaches_target, + "a={aperture}: a reachable disagreeing target must rank first" + ); + // Ranking must not depend on enumeration order. At a=0.65 sites 6 + // and 13 tie at score 0, so the tie-break is what this checks. + assert_eq!( + rank_in(&observed, aperture, (0..N).rev()), + ranked, + "a={aperture}: candidate enumeration order changed the ranking" ); } - - // Synthetic falsifier shape: - // .45 cannot reach hop 10 at this frontier floor. + let tied = rank(&observed, 0.65); assert!( - rank_candidates(&observed, 0.45) - .first() - .is_none_or(|c| c.idx != TARGET), - "narrow aperture unexpectedly reached the planted hop-10 target" + tied.windows(2).any(|w| w[0].score == w[1].score), + "anti-vacuity: the sweep must contain a score tie for the order check" ); - // .55 is the first sweep point whose EWA field reaches hop 10 and the - // disagreement rank should put that useful fact first. - let ranked_055 = rank_candidates(&observed, 0.55); - let selected = ranked_055 - .first() - .copied() - .expect("a=0.55 should expose at least one candidate"); - assert_eq!( - selected.idx, TARGET, - "DAV ranking failed to choose the planted useful observation" - ); + let aperture = 0.55; + let ranked = rank(&observed, aperture); + + let dav = ranked[0].idx; + let ordinal = ranked + .iter() + .map(|c| c.idx) + .min() + .expect("non-empty frontier"); + println!(); + println!("a={aperture:.2}: DAV k=1 picks {dav}, ordinal baseline k=1 picks {ordinal}"); + + // Before observation the selected site is an open hole. assert!( - selected.disagreement > 0.0, - "selected target must be epistemically unresolved before observation" + ranked[0].disagreement > 0, + "selected site must be unresolved" ); - // Deterministic-random baseline = lowest candidate ordinal. At this exact - // frontier it touches node 6 first, so k=1 misses the useful target. - let mut ordinal_baseline: Vec = ranked_055.iter().map(|c| c.idx).collect(); - ordinal_baseline.sort_unstable(); - assert_eq!(ordinal_baseline.first().copied(), Some(6)); - assert_ne!(ordinal_baseline[0], TARGET); - - // Observation is the only place where hidden truth enters. - let revealed = truth(selected.idx); - assert!(revealed, "the planted boundary target is a true fact"); - - // Existing revision.rs is the court of appeal. A physical observation is - // presented as a new independent root; DAV itself never mints evidence. - revise_with_observation(selected.idx, revealed); - - // Replay with the observation present. All three deterministic routes now - // read the same observed value at the selected site, so the epistemic hole - // must collapse. - observed[selected.idx] = Some(revealed); - let after = route_disagreement(&observed, selected.idx); + // DAV cannot close the hole with its own consensus: revision refuses an + // inherited root, the horizon is unchanged, and the hole stays open. + let (laundered, delta) = adopt_route_consensus(&prior, dav); + assert_ne!(delta.evidential_effect, EvidentialEffect::IncreaseEligible); + assert_eq!(laundered, prior, "route consensus changed the belief state"); assert_eq!( - after, 0.0, - "observation + revision did not collapse the selected disagreement" + route_disagreement(&observations(&laundered), dav), + ranked[0].disagreement ); - println!(); - println!( - "selected hop-{} target with a=.55: disagreement {:.3} -> {:.3} after observation", - TARGET.abs_diff(SEED), - selected.disagreement, - after - ); - println!( - "best synthetic recovered-fact/touched-candidate efficiency in sweep: a={:.2} ({:.3})", - best_efficiency.0, best_efficiency.1 + // The closed loop, for DAV and for the baseline. + let dav_cycle = run_cycle(&prior, dav); + let ordinal_cycle = run_cycle(&prior, ordinal); + for (name, c) in [("DAV", &dav_cycle), ("ordinal", &ordinal_cycle)] { + println!( + "{name:>7}: site {} disagreement {} -> {}, residual over withheld sites {} -> {}", + c.selected, + c.before, + c.after, + residual_disagreement(&prior), + c.residual_after + ); + } + assert_eq!( + dav_cycle.after, 0, + "replay did not collapse the selected hole" ); - println!( - "PASS: EWA frontier -> DAV disagreement -> observation -> revision -> replay collapse" + assert_eq!(dav_cycle.residual_after, 0); + assert!( + ordinal_cycle.residual_after > dav_cycle.residual_after, + "the baseline closed as much as DAV, so DAV bought nothing here" ); + + // Replay is deterministic. + assert_eq!(run_cycle(&prior, dav), dav_cycle); + + println!(); + println!("PASS: EWA frontier -> disagreement -> observation -> revision -> replay collapse"); } From 943b430a0a58ea4beca59eb7c06911fc3b9f9fc0 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 6 Oct 2026 05:36:37 +0000 Subject: [PATCH 6/6] ci(jc): run the DAV probe and trigger on the contract modules it uses Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01DgxrCafsJuAahpBs7oC14R --- .github/workflows/jc-proof.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/jc-proof.yml b/.github/workflows/jc-proof.yml index 75db059b0..4119b64cb 100644 --- a/.github/workflows/jc-proof.yml +++ b/.github/workflows/jc-proof.yml @@ -7,6 +7,9 @@ on: paths: - crates/jc/** - crates/lance-graph-contract/src/cam.rs + # The DAV probe below runs these two contract modules end to end. + - crates/lance-graph-contract/src/revision.rs + - crates/lance-graph-contract/src/sigma_propagation.rs - .github/workflows/jc-proof.yml concurrency: @@ -56,3 +59,9 @@ jobs: # execute the comparison here — it exits non-zero if the asymmetry (V3 # absorbs P64 at 0 new bytes vs P64 replicates V3 at 32) fails to certify. run: cargo run --manifest-path crates/jc/Cargo.toml --example substrate_compare + + - name: Run dav_active_observation_probe (EWA -> disagreement -> revision -> replay) + # Its falsifiers are runtime asserts in `main`, so they only count if + # something runs it. Exits non-zero if revision stops being the only + # way an observation enters, or replay stops collapsing the hole. + run: cargo run --manifest-path crates/jc/Cargo.toml --example dav_active_observation_probe