diff --git a/.claude/board/AGENT_LOG.md b/.claude/board/AGENT_LOG.md index d8b83feb..df11bad0 100644 --- a/.claude/board/AGENT_LOG.md +++ b/.claude/board/AGENT_LOG.md @@ -1,3 +1,15 @@ +## 2026-06-18 — B2 resolved: witness-arc boundary documented (NO `WitnessArcEvaluator` trait) + +**Main thread (Opus) + 5+3 council**, branch `claude/witness-arc-boundary-doc`. The parked B2 item — "wire perturbation-sim witness arc into contract witness_table" — was put through the critical-decision protocol (5 analysts + 3 brutal critics, all read both files in full). **Unanimous verdict: do NOT build the trait.** The two "witness arc" notions are different objects (numeric `∑field·arc` standing wave vs W-slot→identity resolution); welding them is an AP6 one-impl trait + AGI-as-glove "never a new trait" violation + a CATCH-CRITICAL dep-direction inversion (zero-dep contract would gain a perturbation-sim dep). integration-lead confirmed the real wiring is downstream D-MBX-A3, gated on D-MBX-A2 (current gating gap) + OQ-11.2 + a §0 dep ruling. + +**Shipped (doc + board only, no type/dep change):** +- `perturbation-sim/src/witness.rs` — added "NOT the same witness arc as contract::witness_table" section; corrected the per-arc complexity overclaim (`q·O(N)` → `q·O(N log N)` as implemented; `q·O(N)` only for precomputed/structured arc spectra — flagged by truth-architect + brutally-honest-tester); amortized quantity is the FIELD transform. +- `lance-graph-contract/src/witness_table.rs` — reciprocal "Not the perturbation-sim witness arc — different object" section; states any future wiring is a consumer-side free function over a borrowed `&[f64]` column, never a trait on the zero-dep crate. +- `EPIPHANIES.md` — `E-WITNESS-ARC-TWO-OBJECTS-1` (the finding + the math-claim correction). +- `TECH_DEBT.md` — `TD-WITNESS-EVAL-WIRING-1` (the seam, its three gating prerequisites, paid-when condition). + +**Math validated (truth-architect, reviewer-only):** Parseval `particle == wave` PROVEN (FWHT is the symmetric involution-up-to-N; tested 1e-9); NaN/degenerate safety PROVEN; only the doc-string asymptotic bookkeeping was off (now fixed). No code/test behavior changed. + ## 2026-06-18 — #526 follow-up: corpus regenerated with inherits_from + validation_kind **Main thread (Opus) — single implementer**, branch `claude/odoo-spo-corpus-regen`. Executes the explicit pending step from PR #526 ("Corpus regenerated against live `/home/user/odoo/addons` — pending next session with Odoo source"). This session HAS the Odoo source, so the two new enrichment passes #526 shipped as code now land their triples in the shipped corpus. diff --git a/.claude/board/EPIPHANIES.md b/.claude/board/EPIPHANIES.md index 22dc2b07..99fc1274 100644 --- a/.claude/board/EPIPHANIES.md +++ b/.claude/board/EPIPHANIES.md @@ -1,3 +1,15 @@ +## 2026-06-18 — E-WITNESS-ARC-TWO-OBJECTS-1 — "witness arc" names TWO different objects; do NOT unify them under a `WitnessArcEvaluator` trait + +**Status:** FINDING (5+3 council, unanimous: convergence-architect DROP, iron-rule-savant REJECT-trait, dto-soa-savant FITS-COLUMN-as-free-fn, dilution-collapse-sentinel KEEP-SEPARATE, truth-architect PROVEN-math, brutally-honest-tester Option-B-LAND, baton-handoff-auditor CATCH-CRITICAL, integration-lead DEFER). B2 resolved as documentation, not code. + +Two code objects share the term **"witness arc"** but operate on **different value categories**: +1. `perturbation-sim::witness` — a **numeric** standing-wave inner product `∑ field·arc` over `&[f64]`, evaluated two ways (particle pointer-chase vs wave/Parseval-FWHT) that must agree (`particle == wave`, PROVEN: FWHT is the symmetric involution-up-to-N the identity needs; tested 1e-9). +2. `lance-graph-contract::witness_table` — a 6-bit W-slot **index → identity** table (`WitnessEntry { mailbox_ref: u32, spo_fact_ref: Option }`); its arc is a chain of W-references across `CausalEdge64` edges, already `O(1)` array indexing. + +**Why they must NOT be welded under a `WitnessArcEvaluator` trait:** (a) no inner-product/transform structure exists over opaque identity tuples — superposing them is the register-loss `I-VSA-IDENTITIES` forbids; (b) a trait with one math impl in an *excluded* crate and zero call-sites is AP6 speculative generality; (c) the AGI-as-glove doctrine bars a new trait/bridge ("new capability = new column, not a new layer"); (d) the trait would force the **zero-dep** contract crate to gain a `perturbation-sim` dependency / `f64` field semantics (baton CATCH-CRITICAL, dep-direction inversion). The genuine relationship is a **pipeline seam** (W-slot arc *addresses*, numeric column *evaluates*) — a consumer-side free function over a borrowed `&[f64]` column, never a unifying trait. + +**Secondary correction (truth-architect + brutally-honest-tester):** the `witness.rs` doc overclaimed per-arc cost as `q·O(N)`; as implemented `witness_from_spectrum` re-transforms each arc (`O(N log N)`), so the honest total is `O(N log N) + q·O(N log N)`, narrowing to `q·O(N)` only for precomputed/structured arc spectra. The amortized quantity is the **field** transform, not the arc dot. Doc-string corrected; no measured speed claim is made. Cross-references added in both files; seam recorded as `TD-WITNESS-EVAL-WIRING-1`, wiring gated as D-MBX-A3 (on D-MBX-A2 + OQ-11.2 + a §0 dep-direction ruling). + ## 2026-06-17 — E-ODOO-SPO-INHERITS-VALKIND — spo_enrich extended with inherits_from (P1b/ruff#19) + validation_kind (P2/ruff#21); corpus regen pending Odoo source **Status:** FINDING for the code shape + tests; CONJECTURE for the wire effect on the shipped corpus (regenerates when a session has `/home/user/odoo/addons` available). `spo_enrich.py` adds two enrichment passes via the same single AST walk #525 introduced (`build_all_facts` returns `(relmap, inherits, constrains)`). 18 new tests on top of #525's 23 (41/41 OK total). Rust loader's predicate-histogram match arm gained `inherits_from` + `validation_kind`. diff --git a/.claude/board/TECH_DEBT.md b/.claude/board/TECH_DEBT.md index 3de1c3c0..68b3e0df 100644 --- a/.claude/board/TECH_DEBT.md +++ b/.claude/board/TECH_DEBT.md @@ -15,6 +15,25 @@ ## Open Debt +### TD-WITNESS-EVAL-WIRING-1 — perturbation-sim Parseval witness evaluator ↔ contract `WitnessTable` are shipped but unconnected by design (2026-06-18) + +**Open — intentionally deferred (5+3 council, B2).** `perturbation-sim::witness` +(Probe-2, #513: `particle == wave` standing-wave evaluator over `&[f64]`) and +`lance-graph-contract::witness_table::WitnessTable<64>` (A3, #427: W-slot → +`WitnessEntry{mailbox_ref:u32, spo_fact_ref:Option}` identity table) both exist, +both have zero consumers, and are **deliberately not wired**. They are *different +objects* sharing the name "witness arc" (numeric field inner-product vs identity +resolution — see `E-WITNESS-ARC-TWO-OBJECTS-1`). The wiring is the downstream +deliverable **D-MBX-A3** (`witness_arc: [u32; W]` per-row column), gated on: +(1) **D-MBX-A2** (BindSpace expressivity gaps — content_ref + S/P/O role slices + +temporal/expert fold; the plan's current gating gap), (2) **OQ-11.2** ratified, and +(3) a **§0 dependency-direction ruling** — the zero-dep contract must NOT gain a +`perturbation-sim` dep; the evaluator stays a consumer-side free function over a +borrowed `&[f64]` column, never a `WitnessArcEvaluator` trait. **Paid when** D-MBX-A3 +lands its column + a consumer that walks a W-slot arc through the field evaluator. +Boundary cross-references added in both files (this commit) so the seam is not +rediscovered as a "missing wiring" bug. + ### TD-CI-TEST-JOB-DEBUGINFO0 — `test` job hit the same link cliff; `debuginfo=0` extended to it (2026-06-16) **Open — fix applied (merged via #511's CI commit), CONFIRM on the next green diff --git a/crates/lance-graph-contract/src/witness_table.rs b/crates/lance-graph-contract/src/witness_table.rs index 4474c6c8..07b728b4 100644 --- a/crates/lance-graph-contract/src/witness_table.rs +++ b/crates/lance-graph-contract/src/witness_table.rs @@ -39,6 +39,22 @@ //! //! This file declares the *column-type primitive only*. It does **not** wire the table //! into `CausalEdge64`, `MailboxSoA`, or any emission path — those are later slices. +//! +//! ## Not the `perturbation-sim` "witness arc" — different object +//! +//! `perturbation-sim::witness` proves a *numeric* identity (`particle == wave`, an +//! `∑ field·arc` inner product over `&[f64]` evaluated two ways via Parseval/FWHT). +//! That arc is a **signed real weight vector**; THIS table's arc is a **chain of +//! W-slot indices resolving to identity tuples** (`mailbox_ref`, `spo_fact_ref`). +//! They share the word "witness arc" and the Markov reference-chain shape, but the +//! value categories do not match (real field magnitude vs opaque identity handle) — +//! there is no inner-product / transform structure over `WitnessEntry`, and slot +//! resolution is already `O(1)`. Wiring the standing-wave evaluator over a numeric +//! SoA column is the downstream, gated D-MBX-A3 step (gated on D-MBX-A2; see +//! `TD-WITNESS-EVAL-WIRING-1`) and lands as a **consumer-side free function over a +//! borrowed `&[f64]` column**, never a `WitnessArcEvaluator` trait on this zero-dep +//! crate. Conflating the two would be a register-loss / Frankenstein hazard +//! (`I-VSA-IDENTITIES`). // ── Type declarations ──────────────────────────────────────────────────────── diff --git a/crates/perturbation-sim/examples/witness.rs b/crates/perturbation-sim/examples/witness.rs index d19370bd..e4f74374 100644 --- a/crates/perturbation-sim/examples/witness.rs +++ b/crates/perturbation-sim/examples/witness.rs @@ -3,8 +3,10 @@ //! //! Builds the per-bus inertia-buffer field, then reads three witness arcs both ways: //! the particle walk (`O(hops)` per arc) and the standing wave (one `field_spectrum` -//! transform, then `O(N)` per arc). They agree to floating point — and the wave form -//! amortizes one transform across all arcs. +//! transform reused across all arcs). They agree to floating point. As implemented, +//! each arc is itself transformed, so the per-arc cost is `O(N log N)` (it narrows to +//! `O(N)` only when the arc spectrum is precomputed or the arc is structured/sparse); +//! the amortized quantity is the one **field** transform, not the per-arc dot. //! //! Run: cargo run --release --manifest-path crates/perturbation-sim/Cargo.toml \ //! --example witness @@ -43,7 +45,8 @@ fn main() { ("alternating", &alt), ]; - // Wave view: transform the field ONCE; every arc is then an O(N) read off it. + // Wave view: transform the field ONCE, then reuse the spectrum across all arcs + // (each arc still transformed → O(N log N) per arc; O(N) only if precomputed). let spectrum = field_spectrum(&field); println!("witness arc as a standing wave — particle (walk) vs wave (Parseval)\n"); @@ -62,7 +65,8 @@ fn main() { } println!( "\n max |particle − wave| = {max_err:.2e} (Parseval: Hᵀ H = N·I, exact up to fp).\n \ - particle = O(hops) pointer-chase per arc; wave = O(N log N) once + O(N) per arc.\n \ + particle = O(hops) pointer-chase per arc; wave = O(N log N) field transform once,\n \ + reused across all arcs (each arc O(N log N) as written; O(N) only if precomputed).\n \ The standing wave IS the witness arc — evaluated all at once, no chain walk.\n \ (Demonstration in perturbation-sim; the contract witness_table evaluator is the\n \ separate gated step — the SoA spine is additive-only behind the iron rules.)" diff --git a/crates/perturbation-sim/src/witness.rs b/crates/perturbation-sim/src/witness.rs index 9734583e..88c8ba7c 100644 --- a/crates/perturbation-sim/src/witness.rs +++ b/crates/perturbation-sim/src/witness.rs @@ -11,19 +11,45 @@ //! the field, and by **Parseval for the Walsh–Hadamard transform** (`Hᵀ H = N·I`, //! the involution-up-to-`N` the pyramid already provides via [`fwht`]): //! `⟨field, arc⟩ = (1/N)·⟨Ĥfield, Ĥarc⟩`. Transform the field **once** -//! (`O(N log N)`); then every witness arc is an `O(N)` dot against its spectrum — -//! the whole arc is evaluated at once, no walk. +//! (`O(N log N)`); then each witness arc is read against the field spectrum — +//! the whole arc is evaluated at once, no hop-by-hop walk. //! //! **The identity `particle == wave` is what this probe proves** ([`particle_equals_wave`]). -//! The payoff is amortization: [`field_spectrum`] computes the standing wave once, -//! and [`witness_from_spectrum`] reads many arcs off it — `O(N log N) + q·O(N)` for -//! `q` arcs, vs the particle view's `q` independent pointer-chasing walks. +//! The amortized quantity is the **field** transform: [`field_spectrum`] computes the +//! standing wave once and [`witness_from_spectrum`] reuses it across many arcs. As +//! implemented, each arc is itself transformed (`fwht` on the arc), so the per-arc +//! cost is `O(N log N)` and the `q`-arc total is `O(N log N) + q·O(N log N)`; it +//! narrows to `O(N log N) + q·O(N)` only when the arc spectrum is precomputed or the +//! arc is structured/sparse (its spectrum known in closed form). The win over the +//! particle view's `q` independent pointer-chasing walks is therefore in the regime +//! "one field, many arcs whose spectra are reusable", not for a single dense arc — +//! this probe makes **no measured** speed claim (see [`crate::sketch`] for the same +//! honest framing of the demo-`N` exact path). //! //! Self-contained, in perturbation-sim — this demonstrates the pyramid/field //! mechanism on a grid field (e.g. the [`crate::inertia_buffer_column`] field). -//! Wiring it as the *actual* `witness_table` evaluator in the contract is a separate, -//! gated step: the witness/SoA types are the cognitive spine — additive only, behind -//! the iron rules. +//! +//! # NOT the same "witness arc" as `lance_graph_contract::witness_table` +//! +//! This module's "witness arc" is a **numeric** object: a signed `&[f64]` weight +//! vector read against an `&[f64]` field by an inner product (`∑ field·arc`). The +//! contract's `WitnessTable` arc is an **identity** object: a chain of 6-bit +//! W-slot indices each resolving to a `WitnessEntry { mailbox_ref: u32, +//! spo_fact_ref: Option }` (which mailbox witnessed a belief, and whether it +//! crystallised to an SPO fact). They share the *word* "witness arc" and the +//! Markov-#1-reference-chain *shape*, but operate on **different value categories** +//! — there is no Parseval identity over identity tuples, and the W-slot table is +//! already `O(1)` array indexing with nothing to transform away. Do **not** unify +//! them under one trait: that would conflate field-evaluation with +//! identity-resolution (a register-loss / Frankenstein hazard, cf. `I-VSA-IDENTITIES`). +//! +//! Wiring this evaluator into a real SoA traversal is a separate, downstream, **gated** +//! step (D-MBX-A3, gated on D-MBX-A2; see `TD-WITNESS-EVAL-WIRING-1`): the witness/SoA +//! types are the cognitive spine — additive only, behind the iron rules. When it +//! happens it is a *consumer-side projection* (W-slot arc → support of an `&[f64]` +//! arc over a borrowed numeric column), evaluated by these free functions — never a +//! `WitnessArcEvaluator` trait on the zero-dep contract. (Contract type: +//! `crates/lance-graph-contract/src/witness_table.rs`.) use crate::sketch::fwht;