From 7bc2f38b5437f3a32f3966c67df4a822c22f1a5f Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 15 Oct 2026 23:39:20 +0000 Subject: [PATCH 1/5] ce64: TrustTexture is the MUL vocabulary for the topology coordinate, not a second reading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bits 59..63 are the epistemic ladder (EpistemicState5 = Topology2 × Certification3). The lower coordinate is the Faktorortung — Direct / IndirectKnownIntermediates / IndirectUnknownIntermediates / Unknown — and TrustTexture's Crystalline / Solid / Fuzzy / Murky are the Meta-Uncertainty-Layer names for the same four cells (Murky = Unknown). The mapping is the identity; the Proceed / Sandbox / Compass column is the MUL's reaction to a cell, and a contradiction needing revision is an epistemic pothole, not a cell of the field. Four sites said otherwise: layout.rs described an "epistemic-trust texture" (0b11 = Contradiction) beside a "factual topology", "correlated but not the same fact", with "historical factual provenance NOT guaranteed" and "no mapping into the canonical state"; lib.rs still called 61..63 "spare"; epistemic_state5.rs and band_reading.rs listed TruthLens::Trust beside ReasoningBand as having written "OTHER meanings". Only ReasoningBand on 61..63 did. Historical provenance is the EdgeProvenance gate (were the bits written at all), not a semantic gap. Doc comments only; no executable change. No class declares either TruthLens variant, so the over-refusal the old prose implied was never live. Board: .claude/board/entries/2026-10-15-epi-trust-is-topology-vocabulary.md (index regenerated). Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_017SNHxJYC1MeW3HsyhGZo1E --- ...-10-15-epi-trust-is-topology-vocabulary.md | 38 +++++++ .claude/board/entries/README.md | 3 +- crates/causal-edge/src/layout.rs | 100 ++++++++++-------- crates/causal-edge/src/lib.rs | 8 +- .../lance-graph-contract/src/band_reading.rs | 50 +++++---- .../src/epistemic_state5.rs | 16 +-- 6 files changed, 137 insertions(+), 78 deletions(-) create mode 100644 .claude/board/entries/2026-10-15-epi-trust-is-topology-vocabulary.md diff --git a/.claude/board/entries/2026-10-15-epi-trust-is-topology-vocabulary.md b/.claude/board/entries/2026-10-15-epi-trust-is-topology-vocabulary.md new file mode 100644 index 000000000..adfddd5c3 --- /dev/null +++ b/.claude/board/entries/2026-10-15-epi-trust-is-topology-vocabulary.md @@ -0,0 +1,38 @@ +# 2026-10-15 — `TrustTexture` is the MUL vocabulary for the topology coordinate, not a second reading + +STATUS: fixed | OUTCOME: doc drift corrected in `causal-edge/src/layout.rs`, +`causal-edge/src/lib.rs`, `lance-graph-contract/src/epistemic_state5.rs`, +`lance-graph-contract/src/band_reading.rs`; executable contract unchanged | +OPEN: none. + +**What the drift was.** Four sites described bits 59..60 as carrying TWO +readings — an "epistemic-trust texture" (`TrustTexture`: how much to trust the +edge; `0b11 = Contradiction`) and a "factual topology" (`CausalTopology`) — +"correlated in practice but not the same fact", with "historical factual +provenance NOT guaranteed for old rows" and "no mapping into the canonical +state" for the Trust lens. `epistemic_state5.rs` and `band_reading.rs` then +listed `TruthLens::Trust` beside `ReasoningBand` as having written "OTHER +meanings" into the merged field. + +**The current contract.** Bits 59..63 are the epistemic ladder +(`EpistemicState5 = Topology2 × Certification3`; README front-page diagram and +`docs/architecture/ce64-semantic-upper-half.md`). Its lower coordinate is the +Faktorortung — Direct / IndirectKnownIntermediates / +IndirectUnknownIntermediates / Unknown — and `TrustTexture`'s Crystalline / +Solid / Fuzzy / Murky are the Meta-Uncertainty-Layer's names for those SAME +four cells (`Murky` = `Unknown`). The mapping is the identity; the Proceed / +Sandbox / Compass column is the MUL's reaction to a cell, not a second +meaning of the bits. A contradiction that needs revision is an **epistemic +pothole** the MUL reacts to, not a cell of the field. Only the historical +`ReasoningBand` on 61..63 wrote other meanings. Historical provenance is the +`EdgeProvenance` gate (were the bits written at all), not a semantic gap. + +**Why no code moved.** No class in the tree declares either `TruthLens` +variant (`.band_reading(` has no production caller; `project_band` is reached +only by the obsolete `reasoning_band_probe`), so the over-refusal the old prose +implied for Trust-declared classes was never live. Gates: `causal-edge` and +`lance-graph-contract` tests + clippy `-D warnings` + fmt unchanged-green. + +Source of the ruling: this session, reading the README diagram against the +crate prose. Related: `2026-10-07-epi-legacy-deprojection.md` (kept; its +"other meanings" line is regraded by this entry, not edited). diff --git a/.claude/board/entries/README.md b/.claude/board/entries/README.md index 0fc798c6a..1fb552809 100644 --- a/.claude/board/entries/README.md +++ b/.claude/board/entries/README.md @@ -25,12 +25,13 @@ index row, (3) no duplicate entry id. Checks 1 and 2 are deliberately opposite directions; the stranding this convention prevents shows up in exactly one of them, never both. -343 entries, 2026-08-06 .. 2026-10-15. +344 entries, 2026-08-06 .. 2026-10-15. | date | entry id | finding | file | |---|---|---|---| | 2026-10-15 | `ledger-correction-wire-contract` | | [2026-10-15-ledger-correction-wire-contract.md](2026-10-15-ledger-correction-wire-contract.md) | | 2026-10-15 | `givens-layer` | | [2026-10-15-givens-layer.md](2026-10-15-givens-layer.md) | +| 2026-10-15 | `epi-trust-is-topology-vocabulary` | | [2026-10-15-epi-trust-is-topology-vocabulary.md](2026-10-15-epi-trust-is-topology-vocabulary.md) | | 2026-10-15 | `D-WAL` | `LanceCycleWriter` vs the lancedb 0.40 MemWAL write path (measured) | [2026-10-15-d-wal-shootout.md](2026-10-15-d-wal-shootout.md) | | 2026-10-15 | `D-HOLO-H14` | | [2026-10-15-d-holo-h14-lane-storage.md](2026-10-15-d-holo-h14-lane-storage.md) | | 2026-10-14 | `revision-layer-invariants` | | [2026-10-14-revision-layer-invariants.md](2026-10-14-revision-layer-invariants.md) | diff --git a/crates/causal-edge/src/layout.rs b/crates/causal-edge/src/layout.rs index 743937826..023e16c06 100644 --- a/crates/causal-edge/src/layout.rs +++ b/crates/causal-edge/src/layout.rs @@ -53,35 +53,35 @@ pub const V1_TEMPORAL_SHIFT: u32 = 52; /// 0 = no corpus anchor. Per cognitive-substrate-convergence-v1.md L-6. pub const W_SHIFT: u32 = 53; -/// Truth-band lens: 2-bit TrustTexture ordinal (bits 59-60). +/// Topology coordinate of the epistemic ladder: 2-bit ordinal (bits 59-60). /// /// ⊘ D-EPI-CANON-0 (2026-10-07): bits 59..63 are ONE field, the 5-bit /// `EpistemicState5` code ([`EPISTEMIC_SHIFT`]), `raw5 = topology | /// certification << 2`. These two bits are its TOPOLOGY coordinate, read with -/// the [`CausalTopology`] ordinals. The `TrustTexture` reading of the same -/// bits is legacy: no mapping into the canonical state exists for it. -/// 0 = Crystalline. Per cognitive-substrate-convergence-v1.md L-7. +/// the [`CausalTopology`] ordinals. 0 = Direct. Per +/// cognitive-substrate-convergence-v1.md L-7. /// -/// Same two bits also carry an ADDITIVE factual view, [`CausalTopology`] -/// (below) — see its doc comment for the wire/ordinal/behavioural/ -/// provenance compatibility statement. `TrustTexture` remains the -/// canonical epistemic-trust reading; `CausalTopology` is a second, -/// orthogonal reading of the identical bits for producers that want to -/// record topology instead of (or alongside) trust texture. No bits move. +/// [`TrustTexture`] is the Meta-Uncertainty-Layer vocabulary for the SAME +/// four cells (Crystalline / Solid / Fuzzy / Murky name Direct / +/// IndirectKnown / IndirectUnknown / Unknown); the mapping between the two +/// enums is the identity. ⊘ The earlier text here — "no mapping into the +/// canonical state exists" and "`TrustTexture` remains the canonical +/// epistemic-trust reading" — described them as two readings; they are one +/// field under two vocabularies (DECISION 2026-10-15). No bits move. pub const TRUTH_SHIFT: u32 = 59; -/// Spare: 3-bit reserved for sprint-12+ (bits 61-63). +/// Certification coordinate of the epistemic ladder (bits 61-63). /// -/// ⊘ D-EPI-CANON-0 (2026-10-07): the CERTIFICATION coordinate of the joint +/// D-EPI-CANON-0 (2026-10-07): the upper coordinate of the joint /// `EpistemicState5` field ([`EPISTEMIC_SHIFT`]): `0 Open, 1 Associated, /// 2 Related, 3 Supports, 4 CausalCandidate, 5 Causes, 6/7 reserved` (the P7a /// codes). The historical [`ReasoningBand`] view below names reasoning levels, /// not certifications; it is legacy, with no mapping into the canonical state. -/// Candidates: Rubicon-commit marker, Markov-decay quantum, I-NOISE-FLOOR-JIRAK threshold. -/// -/// Same three bits also carry an ADDITIVE quantized-projection view, -/// [`ReasoningBand`] (below). No auto-derivation: nothing writes this -/// field except an explicit `with_reasoning_band()` call. +/// ⊘ The name `SPARE_SHIFT`, the "reserved for sprint-12+" headline and the +/// candidate list (Rubicon-commit marker, Markov-decay quantum, Jirak +/// threshold) that stood here predate the merge; the constant keeps its name +/// for source compatibility only. Nothing writes [`ReasoningBand`] except an +/// explicit `with_reasoning_band()` call. /// /// **v1 provenance:** bits 61-63 were temporal bits 9-11, so a v1 edge with /// `temporal >= 512` reads a NON-ZERO band. Apply a version gate on edges of @@ -137,16 +137,24 @@ const _LAYOUT_COVERAGE: () = { ); }; -/// Two-bit truth-band lens — 4 levels of epistemic texture. +/// The Meta-Uncertainty-Layer names for the topology coordinate (bits 59-60). /// -/// Lens projection table (per causaledge64-mailbox-rename-soa-v1.md §2): +/// One field, two vocabularies. Each row is the SAME cell as the +/// [`CausalTopology`] variant of the same ordinal; the last two columns are +/// the MUL's reaction to that cell, not a second meaning of the bits +/// (table per causaledge64-mailbox-rename-soa-v1.md §2, relabelled): /// ```text -/// 0b00 = Crystalline | Mastered | Quiet | Proceed -/// 0b01 = Solid | Calibrated | Mild | Proceed -/// 0b10 = Fuzzy | Uncertain | Active | Sandbox -/// 0b11 = Murky | Contradiction| Loud | Compass (veto) +/// 0b00 = Crystalline | Direct | Quiet | Proceed +/// 0b01 = Solid | IndirectKnownIntermediates | Mild | Proceed +/// 0b10 = Fuzzy | IndirectUnknownIntermediates| Active | Sandbox +/// 0b11 = Murky | Unknown | Loud | Compass (veto) /// ``` /// +/// ⊘ The second column used to read `Mastered / Calibrated / Uncertain / +/// Contradiction`. A contradiction that needs revision is an **epistemic +/// pothole** — something the MUL reacts to (Compass) — not a cell of this +/// field; `Murky` is the MUL word for topology `Unknown`. +/// /// NOTE: Local definition in causal-edge (zero-dep crate). /// /// **CORRECTION (measured):** an earlier version of this note claimed @@ -159,9 +167,9 @@ const _LAYOUT_COVERAGE: () = { /// opposite of the old note: **"Canonical: NONE — both are domain-correct /// and should keep distinct names."** Do not build a cast on the old claim. /// -/// This enum is the LEGACY/COMPATIBILITY projection of bits 59-60; the -/// factual view over the same bits is [`CausalTopology`]. Not deprecated — -/// nothing is ready to move, and the wider rename is owned by the existing +/// This enum is the MUL-vocabulary alias of [`CausalTopology`] over bits +/// 59-60 (ordinal-identical, identity mapping). Not deprecated — nothing is +/// ready to move, and the wider rename is owned by the existing /// TrustTexture-duplication debt item. #[derive(Copy, Clone, Eq, PartialEq, Debug, Default)] #[repr(u8)] @@ -196,16 +204,16 @@ impl TrustTexture { } } -/// Two-bit CAUSAL TOPOLOGY lens — an ADDITIVE factual view over the same -/// two bits (59-60) that [`TrustTexture`] occupies. No bits move; this is -/// a second reading of the identical register, not a new field and not a -/// layout revision (no CE64 v3, no `ENVELOPE_LAYOUT_VERSION` bump). +/// Two-bit CAUSAL TOPOLOGY coordinate of the epistemic ladder (bits 59-60) +/// — the Faktorortung of the edge: where the missing link sits. No bits +/// move; this is the same register [`TrustTexture`] names in MUL vocabulary, +/// not a new field and not a layout revision (no CE64 v3, no +/// `ENVELOPE_LAYOUT_VERSION` bump). /// -/// `TrustTexture` reads those bits as an EPISTEMIC-TRUST texture (how much -/// to trust the edge: mastered/calibrated/uncertain/contradiction). -/// `CausalTopology` reads the identical bits as a FACTUAL TOPOLOGY -/// classification (how the edge's causal path is structured — direct vs. -/// mediated, known vs. unknown intermediates). +/// `CausalTopology` classifies how the edge's causal path is structured — +/// direct vs. mediated, intermediates known vs. unknown, topology unknown. +/// `TrustTexture` names the identical four cells (Crystalline / Solid / +/// Fuzzy / Murky) as the MUL reads them. /// /// ```text /// 0b00 = Direct @@ -226,7 +234,7 @@ impl TrustTexture { /// wire compatibility: exact /// ordinal compatibility: exact /// legacy behavioural projection: intentional -/// historical factual provenance: NOT guaranteed for old rows +/// historical provenance: the EdgeProvenance gate, not a semantic gap /// ``` /// /// - **Wire compatibility is exact** — same two bits (59-60), same shift, @@ -241,17 +249,15 @@ impl TrustTexture { /// `CausalTopology` yet is unaffected by rows a `CausalTopology`-aware /// writer produces, and vice versa — this is a staged migration, not a /// flag day. -/// - **Historical factual provenance is NOT guaranteed for old rows.** A row -/// written before this change had its bits 59-60 stamped with -/// TRUST-TEXTURE semantics (how confident the writer was in the edge), not -/// TOPOLOGY semantics (how the causal path is shaped). The two concepts -/// are correlated in practice but they are not the same fact, and nothing -/// in this change infers, repairs, or backfills the topology of a -/// pre-existing row. **Do not treat `old_edge.topology()` as ground truth -/// about that row's actual causal topology** — it is only the -/// same-ordinal projection through the new lens. Source-authoritative -/// topology begins only when a later producer explicitly writes -/// `CausalTopology` via [`CausalEdge64::with_topology`]. +/// - **Historical provenance is the `EdgeProvenance` gate, not a semantic +/// gap.** A row written through `TrustTexture` carries the same four +/// cells under the MUL names, so `old_edge.topology()` reads what its +/// writer meant. What is NOT guaranteed is that the bits were written at +/// all: under `V1Legacy` / `Unknown` provenance they may be v1 temporal +/// bits, and the reading contract refuses them rather than guessing. +/// ⊘ The earlier text here ("stamped with TRUST-TEXTURE semantics, not +/// TOPOLOGY semantics … not the same fact") treated the two vocabularies +/// as two facts; struck 2026-10-15. /// /// [`CausalEdge64::ZERO`] therefore reads `CausalTopology::Direct` under /// this view exactly as it reads `TrustTexture::Crystalline` under the old diff --git a/crates/causal-edge/src/lib.rs b/crates/causal-edge/src/lib.rs index c79fdedb0..2750902f4 100644 --- a/crates/causal-edge/src/lib.rs +++ b/crates/causal-edge/src/lib.rs @@ -75,9 +75,9 @@ pub use syllogism::{Figure, Syllogism}; #[cfg(feature = "causal-edge-v2-layout")] pub use layout::TrustTexture; -// Additive factual/quantized lenses over the same TrustTexture (bits 59-60) -// and spare (bits 61-63) registers — see layout.rs doc comments for the -// full wire/ordinal/behavioural/provenance compatibility statement. No bits -// move; these are new readings of existing storage, not a new layout. +// The two coordinates of the epistemic ladder (`EpistemicState5`, bits +// 59..63): `CausalTopology` on 59-60 (the same cells `TrustTexture` names in +// MUL vocabulary) and the legacy `ReasoningBand` view of 61-63 — see +// layout.rs doc comments for the compatibility statement. No bits move. #[cfg(feature = "causal-edge-v2-layout")] pub use layout::{CausalTopology, ReasoningBand}; diff --git a/crates/lance-graph-contract/src/band_reading.rs b/crates/lance-graph-contract/src/band_reading.rs index b598f834e..c205f06ca 100644 --- a/crates/lance-graph-contract/src/band_reading.rs +++ b/crates/lance-graph-contract/src/band_reading.rs @@ -10,20 +10,25 @@ //! > read through [`epistemic_state5`](crate::epistemic_state5). The split //! > reading below is a **legacy compatibility surface**, not a peer authority. //! > A class that declared `TruthLens::Topology` + the P7a certification band -//! > wrote exactly the canonical product (identity packing); a class that -//! > declared `TruthLens::Trust` or the historical `ReasoningBand` wrote other +//! > wrote exactly the canonical product (identity packing). `TruthLens::Trust` +//! > is the same lower coordinate under the Meta-Uncertainty-Layer names +//! > (`Crystalline`…`Murky` ≡ `Direct`…`Unknown`, identity mapping), not a +//! > second meaning. Only the historical `ReasoningBand` on 61..63 wrote other //! > meanings, has no canonical declaration, and its bits are never -//! > reinterpreted. [`EdgeProvenance`] stays here unchanged and is shared by -//! > both readings. Kept, not deleted (append-only). +//! > reinterpreted. ⊘ The earlier text here listed `TruthLens::Trust` with +//! > `ReasoningBand` as "other meanings"; struck 2026-10-15. +//! > [`EdgeProvenance`] stays here unchanged and is shared by both readings. +//! > Kept, not deleted (append-only). //! -//! Two bits (the truth tail) and three bits (the band tail) of a causal edge -//! carry FOUR shipped readings between them — `TrustTexture` vs -//! `CausalTopology` on the 2-bit field, `ReasoningBand`-present vs spare on -//! the 3-bit field — and **which reading a producer wrote is not recoverable -//! from the bits**. A consumer that reads one lens while the producer wrote -//! the other gets a plausible wrong answer, silently. This module is the -//! producer knowledge, declared per `(classid, rail)`, that the bits -//! themselves cannot carry. +//! Two bits (the topology coordinate) and three bits (the band tail) of a +//! causal edge carry the readings this module declares: ONE reading under two +//! vocabularies on the 2-bit field (`TrustTexture` is the MUL name for +//! `CausalTopology`), and `ReasoningBand`-present vs spare on the 3-bit +//! field — and **on the 3-bit field, which reading a producer wrote is not +//! recoverable from the bits**. A consumer that reads a band from spare bits, +//! or a certification from a reasoning level, gets a plausible wrong answer, +//! silently. This module is the producer knowledge, declared per +//! `(classid, rail)`, that the bits themselves cannot carry. //! //! # One contract, TWO carriers //! @@ -99,12 +104,16 @@ pub const BAND_STATES: usize = 8; const _: () = assert!(TRUTH_STATES == 4 && (TRUTH_STATES - 1) == 0b11); const _: () = assert!(BAND_STATES == 8 && (BAND_STATES - 1) == 0b111); -/// WHICH projection of the 2-bit truth field this class's producers wrote. +/// WHICH vocabulary this class's producers used for the 2-bit topology +/// coordinate (bits 59-60). /// -/// The two shipped readings are ordinal-identical on the wire (`Crystalline` ≡ -/// `Direct` … `Murky` ≡ `Unknown`), which is precisely why the bits cannot -/// disambiguate themselves. The names below are doc-comment pointers to the -/// edge crate's enums, **never imports** (both crates are zero-dep): +/// The two variants name ONE reading: `Crystalline` ≡ `Direct` … `Murky` ≡ +/// `Unknown`, ordinal-identical on the wire and identical in meaning +/// (`Trust` is the Meta-Uncertainty-Layer's vocabulary for the Faktorortung +/// cells). The declaration records which names the producer wrote with; it +/// does not change what the bits mean. The names below are doc-comment +/// pointers to the edge crate's enums, **never imports** (both crates are +/// zero-dep): /// /// - [`Trust`](TruthLens::Trust) → `causal_edge::layout::TrustTexture` /// (4 variants — NOT `contract::mul::TrustTexture`, NOT the planner's @@ -113,11 +122,12 @@ const _: () = assert!(BAND_STATES == 8 && (BAND_STATES - 1) == 0b111); /// - [`Topology`](TruthLens::Topology) → `causal_edge::layout::CausalTopology`. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)] pub enum TruthLens { - /// Epistemic-trust reading — the canonical default (`layout.rs`: "the - /// canonical epistemic-trust reading"). + /// The Meta-Uncertainty-Layer names (`Crystalline` / `Solid` / `Fuzzy` / + /// `Murky`) for the topology cells. The default. #[default] Trust, - /// Causal-topology reading — the additive factual view of the same bits. + /// The Faktorortung names (`Direct` / `IndirectKnownIntermediates` / + /// `IndirectUnknownIntermediates` / `Unknown`) for the same cells. Topology, } diff --git a/crates/lance-graph-contract/src/epistemic_state5.rs b/crates/lance-graph-contract/src/epistemic_state5.rs index 672e034e2..06e7ab0ee 100644 --- a/crates/lance-graph-contract/src/epistemic_state5.rs +++ b/crates/lance-graph-contract/src/epistemic_state5.rs @@ -53,12 +53,16 @@ //! //! [`band_reading`](crate::band_reading) declared 59..60 and 61..63 as two //! fields. A producer that declared **topology + P7a certification** wrote -//! exactly this product (identity packing, no translation table). A producer -//! that declared the `TrustTexture` lens on 59..60 or the historical -//! `ReasoningBand` on 61..63 wrote OTHER meanings into the same bits; no -//! explicit mapping exists for either, so its bits are never numerically -//! reinterpreted here — such a class has no `Epi5Reading` and projection -//! refuses. The declaration is the migration firewall. +//! exactly this product (identity packing, no translation table). The +//! `TrustTexture` lens on 59..60 is the same topology coordinate under the +//! Meta-Uncertainty-Layer names (Crystalline / Solid / Fuzzy / Murky ≡ +//! Direct / IndirectKnown / IndirectUnknown / Unknown, identity mapping), so +//! a class that declared it wrote the canonical lower coordinate too. Only +//! the historical `ReasoningBand` on 61..63 wrote OTHER meanings (reasoning +//! levels, not certifications); no mapping exists for it, so such a class +//! has no `Epi5Reading` and projection refuses. ⊘ The earlier text here +//! counted the `TrustTexture` lens among the "other meanings"; struck +//! 2026-10-15. The declaration is the migration firewall. use crate::band_reading::EdgeProvenance; use crate::class_view::ClassId; From d5cb9b4330f640d531c63ba005033a6e6a03364e Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 15 Oct 2026 23:55:16 +0000 Subject: [PATCH 2/5] ce64 docs: say the declared-lens gate is unchanged Codex review on #1574 read the provenance paragraph as licence to bypass band_reading::project_truth. Two sentences state that the LensMismatch gate still applies: it checks the declaration a class made, it does not assert a second meaning for bits 59-60. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_017SNHxJYC1MeW3HsyhGZo1E --- crates/causal-edge/src/layout.rs | 4 ++++ crates/lance-graph-contract/src/band_reading.rs | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/crates/causal-edge/src/layout.rs b/crates/causal-edge/src/layout.rs index 023e16c06..70de1918f 100644 --- a/crates/causal-edge/src/layout.rs +++ b/crates/causal-edge/src/layout.rs @@ -255,6 +255,10 @@ impl TrustTexture { /// writer meant. What is NOT guaranteed is that the bits were written at /// all: under `V1Legacy` / `Unknown` provenance they may be v1 temporal /// bits, and the reading contract refuses them rather than guessing. +/// The declared-lens gate in `band_reading::project_truth` +/// (`LensMismatch`) is unchanged by this note: a reader still has to ask +/// for the vocabulary the class declared. That gate checks the +/// declaration, it does not assert a second meaning for the bits. /// ⊘ The earlier text here ("stamped with TRUST-TEXTURE semantics, not /// TOPOLOGY semantics … not the same fact") treated the two vocabularies /// as two facts; struck 2026-10-15. diff --git a/crates/lance-graph-contract/src/band_reading.rs b/crates/lance-graph-contract/src/band_reading.rs index c205f06ca..7b63e5006 100644 --- a/crates/lance-graph-contract/src/band_reading.rs +++ b/crates/lance-graph-contract/src/band_reading.rs @@ -111,7 +111,9 @@ const _: () = assert!(BAND_STATES == 8 && (BAND_STATES - 1) == 0b111); /// `Unknown`, ordinal-identical on the wire and identical in meaning /// (`Trust` is the Meta-Uncertainty-Layer's vocabulary for the Faktorortung /// cells). The declaration records which names the producer wrote with; it -/// does not change what the bits mean. The names below are doc-comment +/// does not change what the bits mean. [`project_truth`](BandReading::project_truth) +/// still refuses a request for the other vocabulary (`LensMismatch`): the +/// gate checks the declaration, it is not a semantic firewall. The names below are doc-comment /// pointers to the edge crate's enums, **never imports** (both crates are /// zero-dep): /// From 600b74b47e8fad09795d40597f3c79c631d10c3e Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 16 Oct 2026 00:01:23 +0000 Subject: [PATCH 3/5] =?UTF-8?q?research:=20mapping=20inventory=20=E2=80=94?= =?UTF-8?q?=20MeTTa/PeTTa=20atoms=20and=20three=20NARS=20engines=20against?= =?UTF-8?q?=20CE64=20and=20the=20polyfill=20crates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Read-from-source inventory (hyperon-experimental, PeTTa, ONA, opennars Java, Narsese.rs vs causal-edge, contract, planner/nars, lance-graph-nal, -relalg, -metta, ogar-loco). Changes no meaning and proposes no byte. Board entry added, index regenerated. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_017SNHxJYC1MeW3HsyhGZo1E --- ...10-15-nars-metta-ce64-mapping-inventory.md | 13 ++ .claude/board/entries/README.md | 3 +- ...10-15-nars-metta-ce64-mapping-inventory.md | 111 ++++++++++++++++++ 3 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 .claude/board/entries/2026-10-15-nars-metta-ce64-mapping-inventory.md create mode 100644 .claude/research/2026-10-15-nars-metta-ce64-mapping-inventory.md diff --git a/.claude/board/entries/2026-10-15-nars-metta-ce64-mapping-inventory.md b/.claude/board/entries/2026-10-15-nars-metta-ce64-mapping-inventory.md new file mode 100644 index 000000000..b61b8e84e --- /dev/null +++ b/.claude/board/entries/2026-10-15-nars-metta-ce64-mapping-inventory.md @@ -0,0 +1,13 @@ +# 2026-10-15 — Mapping inventory: Hyperon/MeTTa/PeTTa atoms and three NARS engines against CE64 and the polyfill crates + +STATUS: measured | OUTCOME: `.claude/research/2026-10-15-nars-metta-ce64-mapping-inventory.md` — read from source +(hyperon-experimental `3f76dc4`, PeTTa `1d19a1d`, ONA `dc4efd0`, opennars `4d1bdb0`, Narsese.rs `16d4d18`) against +`causal-edge`, `lance-graph-contract`, `planner/nars`, `lance-graph-nal`, `-relalg`, `-metta`, OGAR `ogar-loco`. No meaning +of any atom changed; no byte proposed. | OPEN: relalg join + `μ` (blocks MeTTa conjunction and the NAL syllogism alike); +the per-row truth law (nal-polyfill §4 C) remains the one candidate byte; `lance-graph-ona` and `-cog` do not exist and +the inventory scopes what `-ona` honestly could be (oracle harness, argument-order adapter, lanes not bits). + +Findings worth one line each: no foreign system carries a 59..63 or a 40..42 — the ladder and the Pearl mask are ours to +write; lance-graph's abduction/induction argument order matches OpenNARS Java, ONA and PeTTa use the swapped convention +(bind by rule shape, never by function name); ONA's `ATOMS_MAX = 255` fits the u8 S/P/O palette; `Narsese.rs` already +holds the parser `lance-graph-nal` needs. diff --git a/.claude/board/entries/README.md b/.claude/board/entries/README.md index 1fb552809..7f479ffc7 100644 --- a/.claude/board/entries/README.md +++ b/.claude/board/entries/README.md @@ -25,10 +25,11 @@ index row, (3) no duplicate entry id. Checks 1 and 2 are deliberately opposite directions; the stranding this convention prevents shows up in exactly one of them, never both. -344 entries, 2026-08-06 .. 2026-10-15. +345 entries, 2026-08-06 .. 2026-10-15. | date | entry id | finding | file | |---|---|---|---| +| 2026-10-15 | `nars-metta-ce64-mapping-inventory` | | [2026-10-15-nars-metta-ce64-mapping-inventory.md](2026-10-15-nars-metta-ce64-mapping-inventory.md) | | 2026-10-15 | `ledger-correction-wire-contract` | | [2026-10-15-ledger-correction-wire-contract.md](2026-10-15-ledger-correction-wire-contract.md) | | 2026-10-15 | `givens-layer` | | [2026-10-15-givens-layer.md](2026-10-15-givens-layer.md) | | 2026-10-15 | `epi-trust-is-topology-vocabulary` | | [2026-10-15-epi-trust-is-topology-vocabulary.md](2026-10-15-epi-trust-is-topology-vocabulary.md) | diff --git a/.claude/research/2026-10-15-nars-metta-ce64-mapping-inventory.md b/.claude/research/2026-10-15-nars-metta-ce64-mapping-inventory.md new file mode 100644 index 000000000..28a64940c --- /dev/null +++ b/.claude/research/2026-10-15-nars-metta-ce64-mapping-inventory.md @@ -0,0 +1,111 @@ +# Mapping inventory — Hyperon/MeTTa/PeTTa atoms and three NARS engines against CausalEdge64 and the polyfill crates + +**Date:** 2026-10-15. **Status:** INVENTORY (VERIFIED-IN-CODE where a file:line is given; nothing here changes a meaning or a byte). +**Question:** what does each foreign system carry, where does the same thing already live on our side, and what does the NARS polyfill +(`lance-graph-nal`, `lance-graph-relalg`, `lance-graph-metta`, and the not-yet-existing `lance-graph-ona` / `lance-graph-cog`) still have to grow — +without changing what a MeTTa or PeTTa atom means. + +Sources read (local shallow clones, this session; heads as of 2026-10-15): `AdaWorldAPI/hyperon-experimental` `3f76dc4`, `AdaWorldAPI/PeTTa` `1d19a1d`, +`AdaWorldAPI/OpenNARS-for-Applications` `dc4efd0` (ONA), `opennars/opennars` `4d1bdb0` (Pei Wang's Java, "OpenNARS for Research"), `AdaWorldAPI/Narsese.rs` `16d4d18`. +Our side: `causal-edge`, `lance-graph-contract`, `lance-graph-planner/src/nars`, `lance-graph-nal`, `lance-graph-relalg`, `lance-graph-metta`, OGAR `ogar-loco`. +Ten Haiku fact maps, each spot-checked against source, are in the session scratchpad (`nars-map/maps/01..10`). Prior art this builds on: +`.claude/plans/nal-polyfill-v1.md`, `.claude/plans/metta-polyfill-v1.md`, `.arxiv/2026-10_hyperon_metta_to_lance_graph_parity_map.md`, +`.claude/knowledge/nal-recipe-audit/`. + +## 0. The two rules this inventory keeps + +1. **Atoms keep their meaning.** A MeTTa `Atom` stays `Symbol | Variable | Expression | Grounded` (`hyperon-atom/src/lib.rs:827-849`); a PeTTa atom stays a Prolog + term; an ONA `Term` stays its 64-atom heap. We map them to addresses and rows; we do not redefine them. +2. **The engine stays mask-risc.** Everything foreign lowers to procedures over existing R2IL calls (nal-polyfill §4 A). A new byte needs an + execution-level insufficiency proof. Hyperon's interpreter, PeTTa's Prolog, ONA's cycle and OpenNARS's RuleTables are oracles, not engines we port. + +## 1. CausalEdge64 — what each foreign system would put in each band + +| bits | ours (`causal-edge/src/layout.rs`, `edge.rs`) | OpenNARS Java | ONA | Hyperon/MeTTa | PeTTa | +|---|---|---|---|---|---| +| 0..23 | S, P, O palette indices, u8 each | `Statement(subject, predicate)` over a `Term` tree; copula is the class (`Inheritance`, `Similarity`, `Implication`, `Equivalence`, `language/`) | `Term { Atom atoms[64] }`, copulas are atoms; `ATOMS_MAX 255` (`Config.h:142`) — **an ONA atom index already fits a u8 palette slot** | `Expression(functor a₁…aₖ)`: no fixed arity, no copula; a fact `(parent a b)` is functor + 2 args | same shape as MeTTa, stored as `Space(=, [F\|Args], Body)` Prolog clauses (`spaces.pl:38`) | +| 24..31 F, 32..39 C | u8 codes; `expectation = c(f−½)+½` (`edge.rs:345`) | `TruthValue{frequency f32, confidence f64, analytic}`; cap `1−TRUTH_EPSILON = 0.99` (`TruthValue.java:138`) | `Truth{frequency, confidence} double`; `MAX_CONFIDENCE 0.99`, `MIN_CONFIDENCE 0.01` (`Config.h:172-174`) | none; PLN/NARS truth lives in library atoms `(stv f c)` | `lib_nars.metta` `(stv $f $c)` with ONA's formulas | +| 40..42 Pearl `CausalMask` | SO / PO / SPO / SP + marginals (`pearl.rs`) | no counterpart; rules selected by `RuleTables.reason` link figure (`RuleTables.java:55, 411`) | no counterpart; rule selected by `RuleTable.c` premise shapes | none | none | +| 43..45 direction triad | per-plane sign | `Tense {Past, Present, Future}`, `Eternal = null` (`Tense.java:29-39`); temporal copulas `=/> =\|> =\> <\|>` (`Symbols.java:154-159`) | `occurrenceTime`, `occurrenceTimeOffset`, `OCCURRENCE_ETERNAL −1` on `Event`/`Implication` | none | none | +| 46..49 inference mantissa i4 | `InferenceType::to_mantissa` (`contract/nars.rs:64`): Deduction, Induction, Abduction, Revision, Synthesis; +6 Intervention, −6 Counterfactual | rule name chosen by `SyllogisticRules` / `LocalRules` / `CompositionalRules`; not stored on the sentence | rule id in the generated `RuleTable.c` (135 `R1`/`R2` lines in `NAL.h`); not stored on the event | none | none | +| 50..52 plasticity | per-plane hot bit | `BudgetValue{priority, durability, quality}` is the nearest control scalar, a different axis | `Concept.priority`, `Usage` | none | none | +| 53..58 W witness slot | corpus-root handle, 0 = none | `Stamp.evidentialBase: BaseEntry[]`, max 20 000 (`Parameters.java:143`) | `Stamp { long evidentialBase[STAMP_SIZE=10] }` (`Config.h:136`) | none | none | +| 59..63 `EpistemicState5` | `Topology2 × Certification3` | none; nearest is the analytic flag + question/goal punctuation | none; nearest is `Decision.execute` and `predicted_belief` | none | none | + +Two consequences for the polyfill: (a) **no foreign system has a 59..63**, so the epistemic ladder is ours to write (`pearl::hydrate`/`revise`), never ported; +(b) **evidential bases are where the three NARS engines disagree most** (unbounded list / 10 longs / our `Stamp(u64)` bitset of ≤ 64 sources at +`planner/nars/belief.rs:31`, and `lance-graph-nal`'s `&[u64]` root list with `INDEPENDENT / DUPLICATE / OVERLAP / NO_PROVENANCE` classes, `lib.rs:234-244`). + +## 2. Truth functions — same algebra, two argument conventions + +Measured from `isa.rs:228-342`, `planner/nars/truth.rs:55-109`, `exploration.rs:110-124`, `ona/src/Truth.c`, `opennars/.../TruthFunctions.java`, `petta/lib/lib_nars.metta`. + +| function | lance-graph (`isa::truth`, planner `TruthValue`) | OpenNARS Java | ONA | PeTTa `lib_nars` | +|---|---|---|---|---| +| horizon `k` in `c = w/(w+k)` | `HORIZON = 1` (`nal/lib.rs:216`), `w/(w+1)` | `HORIZON = 1` (`Parameters.java:59`) | `TRUTH_EVIDENTIAL_HORIZON_INITIAL 1.0` | `(/ $w (+ $w 1))` | +| deduction | `(f₁f₂, f₁f₂c₁c₂)` | same | same | same | +| **abduction(v1,v2)** | **`(f₁, w2c(f₂c₁c₂))`** | **`(f₁, w2c(f₂c₁c₂))`** (`TruthFunctions.java:250-260`) | **`(f₂, w2c(f₁c₁c₂))`** (`Truth.c:84-87`) | ONA's | +| **induction(v1,v2)** | `(f₂, w2c(f₁c₁c₂))` | `abduction(v2,v1)` = same as ours | `abduction(v2,v1)` = `(f₁, w2c(f₂c₁c₂))` | ONA's | +| revision | exact `Σw`, `c = w2c(Σw)`, capped at code 252 (= 0.99) only at commit (`nal.rs:291-317`); `isa` returns `None` on `Σw ≈ 0`; `exploration` adds `1e-9` and `min(0.99)` | exact `Σw`, `w2c` (`:167-181`); cap by `TruthValue` setter | pairwise, `c = min(MAX_CONFIDENCE, max(w2c(w), c₁, c₂))` (`Truth.c:73-74`), special-cases `c = 0` and `c = 1` | not in `lib_nars` head | +| expectation | `c(f−½)+½` | same | same | — | +| analogy | `(f·f_sim, c·c_sim·f_sim)` (planner only) | same | same | same | +| exemplification, comparison, conversion, negation, intersection/union/difference, eternalize, projection, goal-deduction, decompose | **absent** | present | present (`Truth.c:101-212`) | present | +| synthesis (mean of f and of c) | present (`isa` `Opcode::Synthesis`) | absent | absent | absent | + +Finding: **lance-graph follows the Java argument order; ONA and PeTTa follow the swapped one.** Both engines encode the same NAL rules +(ONA `NAL.h:66-68` `R2((S-->M),(M-->P)) ⊢ (S-->P) Deduction`, `(A-->B),(A-->C) ⊢ (C-->B) Induction`, `(A-->C),(B-->C) ⊢ (B-->A) Abduction`), so the +difference is which premise is `v1`. A parity harness must bind premises by **rule shape**, never by function name. The revision oracle in +`.claude/knowledge/nal-recipe-audit/` already measured our four right / two wrong laws against OpenNARS; the same fixture run through ONA will differ +by ONA's `max(…, c₁, c₂)` clamp, which is not a bug on either side. + +## 3. Term and atom structures — what binds to what + +| foreign | shape (verbatim source) | ours today | binder rule | +|---|---|---|---| +| MeTTa `Symbol` | `SymbolAtom{name: UniqueString}` (`lib.rs:131`) | a label → `classid × NodeGuid` or a term id in a class (metta plan §5) | resolve once through the label codebook; never a string after bind | +| MeTTa `Variable` | `VariableAtom{name, id}` (`:230`) | never a row; a join column | shared variables across conjuncts → `EqU32Via` / `Gather` | +| MeTTa `Expression` | `ExpressionAtom{children: CowArray, evaluated}` (`:158`) | a row of a class keyed by `(functor, arity)`, one lane per argument | refuse shapes the class does not declare | +| MeTTa `Grounded` | `Box`, `Grounded`/`CustomExecute`/`CustomMatch` traits (`:413-622`) | stays in Hyperon | typed refusal on our side | +| `Space::query(&Atom) -> BindingsSet`, `SpaceMut::{add, remove, replace}` (`hyperon-space/src/lib.rs:175, 237-275`) | `LanceSpace` (D-MTP-2, not built) | the seam; `complex_query` (`:340-368`) splits `(, …)` tuple-at-a-time, so `LanceSpace` must receive the whole conjunction as a named space | +| `BindingsSet` is a bag (`PartialEq` "conceptually unordered", `:886`) | `Measure::Keep` gives a mask, not a bag | multiplicity must come from the terminal (`b4_nondeterm` kill condition) | +| PeTTa space | Prolog clauses per space, `assertz(RawTerm)` (`spaces.pl:38`), `match/4` conjunctive (`:204-220`), `add-atom`/`remove-atom` + `-proven` variants (`:14-179`) | same `LanceSpace` seam; PeTTa is an oracle, not a second adapter | diff PeTTa and Hyperon answers, never merge them into one oracle | +| ONA `Term` | hashed `Atom[64]` heap, copulas as atoms, `ATOMS_MAX 255` | `lance-graph-nal::Statement{s:u16, copula, p:u16}`, `Copula {Inheritance=1, Similarity=2, Implication=3, Equivalence=4}` (`lib.rs:94-102`); compound terms out of scope (ledger R10) | atomic statements only today; `(A * B)` products, sequences `&/`, images are R10 | +| ONA `Event` / `Implication` / `Concept` / `Decision` | `Event{term, truth, stamp, occurrenceTime, occurrenceTimeOffset, processed, creationTime}`; `Implication{…, sourceConcept}`; `Concept{belief, belief_spike, predicted_belief, goal_spike, precondition_beliefs[OPERATIONS_MAX+1=11], priority}`; `Decision{desire, execute, operationTerm, operationID[1], arguments}` | `Belief{s,copula,p,id,f,c}` + sealed lanes `f, c, w, evidence` (`nal/lib.rs:130-144, 260-268`); planner `Belief{stmt, truth, stamp, rung, premises, contradiction}` | **no event time, no goal, no operation** on our NAL row; these are what a `lance-graph-ona` crate would have to declare as lanes, not bits | +| OpenNARS `Sentence{term, punctuation, truth, stamp}`, `Task{budget, sentence}`, `Concept{taskLinks, termLinks}` | — | `lance-graph-nal` has judgment + question only (`Question`, `TruthAtLeast`, `Choice`, `Revision`); no goal `!`, no budget | budget is control, keep it off the edge (sag plan §0) | +| `Narsese.rs` `Term` enum | `Word, Placeholder, Variable{Independent,Dependent,Query}, Set*, Intersection*, Difference*, Product, Image{Ext,Int}, Conjunction{,Sequential,Parallel}, Disjunction, Negation, Inheritance, Similarity, Implication{,Predictive,Concurrent,Retrospective}, Equivalence{…}` (`enum_narsese/term/structs.rs:20-77`), `Punctuation`, `Truth`, `Stamp`, `Budget` | `lance-graph-nal` has no parser yet (`NAL::narsese()` is nal-polyfill W-later) | **the parser is already written, in Rust, in our fork** — the front end should consume `Narsese.rs` and refuse every variant outside the four copulas by name | + +## 4. Rules and control — what each engine dispatches on + +| engine | rule store | selection | our counterpart | +|---|---|---|---| +| OpenNARS Java | `SyllogisticRules`, `LocalRules`, `CompositionalRules`, `StructuralRules`, `TemporalRules` | `RuleTables.reason(TaskLink, TermLink)` → `indexToFigure` (`:55, :411`) by where the shared term sits | Pearl mask 40..42 chooses *which question*; the inference mantissa names the rule after the fact; the shared-middle-term pairing is the join `EqU32Via`/`Gather` (nal-polyfill §3) | +| ONA | 135 `R1`/`R2` macro lines in `NAL.h` → generated `RuleTable.c` (`NAL_GenerateRuleTable`) | premise-shape match per cycle; `Decision` when desire expectation ≥ `DECISION_THRESHOLD_INITIAL 0.501` | same join; the decision threshold has no home on the edge (intent lives outside CE64, sag plan §0) | +| Hyperon | `=` rules are atoms in the space; interpreter is a 12-instruction dispatch on `EVAL_SYMBOL` etc. (`interpreter.rs:374-460`) | `interpret_stack` | Datalog-shaped `=` rules → relalg `μ` driven externally (D-MTP-3); everything else stays in Hyperon | +| PeTTa | MeTTa → Prolog clauses (`translator.pl`), builtins via `register_fun` (`:449-463`) | SWI-Prolog resolution | oracle only | +| OGAR `ogar-loco::nars` | the 34 recipes as vocabulary bytes `NARS_BASE = DOMAIN_FLOOR = 0x90` (`nars.rs:74`, `lib.rs:353`), tiers Datapath / Control / Gate | `tier_of`, `is_mask_op` | **none of the 34 implements a NAL operation** (`nal-recipe-audit/recipes.tsv`, 2026-10-11); the bytes are reserved names, not NAL semantics | + +## 5. What the polyfill crates have, crate by crate + +| crate | exists | holds (verified) | missing for the mapping above | +|---|---|---|---| +| `lance-graph-nal` | yes, 953 lines, no tests in `src/` (tests in `tests/`) | `Copula` ×4, `Statement`, `Belief`, `guid` via `FacetCascade::from_semantic_tiles` (classid 4 + S 2 + copula 2 + P 2 + id 2), sealed `Beliefs` with `f, c, w (i32 ×2¹⁶), evidence` lanes, `Aperture` (statement / subject), ops `Question`, `TruthAtLeast`, `Choice`, `Revision` — all `FN = None` (no byte earned); `NalError` ×10 refusals | the parser (use `Narsese.rs`), the syllogism join + per-row truth law (nal-polyfill §4 C, the one candidate byte), `evidence_weight`-based cap parity with ONA's `max(c₁,c₂)` (document only), goals/events | +| `lance-graph-relalg` | yes, 734 lines | `Rel {All, Empty, Plane, Atom(I32 cmp / U32 eq), And, Or, Not}`, `Measure {Count, Sum, Min, Max, Keep}`, `normalize`, `symbolic`, `run` via `FoldDialect` | **no join, no `μ`** (its own docs; D-MTP-1 pre-registration) — the MeTTa conjunction cannot lower yet | +| `lance-graph-metta` | yes, 7 lines + `examples/join_probe.rs` | nothing shipped; deps `mask-risc`, `quack`; `datafrog` fork as oracle | `LanceSpace: Space + SpaceMut`, atom→address binder, `(, …)` → `Rel` joins, bag-valued terminal | +| `lance-graph-ona` | **no** | — | not a port of ONA; the honest scope is (i) an ONA oracle harness (`./NAR shell`, already in `nal-recipe-audit/oracles.md`), (ii) the ONA argument-order adapter for rule binding, (iii) event/goal/operation **lanes** if sensorimotor NAL-7/8 is ever in scope — none of which is a byte on CE64 | +| `lance-graph-cog` | **no**, and the metta plan §6 recommends against the name | — | "cog" would mean Classic AtomSpace/PLN/miner (AGPL, different engine); #1497 owns attention; keep MeTTa under `-metta` | + +## 6. Gaps, ordered by what unblocks the most + +1. **relalg join (`⋈` on shared variables) and `μ`** — blocks `lance-graph-metta` D-MTP-1/3 and the NAL syllogism alike. One mechanism, two front ends. +2. **Per-row truth law into a lane** (nal-polyfill §4 C: `MapPairU8` table terminal or fixed-point multiply) — the only candidate byte; W4 measurement decides. +3. **Parser**: consume `AdaWorldAPI/Narsese.rs` (`enum_narsese` + `lexical`) in `lance-graph-nal`; refuse by variant name. Do not write a second Narsese parser. +4. **Argument-order binding** for the parity harness: bind `v1`/`v2` from the rule's premise shape; run the same fixture through OpenNARS (`RunNal.java`) and ONA, record both (`oracles.md` precedent). +5. **Truth-function census**: our set is `{deduction, induction, abduction, revision, analogy, expectation, surprise, synthesis}`; the engines also carry + exemplification, comparison, conversion, negation, intersection/union/difference, eternalize/projection. Add only the ones a rule in scope needs; each as a scalar oracle in `isa::truth` first. +6. **Evidential base width**: `Stamp(u64)` (planner), `&[u64]` roots (nal), ONA 10, OpenNARS 20 000. Pin the policy before revision over large populations is measured. +7. **Doc drift to fix when touched**: `contract/nars.rs` `InferenceType` docs still describe CAM search strategies ("exact CAM search", "DN-tree traversal"), not NAL; `QueryStrategy` is the same vintage. + +## 7. What this inventory does not claim + +No parity was run in this session; every formula above is read from source, not measured end to end. The Hyperon trie index (`hyperon-space/src/index`) and ONA's +`RuleTable.c` body were not read. The 34-recipe statuses are the 2026-10-11 audit's, unchanged. From 2da8f43713ca160d56f780e7fa1cfcf6619224c9 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 16 Oct 2026 00:15:01 +0000 Subject: [PATCH 4/5] plan: metta-datalog-assimilation-v1 (D-ASM-0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Umbrella plan sequencing D-MTP-2/3/5/6, D-RA-3/4 and D-NALP-4/5/7 toward one target: MeTTa/PeTTa atoms assimilated into a Datalog AST held as relalg values, executed through R2IL/mask-risc, with Hyperon, PeTTa and datafrog as oracles. Adds only what no plan names: binder (D-ASM-1), join as D-CMR-5 preimage (D-ASM-2), bag terminal (D-ASM-3), LanceSpace + three-way harness (D-ASM-4), ONA-shaped 64×u8 compound-term tenant (D-ASM-5), rule catalogue as data with engine argument-order tags (D-ASM-6), mining seam reserved (D-ASM-7). Nothing beyond D-ASM-0 authorized; /5plus3 before non-probe code. Board: INTEGRATION_PLANS prepend, STATUS_BOARD D-ASM section, entry, indexes regenerated. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_017SNHxJYC1MeW3HsyhGZo1E --- .claude/board/INTEGRATION_PLANS.md | 8 + .claude/board/STATUS_BOARD.md | 15 ++ ...6-10-15-metta-datalog-assimilation-plan.md | 7 + .claude/board/entries/README.md | 3 +- .../plans/metta-datalog-assimilation-v1.md | 139 ++++++++++++++++++ 5 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 .claude/board/entries/2026-10-15-metta-datalog-assimilation-plan.md create mode 100644 .claude/plans/metta-datalog-assimilation-v1.md diff --git a/.claude/board/INTEGRATION_PLANS.md b/.claude/board/INTEGRATION_PLANS.md index 7b846772e..30190d85d 100644 --- a/.claude/board/INTEGRATION_PLANS.md +++ b/.claude/board/INTEGRATION_PLANS.md @@ -1,3 +1,11 @@ +## 2026-10-15 — metta-datalog-assimilation-v1 — Hyperon/PeTTa/MeTTa atoms assimilated into a Datalog-AST · NAL · R2IL · ONA-shaped substrate, MeTTa as oracle → `.claude/plans/metta-datalog-assimilation-v1.md` + +**Status:** PROPOSAL; D-ASM-0 only (plan + inventory `.claude/research/2026-10-15-nars-metta-ce64-mapping-inventory.md`). Umbrella over D-MTP-2/3/5/6, D-RA-3/4, D-NALP-4/5/7; adds D-ASM-1 binder, -2 join-as-preimage, -3 bag terminal, -4 LanceSpace + three-way harness, -5 ONA-shaped 64×u8 compound-term tenant, -6 rule catalogue as data, -7 mining seam reserved. `/5plus3` before non-probe code. + +- One Datalog AST as relalg values, two front ends (Hyperon's own `SExprParser`, `Narsese.rs`); atoms keep their meaning, `Space` is the only seam, execution beyond Datalog stays in Hyperon as the oracle. +- No new byte without an insufficiency proof; multiplicity is a terminal; recursion is d′ outside the engine; argument-order of truth functions is an engine tag (OpenNARS vs ONA/PeTTa differ). +- Kill conditions: dedup instead of bag; a differing answer re-pinned; a ported interpreter; any atom meaning changed. + ## 2026-10-14 (2) — metta-polyfill-v1 — Hyperon/MeTTa as a front end over the masking-algebra polyfill → `.claude/plans/metta-polyfill-v1.md` **Status:** PROPOSAL; D-MTP-0 (map + measurements), D-MTP-1 (join probe, measured), D-MTP-1b (range hop, measured) and D-MTP-6 (datafrog oracle) done; D-MTP-2..5 not authorized. diff --git a/.claude/board/STATUS_BOARD.md b/.claude/board/STATUS_BOARD.md index 33d9af721..dbcea6de5 100644 --- a/.claude/board/STATUS_BOARD.md +++ b/.claude/board/STATUS_BOARD.md @@ -12,6 +12,21 @@ Plan: `.claude/plans/wal-shootout-v1.md`. Feeds D-LNC-7; decides nothing. | **D-WAL-6** | version clock: a point of view as one row range | Done: `contract::temporal_pov::VersionClock`; v4 4.2 ns per `rows_at` vs 127 µs per-row scan at 400k rows | row-version oracle over 200 versions with gaps; disables (gap fill, start offset, base guard) each turn it red. Wired into `LanceCycleWriter` 2026-10-15: seeded at the head on open from the manifest's physical row counts, recorded after every commit; deleted rows keep their positions; four tests against storage, three disables red. Reader wiring open | | **D-WAL-7** | `temporal.rs` without row copies | Done: `deinterlace_indices`, `local_trajectories_indices`, `local_trajectory_indices_of`; copying forms keep their signatures as wrappers | clone counter at 0 for the index form; removing the sort turns the two ordering tests red | +## D-ASM — MeTTa/PeTTa atoms assimilated into the Datalog-AST · NAL · R2IL · ONA-shaped substrate (2026-10-15) + +Plan: `.claude/plans/metta-datalog-assimilation-v1.md`. Umbrella over D-MTP-2/3/5/6, D-RA-3/4, D-NALP-4/5/7 (cited, not copied). + +| D-id | scope | status | gate / falsifier | +|---|---|---|---| +| **D-ASM-0** | Plan + inventory (`.claude/research/2026-10-15-nars-metta-ce64-mapping-inventory.md`) | Done 2026-10-15 | — | +| **D-ASM-1** | Binder: `(functor, arity) → ClassView` + label codebook; atoms → addresses once; typed refusal for Grounded/nested/state | Queued (not authorized) | same address twice per fixture atom; refusals named by kind; no string survives bind | +| **D-ASM-2** | Join as D-CMR-5 preimage in relalg (`EqU32Via` / gated `Gather` / range) | Queued (not authorized) | pairs == datafrog as a bag 10²..10⁶; join_10000 answers; `Program` byte-identical across front ends | +| **D-ASM-3** | Bag terminal → `BindingsSet` multiplicity | Queued (not authorized) | `b4_nondeterm` multiset == Hyperon; dedup arm fails; new terminal only with insufficiency proof | +| **D-ASM-4** | `LanceSpace` named space; Hyperon · PeTTa · LanceSpace harness | Queued (not authorized) | golden 32/33 unchanged; every answer == Hyperon multiset or a named refusal | +| **D-ASM-5** | ONA-shaped compound-term tenant (64 × u8 heap), parity vs ONA `Term_*` | Queued (not authorized) | byte-identical hash/extraction; > 64 atoms refused; LAYOUT-CLEAN | +| **D-ASM-6** | Rule catalogue as data (ONA `R1/R2`, OpenNARS tables) with truth label + engine order tag; `Narsese.rs` front end | Queued (not authorized) | each rule re-emits its source line; order tag proven on both engines | +| **D-ASM-7** | Mining seam (`lance-graph-cog` driver tier) — separate plan | Reserved | — | + ## D-MTP — Hyperon/MeTTa over the masking-algebra polyfill (2026-10-14) Plan: `.claude/plans/metta-polyfill-v1.md`. Proposed crate `lance-graph-metta` (not created). diff --git a/.claude/board/entries/2026-10-15-metta-datalog-assimilation-plan.md b/.claude/board/entries/2026-10-15-metta-datalog-assimilation-plan.md new file mode 100644 index 000000000..1e6601121 --- /dev/null +++ b/.claude/board/entries/2026-10-15-metta-datalog-assimilation-plan.md @@ -0,0 +1,7 @@ +# 2026-10-15 — metta-datalog-assimilation-v1: the assimilation plan (D-ASM-0) + +STATUS: open | OUTCOME: `.claude/plans/metta-datalog-assimilation-v1.md` — umbrella over D-MTP-2/3/5/6, D-RA-3/4 and +D-NALP-4/5/7, adding the binder (D-ASM-1), join-as-preimage (D-ASM-2), bag terminal (D-ASM-3), `LanceSpace` + three-way +harness (D-ASM-4), the ONA-shaped 64 × u8 compound-term tenant that would lift ledger R10 (D-ASM-5), the NAL rule catalogue as +data with engine argument-order tags (D-ASM-6), and a reserved mining seam (D-ASM-7). | OPEN: D-ASM-1..7 unauthorized; +`/5plus3` before non-probe code; HY-Q07/Q08 and the stamp-as-atom shape undecided. diff --git a/.claude/board/entries/README.md b/.claude/board/entries/README.md index 7f479ffc7..175531e41 100644 --- a/.claude/board/entries/README.md +++ b/.claude/board/entries/README.md @@ -25,11 +25,12 @@ index row, (3) no duplicate entry id. Checks 1 and 2 are deliberately opposite directions; the stranding this convention prevents shows up in exactly one of them, never both. -345 entries, 2026-08-06 .. 2026-10-15. +346 entries, 2026-08-06 .. 2026-10-15. | date | entry id | finding | file | |---|---|---|---| | 2026-10-15 | `nars-metta-ce64-mapping-inventory` | | [2026-10-15-nars-metta-ce64-mapping-inventory.md](2026-10-15-nars-metta-ce64-mapping-inventory.md) | +| 2026-10-15 | `D-ASM-0` | | [2026-10-15-metta-datalog-assimilation-plan.md](2026-10-15-metta-datalog-assimilation-plan.md) | | 2026-10-15 | `ledger-correction-wire-contract` | | [2026-10-15-ledger-correction-wire-contract.md](2026-10-15-ledger-correction-wire-contract.md) | | 2026-10-15 | `givens-layer` | | [2026-10-15-givens-layer.md](2026-10-15-givens-layer.md) | | 2026-10-15 | `epi-trust-is-topology-vocabulary` | | [2026-10-15-epi-trust-is-topology-vocabulary.md](2026-10-15-epi-trust-is-topology-vocabulary.md) | diff --git a/.claude/plans/metta-datalog-assimilation-v1.md b/.claude/plans/metta-datalog-assimilation-v1.md new file mode 100644 index 000000000..96617169a --- /dev/null +++ b/.claude/plans/metta-datalog-assimilation-v1.md @@ -0,0 +1,139 @@ +# metta-datalog-assimilation-v1 — Hyperon / PeTTa / MeTTa atoms assimilated into a Datalog-AST · NAL · R2IL · ONA-shaped substrate, with MeTTa as the oracle + +**Status:** PROPOSAL (D-ASM-0 only: this plan, its board rows, and the inventory it rests on). Nothing else is authorized. +Every wave below is gated on the measurement of the one before it, and the plan goes through `/5plus3` before the first +non-probe code lands. +**Date:** 2026-10-15. +**Repos:** lance-graph (`lance-graph-relalg`, `lance-graph-metta`, `lance-graph-nal`, `lance-graph-r2il`, `lance-graph-mask-risc`, +contract), the forks `AdaWorldAPI/hyperon-experimental`, `AdaWorldAPI/PeTTa`, `AdaWorldAPI/Narsese.rs`, `AdaWorldAPI/OpenNARS-for-Applications`, +`AdaWorldAPI/datafrog`; OGAR only if a class or vocabulary byte is earned (none is expected). +**Parents:** `.claude/research/2026-10-15-nars-metta-ce64-mapping-inventory.md` (the source-read inventory, D-ASM-0's evidence), +`metta-polyfill-v1.md` (D-MTP-0..6), `relalg-v1.md` (D-RA-3/4), `nal-polyfill-v1.md` (D-NALP-1..11), +`.arxiv/2026-10_hyperon_metta_to_lance_graph_parity_map.md` (HY-Q01..15), `entries/2026-10-03-coresearch-chained-hop.md` (option d′). +**Umbrella, not a rival:** this plan sequences D-MTP, D-RA and D-NALP work toward one target and adds only what none of them names +(D-ASM-1, D-ASM-5, D-ASM-6, D-ASM-7). It mints no D-id for work another plan already owns; those rows are cited, not copied. + +## 1. The target, in one picture + +```text +MeTTa text ──hyperon SExprParser (fork, unchanged)──► Atom PeTTa clauses ──► (oracle only) + │ + D-ASM-1 binder: atoms → addresses, once + ▼ + Datalog AST (relalg values: Fact / Rule / Query over coordinates) ◄── Narsese.rs terms (NAL front end) + │ D-RA-3 values, D-ASM-2 join = D-CMR-5 preimage, D-RA-4 μ via d′ + ▼ + lance-graph-relalg ──► R2IL FoldDialect ──► mask-risc ──► ndarray::simd + │ + D-ASM-3 bag terminal (BindingsSet multiplicity) D-NALP-4 per-row truth law + ▼ + answers diffed three ways: Hyperon interpreter · PeTTa · LanceSpace (D-ASM-4), NAL answers vs ONA · OpenNARS (D-NALP-7) +``` + +"Assimilate" means: everything that is **data** in a MeTTa program (facts, `=` rules in the Datalog fragment, `:` type atoms, +the space contents) becomes rows and algebra values addressed by coordinates; everything that is **execution** beyond Datalog +(nondeterministic rewriting, `superpose`/`collapse` bags of new terms, grounded calls, dependent-type checking, `new-state`) +stays in the Hyperon interpreter and is used as the oracle that our answers are diffed against. No atom changes meaning: +the parser is Hyperon's own, the `Space` trait is the only seam, and refusal is typed, never approximated. + +## 2. What is settled before this plan starts (VERIFIED-IN-CODE, from the inventory) + +- The seam is `hyperon_space::Space` (`common`, `query(&Atom) -> BindingsSet`, `visit`, `as_any`) + `SpaceMut::{add, remove, replace}`; + `match` hands its pattern unchanged to `space.borrow().query(&pattern)` (`stdlib/core.rs:163`). `ModuleSpace` splits conjunctions + itself, so `LanceSpace` is bound as a named space, never as `&self` (D-MTP-2). +- `Atom` is `Symbol | Expression | Variable | Grounded` (`hyperon-atom/src/lib.rs:827-849`). A Narsese statement ` P>` is the + MeTTa fact `(--> S P)`: `lance-graph-nal::guid` already lays an arity-2 fact out as semantic tiles + `[classid_hi, classid_lo, S, copula, P, id, 0, 0]` (`lib.rs:157-170`); the same tiles carry `(f a₁…aₖ)` for k ≤ 5. +- relalg describes one table's row set (`Rel`, `Measure`) and rewrites it before it runs; it has **no join and no μ** by design, + and names a hop as a D-CMR-5 preimage over coordinates, never a foreign key (`relalg-v1.md` §4). D-MTP-1 measured the hop + both ways (`Gather` semijoin and the range preimage, D-MTP-1b); D-RA-4 names the fixpoint driver d′. +- `BindingsSet` is a bag (`hyperon-space/src/lib.rs:886`); `Measure::Keep` is a mask. The `b4_nondeterm` fixture counts duplicates. +- Hyperon's own engine: join_10000 panics (`trie.rs:539`, `TK_MAX_EXPRESSION_SIZE = 1 << 10`), anc_800 takes 417 s; PeTTa stays + near its 0.32 s startup; datafrog does join 10⁶ at 65–69 ns/pair (D-MTP-0/6). These are the bars, not our primitives. +- Truth algebra is shared across OpenNARS, ONA, PeTTa and us; **argument order is not**: lance-graph's abduction/induction match + OpenNARS Java, ONA and PeTTa use the swapped convention (`Truth.c:84-92` vs `TruthFunctions.java:250-287`). A parity harness binds + premises by rule shape. ONA's revision clamps `c = min(0.99, max(w2c(Σw), c₁, c₂))`; ours and OpenNARS's are exact Σw. +- ONA's `Term` is `Atom atoms[COMPOUND_TERM_SIZE_MAX = 64]`, `ATOMS_MAX = 255`, "the encoding used is that of a binary heap" + (`Term.h:34-37, 54-59`; `Config.h:140-142`): a fixed-width, u8-indexed compound term. That is the shape ledger R10 lacks. +- No foreign system carries a 59..63 or a 40..42. The epistemic ladder and the Pearl mask stay ours; nothing is imported into them. +- None of the 34 OGAR recipes implements a NAL operation (`nal-recipe-audit/recipes.tsv`); their bytes are names, not semantics. + +## 3. Decisions (each with the alternative it rejects) + +**A. One Datalog AST, two front ends, as relalg values (DECISION, extends D-RA-3).** `Fact(rel, args)`, `Rule(head, body)`, +`Query(body, project)` are values over coordinates: relation = `(functor classid, arity)`, argument = lane index, constant = +codebook id, variable = a join column. MeTTa (via `SExprParser`) and Narsese (via `Narsese.rs`) both produce it. Rejected: +a MeTTa-specific IR beside a NAL-specific one (two spellings of a join), and Datalog text as a query path (strings are labels). + +**B. The join is the D-CMR-5 preimage, lowered to what exists (DECISION).** A shared variable between two body atoms lowers to +`Pred::EqU32Via { fk, key, v }` when one side is a constant and to `MaskOp::Gather { lane, foreign, under, dst }` (gated semijoin) +otherwise; the range form (D-MTP-1b) when the lane is address-ordered. No new byte. Rejected: a hash join inside mask-risc +(a second engine), and a `Rel::Join` that materialises an intermediate relation (the exact cost §2 measured in Hyperon). + +**C. Multiplicity is a terminal, not a post-pass (DECISION, the b4 kill condition).** A `query` answer is a bag of `Bindings`. +The terminal emits projected key tuples with their multiplicity; the adapter builds `Bindings` from them. Whether this is a +composition of `Keep` + `Gather` + `CountKeyRunsU32` or needs one new terminal is D-ASM-3's measurement, with the +`isa-anti-lasagne-warden` insufficiency proof required for the latter. Rejected: dedup-then-count (loses `superpose` semantics). + +**D. Recursion is a driver outside the engine (DECISION, = D-RA-4 / D-MTP-3).** Datalog-fragment `=` rules are stored in +`LanceSpace` as algebra values; `match` over a derived relation answers with the closure computed by d′, semi-naive, one fold per +iteration, bounded, refusing an unbounded closure rather than truncating. The interpreter never sees these rules in `&self`. + +**E. Compound terms take ONA's shape (DECISION, new: D-ASM-5).** A compound term is a fixed 64-byte tenant of u8 atom indices in +binary-heap order, hashed once, with `Term_Equal`, `Term_ExtractSubterm`, `Term_Complexity`, `Term_Hash` as the parity surface. +Subterm extraction is index arithmetic, so a compound-term predicate is a strided u8 match (`MatchFacet16Strided` family), not a +tree walk. This lifts ledger R10 for NAL-3/4/5 statements and for MeTTa expressions deeper than one level. Rejected: a pointer +tree (allocation in the bulk loop) and widening the 16-byte facet (the key is canon). + +**F. NAL rules are Datalog rules with a truth-function label and an engine-order tag (DECISION, new: D-ASM-6).** ONA's 135 +`R1`/`R2` lines (`NAL.h`) and OpenNARS's syllogistic/local/compositional tables are harvested into the AST as data: premise shapes, +conclusion shape, truth function, and which argument convention the source engine uses. The per-row truth law stays D-NALP-4's +single candidate byte; everything else is the join of D-ASM-2. Rejected: porting `RuleTables.reason` or `RuleTable.c`. + +**G. Three oracles, never averaged (DECISION, = D-MTP-5/6, D-NALP-7).** Hyperon fork, PeTTa, and datafrog for Datalog answers; +ONA `./NAR shell` and OpenNARS `RunNal.java` for NAL truth. Divergences are recorded per engine. An answer that only one oracle +produces is reported, not adopted. + +**H. What stays in Hyperon, by name.** `superpose`/`collapse` over constructed terms, `cons-atom`/`decons-atom`, grounded ops, +`new-state`/`change-state!`, dependent types (`d3_deptypes`), and any `=` rule with a function symbol in its head. `LanceSpace` +refuses these at `add` with a typed error; they live in the module's own `GroundingSpace`. + +## 4. Deliverables and gates + +| D-id | wave | work | gate / falsifier | depends on | +|---|---|---|---|---| +| D-ASM-0 | W0 | this plan, the inventory, board rows | — | — | +| D-ASM-1 | W1 | **Binder**: `(functor, arity) → ClassView` registry + label codebook; `add` of `Symbol`/flat `Expression` facts → rows; `Variable` → join column; `Grounded`/nested/typed-state → typed refusal. Reuses `lance-graph-nal::guid` tiles. Probe: `e1_kb_write` facts round-trip through `add`/`query`/`remove` | every fixture atom resolves to the same address twice; a refused atom is named by kind; no string survives bind | D-MTP-2 scope | +| D-ASM-2 | W2 | **Join as preimage** in relalg: a body-level shared variable lowers to `EqU32Via` / gated `Gather` / range (D-MTP-1b); `normalize` keeps its rewrites; symbolic `∅` still short-circuits | pairs == datafrog as a bag at n = 10²..10⁶; join_10000 answers where Hyperon panics; `Program` byte-identical whichever front end produced the AST | D-RA-3 | +| D-ASM-3 | W2 | **Bag terminal**: emit projected tuples with multiplicity; adapter builds `BindingsSet` | `b4_nondeterm` multiset equal to Hyperon's; a dedup arm fails it (the falsifier must fire); new terminal only with an insufficiency proof | D-ASM-2 | +| D-ASM-4 | W3 | **`LanceSpace`** (`Space + SpaceMut`) as a named space over D-ASM-1..3; three-way harness Hyperon · PeTTa · LanceSpace on `b4`, `c1`, `e1`, `join_n`, `anc_n`; refusals counted | Hyperon golden corpus unchanged (32/33); every LanceSpace answer equal to Hyperon's as a normalised multiset or a named refusal; PeTTa divergences logged | D-MTP-2, D-MTP-5 | +| D-RA-4 / D-MTP-3 | W4 | **μ via d′** for Datalog-fragment rules stored in `LanceSpace` | `anc_n` identical; no fixpoint state in mask-risc; unbounded closure refused | D-ASM-4 | +| D-ASM-5 | W5 | **ONA-shaped compound-term tenant**: 64 × u8 heap, `Term_Hash`/`Equal`/`ExtractSubterm`/`Complexity` parity vs ONA on its `examples/nal/*.nal` terms; strided predicate over subterm positions | byte-identical hash and extraction on every fixture term; a term wider than 64 atoms refused, never truncated; `v3-envelope-auditor` LAYOUT-CLEAN (a tenant, no stride change) | D-ASM-1 | +| D-ASM-6 | W5 | **Rule catalogue as data**: ONA's `R1`/`R2` table and OpenNARS's syllogistic tables harvested into Datalog rules with truth-function label + engine argument-order tag; `Narsese.rs` as the NAL front end into the same AST | each harvested rule re-emits its source line; the order tag is proven by running one fixture through both engines and binding by shape | D-ASM-1, D-NALP-4 | +| D-NALP-5 | W6 | syllogistic population ops = D-ASM-2 join + D-NALP-4 law, now over the shared AST | equals the scalar rule pair by pair; equals ONA and OpenNARS under their own order tags | D-ASM-2, D-ASM-6 | +| D-ASM-7 | W7 | **Mining seam** reserved: `lance-graph-cog` as a driver tier (support = D-ASM-2/3 count, specialisation = lane census, surprisingness via `arm-discovery`), oracle `hyperon-miner`; its own plan, not authorized here | — | D-ASM-3 | + +**Kill conditions.** +- D-ASM-3: if no composition of existing terminals reproduces `b4_nondeterm`'s multiset and the insufficiency proof for a new + terminal fails the warden, the MeTTa adapter answers counts only and says so; it does not dedup. +- D-ASM-4: any answer that differs from Hyperon's and is not a named refusal is a lowering bug, never a re-pin of the fixture. +- D-ASM-5: if heap-order extraction cannot be a strided match (measured: a tree walk per row), the tenant is rejected and R10 stays open. +- D-ASM-6: a rule whose argument order cannot be proven by shape on both engines is kept out of the catalogue. +- Anywhere: a new opcode or vocabulary byte without an execution-level insufficiency proof; any change to what a `Symbol`, + `Expression`, `Variable` or `Grounded` atom means; any Hyperon interpreter code ported rather than called. + +## 5. Order and ownership + +W1 and W2 can start together (binder; join + bag terminal). W3 needs both. W4 needs W3. W5 needs W1 and, for the law, D-NALP-4's +measurement. W6 needs W2 and W5. W7 is a separate plan. Wardens that apply: `isa-anti-lasagne-warden` (D-ASM-2/3), +`zero-copy-warden` (D-ASM-1 binder must not hold atoms), `v3-envelope-auditor` (D-ASM-5), `cypher-lowering-warden`'s rule that a +front end lowers from the bound plan, never the raw AST, `fold-carrier-scientist` (bag vs set carriers in D-ASM-3), +`premise-auditor` before any option set reaches the operator. + +## 6. Open + +- HY-Q07: a `query` whose answer is a **new** expression (not a row) — where is it allocated? Out of scope for W1–W6; D-ASM-7 will meet it. +- HY-Q08: `new-space`/multi-space scope vs Lance versions; D-ASM-4 proves isolation on `e1` only. +- Whether `match &self` can reach a whole conjunction without patching Hyperon (D-MTP-2's open point) — if not, the named-space rule is permanent. +- The 59..63 / 40..42 writer for assimilated facts: a MeTTa fact arrives with no evidence; `Revision` refuses `MissingProvenance` by design. + The stamp has to travel as an atom. Shape not decided. From 67aae593265e9646e83eb1f481a679085b3f7ef6 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 16 Oct 2026 00:17:00 +0000 Subject: [PATCH 5/5] =?UTF-8?q?plan:=20metta-datalog-assimilation-v1=20?= =?UTF-8?q?=C2=A77=20=E2=80=94=20oracle=20parity=20first,=20CE64=20enrichm?= =?UTF-8?q?ent=20second?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each lance-graph-* crate is validated against its original as the oracle (OpenNARS/ONA, datafrog, Hyperon/PeTTa, hyperon-miner); only then is CausalEdge64 used to enrich, to validate (zero enrichment invisible) and to measure expansion potential as fixtures the original cannot run. Per-crate oracle, parity surface, enrichment axis and expansion claim tabled. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_017SNHxJYC1MeW3HsyhGZo1E --- ...6-10-15-metta-datalog-assimilation-plan.md | 5 ++++ .../plans/metta-datalog-assimilation-v1.md | 30 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/.claude/board/entries/2026-10-15-metta-datalog-assimilation-plan.md b/.claude/board/entries/2026-10-15-metta-datalog-assimilation-plan.md index 1e6601121..cec4b5305 100644 --- a/.claude/board/entries/2026-10-15-metta-datalog-assimilation-plan.md +++ b/.claude/board/entries/2026-10-15-metta-datalog-assimilation-plan.md @@ -5,3 +5,8 @@ D-NALP-4/5/7, adding the binder (D-ASM-1), join-as-preimage (D-ASM-2), bag termi harness (D-ASM-4), the ONA-shaped 64 × u8 compound-term tenant that would lift ledger R10 (D-ASM-5), the NAL rule catalogue as data with engine argument-order tags (D-ASM-6), and a reserved mining seam (D-ASM-7). | OPEN: D-ASM-1..7 unauthorized; `/5plus3` before non-probe code; HY-Q07/Q08 and the stamp-as-atom shape undecided. + +Addendum (same day): §7 validation doctrine — each `lance-graph-*` crate is validated against its ORIGINAL as the oracle first +(OpenNARS/ONA for nal, datafrog for relalg, Hyperon/PeTTa for metta, ONA for ona, hyperon-miner for cog); only then is +CausalEdge64 used to enrich, to validate (zero enrichment must be invisible) and to measure expansion potential as fixtures the +original cannot run. The oracle is never a sibling crate and never CE64. diff --git a/.claude/plans/metta-datalog-assimilation-v1.md b/.claude/plans/metta-datalog-assimilation-v1.md index 96617169a..3729e7882 100644 --- a/.claude/plans/metta-datalog-assimilation-v1.md +++ b/.claude/plans/metta-datalog-assimilation-v1.md @@ -137,3 +137,33 @@ front end lowers from the bound plan, never the raw AST, `fold-carrier-scientist - Whether `match &self` can reach a whole conjunction without patching Hyperon (D-MTP-2's open point) — if not, the named-space rule is permanent. - The 59..63 / 40..42 writer for assimilated facts: a MeTTa fact arrives with no evidence; `Revision` refuses `MissingProvenance` by design. The stamp has to travel as an atom. Shape not decided. + +## 7. Validation doctrine — oracle parity first, CE64 enrichment second (DECISION 2026-10-15) + +The target is one unified substrate. It is validated in two passes, in this order, and a crate does not enter pass 2 until pass 1 is green: + +1. **Each `lance-graph-*` crate is validated against its original as the oracle.** The original's answers on its own fixtures are the + ground truth for that crate's surface. Divergences are recorded per engine and never averaged (Decision G). +2. **Then CausalEdge64 is used to enrich, to validate, and to measure expansion potential.** Enrichment = the bands the original does not + have (40..42 Pearl mask, 50..52 plasticity, 53..58 witness, 59..63 epistemic ladder, provenance classes). Validation = the enriched + answer must still reproduce the original's answer when the enrichment is zero (ZERO_FALLBACK, all-zero CE64 fields). Expansion = + a falsifiable claim the original cannot make, measured, not asserted. + +| crate | original (oracle, pinned) | pass-1 parity surface | pass-2 CE64 enrichment axis | expansion claim (falsifiable) | +|---|---|---|---|---| +| `lance-graph-nal` | OpenNARS Java `4d1bdb0` (`RunNal.java`), ONA `dc4efd0` (`./NAR shell`) | NAL-1/2 fixtures, `revision_points.nal`; truth to one u8 code; argument order bound by rule shape | evidence classes (`INDEPENDENT/DUPLICATE/OVERLAP/NO_PROVENANCE`), W witness, 59..63 written by `pearl::hydrate`/`revise` | a population revision that refuses dependent evidence by class where both originals silently pool it; a statement's epistemic state after an executed intervention, which neither original represents | +| `lance-graph-relalg` | `AdaWorldAPI/datafrog` `edd7cfc` (exact Datalog) | bags of tuples at n = 10²..10⁶; `μ` closures | 40..42 as the question asked of a join (SO/PO/SPO/SP) | a join whose pairs carry a Pearl mask and a topology, so a two-hop answer states whether the middle term is a known intermediate | +| `lance-graph-metta` | hyperon-experimental `3f76dc4` (interpreter), PeTTa `1d19a1d` | `b4_nondeterm`, `c1_grounded_basic`, `e1_kb_write`, golden 32/33, `join_n`, `anc_n`; multisets, refusals named | facts assimilated with provenance; `(stv f c)` into F/C; stamp travels as an atom | answers Hyperon panics or times out on (join_10000, anc_800) with identical multisets where it finishes; a `match` whose answer is gated by provenance, which no space in Hyperon or PeTTa can express | +| `lance-graph-ona` (when it exists) | ONA `dc4efd0` (`Term_*`, `Truth_*`, `examples/nal/*.nal`) | `Term_Hash`/`Equal`/`ExtractSubterm` byte parity on the 64 × u8 heap; sensorimotor fixtures if NAL-7/8 enter scope | compound terms as a tenant addressable by strided match; events as rows with time lanes | a compound-term predicate as one fold over the population where ONA walks concepts one at a time | +| `lance-graph-cog` (when it exists) | `trueagi-io/hyperon-miner` (patterns, surprisingness), PeTTa `lib_pln.metta` second, classic `opencog/miner` read-only | mined pattern set and surprisingness on the shared fixture (HY-Q15) | support counted under provenance masks; patterns scored with `NarsTruth` via `arm-discovery` | a mined pattern whose support excludes dependent evidence; attention left to #1497 | + +Rules of the doctrine: +- **The oracle is the original, never a sibling.** `lance-graph-metta` is not validated against `lance-graph-nal`, and PeTTa is not a + substitute for Hyperon (HY-Q12). CE64 is never the oracle in pass 1. +- **Zero enrichment must be invisible.** With every CE64 band at its zero fallback, pass-2 answers equal pass-1 answers byte for byte. + A difference is a lowering bug, not a feature. +- **An expansion claim is a fixture the original cannot run.** It is recorded with the original's actual behaviour on that input + (refusal, panic, timeout, silent pooling) and ours, and graded `MEASURED` only with the command that produced both. +- **Enrichment never changes the original's answer on the original's inputs.** If an enriched reading disagrees with the oracle on an + oracle fixture, the enrichment is wrong, not the oracle. +- The status vocabulary is the repo's: `MEASURED` with its command, `VERIFIED-IN-CODE` with its location, `HYPOTHESIS`, `OPEN`.