diff --git a/.claude/board/INTEGRATION_PLANS.md b/.claude/board/INTEGRATION_PLANS.md index 7fcffd053..c13d8e258 100644 --- a/.claude/board/INTEGRATION_PLANS.md +++ b/.claude/board/INTEGRATION_PLANS.md @@ -1,14 +1,3 @@ -## 2026-09-25 (1) — ce64-spofc-learning-v1 — CE64 as the mantissa that carries SPOFC evidence between cycles → `.claude/plans/ce64-spofc-learning-v1.md` - -**Status:** PROPOSAL; leg A shipped (draft PR stacked on #1293). The driver now -packs each emitted CE64 from its candidate's SPOFC record: palette-space S/O -instead of a row id, SPOFC truth, the Pearl mask as the inverse of -`edge_to_layer_mask` (the raw `predicates & 7` turned SUPPORTS into -CONTRADICTS), and topology bits 59–60 written for the first time in the live -path. Legs B–E (evidence identity, owner write-back, cross-cycle revision, -completions) are blocked on named dependencies — the W4a writer, a per-edge -evidence-identity carrier, a predicate palette — and are not substituted. - ## 2026-09-19 (1) — waben-fold-execution-loop-v1 — from the merged folds to one addressed execution loop → `.claude/plans/waben-fold-execution-loop-v1.md` **Status:** PROPOSAL. No code authorized; this is the grounded implementation diff --git a/.claude/board/STATUS_BOARD.md b/.claude/board/STATUS_BOARD.md index 940776dbc..be320abd7 100644 --- a/.claude/board/STATUS_BOARD.md +++ b/.claude/board/STATUS_BOARD.md @@ -1,17 +1,3 @@ -## D-CSL — CE64 as the mantissa that carries SPOFC evidence between cycles (2026-09-25) - -Plan: `plans/ce64-spofc-learning-v1.md`. Predecessor: #1293 (SPOFC candidate aggregation). - -| D-id | scope | status | gate / falsifier | -|---|---|---|---| -| **D-CSL-A** | emit CE64 from the SPOFC record: palette-space S/O, SPOFC truth, Pearl mask as the inverse of `edge_to_layer_mask`, topology bits 59–60 by relation kind | In PR (#1294) | `driver::tests::{emitted_edge_carries_the_p64_target_and_its_evidence, content_partner_edges_do_not_claim_a_direct_topology, causal_mask_round_trips_through_p64_layers}` | -| **D-CSL-A2** | characterise `learn`: repeat observation recounted; `ALL_FROZEN` emission plasticity | In PR (#1294) | `tests/ce64_recount_probe.rs` — flips deliberately with D-CSL-D | -| **D-CSL-B** | per-edge evidence identity (stamp) so a repeat or shared root is not fresh support | Queued — blocked (no carrier; W-slot is a corpus root, CE64 bits closed to new semantics) | a revision with the same observation must not raise confidence | -| **D-CSL-C** | write emitted edges back through the owner path | Queued — blocked on W4a | `persist_cycle` BLOCKED→W4a (`COMPONENT-MAP.md` §6) | -| **D-CSL-D** | cross-cycle revision of the stored edge with the cycle's SPOFC observation | Queued — after B, C | `ce64_recount_probe` flips | -| **D-CSL-E** | completions ("Sudoku autocomplete"): inferred edges marked `Indirect*`, one-way probe only | Queued | per `mul-ewa-trust-propagation-v1.md` §0b: trust must not inflate from thinking longer | -| **D-CSL-F** | Shannon entropy over a candidate's support distribution | Queued | new code; none exists | - ## D-RPT — ReportPlan / zero-copy pivot / report-as-OGAR-projection (2026-09-23) Entry: `entries/2026-09-23-report-plan-zero-copy-pivot-docir-convergence.md`. diff --git a/.claude/board/SUPERSESSION-INDEX.md b/.claude/board/SUPERSESSION-INDEX.md index 62675723e..8aa87d1f9 100644 --- a/.claude/board/SUPERSESSION-INDEX.md +++ b/.claude/board/SUPERSESSION-INDEX.md @@ -14,7 +14,7 @@ ## What this table says **`BindSpace` is the shape of the problem.** Marked RETIRE, and simultaneously the -most-referenced symbol here: **69 crate files, 49 plans, 43 of them blind.** +most-referenced symbol here: **69 crate files, 48 plans, 42 of them blind.** That is a programme, not a cleanup. **`GateState` is the sharpest case: 1 plan names it and *every one* is blind.** @@ -52,19 +52,19 @@ coverage instead. | `A2AMessage` | BLOCKED | — | 2 | 1 | 0 | | `StepMask` | BLOCKED | — | 3 | 10 | 4 | | `commit_to_l4` | BLOCKED | — | 2 | 2 | 0 | -| `dispatch_busdto` | BLOCKED | — | 3 | 9 | 6 | -| `persist_cycle` | BLOCKED | — | 11 | 9 | 6 | +| `dispatch_busdto` | BLOCKED | — | 3 | 8 | 5 | +| `persist_cycle` | BLOCKED | — | 11 | 8 | 5 | | `CognitiveMarkers` | REPURPOSE | `Commit` | 1 | 0 | 0 | | `DominoCascade` | REPURPOSE | `Commit` | 7 | 1 | 0 | | `GateDecision` | REPURPOSE | — | 25 | 28 | 25 | | `GateState` | REPURPOSE | — | 14 | 1 | 1 | | `MergeMode` | REPURPOSE | — | 8 | 14 | 13 | | `ResonanceDto` | REPURPOSE | `PerturbationDto` | 2 | 12 | 7 | -| `BindSpace` | RETIRE | — | 69 | 49 | 43 | +| `BindSpace` | RETIRE | — | 69 | 48 | 42 | | `CollapseGateEmission` | RETIRE | — | 5 | 14 | 12 | | `ThinkingStyle` | RETIRE-toward-contract | — | 52 | 28 | 24 | -## Table 2 — plans naming a ruled symbol without citing the ruling (77) +## Table 2 — plans naming a ruled symbol without citing the ruling (76) Route is **mechanical triage, not a verdict**: `ARCHIVE?` = the plan's own status says it shipped; `RESCOPE` = it targets a symbol marked RETIRE; `READ` = neither signal fires @@ -112,7 +112,6 @@ a licence to act on it. | **RESCOPE** | `alpha-reason-witness-shader-field-archaeology-pass-1` | `BindSpace`, `MergeMode`, `ResonanceDto` | SOURCE AUDIT / PLAN ONLY. No production wiri | 0/1 | | **RESCOPE** | `bindspace-mailbox-soa-dependency-map-v1` | `BindSpace`, `dispatch_busdto`, `persist_cycle` | MAP / preflight. No source wired yet. Read-b | 0/2 | | **RESCOPE** | `bindspace-mailbox-soa-w3-w4a-impl-v1` | `BindSpace`, `dispatch_busdto`, `persist_cycle` | v2 — 5-consolidation + 3-brutal-critic pass | 0/1 | -| **RESCOPE** | `ce64-spofc-learning-v1` | `BindSpace`, `dispatch_busdto`, `persist_cycle` | PROPOSAL + first leg shipped (draft PR, stac | 0/7 | | **RESCOPE** | `cognitive-substrate-convergence-v3` | `BindSpace`, `CollapseGateEmission`, `MergeMode` | ACTIVE — sprint-12 Wave F + Wave G complete | 4/16 | | **RESCOPE** | `mailbox-cycle-aware-write-contract-v1` | `BindSpace`, `dispatch_busdto`, `persist_cycle` | CONJECTURE / design. 5+3-gated before code. | 0/1 | | **RESCOPE** | `unified-integration-v1` | `BindSpace`, `MergeMode`, `ThinkingStyle` | Active — brainstorm phase complete; delivera | 0/0 | @@ -158,6 +157,6 @@ a licence to act on it. | **RESCOPE** | `unified-soa-rubikon-integration-v1` | `BindSpace` | — | 0/8 | - **ARCHIVE?**: 0 -- **RESCOPE**: 57 +- **RESCOPE**: 56 - **READ**: 20 - ruled symbols tracked: 14 diff --git a/.claude/plans/ce64-spofc-learning-v1.md b/.claude/plans/ce64-spofc-learning-v1.md deleted file mode 100644 index 66c0c809a..000000000 --- a/.claude/plans/ce64-spofc-learning-v1.md +++ /dev/null @@ -1,125 +0,0 @@ -# ce64-spofc-learning-v1 — CE64 as the mantissa that carries SPOFC evidence between cycles - -**Status:** PROPOSAL + first leg shipped (draft PR, stacked on #1293). Legs B–E are -blocked on the dependencies named in § Missing dependencies; none of them is -substituted here. - -## Overview - -CE64 was meant to keep what a cycle learned for the next cycle. In the live -dispatch path that role is dormant. #1293 made stage [3] collect each row's -supporting relationships into one SPOFC record (support count, best partner, -predicate union, `TruthU8`). This plan carries that record the rest of the way: -into the emitted CE64, back into the store, and into the next cycle's revision — -without recounting evidence the store already holds. - -## Checklist - -- [x] **D-CSL-A. Emit CE64 from SPOFC** (this PR): palette-space S/O, SPOFC truth, - Pearl mask as the inverse of `edge_to_layer_mask`, topology by how the - relation was found. Disable-verified tests. -- [x] **D-CSL-A2. Characterise `learn`** (this PR, `tests/ce64_recount_probe.rs`): it - pools a repeated observation as fresh evidence; the driver's emission - plasticity (`ALL_FROZEN`) stops it moving S/P/O. -- [ ] **D-CSL-B. Evidence identity.** Decide what tells "same evidence again" from "a - new witness" when a stored edge is revised. Blocked: see § Missing, item 2. -- [ ] **D-CSL-C. Write-back through the owner path.** Blocked on W4a (item 1). -- [ ] **D-CSL-D. Cross-cycle revision.** After B and C: revise the stored edge with the - cycle's SPOFC observation; the probe in A' flips deliberately. -- [ ] **D-CSL-E. Completions ("Sudoku autocomplete").** One-way probe only, per - `mul-ewa-trust-propagation-v1.md` §0b; inferred edges marked by topology. -- [ ] **D-CSL-F. Support entropy.** Shannon entropy over a candidate's support - distribution, as a spread signal beside `m`. New code; nothing like it exists. - -## Verified facts this rests on - -CE64 layout (default `causal-edge-v2-layout`, `causal-edge/src/layout.rs`, const-asserted -to cover all 64 bits once): - -| bits | field | -|---|---| -| 0–23 | S, P, O — three palette256 indices | -| 24–31 / 32–39 | NARS frequency / confidence, u8 | -| 40–42 | Pearl causal mask | -| 46–49 | inference mantissa (signed i4) | -| 50–52 | plasticity (`0` = `ALL_FROZEN`, `plasticity.rs:17`) | -| 53–58 | W-slot: witness **corpus** root handle, 0..=63 | -| 59–60 | `CausalTopology`: Direct 0, IndirectKnownIntermediates 1, IndirectUnknownIntermediates 2, Unknown 3 | -| 61–63 | `ReasoningBand` | - -- **`pack` defaults bits 59–60 to 0 = `Direct`.** Every edge emitted before this - PR claimed a direct relation, including content-similarity partners. The two - bits share their ordinals with `TrustTexture`; the last writer wins. -- **The 24-bit S/P/O can carry the target.** The emission simply never wrote it: - it packed a row id into palette space (`s = row%256`, `o = (row/4)%256`). -- **`predicates & 0b111` was not the inverse of `edge_to_layer_mask`** - (`p64-bridge/src/lib.rs:61`): plane 2 is SUPPORTS, but Pearl bit 2 reads back as - CONTRADICTS. A supporting relation round-tripped as a contradiction. -- **`learn` (`edge.rs:731`) pools unconditionally**: `c = ws/(ws+1)` with - `ws = w_self + w_obs`, no source identity. Revising twice with one observation - counts it twice (pinned in A'). -- **Nothing in `run` writes an edge back.** `persist_cycle` - (`engine_bridge.rs:784`) writes only `emitted_edges[0]`, has test-only callers, - and `ShaderDriver.bindspace` is `Arc`. The only stored-edge read that - crosses cycles is the cascade query `backing.edge(row).s_idx()`. -- **`tables.revise(...)` is computed and discarded** in stage [3] - (`_revised_truth`). -- **Confidence convention matches arm-discovery; frequency does not.** SPOFC - `c = m·255/(m+k)` is `evidence_confidence_u8`, shared with `arm_to_truth_u8`. - SPOFC `f` is the best resonance; arm-discovery's `f` is a conditional ratio - `cooccur/antecedent`. There is no antecedent count in a dispatch, so the ratio - is not available; the difference is recorded, not papered over. - -## The "Sudoku" framing, stated against the code - -- **8× support = 8× evidence.** In SPOFC terms a row supported eight ways has - `m = 8`, `c = 226/255`. That is the evidence a completion is constrained by. - It is only honest if the eight are independent; the pre-pass credits each - content pair to both rows, and cascade hits through one shared palette target - are counted per row. Independence is item B. -- **Bits 59–60 as the grid folding itself.** Topology is the one place a CE64 - says how it was obtained: `Direct` (observed plane edge), `IndirectKnown` - (a completion whose intermediates are named — its derivation), `IndirectUnknown` - (a fill with the path unknown), `Unknown` (similarity, no causal path). An - inferred completion must land as `Indirect*`, never as `Direct`, so a later - cycle cannot read it back as an observation. This PR is the first writer of - bits 59–60 in the live path (Direct / Unknown only; nothing is inferred yet). -- **Oberflächenspannung / EWA.** `jc::ewa_sandwich` (`crates/jc/src/ewa_sandwich.rs`, - contract twin `sigma_propagation::ewa_sandwich`) is SPD covariance push-forward, - `Σ' = M·Σ·Mᵀ`. It propagates uncertainty *shape* and counts no evidence. Its - only epistemic use is the PROPOSED `mul-ewa-trust-propagation-v1.md`, which - names the circularity: Σ → trust → gate → Σ. A fill by a minimisation principle - is "plausible everywhere, grounded nowhere", so a completion from it must never - raise confidence as if observed. The learned prior it could supply is the - surface; the evidence stays the SPOFC count. The driver's "Kerbl EWA" - (`alpha_front_to_back_composite`) is scalar alpha compositing and is unrelated. -- **Shared upstream.** Two supports that trace to one root are one witness - (`lance-graph-contract/src/fusion.rs` anti-alchemy law; `shared_roots`, - `inherited_roots`). `nars::belief::revise_at` pools only on disjoint, non-empty - stamps and otherwise falls back to CHOICE; `admit_derived` admits derivations - with an empty stamp so they never pool. That is the discipline item B needs; - where its carrier lives in the dispatch path is the open question. - -## Missing dependencies (named, not substituted) - -1. **The W4a owner write path.** `COMPONENT-MAP.md` §6: `persist_cycle` / - `dispatch_busdto` are BLOCKED→W4a, the batch writer pairing - `cast(on_behalf = mailbox_owner())`. A write-back that bypasses it violates the - V3 ownership rule. Item C waits for it. -2. **An evidence-identity carrier per stored edge.** `learn` has none. The W-slot - (bits 53–58) is a witness *corpus root*, not a per-observation source set, and - `le-contract.md` forbids new awareness semantics in CE64 bits. `nars::Stamp` - exists in the planner, not in the driver's store. Where the stamp lives (a SoA - lane beside the edge, per V3) is a design decision this plan does not make. -3. **A predicate palette.** P stays 0 because nothing assigns a palette index to a - predicate. Using the p64 plane index would be inventing one. -4. **A production feed into the planes.** `update_planes` has no production caller; - `edges_to_layered_rows` has none outside p64-bridge, and `convergence.rs` - addresses `%64` where p64-bridge uses `/4`. Closing the topology loop waits on - that being reconciled. - -## Effects of leg A - -Emitted edges change for every dispatch (S/O address space, confidence, Pearl -bits, topology). `cycle_fp` and top-k are untouched: the braid and ranking read -the candidates, not the edges. diff --git a/crates/cognitive-shader-driver/src/driver.rs b/crates/cognitive-shader-driver/src/driver.rs index 6128f87c4..be69406b0 100644 --- a/crates/cognitive-shader-driver/src/driver.rs +++ b/crates/cognitive-shader-driver/src/driver.rs @@ -27,7 +27,6 @@ use std::sync::RwLock; use bgz17::palette_semiring::PaletteSemiring; use causal_edge::edge::{CausalEdge64, InferenceType}; -use causal_edge::layout::CausalTopology; use causal_edge::pearl::CausalMask; use causal_edge::plasticity::PlasticityState; use causal_edge::tables::{unpack_c, unpack_f, NarsTables}; @@ -512,13 +511,23 @@ impl ShaderDriver { if h.resonance < 0.2 { continue; } - // Every hit came out of the candidate table, so its SPOFC record - // exists; a miss here would be a stage-[3] bug, not a data case. - let Some(spofc) = candidates.spofc(h.cycle_index as usize, h.row) else { - debug_assert!(false, "hit without a SPOFC record"); - continue; - }; - emitted[emitted_n as usize] = spofc_edge(&backing, &spofc, style_ord).0; + let f = (h.resonance.clamp(0.0, 1.0) * 255.0) as u8; + let c = (h.resonance.clamp(0.0, 1.0) * 255.0) as u8; + let s_palette = (h.row % 256) as u8; + let o_palette = ((h.row / 4) % 256) as u8; + let edge = CausalEdge64::pack( + s_palette, + 0, + o_palette, + f, + c, + CausalMask::from_bits(h.predicates & 0x07), + 0, + style_ord_to_inference(style_ord), + PlasticityState::from_bits(0), + (h.cycle_index & 0xFFF) as u16, + ); + emitted[emitted_n as usize] = edge.0; emitted_n += 1; } @@ -724,67 +733,6 @@ impl ShaderDriver { /// plane. The specific planes each Pearl level unlocks are a calibration a later /// probe may retune; the identity-at-base and superset-monotone properties are /// invariant. -/// Pearl causal-mask bits for a set of p64 predicate planes: the inverse of -/// the causal half of `p64_bridge::edge_to_layer_mask` (bit0 ↔ CAUSES, -/// bit1 ↔ ENABLES, bit2 ↔ CONTRADICTS). Planes with no Pearl counterpart -/// (SUPPORTS, REFINES, …) contribute no bit; `edge_to_layer_mask` reaches them -/// through the inference type instead. -/// -/// Emission used `predicates & 0b111` directly, which put SUPPORTS (plane 2) on -/// Pearl bit2 — read back by `edge_to_layer_mask` as CONTRADICTS. -fn layers_to_causal_mask(predicates: u8) -> CausalMask { - use p64_bridge::{CAUSES, CONTRADICTS, ENABLES}; - let mut bits = 0u8; - if predicates & (1 << CAUSES) != 0 { - bits |= 0b001; - } - if predicates & (1 << ENABLES) != 0 { - bits |= 0b010; - } - if predicates & (1 << CONTRADICTS) != 0 { - bits |= 0b100; - } - CausalMask::from_bits(bits) -} - -/// The palette archetype the store holds for `row`: the S byte of its stored -/// edge, the same value stage [3] queries the P64 cascade with. -fn row_palette(backing: &BackingStore<'_>, row: u32) -> u8 { - backing.edge(row as usize).s_idx() -} - -/// One emitted CE64, packed from a candidate's SPOFC record. -/// -/// - **S / O** are palette256 indices, the address space the P64 planes and -/// `edge_to_block` use: S is the row's archetype, O the partner's (a P64 -/// target is already one; a row partner resolves through the store). -/// - **P** stays 0: no predicate palette exists to index into yet. -/// - **f / c** are the SPOFC truth — confidence counts supporting relations -/// instead of echoing resonance. -/// - **Topology** says how the relation was found. A P64 target is one plane -/// edge from the row's archetype (`Direct`); a content-similarity partner -/// carries no causal path at all (`Unknown`). Left at the packed default, -/// every edge would claim `Direct`. -fn spofc_edge(backing: &BackingStore<'_>, spofc: &Spofc, style_ord: u8) -> CausalEdge64 { - let (o_palette, topology) = match spofc.object { - SupportPartner::Palette(t) => (t, CausalTopology::Direct), - SupportPartner::Row(r) => (row_palette(backing, r), CausalTopology::Unknown), - }; - CausalEdge64::pack( - row_palette(backing, spofc.subject), - 0, - o_palette, - spofc.truth.frequency, - spofc.truth.confidence, - layers_to_causal_mask(spofc.predicates), - 0, - style_ord_to_inference(style_ord), - PlasticityState::from_bits(0), - 0, - ) - .with_topology(topology) -} - fn rung_widened_layer_mask(base: RungLevel, level: RungLevel, req_mask: u8) -> u8 { if (level as u8) <= (base as u8) { return req_mask; @@ -1535,144 +1483,6 @@ mod tests { assert_eq!(table.iter().count(), 1, "one candidate, not four"); } - /// The emitted CE64 carries what SPOFC collected. The fixture stores the - /// row's archetype as palette 2 — not 0, which `row % 256` would also give - /// for row 0 — so S can only be right if it is read from the store. - #[test] - fn emitted_edge_carries_the_p64_target_and_its_evidence() { - let q = lance_graph_contract::qualia::QualiaI4_16D::ZERO; - let stored = CausalEdge64::pack( - 2, - 0, - 0, - 0, - 0, - CausalMask::from_bits(0), - 0, - InferenceType::Deduction, - PlasticityState::from_bits(0), - 0, - ); - let bs = BindSpaceBuilder::new(1) - .push( - &[0u64; WORDS_PER_FP], - MetaWord::new(1, 1, 200, 200, 5), - stored.0, - q, - 0, - 0, - ) - .build(); - let semiring = PaletteSemiring::build(&Palette { - entries: (0..4).map(|_| Base17 { dims: [0i16; 17] }).collect(), - }); - let mut planes = [[0u64; 64]; 8]; - // Planes are indexed by palette block (`s / 4`): archetype 2 lives in - // block 0, whose SUPPORTS edge to block 0 makes the four equidistant - // entries 0..4 its candidate targets. SUPPORTS has no Pearl bit, so - // it also tells the fixed mask from the old `predicates & 0b111`. - planes[p64_bridge::SUPPORTS][0] = 1; - let driver = CognitiveShaderBuilder::new() - .bindspace(Arc::new(bs)) - .semiring(Arc::new(semiring)) - .planes(planes) - .build(); - let req = ShaderDispatch { - rows: ColumnWindow::new(0, 1), - meta_prefilter: MetaFilter::ALL, - layer_mask: 1 << p64_bridge::SUPPORTS, - radius: u16::MAX, - style: StyleSelector::Ordinal(1), - ..ShaderDispatch::default() - }; - let backing = driver.backing(); - let passed = backing.prefilter(req.rows, &req.meta_prefilter); - let table = driver.collect_candidates(&backing, &req, &passed, 1, req.layer_mask); - let spofc = table.spofc(0, passed[0]).expect("cascade support"); - let SupportPartner::Palette(target) = spofc.object else { - panic!("the partner must be a P64 target, got {:?}", spofc.object); - }; - - let bus = driver.dispatch(&req).bus; - assert_eq!(bus.emitted_edge_count, 1, "one candidate, one edge"); - let e = CausalEdge64(bus.emitted_edges[0]); - assert_eq!(e.s_idx(), 2, "S is the row's stored archetype"); - assert_eq!(e.o_idx(), target, "O is the P64 target"); - assert_eq!(e.p_idx(), 0, "no predicate palette to index yet"); - assert_eq!(e.topology(), CausalTopology::Direct); - assert_eq!( - e.causal_mask() as u8, - 0, - "a SUPPORTS relation sets no Pearl bit (it used to set CONTRADICTS)" - ); - assert_eq!(e.confidence_u8(), spofc.truth.confidence); - assert_eq!(e.frequency_u8(), spofc.truth.frequency); - // Four supporting relations, so more confident than any one of them. - assert!(e.confidence_u8() > evidence_confidence_u8(1, NARS_PERSONALITY_K)); - } - - /// A content-similarity partner is not a causal path, so its edge says - /// `Unknown` instead of inheriting the packed default `Direct`. - #[test] - fn content_partner_edges_do_not_claim_a_direct_topology() { - let n = 16u32; - let bus = empty_plane_driver(n).dispatch(&all_rows(n)).bus; - assert!(bus.emitted_edge_count > 0, "the fixture must emit"); - for &raw in &bus.emitted_edges[..usize::from(bus.emitted_edge_count)] { - let e = CausalEdge64(raw); - assert_eq!(e.topology(), CausalTopology::Unknown); - assert_eq!( - e.confidence_u8(), - evidence_confidence_u8(n - 1, NARS_PERSONALITY_K) - ); - } - } - - /// The Pearl bits emission writes read back as the same planes through - /// `p64_bridge::edge_to_layer_mask`. Emitting `predicates & 0b111` put - /// SUPPORTS on Pearl bit 2, which reads back as CONTRADICTS. - #[test] - fn causal_mask_round_trips_through_p64_layers() { - use p64_bridge::{edge_to_layer_mask, CAUSES, CONTRADICTS, ENABLES, SUPPORTS}; - let pearl_planes: u8 = (1 << CAUSES) | (1 << ENABLES) | (1 << CONTRADICTS); - for predicates in 0..=u8::MAX { - // Induction maps to SUPPORTS, outside the Pearl planes, so it - // cannot mask a wrong Pearl bit. - let e = CausalEdge64::pack( - 0, - 0, - 0, - 0, - 0, - layers_to_causal_mask(predicates), - 0, - InferenceType::Induction, - PlasticityState::from_bits(0), - 0, - ); - assert_eq!( - edge_to_layer_mask(&e) & pearl_planes, - predicates & pearl_planes, - "predicates {predicates:#010b}" - ); - } - // The old emission, for contrast: SUPPORTS alone became CONTRADICTS. - let old = CausalMask::from_bits((1u8 << SUPPORTS) & 0b111); - let e = CausalEdge64::pack( - 0, - 0, - 0, - 0, - 0, - old, - 0, - InferenceType::Induction, - PlasticityState::from_bits(0), - 0, - ); - assert_ne!(edge_to_layer_mask(&e) & (1 << CONTRADICTS), 0); - } - /// The repeats are evidence, not noise: each row keeps a count of its /// supporting relationships and the best one, in SPOFC form. #[test] diff --git a/crates/cognitive-shader-driver/tests/ce64_recount_probe.rs b/crates/cognitive-shader-driver/tests/ce64_recount_probe.rs deleted file mode 100644 index 4580eff53..000000000 --- a/crates/cognitive-shader-driver/tests/ce64_recount_probe.rs +++ /dev/null @@ -1,64 +0,0 @@ -//! Does `CausalEdge64::learn` know an observation it has already absorbed? -//! -//! CHARACTERISATION probe for the cross-cycle follow-up to #1293, not a -//! desired-behaviour contract. If emitted edges were written back and revised -//! each cycle with `learn`, the same SPOFC observation would arrive again on -//! the next dispatch over an unchanged store. These tests pin what `learn` -//! does with it today, so the change that adds evidence identity has to flip -//! them deliberately. - -use causal_edge::edge::{CausalEdge64, InferenceType}; -use causal_edge::pearl::CausalMask; -use causal_edge::plasticity::PlasticityState; - -fn edge(s: u8, f: u8, c: u8, plasticity: PlasticityState) -> CausalEdge64 { - CausalEdge64::pack( - s, - 0, - 0, - f, - c, - CausalMask::from_bits(0), - 0, - InferenceType::Deduction, - plasticity, - 0, - ) -} - -/// Revising with one observation twice counts it twice: `learn` pools the -/// evidence weight unconditionally, with nothing to tell a repeat from a new -/// independent witness. -#[test] -fn learn_counts_a_repeated_observation_as_fresh_evidence() { - let obs = edge(1, 200, 127, PlasticityState::ALL_HOT); - let mut once = obs; - once.learn(obs, 0); - let mut twice = once; - twice.learn(obs, 0); - assert!( - once.confidence_u8() > obs.confidence_u8(), - "anti-vacuity: one revision must raise confidence" - ); - assert!( - twice.confidence_u8() > once.confidence_u8(), - "same observation, second revision: {} -> {}", - once.confidence_u8(), - twice.confidence_u8() - ); -} - -/// The driver emits with `PlasticityState::from_bits(0)`, which is -/// `ALL_FROZEN`: `learn` can then never move S/P/O, whatever the evidence. -#[test] -fn driver_emission_plasticity_freezes_every_plane() { - assert_eq!(PlasticityState::from_bits(0), PlasticityState::ALL_FROZEN); - let mut stored = edge(1, 200, 10, PlasticityState::from_bits(0)); - let stronger = edge(2, 200, 250, PlasticityState::ALL_HOT); - stored.learn(stronger, 0); - assert_eq!(stored.s_idx(), 1, "a frozen plane keeps its archetype"); - // With the planes hot, the same observation does move S. - let mut hot = edge(1, 200, 10, PlasticityState::ALL_HOT); - hot.learn(stronger, 0); - assert_eq!(hot.s_idx(), 2); -}