diff --git a/.claude/board/AGENT_LOG.md b/.claude/board/AGENT_LOG.md index 19157023..ac8c4849 100644 --- a/.claude/board/AGENT_LOG.md +++ b/.claude/board/AGENT_LOG.md @@ -1,3 +1,61 @@ +## 2026-06-15 — integrated-cognitive-planner-v1: 3-hardener verdicts folded (§9) + §0 anti-invention guardrail + +**Main thread (Opus 4.8 1M) + 3 Opus brutal hardeners** (PP-13 brutally-honest-tester / PP-15 baton-handoff-auditor / PP-16 preflight-drift-auditor), all pinned to the plan by `file:line`. Verdicts: **HOLD / CATCH-LATENT / READY-TO-DISPATCH** — all fixes spec-text, no architectural rewrite; all three confirmed the grounding + dependency-wall claims + measure-first ratio. + +**Folded into the plan:** new **§9 hardening ledger** (5 LOCKED decisions + latent boundary fixes + P2s + sub-line drift) and new **§0 ANTI-INVENTION GUARDRAIL** (operator msg: *"prevent any agents telling us to invent additional skewed properties in the SoA when we already have a lot of good and well tested ideas"*) — read-first, enforced by dto-soa/iron-rule savants + the 3 hardeners. Inline fixes: emit channels are SEPARATE-not-derived (was the I-LEGACY trap); §4 "closes seam #2" → closure-injected (planner can't reach async `at_version`). **Biggest catches:** (1) `cycle()` must stay INHERENT not a trait method (object-safety, would break n8n-rs/crewai-rust `Box`); (2) DUAL `RungLevel` — contract bare enum vs thinking_engine `cognitive_stack::RungLevel` which already has `from_u8`+`should_elevate`, MIRROR don't duplicate (PP-16 top catch = the §0 guardrail in action); (3) THREE `PlanResult` (incl arigraph/language.rs:34); (4) `MailboxId` has no safe sentinel; (5) "#495 rides #496" mis-attributed — ValueSchema is branch-only post-#495. + +**Next:** scope the tesseract-rs transcode POC (first consumer against the now-Full slab) → open #496 carrying plan + ValueSchema + FULL-default + guardrail + hardening. + +## 2026-06-15 — ValueSchema POC default: `ClassView::value_schema` flipped Bootstrap→Full (operator decision (a)) + +**Main thread (Opus 4.8 1M).** Operator: *"(a) flip the blanket default to Full (all unconfigured classes → Full) / any consumer that needs to save memory can create [its] smaller settings / any consumer that needs more data and more efficiency can afford a separate class"* + *"prevent any agents telling us to invent additional skewed properties in the SoA when we already have a lot of good and well tested ideas"* + consumers *woa-rs / medcare-rs / q2 / tesseract-rs (favourite) — transcode that creates a testable POC*. + +**Shipped (contract, 1-line behavior flip + guard test):** `ClassView::value_schema` (class_view.rs:233) `Bootstrap → Full`. Layout-preserving (no stride / `ENVELOPE_LAYOUT_VERSION` change). TYPE-level `ValueSchema::default()` stays `Bootstrap` (substrate zero-fallback intact) — only the class→schema *resolution* default flipped, so specialisation is opt-IN (mint a class to go smaller/denser). **Zero invention** (honours the anti-skew guardrail): `Full` activates the already-existing, already-tested 9 `ValueTenant`s (helix-48 = `HelixResidue` tenant already in Full+Compressed — NOT added). Guard test `value_schema_default_is_full_temporary_poc` added (asserts the POC default + that the type default + edge-codec axis are untouched). `cargo test -p lance-graph-contract` → **613 lib green**. Tracked as **TD-VALUESCHEMA-FULL-POC-DEFAULT** (revert-before-merge obligation). + +**Next:** fold the 3-hardener findings + a §0 ANTI-INVENTION GUARDRAIL into the plan; scope the tesseract-rs transcode POC (first consumer, against the now-Full slab); #496 carries it all. + +## 2026-06-15 — integrated-cognitive-planner-v1: 5-savant EXPANSION pass folded (3 doc errors corrected + §2.1/§3.1/§4.1/§8 added) + +**Main thread (Opus 4.8 1M) + 5 Opus expansion savants** (convergence-architect / bus-compiler / truth-architect / scenario-world / trajectory-cartographer), all pinned to `integrated-cognitive-planner-v1.md` by `file:line` (per "always have reference documentation that the agents can target, otherwise they will hallucinate"). Each returned a brief; main thread folded them into the doc (no agent edited the doc — collision-free). + +**3 doc errors CORRECTED (the reference-doc discipline working — agents bit the doc, not the void):** (1) `cache/convergence.rs` is wired+tested (8 tests), NOT stubbed — only 3 unused imports unwired (seam #5); (2) emit cutover is 5 sites incl. the contract twin `plan.rs:44`, NOT 4 — and the planner has NO mailbox so `KanbanMove.mailbox` must come from `PlanContext` (seam #1); (3) the temporal dep-wall fold is **A-then-B both-required**, NOT A-vs-B (seam #2); plus `documentid`=`dn_hash` NOT `local_key` and the `NiblePath`↔prefix bijection overflows 16-nibble `MAX_DEPTH` → must be tier-structured (§3). + +**EXPANDED:** §2 seam FOLDs rewritten with settle()/5-sites/mailbox (S2), A-then-B/one-`as_of`-field (S4), `RungLevel` constructors + `PlannerContract::rung_for` + entropy→rung bridge (S3), third-crate `lance-graph-cognitive-cycle` vs cycle-as-method (S2/S1). NEW: §2.1 ExecTarget routing (Jit/Elixir/SurrealQl/Native + `can_drive` invariant), §3.1 causal-arc persistence (promote/DemotionSink/unbundle@0.8), §4.1 0-friction strategy↔step table, §8 cross-savant synthesis (T1 cycle-home fork, T2 `&mut`-vs-`&self`, C1 Think-carrier resonance [DEFERRED per #372], C2 rung 1:1, C3 carriers-provisioned-before-consumers, + the 7-item additive new-code ledger). 5 new probes (P-RUNG-FROM-ENTROPY-VARIES, P-RUNG-ROUNDTRIP, P-ARC-PROMOTE-IS-REVISION, P-GRANGER-VERSION-LAG) + 6 new OQs. + +**Next:** 3 brutally-honest hardeners bite §8 first → fold → open #496. Branch `4e3496a`→ (this commit), ValueSchema intact. + +## 2026-06-15 — integrated-cognitive-planner-v1 reference map written (capture-before-dilution; pre 5-savant/3-brutal sweep) + +**Main thread (Opus 4.8 1M).** Operator: *"schreibe alle ideen meticulously mapped before any thing dillutes / then open 5 savents for expansion then harden with 3 brutally honest agents / allways have reference documentation that the agents can target, otherwise they will hallucinate / dann öffne 496."* + *"ohne 495 kannst du schlecht einschätzen was dupliziert wurde"* (keep `ValueSchema`, do NOT reset). + +**Written (this commit):** `.claude/plans/integrated-cognitive-planner-v1.md` — the file:line-grounded reference map the expansion/hardening agents MUST target (so they don't hallucinate). 4-layer P0 architecture (FORGET LADYBUG: thinking-engine>P64>cognitive-shader-driver), §1 grounded current state, §2 the 6 seams with FOLDs, §3 `(hhtl-guid):path:documentid`/`ScopedReference` addressing + Pinpoint/TiKV lessons, §4 the 8-step cognitive cycle → Rubicon phases, §5 measure-first probes, §6 open questions, §7 reference index. Grounded by a prior 5-agent integrated-planner research sweep + a 3-agent Pinpoint/TiKV/addressing sweep. Board hygiene: prepended `INTEGRATION_PLANS.md`. + +**Verdict captured:** the integrated cognitive planner ~90% EXISTS (#437–#492 + unmerged `jolly-cori-clnf9`); remaining = 6 additive seams + addressing + a `CognitiveCycle` sequencer. NOT a new build. Branch held at `4e3496a` (ValueSchema intact). **Next:** 5 savant (expansion) agents → 3 brutally-honest (hardening) agents, both targeting this doc by file:line → incorporate → open #496. + +## 2026-06-14 — `ValueSchema` value-slab presets (Full + Cognitive/Compressed/Bootstrap) — closes the helix-48 dilution gap + +**Main thread.** Operator: *"create different Schema presets, the 'full' is one of the options."* Context: after confirming the SoA-extension ((12+4) edges + turbovec residue + signed) was already locked as `EdgeCodecFlavor` (commit `920671d`) on #489's `EdgeBlock`, **helix-48** was the one element still only a TODO-comment in the `value(480)` slab — the dilution risk the operator flagged. + +**Shipped (contract, additive, build-verified):** `canonical_node::{ValueSchema, ValueTenant, VALUE_TENANTS}` — the value-side analog of `EdgeCodecFlavor`. 9 stable append-only `ValueTenant`s (discriminant == `FieldMask` bit == `VALUE_TENANTS` index) carving the value slab contiguously `[32,186)` (154 of 480 B; reserve-don't-reclaim). Four presets via `FieldMask`: `Bootstrap` (EMPTY default), `Cognitive` (58 B), `Compressed` (98 B), `Full` (154 B = all tenants). `ClassView::value_schema()` defaulted to `Bootstrap` (non-breaking, mirrors `edge_codec_flavor`). Layout-preserving (no stride change, no `ENVELOPE_LAYOUT_VERSION` bump). **helix-48 + turbovec-`Pq32x4` + signed-`CoarseResidue` are now all first-class tenants — the dilution gap is closed.** + +**Reused, not duplicated** (operator's "refactor into what exists"): `class_view::FieldMask` (presence) + `soa_envelope::ColumnDescriptor` (carve) — no new presence type. +6 tests + 3 compile-time canon asserts; `cargo fmt` / `clippy -D warnings` / `test -p lance-graph-contract` all green (611 lib tests). Pushed to #495 (safe fallback intact). `EdgeCodecFlavor` (operator's earlier idea, `920671d`) untouched. + +## 2026-06-14 — Doc-sweep: stale `lance 6.0.0 / lancedb 0.29.0` → canonical `7.0.0 / 0.30.0` across CLAUDE.md + plans + boards + +**Main thread.** Operator: *"it's 7.0.0 + 0.30, please update all plans boards accordingly"* + *"update the .claude/board ledgers epiphany technical debt implemented plans phases etc"*. Swept every stale `lance =6.0.0 / lancedb =0.29.0` reference to the canonical stack the workspace already runs. + +**Canonical stack (locked, this entry is the pointer):** `lance =7.0.0` · `lance-linalg =7.0.0` · `lancedb =0.30.0` · `object_store 0.13.2` · `arrow 58` · `datafusion 53`. The lance family moves in lockstep at `=7.0.0`. Shipped to main by **PR #445** (`claude/jolly-cori-clnf9`); the algebra is in `EPIPHANIES` **E-LANCE7-OBJECTSTORE-SURREALDB** (the 6→7 bump is the *coherence fix* that aligns object_store 0.13 — lancedb 0.29→lance 6→object_store 0.12; lancedb 0.30→lance 7→object_store 0.13.2). + +**D-MBX-11 is SUPERSEDED, not done-as-specced:** main jumped `=6.0.0 → =7.0.0` directly, skipping the planned `=6.0.1` patch (which never existed on the lancedb dep path — lancedb 0.30 is the first release pinning lance =7). Marked Superseded in STATUS_BOARD, D-MBX-COMPLETION-MAP, and the three plans that carried it. + +**Edited (direct — canonical docs + live dashboards + working plans):** `CLAUDE.md` Key Dependencies block; `STATUS_BOARD.md` (D-MBX-11 row → Superseded); `D-MBX-COMPLETION-MAP.md` (DAG line → Superseded); `INTEGRATION_PLANS.md` (dated inline correction); plans `unified-soa-convergence-v1` (stack table + 3 D-MBX-11 refs), `bindspace-singleton-to-mailbox-soa-v1` (stack table + note + deliverable row), `reliability-checklist-arc-v1` (P9 + deferred note), `wikidata-lazy-spine-hydration-v1` (2 Cargo.lock factual refs). + +**Left intact (append-only history — already superseded by the newer E-LANCE7 entry):** `EPIPHANIES.md` 814 (P9-blocked note) + 1531 (E-SOA refinement "6.0.1 pending"); `PR_ARC_INVENTORY.md` (#425 history); `LATEST_STATE.md` #425 PR-row; `unified-soa-convergence-v1-addendum-…-review.md` (already self-corrected to 7.0.0 at author-time); the 2026-05-29 handover. Corrected via this prepend + the inline dated notes above rather than rewriting dated records. + +**`TD-SURREALDB-KVLANCE-LANCE7` stays Open** — the real residual: the `AdaWorldAPI/surrealdb` fork's `kv-lance` feature still pins `lance/lance-index =6.0.0` + `lancedb =0.29.0` (self-contradictory against its own object_store 0.13). Paid by the companion surrealdb-fork bump, not by this sweep. + +**Self-correction banked:** my earlier in-session "lance 6 vs 7 reconcile, lean 6" framing was a rediscovery of an already-settled fact — the workspace was on 7 since #445, recorded in E-LANCE7 + TD-SURREALDB. Reading CLAUDE.md + the board as mandatory (per the operator) short-circuits that tax; the stale CLAUDE.md "Key Dependencies =6.0.0" block (months stale, dated 2026-04-21) was the thing that made the rediscovery easy to fall into — now fixed. + ## 2026-06-14 — Lo design LOCKED: mailbox=delegate, surreal_container=Lo (SurrealQL kanban + Lance-timeline trigger), ractor parked **Main thread (Opus 4.8 1M).** Operator locked the Lo/Tesseract-4th-face architecture across this session's convergence. **Supersedes the earlier "Lo = surrealdb + ractor" framing** (ractor was never the trigger): diff --git a/.claude/board/D-MBX-COMPLETION-MAP.md b/.claude/board/D-MBX-COMPLETION-MAP.md index dc888b2b..00e03197 100644 --- a/.claude/board/D-MBX-COMPLETION-MAP.md +++ b/.claude/board/D-MBX-COMPLETION-MAP.md @@ -18,7 +18,7 @@ │ │ │ FOUNDATIONS (should land EARLY — everything downstream needs them) ───────── D-MBX-10 SoA version byte (MailboxSoAHeader; I-LEGACY-API-FEATURE-GATED) [gates OQ-11.5] - D-MBX-11 lance =6.0.0 -> =6.0.1 bump (mechanical, 5 Cargo.toml) [no gate — DO NOW] + D-MBX-11 lance bump DONE via #445 (=6.0.0 -> =7.0.0, NOT =6.0.1) [SUPERSEDED] │ HOT-PATH SoA EXPRESSIVITY ────────────────────────────────────────────────── D-MBX-A2 close BindSpace gaps (content_ref, S/P/O role slices, fold) [gates OQ-1/OQ-2] diff --git a/.claude/board/IDEAS.md b/.claude/board/IDEAS.md index c64fa88f..5d869181 100644 --- a/.claude/board/IDEAS.md +++ b/.claude/board/IDEAS.md @@ -87,6 +87,24 @@ Agents filter by `@`-mention or domain to see what's theirs. (Prepend new ideas here with today's date. Format:) +## 2026-06-15 — Research synergy: CLAM residue ladder ⋂ knee/hip attractor basins (HHTL cascade in REVERSE, fine→coarse ascent) + +`[P3 @cascade-architect @savant-research domain:codec]` + +**Genesis:** investigating "sync HHT across NodeGuid / bgz-hhtl-d / OGAR" (2026-06-15). The bgz-hhtl-d ↔ NodeGuid **address** sync is **POSTPONED — different domain**: bgz HHT addresses *weight rows* (256-centroid palette), NodeGuid HHT addresses *graph nodes*. Forcing an address-space unification is a frankenstein blur. The live thread is the SHARED substrate underneath both. + +**Grounded observation:** bgz-hhtl-d builds its palette via **CLAM furthest-point sampling** and its HIP families via **farthest-pair recursion (4 levels → 16 groups)** (`bgz-tensor/BGZ_HHTL_D.md:112-116`; `hhtl_d.rs:8-11` Slot D = HEEL 2b / HIP 4b / TWIG 8b). The graph HHTL cascade (HEEL→HIP→TWIG→LEAF, `canonical_node.rs`) is the same clustering shape. So both domains sit on a **CLAM clustering ladder with a residue at each level** — the ndarray CLAM tree (46 tests, build+search+rho_nn) is the common substrate. + +**The idea (operator's, reframed):** forward HHTL is *descent* (coarse→fine routing: heel→hip→twig→leaf). Research whether the CLAM **residue ladder** defines **attractor basins** at the mid-tiers (knee/hip) that support **reverse** traversal — LEAF→TWIG→HIP→HEEL *ascent*, where a fine residue is "attracted" up into a coarser basin (a *settling* dynamic, not a routing one). If real, this is a **domain-AGNOSTIC** cascade synergy (weight rows AND graph nodes, at the CLAM level) WITHOUT the postponed address-space unification — the synergy lives at the substrate, not the key. + +**Synergy candidates to map (research scope):** +- ndarray CLAM tree residue (canonical substrate) ↔ bgz-hhtl-d HIP farthest-pair ladder (same algo, different payload). +- `.claude/knowledge/two-basin-routing.md` (existing attractor-basin doctrine) — does it already describe the reverse-ascent? +- helix-48 golden-spiral residue (the `HelixResidue` value tenant) — is the spiral the residue ladder's geometry? +- Staunen↔Wisdom entropy ladder (`ndarray/src/hpc/entropy_ladder.rs`) — is entropy *descent* the same coordinate as residue *ascent* (high-entropy leaf → low-entropy heel)? + +**Status:** RESEARCH / speculation, **PROBE-GATED** (measure-first). Falsifier before any build, e.g.: *"does a leaf residue's nearest coarser-tier centroid form a stable basin under repeated ascent (fixed point), or does it wander?"* NOT scheduled. The bgz-hhtl-d address lift/lower stays **Deferred (different domain)** — reactivate only if this CLAM-substrate synergy proves out. + ## 2026-05-13 — CORRECTION-OF previous same-day splat row: split into two distinct ideas (arch + render) Earlier this session conflated EWA-Sandwich with a Gaussian-splat anatomical renderer. Per user 2026-05-13 follow-up + source confirmation: EWA-Sandwich is **Pillar 6** of the JC pillars framework — Σ push-forward `M·Σ·Mᵀ` for multi-hop edge propagation in the SPD cone. Already implemented at `crates/jc/src/ewa_sandwich.rs` (450 LOC) + `crates/lance-graph-contract/src/sigma_propagation.rs` (488 LOC) + `crates/jc/examples/osint_edge_traversal.rs` + `crates/jc/examples/splat_perturbationslernen.rs`. Not a new idea — an existing certified pillar. See EPIPHANIES 2026-05-13 CORRECTION-OF entry. diff --git a/.claude/board/INTEGRATION_PLANS.md b/.claude/board/INTEGRATION_PLANS.md index bd8fe084..13827fd5 100644 --- a/.claude/board/INTEGRATION_PLANS.md +++ b/.claude/board/INTEGRATION_PLANS.md @@ -1,3 +1,17 @@ +## 2026-06-15 — integrated-cognitive-planner-v1 (ONE Rubicon/kanban/ractor/thinking-style/AST↔Elixir planner; ~90% EXISTS, 6 additive seams + addressing + cognitive-cycle sequencer) + +**Status:** RESEARCH MAP + REFERENCE DOC (capture-before-dilution; pre-expansion). **Plan file:** `.claude/plans/integrated-cognitive-planner-v1.md`. +**Owns:** the 6 integrated-planner seams + the `(hhtl-guid):path:documentid` / `ScopedReference` addressing model + the 8-step cognitive-cycle sequencer. +- 4-layer P0 architecture (FORGET LADYBUG): SurrealDB (orchestrates META AST/Elixir, never thinks/writes, projects read-view) → `lance-graph-planner::PlannerAwareness` (coordination; emits `KanbanMove(ExecTarget)`, Rubicon DAG) → **thinking-engine > P64 > cognitive-shader-driver** (the cognition: Φ StreamDto → Ψ ResonanceDto → B BusDto) → ractor (`lance-graph-supervisor`) drives `try_advance_phase` → `lance-graph-callcenter` WRITES (outer boundary). temporal-aware via Lance-version-as-of + temporal.rs deinterlace (HLC). +- **§2 the 6 seams** (file:line FOLDs): (1) planner emits no `KanbanMove` [D-MBX-A6-P3]; (2) temporal.rs unconsumed + dep-wall; (3) loop only on jolly (unmerged `463d71bd`); (4) rung inert; (5) think-delegation inverted/lab-only (NOT Ladybug); (6) plan.rs:42 write mis-framing. +- **§3 addressing:** `(hhtl-guid):path:documentid` = `NodeGuid`-prefix : value-tenant : `local_key`; `ScopedReference` = (NiblePath scope, QueryReference as-of) = TiKV-TSO snapshot-handle scoped to a key-range. ADOPT TiKV prefix-route + snapshot-handle + coprocessor-pushdown↔DependsClosure; Pinpoint entity-MID=identity + cross-doc entities=EdgeBlock + content-addressed documentid + as-of-T-first-class. +- **§4 the cognitive cycle:** fanout→consolidate→induction→synthesize→think→deduction→meta-awareness→abduction mapped onto Rubicon phases; a `CognitiveCycle` sequencer (method on the integrated Planner) is the only new code — closes seams #1/#2/#4/#5. +- **§5 probes:** P-DEDUP-ASOF, P-TICKET-SNAPSHOT, P-SCOPE-CLASSIFY, P-RUNG-VARIES (exists), P-CYCLE-SPIRAL. +**Key decisions:** the integrated planner ~90% EXISTS across #437–#492 + unmerged `jolly-cori-clnf9`; remaining work is additive seams, NOT a new build. This doc is THE reference target for the 5-savant expansion + 3-brutal-hardening sweep (agents MUST cite by file:line; un-grounded claims = hypotheses). Rides #496 with #495's `ValueSchema`/`EdgeCodecFlavor`. +**Repos:** lance-graph, branch `claude/wonderful-hawking-lodtql`. Grounded by a 5-agent integrated-planner research sweep + a 3-agent Pinpoint/TiKV/addressing sweep (2026-06-15). + +--- + ## 2026-06-14 — entropy-ladder-spo-rung-v1 (Staunen↔Wisdom entropy coordinate unifies SPO rungs + NARS reliability + edge-codec; R1 shipped, R2–R6 roadmap) **Status:** PLATEAU — R1 (foundation) SHIPPED; R2–R6 planned (probe-gated where marked). **Plan file:** `.claude/plans/entropy-ladder-spo-rung-v1.md`. @@ -124,6 +138,7 @@ **Predecessors:** `bindspace-singleton-to-mailbox-soa-v1` (§11 rulings); `causaledge64-mailbox-rename-soa-v1` (canonical 5-crate + 7-PR plan); `cognitive-substrate-convergence-v1/v2/v3` (Σ10 Rubicon shipped #388). **Council bypass note:** the underlying §11 epiphanies are author-stated (user) — `epiphany-brainstorm-council` (shipped #433) is bypassed for them; the plan's *spec content* IS open to council review via PR. **Workspace stack verified 2026-05-29:** arrow 58 ✓ · datafusion 53 ✓ · lancedb =0.29.0 ✓ · lance =6.0.0 → **=6.0.1** (one patch bump pending, D-MBX-11). +**[2026-06-14 UPDATE — SUPERSEDED]** Stack shipped past the planned `=6.0.1`: main is now **lance/lance-linalg `=7.0.0` · lancedb `=0.30.0` · object_store 0.13.2** (arrow 58 / datafusion 53 unchanged) via PR #445. `D-MBX-11` closed; residual = surrealdb-fork pin (`TD-SURREALDB-KVLANCE-LANCE7`). See `EPIPHANIES` `E-LANCE7-OBJECTSTORE-SURREALDB`. --- ## 2026-05-28 — normalized-entity-holy-grail-v1 (typed unified normalization + Op chain over OGIT/OWL/DOLCE/Odoo with three-context execution — the trunk that unifies BP-1 + EXT-1..6 + jit + MailboxSoA into one consumer surface) diff --git a/.claude/board/LATEST_STATE.md b/.claude/board/LATEST_STATE.md index 273c30eb..3e2f5745 100644 --- a/.claude/board/LATEST_STATE.md +++ b/.claude/board/LATEST_STATE.md @@ -520,5 +520,6 @@ PR sequence: #360 → #361 → post-#360 substrate-sweep (this PR). ### Current Contract Inventory — new entry - **`canonical_node::EdgeCodecFlavor`** (NEW; re-exported from `lib.rs`). Per-class selector for how a node's 16-byte `EdgeBlock` (+ optional value-slab residue) is *interpreted* — `CoarseOnly` (1 B palette index, the canon zero-fallback default), `CoarseResidue` (1 + ⌈D/2⌉ B, value-slab signed-4-bit residue), `Pq32x4` (16 B = 32×4-bit product code, the turbovec PQ model). `bytes_per_vector(dim)` + `is_layout_preserving()` (always `true`). **Iron invariant:** the flavor is interpretation, NOT layout — every variant leaves `NODE_ROW_STRIDE = 512` untouched, so adoption needs no `ENVELOPE_LAYOUT_VERSION` bump (canon "registry-resolved via `classid → ClassView`"). Default `CoarseOnly` matches the all-zero bootstrap. Selection surface: new defaulted `ClassView::edge_codec_flavor(&self, ClassId) -> EdgeCodecFlavor` (non-breaking — `RegistryClassView` inherits the default; per-class override is the follow-up wiring in `lance-graph-ontology`). +3 tests; contract lib 609 green; clippy `-D warnings` clean. +- **`canonical_node::ValueSchema` + `ValueTenant` + `VALUE_TENANTS`** (NEW; re-exported from `lib.rs`). The **value-side analog of `EdgeCodecFlavor`**: per-class presets for which tenants the 480-byte `NodeRow::value` slab materialises. `ValueTenant` = 9 stable append-only positions (discriminant == `FieldMask` bit == `VALUE_TENANTS` index): Meta(`MetaWord`) · Qualia(`QualiaI4_16D`) · MaterializedEdges(4×`CausalEdge64`) · Fingerprint(32 B) · **HelixResidue(48 B)** · **TurbovecResidue(`Pq32x4` 16 B)** · Energy(f32) · Plasticity(u32) · EntityType(u16). `VALUE_TENANTS` = the stable row-relative byte carve `[32,186)` (reserve-don't-reclaim, contiguous, compile-time asserted ≤ 480). Presets: `Bootstrap` (EMPTY, zero-fallback **default**) · `Cognitive` (58 B: hot SoA columns, no codec residues) · `Compressed` (98 B: codec stack + fingerprint, no hot lifecycle) · `Full` (154 B: all 9 tenants). Built on existing `class_view::FieldMask` (presence) + `soa_envelope::ColumnDescriptor` — **no new presence type** (per "refactor into what exists"). `is_layout_preserving()` always `true` (carves WITHIN the reserved slab; `NODE_ROW_STRIDE=512` untouched → no `ENVELOPE_LAYOUT_VERSION` bump). Selection surface: defaulted `ClassView::value_schema(&self, ClassId) -> ValueSchema` (default `Bootstrap`, non-breaking — mirrors `edge_codec_flavor`). **Closes the SoA-extension dilution gap**: the formerly-comment-only helix-48 is now a first-class tenant alongside turbovec-`Pq32x4` + signed-`CoarseResidue`. +6 tests + 3 compile-time canon asserts; contract lib 611 green; clippy `-D warnings` + fmt clean. - **Encode/measure kernels live in `ndarray` (the hardware layer), not the contract:** `ndarray::hpc::edge_codec` (Codebook k-means, `CoarseResidueCodec`, `ProductQuantizer`, `reconstruct_coarse`) + `ndarray::hpc::reliability` (Pearson r, Spearman ρ, Cronbach α, ICC(2,1), `FidelityReport`). Harness `examples/edge_codec_compare` measures all flavors × {blob, continuous} regimes. **Measured:** CoarseResidue dominates agreement (ICC 0.97–0.99, ρ 0.98, α 0.99); Pq32x4 keeps rank (ρ 0.60–0.67) but not absolute distance (ICC 0.11–0.29); CoarseOnly collapses on continuous (ICC 0.003); AMX `matmul_i8_to_i32` assign 100% vs scalar, 24–28 GMAC/s. ndarray commit `d3b608f`. - **Deferred (flagged):** turbovec PQ4 *throughput* path (the FastScan nibble-LUT for the Pq32x4 flavor) blocked on the **#493 P2** build break — `lance-graph-turbovec` requests the `ndarray-simd` turbovec feature that was REMOVED (turbovec commit `7fa217c`); the polyfill fns are gone. turbovec's API is end-to-end (owns encode+scan), so it is a *PQ4 flavor*, not a residue-nibble-scan primitive. Fidelity (what ICC/Pearson/α measure) is independent of the fast kernel, so this is throughput-only follow-up. diff --git a/.claude/board/STATUS_BOARD.md b/.claude/board/STATUS_BOARD.md index 1ecbbcb0..872893db 100644 --- a/.claude/board/STATUS_BOARD.md +++ b/.claude/board/STATUS_BOARD.md @@ -653,7 +653,7 @@ Plan path: `.claude/plans/unified-soa-convergence-v1.md`. Handover `.claude/hand | D-EW64-1 | `episodic_edges::{EpisodicEdges64, EdgeRef}` — AriGraph episodic edges (4x[4b family|12b local]); intra=inherited (~98.6%), cross=4-bit nibble->OGIT-class palette (~1.4%) | lance-graph-contract | 120 | LOW | **Shipped (contract)** | 527 lib tests; clippy clean; SoA columns = D-EW64-2 (CI-gated) | | D-VIEW-1 | `view_angle::ViewAngle` — 4-bit view-schema selector; presence-bitmask-as-attention (inherited) | lance-graph-contract | 40 | LOW | **Shipped (contract)** | 527 lib tests; clippy clean | | D-MBX-10 | SoA version byte at layout root (`MailboxSoAHeader`); refuse v(N>M) bytes on v(M) reader; field-isolation matrix tests on every column op (`I-LEGACY-API-FEATURE-GATED` discipline) | lance-graph-contract | 100 | HIGH | **Queued** | foundation — should land early in P2; gates on OQ-11.5 | -| D-MBX-11 | Lance `=6.0.0 → =6.0.1` patch bump (5 Cargo.toml files identified) | workspace Cargo.toml | 10 | LOW | **Queued (mechanical)** | none — can land in parallel with par-tile prereq | +| D-MBX-11 | Lance bump (5 Cargo.toml) — **OBE: main jumped `=6.0.0 → =7.0.0`, not `=6.0.1`** | workspace Cargo.toml | 10 | LOW | **Abandoned (superseded by #445, 2026-06-14)** | done by PR #445 (lance/lance-linalg `=7.0.0`, lancedb `=0.30.0`, object_store 0.13.2); `=6.0.1` never existed on the lancedb path. Residual: TD-SURREALDB-KVLANCE-LANCE7 (fork still pins 6) | | D-MBX-12 | 8-PR workspace-wide consumer alignment: 12.1 AriGraph · 12.2 Vsa16k audit · 12.4 lance-graph · 12.5 planner · 12.6 shader-driver · 12.7 callcenter · 12.8 ontology audit · 12.9 thinking-styles | per-crate | 800 | per-PR | **Queued (multi-PR)** | sequencing per OQ-11.8: 12.4 → 12.5 → 12.6 → 12.7 → 12.1 → 12.9 → 12.2 → 12.8 | | D-MBX-A6-P1 | contract slice of D-MBX-A6: `kanban::{KanbanColumn, KanbanMove}` + `soa_view::{MailboxSoaView, MailboxSoaOwner}` + `StepDomain::Kanban` — the planner⟷ractor⟷surreal seam, zero-dep, no parallel DTO family | lance-graph-contract | 340 | HIGH | **Shipped** | #437 (merged 9161bd7); + `class_id` N1 hook ride-along | | D-MBX-A6-P2 | Rubicon lifecycle enforcement + exec-target tag: `KanbanColumn::{next_phases, can_transition_to, is_absorbing}` (the lifecycle DAG) + `MailboxSoaOwner::try_advance_phase` (checked, `RubiconTransitionError`) + `ExecTarget{Native,Jit,SurrealQl,Elixir}` on `KanbanMove` | lance-graph-contract | 120 | LOW | **In PR** | builds on P1; 489 lib tests (+4); downstream cargo-check clean; gates the ractor owner-impl + planner emit (P3) | diff --git a/.claude/board/TECH_DEBT.md b/.claude/board/TECH_DEBT.md index 10161a74..573594a1 100644 --- a/.claude/board/TECH_DEBT.md +++ b/.claude/board/TECH_DEBT.md @@ -15,6 +15,22 @@ ## Open Debt +### TD-COARSERESIDUE-NO-VALUE-TENANT — `EdgeCodecFlavor::CoarseResidue` residue has no dedicated value-slab tenant (codex #496, 2026-06-15) + +**Surfaced by** codex P2 on PR #496 (`canonical_node.rs:336`). `EdgeCodecFlavor::CoarseResidue` (`canonical_node.rs:213`) declares its per-dimension signed-4-bit residue is "carried in the reserved value slab" (cost `1 + ⌈D/2⌉`, `bytes_per_vector` :228), but the `ValueTenant` catalogue (`canonical_node.rs:324-343`) has a slot only for `Pq32x4` (`TurbovecResidue = 5`, 16 B at offset 160) — **none for `CoarseResidue`**. So `Full`/`Compressed` presets report all codec tenants present while a class pairing `CoarseResidue` with those schemas has no addressable column for its residue (it would collide with another tenant). + +**Pre-existing, not introduced by #496:** the `EdgeCodecFlavor` enum rode #495 / `920671d` (entropy-ladder D-EL-1); #496 only adds the `ValueSchema`/FULL-default on top. The #495 AGENT_LOG claim that "signed-`CoarseResidue` is a first-class tenant" was aspirational — no such tenant exists in `VALUE_TENANTS`. + +**Pay it by** (operator sign-off REQUIRED per §0 anti-invention guardrail — adding a tenant is "inventing a property"): either (a) mint a `CoarseResidue` `ValueTenant` (append-only, after `EntityType=8`, carving the remaining value slab — needs sign-off), or (b) document that `CoarseResidue` reuses the `TurbovecResidue` slab region (both are "edge residue in the value slab"; the flavor disambiguates the read mode) — zero new tenant, the guardrail-preferred path. Decide before any class actually selects `CoarseResidue` with a dense preset. Cross-ref: `EdgeCodecFlavor` (920671d), entropy-ladder-spo-rung-v1 D-EL-1. + +### TD-VALUESCHEMA-FULL-POC-DEFAULT — `ClassView::value_schema` blanket default flipped Bootstrap→Full for the consumer-POC phase (2026-06-15) + +**Surfaced by** operator decision (a): *"flip the blanket default to Full (all unconfigured classes → Full) / any consumer that needs to save memory can create [its] smaller settings / any consumer that needs more data and more efficiency can afford a separate class."* Enables the downstream consumers (tesseract-rs / woa-rs / medcare-rs / q2) to transcode against a fully-materialised `NodeRow` while the POC is built. + +**The debt:** `ClassView::value_schema` (`class_view.rs:233`) returns `ValueSchema::Full` instead of the canon zero-fallback `ValueSchema::Bootstrap`. This INVERTS the zero-fallback ladder for the value-slab *resolution* (specialisation is now opt-IN: mint a class to go smaller/denser). It is layout-preserving (no `NODE_ROW_STRIDE` / `ENVELOPE_LAYOUT_VERSION` change — Full carves within the reserved 480 B) and a one-line revert. The TYPE-level `ValueSchema::default()` stays `Bootstrap`, so the substrate zero-fallback semantics are intact — only the class→schema resolution default flipped. **No invention** (honours the operator's anti-skew guardrail): `Full` activates the already-existing, already-tested 9 `ValueTenant`s; it adds no new property. + +**Pay it by:** reverting `class_view.rs:233` to `ValueSchema::Bootstrap` once the consumer POCs settle on their real per-class presets, AND flipping the guard test `value_schema_default_is_full_temporary_poc` (`class_view.rs`) back to assert Bootstrap. The edge-codec axis (`edge_codec_flavor` → `CoarseOnly`) is a separate knob, untouched; flip it to a residue/PQ flavor only if a consumer POC needs full edge fidelity too. Tests: 613 lib green. + ### TD-NDARRAY-SIMD-POPCNT-NATIVE — `extract_rules` SIGILLs under `-C target-cpu=native` on larger RowMasks (2026-06-14) **Surfaced by** the `invariance_witness_probe` (lance-graph-arm-discovery, `--features ndarray-simd`). diff --git a/.claude/plans/bindspace-singleton-to-mailbox-soa-v1.md b/.claude/plans/bindspace-singleton-to-mailbox-soa-v1.md index c42447d7..9b42bd94 100644 --- a/.claude/plans/bindspace-singleton-to-mailbox-soa-v1.md +++ b/.claude/plans/bindspace-singleton-to-mailbox-soa-v1.md @@ -545,11 +545,11 @@ For the §2.7 transparent SurrealDB view to be a literal zero-copy view (not an |---|---|---| | Arrow | `arrow = "58"` | `arrow = "58"` (compatible) | | DataFusion | `datafusion = "53"` | **`datafusion = "53"`** ✓ already on target | -| Lance | `lance = "=6.0.0"` | **`lance = "=6.0.1"`** (patch bump) | -| LanceDB | `lancedb = "=0.29.0"` | **`lancedb = "=0.29.0"`** ✓ already on target | -| `surrealdb` (kv-lance fork) | commented out (`BLOCKED(C)`) | unblock against Lance 6.0.1 + the SoA version gate | +| Lance | `lance = "=7.0.0"` | **`lance = "=7.0.0"`** ✓ SHIPPED #445 (jumped past `=6.0.1`) | +| LanceDB | `lancedb = "=0.30.0"` | **`lancedb = "=0.30.0"`** ✓ SHIPPED #445 (was `=0.29.0` at author-time) | +| `surrealdb` (kv-lance fork) | commented out (`BLOCKED(C)`) | unblock against Lance **7.0.0** + the SoA version gate (fork still pins `=6.0.0` → `TD-SURREALDB-KVLANCE-LANCE7`) | -**One bump pending:** `lance =6.0.0 → =6.0.1` (patch). All other pins already align. Deliverable `D-MBX-11`. +**[2026-06-14 SUPERSEDED]** No bump pending — main shipped `lance =6.0.0 → =7.0.0` + `lancedb =0.29.0 → =0.30.0` (PR #445), past the planned `=6.0.1`. `D-MBX-11` is closed by #445; residual = surrealdb-fork pin (`TD-SURREALDB-KVLANCE-LANCE7`). #### §11.6.4 — `lance-graph-planner` DTO surface overhaul @@ -561,7 +561,7 @@ The kanban/ractor lifecycle (§11.3 — Planning / Cognitive work / Evaluation o |---|---|---|---| | **D-MBX-A6** | `lance-graph-planner` DTO surface overhaul: planner DTOs re-expressed as operations on the SoA + 4-phase kanban transitions | lance-graph-planner | **Queued** | | **D-MBX-10** | SoA version byte at layout root + field-isolation matrix tests for every column addition/widening (`I-LEGACY-API-FEATURE-GATED` discipline) | contract + cognitive-shader-driver | **Queued** | -| **D-MBX-11** | Lance 6.0.0 → 6.0.1 patch bump across the workspace (single-line bump in each Cargo.toml; verifies the SurrealDB transparent-view stack pin) | workspace Cargo.toml | **Queued (mechanical)** | +| **D-MBX-11** | ~~Lance 6.0.0 → 6.0.1 patch bump~~ → **shipped as `=6.0.0 → =7.0.0` / lancedb `=0.30.0`** (PR #445; verifies the SurrealDB transparent-view stack pin) | workspace Cargo.toml | **Superseded (#445, 2026-06-14)** | | **D-MBX-12** | Each of the nine half-baked consumers (§11.6.1) audited and re-aligned to consume THE SoA — one PR per consumer | per-crate | **Queued (multi-PR sequence)** | ### Open questions added in §11.6 diff --git a/.claude/plans/integrated-cognitive-planner-v1.md b/.claude/plans/integrated-cognitive-planner-v1.md new file mode 100644 index 00000000..3c5c7e34 --- /dev/null +++ b/.claude/plans/integrated-cognitive-planner-v1.md @@ -0,0 +1,301 @@ +# Integrated Cognitive Planner — meticulous reference map (v1, 2026-06-15) + +## READ BY / AGENT TARGET (mandatory) + +This is THE reference doc for the integrated-cognitive-planner arc. Any savant +(expansion) or brutally-honest (hardening) agent **MUST cite this map by +`file:line`** and may not assert architecture not grounded here — if a claim +isn't in §1/§7, it's a hypothesis, not a fact. Grounded by a 5-agent research +sweep (2026-06-15, integrated-planner axes) + a 3-agent external-pattern sweep +(Google Pinpoint / TiKV / addressing). Capture-before-dilution of a long design +session (post-#495 merge; #495's `ValueSchema`/`EdgeCodecFlavor` ride #496). + +**Verdict of the research:** ~90% of the substrate EXISTS across #437–#492 + +the unmerged `jolly-cori-clnf9`. The remaining work is **6 small additive +seams + the addressing/ScopedReference + the cognitive-cycle sequencer** — NOT +a new build. The recurring failure mode this doc prevents: re-deriving what +already ships. + +**Expansion pass (2026-06-15):** 5 savants deepened §1–§7 (each `file:line`-grounded) +and CORRECTED three doc errors — see §8 (cross-savant synthesis + the 2 tensions +T1/T2 + the 7-item additive new-code ledger), §2.1 (ExecTarget routing), §3.1 +(causal-arc persistence), §4.1 (0-friction strategy↔step table). Corrections folded +inline: `cache/convergence.rs` is wired+tested NOT stubbed (seam #5); emit cutover is +5 sites incl. the contract twin (seam #1); the dep-wall fold is A-then-B NOT either/or +(seam #2); `documentid`=`dn_hash` NOT `local_key` (§3); the `NiblePath`↔prefix bijection +overflows 16-nibble `MAX_DEPTH` and must be tier-structured (§3). + +**Hardening pass (2026-06-15):** 3 brutally-honest agents (PP-13 HOLD / PP-15 CATCH-LATENT +/ PP-16 READY-TO-DISPATCH) — verdicts + 5 LOCKED decisions + the latent boundary fixes are +in **§9**, and the operator's anti-invention guardrail is now **§0 (READ FIRST)**. Net: the +plan is dispatch-ready once §9's spec-text fixes land in the §8 ledger; no architectural +rewrite. Biggest catches: emit channels are separate-not-derived; `cycle()` must stay inherent +(object-safety); seam #2's read is closure-injected (planner can't reach async `at_version`); +the DUAL `RungLevel` must not be re-derived; "#495 rides #496" is mis-attributed (branch-only). + +--- + +## §0 — ANTI-INVENTION GUARDRAIL (operator-locked 2026-06-15, READ FIRST) + +**No agent invents new skewed SoA properties. We already have good, well-tested ideas; transcodes map ONTO them, never extend them.** For any work targeting this plan: +- The value slab is the **9 `ValueTenant`s** (`canonical_node.rs`); the node is **`key|edges|value`** (512 B, locked CANON); the **four BindSpace columns** (FingerprintColumns / QualiaColumn / MetaColumn / EdgeColumn) are **closed**. New capability lands as a **new column / new class**, never a new layer / struct / skewed field (AGI-as-SoA PR #223; RESERVE-don't-reclaim CANON). +- Before reaching for any new carrier, apply I-VSA-IDENTITIES **Test-0 (register laziness):** if the thing has a name / enum / id, use the register (HashMap / enum / class) — NOT a fancy property. +- The **§8 7-item additive ledger is the MAX scope.** Anything beyond it — a new tenant, a new column, a new struct, a "skewed" field — requires explicit operator sign-off. An agent that wants one **STOPS and surfaces it**, it does not implement it. +- Specialisation is **opt-IN** (`TD-VALUESCHEMA-FULL-POC-DEFAULT`: the POC FULL default): a consumer mints a class to go smaller/denser; it never adds a property to the shared slab. +- Enforced by `dto-soa-savant` + `iron-rule-savant` (epiphany council) and the 3 pre-merge hardeners (§9). PP-16's top catch — "don't duplicate `should_elevate`, it already ships in thinking-engine" — is this guardrail in action. + +--- + +## P0 — The architecture (4 layers). FORGET LADYBUG. + +``` + SurrealDB (BUILDING BLOCK — orchestrates the META AST/Elixir level; GOOD at it) + │ returns the AST via the contract → ExecTarget::{SurrealQl, Elixir} + │ NEVER thinks, NEVER writes. PROJECTS a read-view (kanban time-series). + ▼ + lance-graph-planner :: PlannerAwareness = the SHARED COORDINATION contract + │ orchestrate → ThinkingContext (style / rung / ExecTarget) + │ emits Vec(ExecTarget); rubicon-DAG lifecycle + │ DELEGATES the thinking ▼ (it COORDINATES; it does not think) + ▼ + thinking-engine → P64 → cognitive-shader-driver = THE COGNITION + │ Φ StreamDto → Ψ ResonanceDto → B BusDto (thinking-engine/src/dto.rs) + │ via p64-bridge convergence; driver.rs:581 dispatch + engine_bridge.rs:29 + │ ⚠ NOT `StepDomain::Ladybug` — that is legacy ladybug-rs (forget it; + │ only residue is in lance-graph-cognitive, minimal impact). + ▼ + ractor (lance-graph-supervisor) DRIVES the KanbanMove lifecycle + │ MailboxSoaOwner::try_advance_phase (Planning→CognitiveWork→Evaluation→…) + ▼ on Commit + lance-graph-callcenter WRITES = the OUTER BOUNDARY + lance_membrane.rs:315 commit_event → audit_sink/lance_sink.rs:292 (RocksDB/kvs-lance/ORM) + SurrealDB PROJECTS the kanban columns read-only. + + temporal-aware throughout: Lance-version read-as-of + temporal.rs deinterlace (HLC). +``` + +--- + +## §1 — GROUNDED CURRENT STATE (what EXISTS, `file:line`) + +**Planner core** +- `lance-graph-planner/src/lib.rs:99` `PlannerAwareness { strategies, selector }`; entry points `plan_full` (:171), `plan_auto` (:264); impls `OrchestrationBridge` (`orchestration_impl.rs`). +- 16 strategies (lib.rs:21 table), `selector.rs`, `compose.rs`, `pipeline.rs` (DAG), `cache/` (autocomplete), `ir/` (Polars-arena `LogicalPlan`, `ir/mod.rs:92`). +- `strategy/style_strategy.rs` (Strategy #18, **D-MBX-A6-P3a**): `reliability_of` (:168) over recipe kernels; `plan()` (:138) is a deliberate **pure pass-through — emits NO KanbanMove** (:144-151, "faking one here would be theatre"). +- `PlanResult.emitted_edges: Vec` (lib.rs:123) — **always `Vec::new()`** at every construction site (:216/254/312 + api.rs). + +**Temporal (the deinterlace = "klares zeitliches Bewusstsein")** +- `lance-graph-planner/src/temporal.rs` — 4-frame deinterlace (lance-version / surrealql `knowable_from` / ractor `V_ref` / cognitive trajectory) via HLC: `EpistemicMode{Strict,Aware,Retro}`+`for_rung` (:63-87), `TemporalStatus` (:90), `QueryReference{server_id,ref_version,hlc_tick,mode,rung}`+`::at` (:107-138), `classify` (:147), `DependsClosure`/`classify_ready`/`NoDeps` (:218-269), `deinterlace` (:301). Tested; **ZERO non-test callers** (only `temporal.rs` + lib.rs doc reference it). +- Lance read-as-of lives on the OTHER side of a dep wall: `lance-graph/src/graph/versioned.rs:419` `VersionedGraph::at_version → checkout_version` (real, tested). Planner deps `contract` NOT `lance-graph` core (anti-circular) → cannot reach it. +- Granger is a SEPARATE module: `lance-graph-cognitive/src/search/temporal.rs::granger_effect`. +- `prediction/{mod,scenario,temporal,ingestion}.rs` = simulated-time NARS rounds (abstract, not Lance versions). + +**Kanban / ExecTarget (contract, #437 A6-P1 + #439 A6-P2, both merged)** +- `lance-graph-contract/src/kanban.rs:32` `KanbanColumn` Rubicon DAG (`next_phases`/`can_transition_to`/`is_absorbing`); `:112` `KanbanMove{mailbox,from,to,witness_chain_position,libet_offset_us,exec}` (`Copy`, ≤16 B); `:136` `ExecTarget{Native,Jit,SurrealQl,Elixir}`. +- `soa_view.rs:112` `MailboxSoaOwner::try_advance_phase` → `KanbanMove` | `RubiconTransitionError`. +- `scheduler.rs:46` `NextPhaseScheduler::on_version`; concrete `LanceVersionScheduler` deferred (scheduler.rs:20). + +**Escalation / NARS / MUL (the cycle primitives)** +- `escalation.rs`: `CollapseHint{Flow,Fanout,RungElevate}` (:45), `fanout_width` (:59), `rung_delta(emergence,coherence)` (:75), `InnerCouncil::deliberate` (:144, 3 archetypes + split-amplify), `EpiphanyDetector::observe` (:241, surprise>baseline×1.5 ∧ window≥4), `GhostEcho{…,Staunen,Wisdom,…}` (:289), `WisdomMarker` (:312, decays to FLOOR 0.1). **Consumed** by `planner::mul::escalation`. +- `nars::InferenceType{Deduction,Induction,Abduction,Revision,Synthesis}`; carried on `ThinkingContext.inference_type` (plan.rs:19). +- `mul/` `MulAssessment` (Dunning-Kruger / trust / compass / homeostasis). +- `cognitive_shader.rs:157` `RungLevel(0..9)`; `ThinkingContext.rung` (plan.rs:22). + +**Cognition pipeline (thinking-engine > P64 > shader-driver)** +- `thinking-engine/src/dto.rs`: Φ `StreamDto` (:40), Ψ `ResonanceDto` (:59), B `BusDto` (:120). (ResonanceDto rename in progress — `TD-RESONANCEDTO-DUP-1`.) +- `p64-bridge/src/lib.rs` convergence (CausalEdge64/palette). +- `cognitive-shader-driver/src/driver.rs:581` `CognitiveShaderDriver::dispatch`; `engine_bridge.rs:29` wires thinking-engine ↔ ShaderBus; deps planner (lab) + p64-bridge + (opt) thinking-engine. + +**The loop (jolly-cori-clnf9 ONLY — unmerged)** +- `cognitive-shader-driver/src/mailbox_soa.rs:349/397` `impl MailboxSoaView + MailboxSoaOwner for MailboxSoA` + driving test `:648` (`463d71bd`, +149 LOC). On main/this branch `MailboxSoA` has **no owner impl** → loop can't run in-tree. + +**Surreal + callcenter write** +- Contract correctly declares surreal=project-read-only, callcenter=commit (kanban.rs:1-21). +- `lance-graph-callcenter/src/lance_membrane.rs:315` `commit_event` (sole writer, version tick) → `audit_sink/lance_sink.rs:292` real Lance `InsertBuilder…Append`. +- `surreal_container` ~all stub, BLOCKED on lance-7 fork (`TD-SURREALDB-KVLANCE-LANCE7`). + +**Canonical node + addressing (contract; #489/#490 + #495-mine)** +- `canonical_node.rs:35` `NodeGuid` = `classid(u32)|HEEL(u16)|HIP(u16)|TWIG(u16)|family(u24)|identity(u24)`; `local_key()` (:106) = trailing 6 B; zero-fallback ladder. `EdgeBlock` (:181) 12+4. `EdgeCodecFlavor` (:207, #495-mine). `ValueSchema`/`ValueTenant`/`VALUE_TENANTS` (#495-mine — unmerged, rides #496). +- `hhtl.rs` `NiblePath` radix walk (`child`, `is_ancestor_of`). + +--- + +## §2 — THE 6 SEAMS (gap → tracking → FOLD `file:line`) + +1. **Planner emits `KanbanMove`** — gap: `emitted_edges` always empty; planner imports none of `kanban`/`soa_view`. Tracking: **D-MBX-A6-P3**. FOLD (S2): the inputs ALREADY exist — `StyleStrategy::reliability_of` (style_strategy.rs:168) already computes the settled `ThoughtCtx` but discards all but `confidence` (:178); refactor to `settle() → ThoughtCtx` keeping `dissonance` (recipe_kernels.rs:31) + `rung` (:37). Adapter `thoughtctx_to_kanban_move` (planner-side, pure): `exec` per §2.1; `to` from `tc.gate_state()` (recipe_kernels.rs:58, expose it) vs `KanbanColumn::can_transition_to`; `libet_offset_us=-550_000` iff `to==CognitiveWork`; `witness_chain_position=0` (no arc yet). **Cutover = 5 sites, NOT 4: lib.rs:123/216/254/312 + api.rs:190 + the CONTRACT TWIN plan.rs:44** (skipping it diverges the `PlannerContract` trait). Add `emitted_moves: Vec` beside `emitted_edges` as a **SEPARATE channel, NOT derived** (PP-13/PP-15 §9: `emitted_edges` keeps carrying CausalEdge64/EpisodicEdges64 words from the collapse-gate path; there is NO `KanbanMove→u64` cast — inventing one is the I-LEGACY trap) → resolves OQ-11.7. **Missing input: `KanbanMove.mailbox` (kanban.rs:114) — the planner has NO mailbox; add `mailbox: Option` to `PlanContext` (traits.rs:69), caller-supplied, sentinel default.** +2. **temporal.rs unconsumed + dep-wall** — gap: `deinterlace`/`QueryReference` 0 callers; planner ⊥ lance-core. FOLD (S4 — two layers, BOTH required, ordered, NOT either/or): **(A)** relocate the *policy* `temporal.rs` → zero-dep `contract::temporal` (`classify`/`deinterlace`/`EpistemicMode` name no lance/arrow/async; `DeinterlaceRow` is the airgap, mirroring scheduler.rs:31's `MailboxSoaView`) so BOTH planner+core `use contract::temporal::*`; **(B)** add `lance-graph/src/graph/temporal_read.rs` — the ONLY site joining `VersionedGraph::at_version(T)` (versioned.rs:419) → `deinterlace` (temporal.rs:301), in core where both are nameable. A-alone never feeds real rows to `deinterlace`; B-alone can't share `classify` with planner. Add ONE field `as_of: QueryReference` to `PlanContext` (traits.rs:69) — NOT two loose `ref_version`/`rung` (rung lives inside `QueryReference`, temporal.rs:121, drives `mode` via `for_rung`). +3. **Loop only on jolly** — gap: `MailboxSoaOwner for MailboxSoA` is +149 LOC on `463d71bd`, unmerged. FOLD: cherry-pick `mailbox_soa.rs:349-460` + test `:648` (purely additive, traits already on main). +4. **Rung inert** — gap: `RungLevel::Surface` hardcoded (orchestration_impl.rs:151, api.rs:178, pipeline.rs:593(test fixture — leave), thinking/mod.rs:86); `rung_delta` imported never called; Staunen/Wisdom orphaned. **Root cause (S3): `RungLevel` has NO constructor** — no `from_ordinal`/`shift`/`from_entropy` (cognitive_shader.rs:157 is a bare enum), so every site CAN'T do anything but default `Surface`. FOLD (S3): (1) add `RungLevel::{from_ordinal, shift(i8), from_entropy(f32)}` after cognitive_shader.rs:169 + a `PlannerContract::rung_for(&self,&SituationInput)->RungLevel` trait method (default Surface, mirrors `gate_check`, so the contract itself KNOWS the rung). (2) bridge the 3-level `EntropyRung` (ndarray entropy_ladder.rs:64) ↔ 10-level `RungLevel` via `from_entropy(h)=from_ordinal(round((1−h)·9))` — bare `f32`, NO ndarray type crosses the wall (scalar `h` is the wire, like seam #2's `QueryReference`). (3) drive the 2 PRODUCTION sites (thinking/mod.rs:86 has `mul` in scope; orchestration_impl.rs:151): `rung = from_entropy(nars_entropy(f,c)).shift(rung_delta(emergence,coherence))`; rises on sustained `mul::GateDecision::Block`; floored by a live `WisdomMarker` (fresh Epiphany→low rung, decayed→high). (4) bind `ShaderDispatch.rung = think_ctx.rung` (was Surface default, cognitive_shader.rs:219). NB the two `GateDecision` types: planner-contract driver = `mul::GateDecision::Block` (mul.rs:150); `collapse_gate::BLOCK` (collapse_gate.rs:79) is the shader-side echo. +5. **Think-delegation (thinking-engine>P64>shader-driver, NOT Ladybug)** — gap: planner doesn't call shader-driver; driver→planner is lab-only (`planner_bridge.rs`). **Correction (S2): `cache/convergence.rs` is NOT stubbed — it is wired + tested (8 tests, :363-436); only the `#[allow(unused_imports)]` for CausalEdge64/SpoBase17/DistanceMatrix (:22-27) is unwired** (the triplet→palette path works). Carrier ALREADY aligned 1:1: `ThinkingContext.rung` (plan.rs:22) ↔ `ShaderDispatch.rung` (cognitive_shader.rs:190) same `RungLevel`; only new code = a field-copy builder mirroring `dispatch_from_top_k` (engine_bridge.rs:93). FOLD (S2): bridge home = a NEW third crate **`lance-graph-cognitive-cycle`** {planner, shader-driver, p64-bridge} — confirmed by BOTH Cargo.tomls that planner ⊥ shader-driver (planner has no driver dep; driver deps planner only as optional `with-planner`). Route `ThinkingContext → ShaderDispatch(rung) → CognitiveShaderDriver::dispatch (driver.rs:581) → ShaderBus.emitted_edges[..count] (cognitive_shader.rs:353) → PlanResult.emitted_moves`. **Never `StepDomain::Ladybug`.** (TENSION with S1's "cycle is a method ON PlannerAwareness" — see §8.) +6. **Write mis-framing (doc)** — gap: `plan.rs:42-44` "the vart/surreal seam persists". FOLD (zero-code): → "callcenter (`commit_event` → `LanceAuditSink`) calcifies; surreal projects read-only." Hardenable further (S2 OQ-11.8): a `const fn ExecTarget::can_drive(self, to:KanbanColumn)->bool` makes "Surreal never writes/thinks" a COMPILE-checked invariant (bars `SurrealQl`+`Commit`/`CognitiveWork`), extending the `MailboxSoaView`/`Owner` split from SoA-access up to plan-routing. + +--- + +## §2.1 — ExecTarget routing (AST ↔ Elixir ↔ SurrealQl ↔ Native) — S2 + +The operator's law: **Surreal RETURNS the AST via the contract; the planner ROUTES `ExecTarget` (kanban.rs:136); callcenter `commit_event` (lance_membrane.rs:315, sole version-ticking writer, the Rubicon `CommitHook` seam :301) WRITES via Lance. Thinking + writing NEVER through Surreal.** Decision rules, in the §2-seam-1 adapter reading the settled `ThoughtCtx`: + +- **`Jit`** — style `tau()` resolvable (style_strategy.rs:15: `τ → JitTemplate → KernelHandle`) + high `tc.confidence` + low `tc.dissonance`. The kernel hot path. +- **`Elixir`** — the interpreted `recipe_kernels` layer (style_strategy.rs:21); the deliberative DEFAULT for a thinking step not JIT-warmed (cold, or high `tc.dissonance` needing interpreted tactics). +- **`SurrealQl`** — a pure read-projection over the kanban SoA columns ONLY (kanban.rs:143 "lowered to SurrealQL and run in the substrate"). **Structurally barred from mutation:** `surreal_container` implements `MailboxSoaView` (soa_view.rs:11) NOT `MailboxSoaOwner` (:107-112) — it can never drive a `Commit`. A thinking/writing step that picked `SurrealQl` would be a category error the trait system already forbids — this is seam #6 made concrete. +- **`Native`** (default, kanban.rs:138) — in-process graph traversal. + +**The AST flow mapped:** Surreal RETURNS the AST → through the contract surface `OrchestrationBridge::route` (orchestration_impl.rs:47) consuming a `UnifiedStep`; planner ROUTES → `ExecTarget` selection (the four rules); callcenter WRITES → `LanceMembrane::commit_event` (lance_membrane.rs:315) on `KanbanColumn::Commit` (the absorbing terminal). Lance writes its own bytes (audit_sink/lance_sink.rs:292); Surreal is nowhere in this write path. + +**`BusDto` is the accountable delegation packet** (thinking-engine/src/dto.rs:120, "the first accountable structured thought"): peak `energy` (support) + `top_k` (spread/dark-horse) + `ShaderBus.gate` (cognitive_shader.rs:356) + `tc.dissonance` are SEPARATE channels — support ≠ contradiction in one scalar. Indices, never strings (text is LAZY at Γ `ThoughtStruct`, dto.rs:132). Round-trip proven by `dispatch_busdto`/`unbind_busdto` (engine_bridge.rs:231/310). The planner→driver delegation returns the `BusDto` + `emitted_edges[..count]`; no prose crosses the seam. + +--- + +## §3 — ADDRESSING: `identity / ScopedReference / (hhtl-guid):path:documentid` + +Resolves left→right, mirroring `NodeGuid`: +``` +(hhtl-guid) : path : documentid +classid|HEEL|HIP|TWIG : VALUE_TENANTS offset : dn_hash (content) ⇒ leaf local_key += routing prefix (radix) : intra-row value-slab path : dedup key, resolves the entity-MID +↔ TiKV Region-prefix / Pinpoint collection ↔ Pinpoint document-id (content-addressed) +``` + +**Three DISTINCT hashes — the doc previously conflated two (S5 correction):** +- **identity / local_key** = the *arc anchor*: `local_key()` (canonical_node.rs:106) = trailing 6 bytes (family ++ identity), a MINTED stable address (uniqueness-guarded, canonical_node.rs:139), **never a content hash**. Survives every revision — Pinpoint's alias→Knowledge-Graph-MID collapse (one stable id per entity; surface forms resolve to it). This is the entity-MID. +- **documentid** = the *dedup key*, a DISTINCT object from the leaf: the live `dn_hash(canonical_dn(triplet)) → u64` (fingerprint.rs:65, used at spo_bridge.rs:127). Same content → same key = Pinpoint dedup, **ALREADY shipped** (not an unbuilt ADOPT). The address resolves a row by `local_key`; dedup happens via `dn_hash` at ingest. Complementary, not the same field. (If you content-hashed the identity, every revision would mint a new address and shatter the arc — the anti-pattern.) +- **shape_hash** = a THIRD hash, `StructuralSignature(u32)` (class_signature.rs:31, FNV-1a over field/method structure) — the shape-family / ground-truth-drift key. Canon dropped it from the GUID (identity errata 2026-06-13) but drift-detection carries it ALONGSIDE the address, never inside it. + +**Bijection width constraint (the real P-SCOPE-CLASSIFY blocker, S5):** the prefix `classid|HEEL|HIP|TWIG` is bytes 0..10 of `NodeGuid` = 10 bytes = **20 nibbles**, but `NiblePath` (hhtl.rs:55) holds only `MAX_DEPTH = 16` nibbles in its `u64` (hhtl.rs:45). A flat byte→2-nibble lowering OVERFLOWS the path word. The bijection MUST be tier-structured, and the tier widths are **struct-defined fixed, NOT cache-allocated** (CodeRabbit #496 correction): HEEL/HIP/TWIG are `u16` fields = 4 nibbles each (classid 8 + 4+4+4 = 20 nibbles — the overflow), fixed by layout. The DOLCE basin (hhtl.rs:18-23) is a **static canonical enum ordering** (ENDURANT=0, PERDURANT=1, QUALITY=2, ABSTRACT=3; 0x4–0xF reserved), collision-free by design — **not a dynamic cache**. So `from_guid_prefix` must deterministically **subset** the 20 nibbles into ≤16 (a fixed layout decision — e.g. fold/drop the high classid nibbles), never *allocate* widths. Proposed `NiblePath::from_guid_prefix(&NodeGuid) -> Option` next to `from_packed` (hhtl.rs:199), `None` when depth exceeds `MAX_DEPTH`. `is_ancestor_of` (hhtl.rs:176) is a base-16 prefix-equality test = TiKV `[start,end)` range-containment (reflexive ⇒ closed-start; empty path = "no region assigned" sentinel). Proven by `is_ancestor_of_is_cheap_prefix_reachability` (hhtl.rs:387). + +- **ScopedReference** (the genuinely NEW piece; "ticket" — but **NOT** named `ticket`: collides with `grammar::ticket::FailureTicket`) = `(NiblePath scope, QueryReference as-of)` = a TiKV-TSO snapshot-handle scoped to a key-range = "this subtree, as-of Lance version T". `QueryReference::at(ref_version,rung)` is already the as-of half. **Retrieval shape (additive, S5):** `admits(row,path,knowable,deps) = scope.is_ancestor_of(path) (hhtl.rs:176, range-containment) && classify_ready(...).dispatchable(mode) (temporal.rs:258/249)`; `retrieve_arc(rows,deps) = deinterlace (temporal.rs:301, TIME∧DATA filter + HLC sort) with the is_ancestor_of pre-filter`. A METHOD on the carrier (Click litmus: accept). **Snapshot-isolation (P-TICKET-SNAPSHOT) is FREE not built (S4):** two reads at the same `Copy` handle call `at_version(ref_version)` (versioned.rs:419); Lance versions are immutable → byte-identical batches regardless of concurrent head ticks. The handle pins the version; the version pins the bytes; Lance's versioning IS the MVCC. +- **Bardioc's** "which export-restriction at data-window T" = `deinterlace(rows, QueryReference::at(T,rung), deps)` (temporal.rs:301) → rows Contemporary-at-T. **But the marking carrier is MISSING (S4, highest-value gap):** `Marking{Public,Internal,Pii,Financial,Restricted}` exists (property.rs:771) but is schema-level/static (`&'static`, `const fn with_marking`) — NO version axis, so it cannot answer "which held at T"; `CognitiveEventRow` (external_intent.rs:113) carries no marking. **Minimal additive seam:** emit a versioned `MarkingRow{predicate, Marking, knowable_from: LanceVersion}` into the SPO store on each classification change; `impl DeinterlaceRow for MarkingRow` → `deinterlace` returns the marking `Contemporary` at T. `Marking` + `DeinterlaceRow`, both exist, joined with zero new machinery. Route: **read-as-of, NEVER counterfactual** (Bardioc asks "what *was*", not "what *would be*" — the latter = `counterfactual.rs`, the wrong surface for audit). + +**ADOPT** — TiKV: prefix-routes-to-placement (`NiblePath::is_ancestor_of` = range-containment); snapshot-as-handle (never implicit "latest"); coprocessor pushdown ↔ `DependsClosure`/`deinterlace` filter-at-source; a **batched monotonic ticket-oracle = TSO over Lance versions** (but keep our decentralized HLC `Option`, no central oracle). Pinpoint: entity-MID = `identity`; cross-doc entities = `EdgeBlock`/`MaterializedEdges` (entities are EDGES between leaves, not a sidecar index); content-addressed `documentid` (free dedup) — **already implemented as `dn_hash` (spo_bridge.rs:127); the seam is wiring it into the `NodeGuid` address, not building it**; as-of-T first-class from day one (their post-2023-08-01 date-epoch trap = our `I-LEGACY-API` violation to avoid). +**DON'T** — Pinpoint filename-as-id / no-dedup / no-versioning; TiKV central TSO bottleneck. + +### §3.1 — Causal-arc persistence (the revision-aware memory mechanism, S5) + +A causal arc = stable anchor + append-only adjacency. **Anchor:** `local_key` (canonical_node.rs:106), bytes 13..16 never move (RESERVE-don't-reclaim, canonical_node.rs:16). **Adjacency:** `EpisodicEdges64` (episodic_edges.rs:103), 4 MRU slots, slot 0 = hottest. A revision is `promote(e)` (episodic_edges.rs:168): re-rank, never overwrite; the coldest (`coldest()`, :227) demotes via `DemotionSink::demote` (:311) to the cold connectome — NOT deleted. **Recency = slot index; causality = demoted history + co-addressed `CausalEdge64` plasticity** (:163) — separate channels (resolves the recency≠causality anti-pattern). **Stabilization:** an `Episode` (episodic.rs:43) unbundles into individually-addressable facts only at `truth.confidence ≥ UNBUNDLE_HARDNESS_THRESHOLD = 0.8` (episodic.rs:166); `rebundle_cold` (:273) retires per-triplet addressability for aged low-confidence episodes but keeps them fingerprint-searchable. Visible-after-revision: the fingerprint bundle always; per-triplet facts only while hot + confident ≥ 0.8. **As-of replay makes revision non-destructive:** versions are append-only; `ScopedReference(scope, QueryReference::at(T))` reconstructs the arc as knowable at T (`classify → Contemporary`, temporal.rs:150), excluding later revisions (`Anachronistic`, dropped under Strict, :153). The arc at any past version is permanently reconstructable. + +--- + +## §4 — THE COGNITIVE CYCLE (8 steps → primitives → Rubicon phases) + +| Step | Primitive (`file:line`) | Rubicon phase | +|---|---|---| +| fanout | `escalation::CollapseHint::Fanout` + `fanout_width` (:45/:59) | Planning | +| consolidate | `escalation::InnerCouncil::deliberate` (:144) | Planning | +| induction | `nars::InferenceType::Induction` | Planning→Σ | +| synthesize insights | `escalation::EpiphanyDetector::observe` (:241) + `InferenceType::Synthesis` | CognitiveWork | +| think | `CognitiveShaderDriver::dispatch` (driver.rs:581; thinking-engine>P64) | CognitiveWork ← seam #5 | +| deduction | `nars::InferenceType::Deduction` | CognitiveWork | +| meta awareness | `mul::MulAssessment` (DK/trust/compass) | Evaluation | +| abduction | `nars::InferenceType::Abduction` | Evaluation→{Commit\|Plan\|Prune} | + +Spiral: abduction → `KanbanColumn::Plan` → re-deliberate → next fanout (Peirce abductive-inductive-deductive loop, gated by EpiphanyDetector synthesis + MUL anti-Mount-Stupid). **Add = a `CognitiveCycle` sequencer** (method on the integrated Planner) that drives the 8 steps through the kanban phases, setting `ThinkingContext.inference_type` per step. Everything it calls EXISTS; the sequencer is the only new code — and it is the consumer that closes seams #1 (emit per phase), #2 (as-of read per step — but the read is CLOSURE-INJECTED, see §9: the planner can't reach the async `at_version` in core), #4 (rung drive), #5 (think delegation). **The spiral re-entry is a GROUNDED legal Rubicon edge (S1):** `KanbanColumn::Plan.next_phases() == &[Planning]` (kanban.rs:95) and `Plan.is_absorbing() == false` (kanban.rs:71) — `Plan → Planning` already compiles; P-CYCLE-SPIRAL is its only falsifier. + +**Fields vs methods (the load-bearing call, S1):** the sequencer adds exactly THREE state fields to `PlannerAwareness` (lib.rs:99) — `phase: KanbanColumn` (default Planning), `checklist: Checklist` (built by the existing `mul::escalation::boot_checklist()`, mul/escalation.rs:36), `epiphany: EpiphanyDetector` (escalation.rs:213). `mul`/`thinking`/`elevation`/`cache` stay STATELESS module calls (lib.rs:177/183 construct-and-drop) — they do NOT become fields. The 8 steps are `&mut self` methods; the public entry is one new `cycle(&mut self, query, situation) -> Result` ALONGSIDE `plan_full` (lib.rs:171) / `plan_auto` (lib.rs:264), both UNCHANGED. + +**Subsumption (S1):** the integrated planner is `PlannerAwareness` GAINING the cycle (+ a zero-cost `pub type Planner = PlannerAwareness` alias for the operator's literal name) — NOT a rename (would force touching the `OrchestrationBridge` impl orchestration_impl.rs:46 + every `Box` consumer) and NOT a wrapper (re-introduces the delegation boilerplate the contract dedup killed). (NB: S2 argues the *think-step* must call into a third crate because planner ⊥ shader-driver — the reconciliation is closure-injection à la `run_convergence`; see §8.) + +**Carrier (S1):** the cycle threads the CONTRACT `plan::ThinkingContext` (plan.rs:16), NOT the planner `thinking::ThinkingContext` (thinking/mod.rs:31) — the `inference_type: InferenceType` field the table sets exists only on the contract type (plan.rs:19; the planner type has `nars_type` instead). The `thinking_to_contract` converter (orchestration_impl.rs:163) is the existing bridge. + +**Rung threads every step (S3):** each step's `ThinkingContext.rung` (plan.rs:22) is `from_entropy(nars_entropy(f,c)).shift(rung_delta)` — it RISES on sustained `mul::GateDecision::Block` (can't settle → deepen) and is FLOORED by any live `WisdomMarker` (settled insight → dispatch deep). The "think" step carries it into cognition via `ShaderDispatch.rung` (seam #5). Rung is the depth axis of the spiral; entropy (Staunen→Wisdom) is its source coordinate — the same one entropy-ladder-spo-rung-v1 persists as the 2-bit edge class. + +### §4.1 — 0-friction strategy↔step collapses (S1) + +| Boundary | Verdict | Collapse | +|---|---|---| +| `PlanResult.emitted_edges` (lib.rs:123) ≡ cycle step-5/8 output | **OPPORTUNITY** | same `Vec`, same doc — the carrier was provisioned before the cycle existed (seam #1) | +| CollapseGate strategy #13 ≡ step-8 abduction terminal | **OPPORTUNITY** | both the Commit/Plan/Prune 3-way (kanban.rs:94); `mul::GateDecision` is a third encoding of the same trichotomy | +| TruthPropagation strategy #12 ≡ steps 3/6/8 NARS setters | **OPPORTUNITY** | same NARS→semiring map (nars.rs:45) | +| StyleStrategy::reliability_of (style_strategy.rs:168) ≡ step-7 council confidence | **WORTH-EXPLORING** | probe OQ-CSV-CYCLE-1 (extends P-RUNG-VARIES) | +| JitCompile strategy #14 ≡ KanbanMove.exec=Jit (kanban.rs:128) | **WORTH-EXPLORING** | probe OQ-CSV-CYCLE-2 (τ-address → ExecTarget) | +| Parse strategies #1-4 ≡ step-1 fanout | **DROP** | syntactic-parse vs search-breadth, no shared algebra | +| WorkflowDAG strategy #15 ≡ Rubicon kanban DAG | **DROP** | dynamic workflow topology vs fixed 6-state automaton | + +--- + +## §5 — PROBES (measure-first; falsifiable, declared before running) + +- **P-DEDUP-ASOF**: ingest the same doc at versions T₁,T₂ → assert one `identity` and as-of-T₁ excludes the T₂ copy (collapses Pinpoint's no-dedup + no-versioning into one invariant). +- **P-TICKET-SNAPSHOT**: one `ScopedReference` per session → two reads at the same ticket see byte-identical as-of-T snapshots across split basins (TiKV snapshot-isolation, mapped). +- **P-SCOPE-CLASSIFY**: `ScopedReference` admits a row iff `scope.is_ancestor_of(row.niblepath) && classify(...)==Contemporary` (needs the `NiblePath`↔`classid|HEEL|HIP|TWIG` byte↔nibble bijection — currently unwritten, `hhtl.rs:48`). +- **P-RUNG-VARIES** (exists, `style_strategy.rs:264`): reliability varies by style → a rung/style gate is non-cosmetic. +- **P-CYCLE-SPIRAL**: abduction → Plan → fanout actually changes the next cycle's candidate set (else the spiral is decorative). +- **P-RUNG-FROM-ENTROPY-VARIES** (S3, additive sibling of P-RUNG-VARIES): `RungLevel::from_entropy(1.0 − reliability_of(style, ctx))` (style_strategy.rs:168) must produce DIFFERENT rungs for different styles over the same ctx. If Analytical and Creative land on the same rung, the entropy→rung map is cosmetic and must NOT be wired. Inherits the ρ=−0.78 reliability-proxy grounding (entropy_ladder.rs:281). +- **P-RUNG-ROUNDTRIP** (S3, gated on entropy-ladder R2 / D-EL-2): `RungLevel::from_entropy_class(entropy_class(h))` must land in the same 3-level `EntropyRung` band as `from_entropy(h)` for all h — else the 2-bit `CausalEdge64`-spare-bits persist is lossier than the band semantics allow and needs 3 bits. This is what makes the rung persist across the Lance tombstone WITHOUT a `RungState` singleton. +- **P-ARC-PROMOTE-IS-REVISION** (S5): a sequence of `EpisodicEdges64::promote` (episodic_edges.rs:168) on one `local_key` preserves slot-0 = most-recent and routes exactly `coldest()` to the `DemotionSink` (assert `evicted == coldest()`, episodic_edges.rs:593); then assert the demoted edge is still reachable via the cold connectome AND an as-of-T₁ `ScopedReference` read excludes a T₂-promoted edge. Falsifies "revision destroys the path" — proves recency (slots) and history (sink) are separate channels. +- **P-GRANGER-VERSION-LAG** (S4, HYPOTHESIS): with Granger's `lag` = Lance-version-delta, `granger_effect(series_a, series_b, max_lag)` over `[for V in T-k..T: fingerprint(deinterlace(at_version(V)))]` returns a signal that subtree A's as-of-V state predicts subtree B's as-of-(V+lag) state beyond autocorrelation. Constraint (search/temporal.rs:35/39): ≥3 versions, `max_lag ≤ window/2`. + +--- + +## §6 — OPEN QUESTIONS / DEFERRALS + +- OQ-11.6 surreal external trigger (`Notification→KanbanMove` `LanceVersionScheduler`) — fork-blocked (`TD-SURREALDB-KVLANCE-LANCE7`). NB Frame 2 (`knowable_from`) IS Surreal's `DEFINE TABLE` timeline (temporal.rs:280) → the `Unknowable` axis stays dark until the fork lands. +- OQ-11.7 planner DTO cutover scope — S2 makes it concrete: `emitted_moves` is the new truth, `emitted_edges` the derived legacy view (keep both per I-LEGACY-API-FEATURE-GATED). +- The jolly→main merge of the loop (`463d71bd`). +- `temporal.rs` dep-wall — **DECIDED (S4): A-then-B, both required** (policy→contract + a lance-core `temporal_read` join). Residual: where the `at_version→deinterlace` consumer lives (core `temporal_read` vs S5's "callcenter `commit_event` returns a stamped `ScopedReference`"). +- ResonanceDto rename (`TD-RESONANCEDTO-DUP-1`). +- `StepDomain::Ladybug` → mark deprecated (forget Ladybug). +- OQ-CYCLE-MUT (S1): `EpiphanyDetector::observe` is `&mut self` (escalation.rs:241) but `route`/`plan_full` are `&self` → interior mutability on the `epiphany` field (RwLock/LazyLock per data-flow.md) OR `cycle()` is the sole `&mut` entry kept OFF the contract trait. +- OQ-11.8 (S2): bind `ExecTarget` legality to `KanbanColumn` — `const fn ExecTarget::can_drive(self, to)->bool` beside `KanbanColumn::can_transition_to` (kanban.rs:102); bars `SurrealQl` from `CognitiveWork`/`Commit` → "Surreal never writes/thinks" becomes a compile invariant (folds seam #6 from doc-fix to type-guarantee). Falsifier: assert `KanbanMove{exec:SurrealQl, to:Commit}` rejected. +- OQ-rung-state (S3): the sustained-BLOCK counter + WisdomMarker age need cycle-to-cycle persistence, but `RungState` (named escalation.rs:39) does NOT exist. Candidate: ride D-EL-2's 2-bit entropy-class on the per-mailbox SoA edge (co-located with `last_active_cycle`), read back via `from_entropy_class` — NOT a new singleton. Also confirm `MulAssessment` exposes the NARS `(f,c)`/emergence/coherence scalars feeding `nars_entropy`/`rung_delta` (mul/escalation.rs:22-27 shows only trust/humility/flow/load — entropy inputs may need deriving). +- OQ-11.9 (S4, the strong second-order): does the cycle build `Think.global_context` via `deinterlace(at_version(T))` — think *as-of-T* (historical cognition gated by `EpistemicMode`), not merely read-as-of-T? If yes → defensible-audit re-thinking (auditor proves a decision used only T-contemporaneous knowledge via `EpistemicMode::Strict`). HYPOTHESIS, grounded in `deinterlace` output "IS the standing wave" (temporal.rs:20) = `Think.global_context` shape. +- OQ-CSV-CYCLE-1/2 (S1, from §4.1): does `StyleStrategy::reliability_of` subsume the step-7 council confidence; does τ-address resolution determine `ExecTarget` (making JitCompile-as-strategy redundant with exec-on-move)? + +--- + +## §7 — REFERENCE INDEX (the file:line grounding agents MUST target) + +- Planner: `lance-graph-planner/src/{lib.rs:99/123/171, strategy/style_strategy.rs:138/168, temporal.rs:107/147/301, orchestration_impl.rs:151, traits.rs:69, ir/mod.rs:92}` +- Contract: `lance-graph-contract/src/{plan.rs:16/42/144, orchestration.rs:37/56/390, kanban.rs:32/112/136, jit.rs:48, escalation.rs:45/144/241/289/312, scheduler.rs:46, soa_view.rs:112, canonical_node.rs:35/106/181/207, hhtl.rs, cognitive_shader.rs:157}` +- Cognition: `thinking-engine/src/dto.rs:40/59/120`, `p64-bridge/src/lib.rs`, `cognitive-shader-driver/src/{driver.rs:581, engine_bridge.rs:29, mailbox_soa.rs:349(jolly)}` +- Write boundary: `lance-graph-callcenter/src/lance_membrane.rs:315`, `audit_sink/lance_sink.rs:292` +- Lance versioning: `lance-graph/src/graph/versioned.rs:419` +- External patterns: Google Pinpoint (entity-MID, collection-ACL, no-dedup/no-version traps); TiKV (key→region→store via PD, MVCC/TSO snapshot reads, coprocessor pushdown). +- Emit/cycle (S1/S2): `lance-graph-planner/src/{lib.rs:107/216/254/312, api.rs:190, compose.rs, thinking/mod.rs:31/86, mul/escalation.rs:21/36}`, `lance-graph-contract/src/{recipe_kernels.rs:25/31/37/58/79, plan.rs:44, mul.rs:144/150, collapse_gate.rs:59/79, cognitive_shader.rs:178/190/219/349/353/356/427}`, `cognitive-shader-driver/src/{driver.rs:582, engine_bridge.rs:93/143/231/310, planner_bridge.rs:1(LAB), Cargo.toml:54(with-planner)}`, `lance-graph-planner/Cargo.toml`. +- Rung/entropy (S3): `lance-graph-contract/src/cognitive_shader.rs:155-169`, `ndarray/src/hpc/entropy_ladder.rs:55/64/99/208/281`, `.claude/plans/entropy-ladder-spo-rung-v1.md`. +- Temporal (S4): `lance-graph-planner/src/temporal.rs:67/107/121/135/147/249/258/301`, `lance-graph/src/graph/versioned.rs:419/450/461`, `lance-graph-cognitive/src/search/temporal.rs:30`, `lance-graph-callcenter/src/{version_watcher.rs:57, external_intent.rs:113}`, `lance-graph-contract/src/{property.rs:771, scheduler.rs:46}`. +- Addressing/episodic (S5): `lance-graph-contract/src/{hhtl.rs:45/55/72/93/176/199/235/387, canonical_node.rs:16/106/139/329/351, episodic_edges.rs:103/168/227/311/593, soa_envelope.rs:87/107}`, `lance-graph/src/graph/{fingerprint.rs:65, arigraph/episodic.rs:43/161/166/273, arigraph/spo_bridge.rs:127}`, `lance-graph-ontology/src/odoo_blueprint/class_signature.rs:31`. + +--- + +## §8 — CROSS-SAVANT SYNTHESIS (2026-06-15, 5-savant expansion pass) + +Five expansion savants (S1 convergence-architect / S2 bus-compiler / S3 truth-architect / S4 scenario-world / S5 trajectory-cartographer) deepened §1–§7, each citing `file:line`. Net: the integrated planner is confirmed **~90% existing**; the new code is small + additive. This section holds what only emerges from holding all five together — the hardeners (3 brutal agents) bite HERE first. + +**TENSION T1 — where the cycle lives (S1 ⊥ S2, must be resolved before D-MBX-A6-P3 impl).** +S1: the `CognitiveCycle` is a method ON `PlannerAwareness` (+ `pub type Planner` alias) — no new crate. S2: planner ⊥ shader-driver (proven by BOTH Cargo.tomls) → the *think-step* (seam #5) can't call `CognitiveShaderDriver::dispatch` from inside the planner crate, so it needs a third crate `lance-graph-cognitive-cycle`. **Reconciliation (recommended): the cycle COORDINATION is a method on `PlannerAwareness` (S1), but the think-step delegates via CLOSURE-INJECTION — `cycle(&mut self, …, think: impl Fn(&ThinkingContext)->Vec)` — exactly the `run_convergence(triplets, apply)` precedent (cache/convergence.rs:223) where the planner never names the driver type.** The third crate then becomes thin: it owns only the `|ctx| driver.dispatch(to_dispatch(ctx))` closure + the `main`-side wiring, not the sequencer. Falsifier for the reconciliation: does a closure-typed think-step keep `cycle()` object-safe / `&self`-compatible? (interacts with T2.) + +**TENSION T2 — `&mut self` vs the `&self` contract surface (S1, latent baton-handoff issue).** +`EpiphanyDetector::observe` is `&mut self` (escalation.rs:241); `OrchestrationBridge::route` (orchestration_impl.rs:47) + `PlannerContract::plan_full` (plan.rs:148) are `&self`. So `cycle()` cannot both mutate `epiphany` AND ride the existing contract trait unchanged. Two ways out: (a) interior mutability on the `epiphany` field (RwLock/LazyLock per data-flow.md "no &mut self during computation"); (b) `cycle()` is the sole `&mut` entry, deliberately kept OFF the `PlannerContract` trait. Decide before impl — see OQ-CYCLE-MUT. + +**CONVERGENCE C1 — three savants independently hit the `Think`-carrier (S1 §SECOND-ORDER + S4 §SECOND-ORDER).** +S1: the 8-step order ≅ the `Think` struct's TEKAMOLO field-DAG (CLAUDE.md §The-Click); `CycleOutcome` should BE a `Think`-shaped carrier, and `cycle()` ≅ `Think::resolve()`. S4: `deinterlace(at_version(T))` builds `Think.global_context` *as-of-T* → the system can **think-as-of-T**, not just read-as-of-T (defensible-audit primitive). **Joint implication:** the cycle + the temporal as-of read are two faces of one object — a `Think` whose `global_context` is the deinterlaced as-of-T frame and whose `resolve()` is the 8-step cycle. **GATED:** `Think` carrier unification is already DEFERRED (LATEST_STATE PR #372) — so this is WORTH-EXPLORING, NOT do-now. Do not let a hardener treat it as in-scope for #496. + +**CONVERGENCE C2 — the rung carrier is already aligned 1:1 (S2 + S3).** +S2: `ThinkingContext.rung` (plan.rs:22) ↔ `ShaderDispatch.rung` (cognitive_shader.rs:190) are the SAME `RungLevel`, matching default — the only missing code is a field-copy builder. S3: `RungLevel` is inert ONLY because it has no constructor; add `from_ordinal`/`shift`/`from_entropy` and the 4 hardcode sites have something to call. **Joint:** seam #4 (drive) + seam #5 (carry) close together — give `RungLevel` constructors (S3), drive it from entropy+delta at the 2 production sites (S3), copy it into `ShaderDispatch` at the seam-#5 lowering (S2). One `RungLevel` flows planner→cognition. + +**CONVERGENCE C3 — carriers provisioned before their consumers (S1 + S2 + S5).** +`PlanResult.emitted_edges` (S1: same field/type/doc in both `PlanResult` twins, awaiting the cycle); `dn_hash` dedup (S5: Pinpoint's lesson already shipped at spo_bridge.rs:127); `QueryReference`'s `Copy` as-of half (S4: snapshot-isolation free). The recurring shape: the substrate was built anticipating these seams; the work is WIRING existing carriers, not building new ones. This is the doc's thesis (~90% exists) confirmed three independent ways. + +**The additive new-code ledger (everything else is wiring):** (1) the `CognitiveCycle` sequencer (T1/T2); (2) `RungLevel::{from_ordinal,shift,from_entropy}` + `PlannerContract::rung_for` (C2); (3) the `temporal.rs` A→contract relocation + B core `temporal_read` join (seam #2); (4) `ScopedReference` + its `admits`/`retrieve_arc` methods (§3); (5) `MarkingRow: DeinterlaceRow` for Bardioc (§3); (6) the tier-structured `NiblePath::from_guid_prefix` bijection (§3, the width-overflow fix); (7) optional `const fn ExecTarget::can_drive` (seam #6 hardening, OQ-11.8). Each is small, additive, and has a falsifying probe in §5. + +--- + +## §9 — HARDENING VERDICTS (3 brutally-honest agents, 2026-06-15) + +PP-13 brutally-honest-tester → **HOLD** (3 P1, all spec-text fixes). PP-15 baton-handoff-auditor → **CATCH-LATENT** (4 latent boundary drops). PP-16 preflight-drift-auditor → **READY-TO-DISPATCH** (2 spawn-caution addenda). All three confirmed the load-bearing `file:line` grounding is real, the dependency-wall claims hold, and the measure-first ratio (9 probes / 7 ledger items) is honest. The fixes are spec-text, NOT architectural rewrites. + +**LOCKED decisions (fold into the §8 ledger before any worker dispatch):** +1. **Emit channels are SEPARATE, neither derived (PP-13 P1-1 + PP-15 B2).** `emitted_edges: Vec` (CausalEdge64/EpisodicEdges64 words, collapse-gate path) and `emitted_moves: Vec` (16-B lifecycle records) are independent — NO `KanbanMove→u64` cast exists; inventing one is the I-LEGACY trap. Also note `ShaderBus.emitted_edges` is `[u64;8]` not `Vec` (the seam-#5 lowering crosses array→Vec). +2. **`cycle()` is an INHERENT method on `PlannerAwareness`, NEVER a trait method (PP-13 P1-3).** The `impl Fn` closure-injection arg is not object-safe → must stay OFF `PlannerContract`/`OrchestrationBridge` (the `Box` consumers: n8n-rs, crewai-rust). Only `rung_for` goes on the trait. The `run_convergence` precedent (convergence.rs:223) is a free function — its object-safety doesn't transfer to a trait method. +3. **Seam #2's as-of read is CLOSURE-INJECTED too (PP-15 B8).** The planner cannot reach `at_version` (async, in lance-graph core, behind the anti-circular wall) — so the sequencer does NOT close seam #2 by itself; the temporal read is closure-injected exactly like the think-step (T1), OR core pre-deinterlaces and hands rows over. +4. **DUAL `RungLevel` — do NOT duplicate (PP-16 CoC-1, SPAWN-CAUTION — paste into the rung-seam worker prompt):** the contract `cognitive_shader::RungLevel` (cognitive_shader.rs:157) is the bare-enum target for the new constructors; `thinking_engine::cognitive_stack::RungLevel` (cognitive_stack.rs:264) ALREADY has `from_u8` + `should_elevate(consecutive_blocks, free_energy, cascade_depth)` (:278-314) — MIRROR its shape, never re-derive. (The plan disambiguates the dual `GateDecision` + dual `ThinkingContext` but was silent on the dual `RungLevel` — and seam #4 sits exactly on it.) +5. **P-RUNG-ROUNDTRIP is ill-posed as stated (PP-13 P1-2).** `entropy_class` quantizes at QUARTERS, `EntropyRung` bands at THIRDS — boundaries don't nest (counterexample: `class(0.3)==class(0.4)==1` straddle two bands). Restate as a one-band-tolerance probe OR require a thirds-banded 2-bit quantizer. Also `ThoughtCtx.rung` is `1..=9` while `RungLevel` is `0..9` → `from_ordinal` must clamp the off-by-one. + +**Latent boundary fixes (PP-15, pin before D-MBX-A6-P3 impl):** +- **THREE `PlanResult`** (B2): inherent lib.rs:107, contract plan.rs:30 (NO live producer today — only nominally twinned), AND `arigraph/language.rs:34`. Name the 3-way collision; specify the inherent→contract adapter. +- **`MailboxId` sentinel (B4):** the type is `collapse_gate.rs:121` (NOT kanban.rs:114 — that's the field; citation fix). `0` is a real mailbox, `u32::MAX` is already overloaded (#386) → do NOT collapse `Option` to a magic value; emit NO move without a real mailbox (matches StyleStrategy's no-theatre stance). +- **Newtype the address u64s (B7):** `dn_hash` + `local_key` are both bare `u64` → wrap `DnHash(u64)`/`LocalKey(u64)` at the `MarkingRow`/addressing boundary; cite the pre-existing `StructuralSignature` ~50% collision (`TECH_DEBT.md:134`) in §3 (it's not a clean third hash). + +**P2 / nits:** `ExecTarget::can_drive` must enumerate all 24 (exec×column) cells (default-allow + SurrealQl deny-list); `MarkingRow` predicate should be an interned id, not `String` (the `&str` carrier forces a heap alloc per row); split P-ARC-PROMOTE-IS-REVISION into the in-tree half (eviction identity) + the DemotionSink-gated half. + +**Sub-line drift to fix (PP-16, low-impact):** `ThinkingContext.rung` is plan.rs:**23** (not :22, cited ~5×); `try_advance_phase` soa_view.rs:**128**; `NextPhaseScheduler::on_version` scheduler.rs:**76**; `QueryReference::at` temporal.rs:**135**; `convergence.rs` has **9 tests, mod at :246, span :249-437** (not "8, :363-436"). And **"#495 rides #496" is mis-attributed (DRIFT-6, SPAWN-CAUTION):** `ValueSchema`/`ValueTenant`/`EdgeCodecFlavor` are POST-#495 BRANCH commits (`4e3496ab` + `920671d2`), present on this branch but NOT on origin/main, and NOT part of the already-merged #495 — **target the branch tree; do not verify these against origin/main** (a worker who does gets a false negative and thrashes). diff --git a/.claude/plans/reliability-checklist-arc-v1.md b/.claude/plans/reliability-checklist-arc-v1.md index f3a60184..82cfd03d 100644 --- a/.claude/plans/reliability-checklist-arc-v1.md +++ b/.claude/plans/reliability-checklist-arc-v1.md @@ -49,8 +49,8 @@ - **Realizes:** E-CALIBRATE-RELIABILITY-PSYCHOMETRICALLY. Complementary to P1 (audits the checklist, doesn't gate the hot path). - **Size:** M-L. **Deps:** thinking-engine cronbach.rs (exists). **Risk:** heavier; only worth it if P2 shows the gate matters AND checklist completeness is in question. -### P9 — D-MBX-11 lance 6.0.0→6.0.1 bump (mechanical) -- **What:** the version bump (5 Cargo.tomls). **Size:** XS. **Risk:** none (off critical path). Quick unblock for stack alignment. +### P9 — D-MBX-11 lance bump (mechanical) · **[2026-06-14 SUPERSEDED by #445: shipped `=6.0.0 → =7.0.0`, not `=6.0.1`]** +- **What:** the version bump (5 Cargo.tomls). **Size:** XS. **Risk:** none (off critical path). **Done by PR #445** (lance/lance-linalg `=7.0.0`, lancedb `=0.30.0`, object_store 0.13.2); residual surrealdb-fork pin = `TD-SURREALDB-KVLANCE-LANCE7`. ### P10 — Polyglot IR-conformance loop (the GEL hub floor) - **What:** assert the 4 dialects + 2 IR-routes (in-strategy vs ArenaIR) produce equivalent LogicalOp for equivalent queries; attach to consumer-conformance harness. @@ -74,5 +74,5 @@ ## RECALIBRATED (3-agent panel, 2026-05-30) — see EPIPHANIES "RECALIBRATION" **Keystone added: M1 `Tactic::requires() -> AtomMask`** (reliability is a missing accessor, not a gate — extraction not construction; makes P1/P7/P11 derived). **Recalibrated order:** 1) M1 (contract, zero-dep, teeth-test). 2) P2 + build its missing witness corpus (honest cosmetic/not pass-fail). 3) M2 completeness auditor (unknown-unknown finder, reuses neural-debug). -**Deferred/dropped:** P5 P0-blocked (I4x32 pack/unpack todo!() + 32-vs-33 fork); P6 cosmetic (recipe.rs never compiles in); P9 still blocked (lancedb pins lance=6.0.0); P10 off-arc; P3/P4 AP6 theater until a real consumer exists; P1 must reframe as M1-derived (don't dup recipes::Coverage); P8 gated on P2-pass. +**Deferred/dropped:** P5 P0-blocked (I4x32 pack/unpack todo!() + 32-vs-33 fork); P6 cosmetic (recipe.rs never compiles in); P9 SUPERSEDED (shipped `=7.0.0`/`=0.30.0` via #445 — lancedb 0.30 resolves the old "0.29 pins lance=6.0.0" block); P10 off-arc; P3/P4 AP6 theater until a real consumer exists; P1 must reframe as M1-derived (don't dup recipes::Coverage); P8 gated on P2-pass. **Added missing:** M2 (completeness auditor), M3 (version-arc scheduler wire). diff --git a/.claude/plans/unified-soa-convergence-v1.md b/.claude/plans/unified-soa-convergence-v1.md index 947fac64..87812e85 100644 --- a/.claude/plans/unified-soa-convergence-v1.md +++ b/.claude/plans/unified-soa-convergence-v1.md @@ -241,11 +241,11 @@ Current pins (verified 2026-05-29): |---|---|---|---| | arrow | `"58"` | `"58"` | ✓ | | datafusion | `"53"` | `"53"` | ✓ | -| lance | `"=6.0.0"` | `"=6.0.1"` | **patch bump** | -| lancedb | `"=0.29.0"` | `"=0.29.0"` | ✓ | +| lance | `"=7.0.0"` | `"=7.0.0"` | ✓ **SHIPPED #445** (jumped past the planned `=6.0.1`) | +| lancedb | `"=0.30.0"` | `"=0.30.0"` | ✓ **SHIPPED #445** (was `=0.29.0` at author-time) | | ndarray | path-dep | path-dep | ✓ (governed by `PR-NDARRAY-MIRI-COMPLETE`) | -**Only one bump pending: `lance =6.0.0 → =6.0.1`** across the workspace Cargo.toml files. Mechanical; one-line per crate. Files identified: `crates/lance-graph/Cargo.toml:38`, `crates/lance-graph-benches/Cargo.toml:10`, `crates/lance-graph-callcenter/Cargo.toml:30`, `crates/lance-graph-ontology/Cargo.toml:46`, `crates/holograph/Cargo.toml:38`. +**[2026-06-14 SUPERSEDED]** No bump pending — main shipped `lance =6.0.0 → =7.0.0` + `lancedb =0.29.0 → =0.30.0` (lockstep, 7 crates, PR #445), jumping past the planned `=6.0.1` (which never existed on the lancedb path; lancedb 0.30 is the first release pinning lance =7). D-MBX-11 is closed by #445; the only residual is the surrealdb-fork pin (`TD-SURREALDB-KVLANCE-LANCE7`). Files that carried the pins: `crates/lance-graph/Cargo.toml:38`, `crates/lance-graph-benches/Cargo.toml:10`, `crates/lance-graph-callcenter/Cargo.toml:30`, `crates/lance-graph-ontology/Cargo.toml:46`, `crates/holograph/Cargo.toml:38`. ### 4.3 SurrealDB transparent-view enablement @@ -386,7 +386,7 @@ This is exactly the re-encode boundary R1 forbids: the planner reads its own DTO - **D-CE64-MB-1-impl** (par-tile crate apex + `Mailbox` + 3 backings + AttentionMask SoA + `BindSpaceView`). Already specced (Sprint-11 W1). Blocking gate. - **`PR-NDARRAY-MIRI-COMPLETE`** — close `U16x32 / U32x16 / U64x8` SIMD method gaps. Cross-repo (ndarray PR). Blocking gate. -- **D-MBX-11** — Lance 6.0.0 → 6.0.1 patch bump (mechanical, can land in parallel with par-tile). +- **D-MBX-11** — ~~Lance 6.0.0 → 6.0.1 patch bump~~ **SUPERSEDED by #445** (main shipped `=6.0.0 → =7.0.0` / lancedb `=0.30.0`; no `=6.0.1` step). ### Phase P2 — SoA version gate + stack alignment @@ -521,9 +521,9 @@ This is exactly the re-encode boundary R1 forbids: the planner reads its own DTO **Gates on:** none (foundation work); should land early in P2. -### D-MBX-11 — Lance 6.0.0 → 6.0.1 patch bump +### D-MBX-11 — Lance 6.0.0 → 6.0.1 patch bump · **[2026-06-14 SUPERSEDED by PR #445 — shipped `=6.0.0 → =7.0.0` / lancedb `=0.30.0`, not `=6.0.1`]** -**Owner:** workspace Cargo.toml. **~10 LOC (mechanical).** **Risk: LOW.** +**Owner:** workspace Cargo.toml. **~10 LOC (mechanical).** **Risk: LOW.** **(Closed by #445; detail below is the original as-authored spec.)** **Adds:** patch bump in `crates/lance-graph/Cargo.toml:38`, `crates/lance-graph-benches/Cargo.toml:10`, `crates/lance-graph-callcenter/Cargo.toml:30`, `crates/lance-graph-ontology/Cargo.toml:46`, `crates/holograph/Cargo.toml:38`. @@ -587,7 +587,7 @@ Sub-PRs: ### Per-phase acceptance -- **P1 (prereqs):** par-tile crate exists; ndarray SIMD primitives complete; `lance =6.0.1` workspace-wide. +- **P1 (prereqs):** par-tile crate exists; ndarray SIMD primitives complete; `lance =7.0.0` workspace-wide (shipped #445; was specced as `=6.0.1`). - **P2 (version gate):** `MailboxSoAHeader` carries version; round-trip read/write green; refusal-on-mismatch path tested. - **P3 (shader columns):** all new columns present; field-isolation matrix green; existing tests still pass. - **P4 (singleton dissolution):** `BindSpace::zeros(4096)` removed; `serve.rs` builds a sea-star of `MailboxSoA`s; integration test passes a full think-cycle through the new path. diff --git a/.claude/plans/wikidata-lazy-spine-hydration-v1.md b/.claude/plans/wikidata-lazy-spine-hydration-v1.md index 92f716c2..b427032a 100644 --- a/.claude/plans/wikidata-lazy-spine-hydration-v1.md +++ b/.claude/plans/wikidata-lazy-spine-hydration-v1.md @@ -435,7 +435,7 @@ guard: addressing = exact CAM; similarity = discovery-only, `Fragment` + `compact` so a P-frame is a fragment append and GOP-compaction is fragment compaction (the integration map's literal intent). This is a NEW Lance-binding task, not a shipped seam — labelled CONJECTURE until a - spike proves the Lance version on `Cargo.lock` (`lance =6.0.0`) exposes the + spike proves the Lance version on `Cargo.lock` (`lance =7.0.0`, per #445) exposes the needed fragment surface to this crate. - `aerial` untouched. The frame model is a hub-side cold-floor concern. @@ -722,7 +722,7 @@ proposes making aerial depend on heavy crates. | # | Risk | Mitigation | |---|---|---| | R1 | **`EpisodicWitness64` does not exist** (cited in both companion docs). | Plan cites only `WitnessTable<64>`/`WitnessEntry` (verified). The 16-bit "book" witness tier is CONJECTURE. Flag to integration-lead: the companion docs should be corrected or `EpisodicWitness64` shipped. | -| R2 | **Lance *fragment*-versioning not wired** (only dataset-level `VersionedGraph`). | D-LWS-4 ships option (a) dataset-versioning now; option (b) fragment APIs is a NEW spike, CONJECTURE until the `lance =6.0.0` fragment surface is confirmed reachable from this crate. | +| R2 | **Lance *fragment*-versioning not wired** (only dataset-level `VersionedGraph`). | D-LWS-4 ships option (a) dataset-versioning now; option (b) fragment APIs is a NEW spike, CONJECTURE until the `lance =7.0.0` fragment surface is confirmed reachable from this crate. | | R3 | **CLAM is a probe, not a clusterer.** | Every "CLAM-clustered" claim builds on `measure_cluster_radii` (offline placement decision); the clusterer that acts on radii is NEW. P1 gates whether radii coincide with cohorts at all. | | R4 | **All three probes are CONJECTURE.** A failing probe invalidates the design at fixture scale. | D-LWS-8 runs them on real TTL + fixtures BEFORE D-LWS-9; gates are kill-switches, not decoration. | | R5 | **D-ARM-7 (Jirak floor) is Queued, not shipped.** | Hard prerequisite enforced in code (D-LWS-5 write-refusal acceptance test), not just documented. No live write without it. | diff --git a/CLAUDE.md b/CLAUDE.md index f2097e61..ed61029a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -976,12 +976,12 @@ cd crates/lance-graph-python && maturin develop ## Key Dependencies ```toml -# Verified against Cargo.lock 2026-05-30. The lance family moves in lockstep at =6.0.0. +# Verified against Cargo.lock 2026-06-14. The lance family moves in lockstep at =7.0.0 (PR #445). arrow = "58" datafusion = "53" -lance = "=6.0.0" # exact-pinned: lancedb 0.29.0 transitively requires lance =6.0.0 -lance-linalg = "=6.0.0" -lancedb = "=0.29.0" +lance = "=7.0.0" # exact-pinned: lancedb 0.30.0 transitively requires lance =7.0.0 +lance-linalg = "=7.0.0" +lancedb = "=0.30.0" # 0.30 → lance 7 → object_store 0.13.2 (0.29 → lance 6 → object_store 0.12) ndarray = { path = "../../../ndarray" } # AdaWorldAPI fork, default, optional fallback nom = "7.1" snafu = "0.8" diff --git a/crates/lance-graph-contract/src/canonical_node.rs b/crates/lance-graph-contract/src/canonical_node.rs index ad2911c7..69b0ee5d 100644 --- a/crates/lance-graph-contract/src/canonical_node.rs +++ b/crates/lance-graph-contract/src/canonical_node.rs @@ -259,6 +259,7 @@ const _: () = assert!(core::mem::size_of::() == 512); // ── SoaEnvelope binding for [NodeRow] ──────────────────────────────────────── +use crate::class_view::FieldMask; use crate::soa_envelope::{ColumnDescriptor, ColumnKind, SoaEnvelope}; /// Stable column-id ordinals for [`NodeRow`]'s three top-level slots. @@ -304,6 +305,230 @@ pub const NODE_ROW_COLUMNS: &[ColumnDescriptor] = &[ /// Row stride for [`NodeRow`] in bytes — equal to `size_of::()`. pub const NODE_ROW_STRIDE: usize = 512; +// ── Value-slab schema presets: which tenants a class materialises ───────────── + +/// Full-row byte offset of the value slab (key 16 + edges 16). +pub const VALUE_SLAB_ROW_OFFSET: usize = 32; +/// Bytes available in the [`NodeRow::value`] slab. +pub const VALUE_SLAB_LEN: usize = 480; + +/// A named tenant of the 480-byte [`NodeRow::value`] slab. +/// +/// Stable, append-only positions — the canon "reserve, don't reclaim" rule and +/// the [`FieldMask`] N3 contract: a tenant's presence bit and its byte offset in +/// [`VALUE_TENANTS`] never move once instances persist, and retired tenants are +/// never reused. **The discriminant IS the [`FieldMask`] bit position** and the +/// index into [`VALUE_TENANTS`] (asserted at compile time below). +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[repr(u8)] +pub enum ValueTenant { + /// `MetaWord` — thinking / awareness / NARS / free-energy bits. + Meta = 0, + /// `QualiaI4_16D` — 16 signed-4-bit chroma channels. + Qualia = 1, + /// The 4 out-of-family edges materialised as full `CausalEdge64`. + MaterializedEdges = 2, + /// `Fingerprint<256>` — 32-byte identity print. + Fingerprint = 3, + /// helix golden-spiral Place/Residue (48 B). + HelixResidue = 4, + /// turbovec PQ residue ([`EdgeCodecFlavor::Pq32x4`], 16 B). + TurbovecResidue = 5, + /// Spatio-temporal accumulator (`f32`). + Energy = 6, + /// Hebbian plasticity counter + last-active stamp. + Plasticity = 7, + /// OGIT entity-type / class discriminator (`u16`). + EntityType = 8, +} + +/// Stable byte carve of the value slab. Offsets are **row-relative** (within one +/// row packet, in the value region `[32, 512)`) — consistent with +/// [`NODE_ROW_COLUMNS`], one level finer. Contiguous, in [`ValueTenant`] +/// discriminant order, no gaps; the Full set fits the slab (all asserted at +/// compile time below). This is the per-class carve the canon defers to +/// `ClassView`; it is NOT surfaced as its own top-level envelope column. +pub const VALUE_TENANTS: &[ColumnDescriptor] = &[ + ColumnDescriptor { + name_id: ValueTenant::Meta as u16, + kind: ColumnKind::U64, + elems_per_row: 1, + row_offset: 32, + }, + ColumnDescriptor { + name_id: ValueTenant::Qualia as u16, + kind: ColumnKind::U64, + elems_per_row: 1, + row_offset: 40, + }, + ColumnDescriptor { + name_id: ValueTenant::MaterializedEdges as u16, + kind: ColumnKind::U64, + elems_per_row: 4, + row_offset: 48, + }, + ColumnDescriptor { + name_id: ValueTenant::Fingerprint as u16, + kind: ColumnKind::U8, + elems_per_row: 32, + row_offset: 80, + }, + ColumnDescriptor { + name_id: ValueTenant::HelixResidue as u16, + kind: ColumnKind::U8, + elems_per_row: 48, + row_offset: 112, + }, + ColumnDescriptor { + name_id: ValueTenant::TurbovecResidue as u16, + kind: ColumnKind::U8, + elems_per_row: 16, + row_offset: 160, + }, + ColumnDescriptor { + name_id: ValueTenant::Energy as u16, + kind: ColumnKind::F32, + elems_per_row: 1, + row_offset: 176, + }, + ColumnDescriptor { + name_id: ValueTenant::Plasticity as u16, + kind: ColumnKind::U32, + elems_per_row: 1, + row_offset: 180, + }, + ColumnDescriptor { + name_id: ValueTenant::EntityType as u16, + kind: ColumnKind::U16, + elems_per_row: 1, + row_offset: 184, + }, +]; + +// Compile-time canon: VALUE_TENANTS is discriminant-ordered, contiguous within the +// value slab, and the Full carve fits the 480-byte slab. +const _: () = { + let mut i = 0usize; + let mut prev_end = VALUE_SLAB_ROW_OFFSET; + while i < VALUE_TENANTS.len() { + let c = &VALUE_TENANTS[i]; + assert!( + c.name_id as usize == i, + "ValueTenant discriminant must equal its VALUE_TENANTS index" + ); + assert!( + c.row_offset as usize == prev_end, + "VALUE_TENANTS must be contiguous within the value slab (no gaps/overlap)" + ); + prev_end = c.row_offset as usize + c.col_bytes_per_row(); + i += 1; + } + assert!( + prev_end <= NODE_ROW_STRIDE, + "value tenants must fit within the 512-byte row" + ); + assert!( + prev_end - VALUE_SLAB_ROW_OFFSET <= VALUE_SLAB_LEN, + "value tenants must fit the 480-byte slab" + ); +}; + +/// Which value-slab schema a class materialises — the value-side analog of +/// [`EdgeCodecFlavor`]. A preset is a presence [`FieldMask`] over [`ValueTenant`] +/// positions; a class selects it via +/// [`ClassView::value_schema`](crate::class_view::ClassView::value_schema). +/// +/// **Layout-preserving:** every preset carves WITHIN the reserved 480-byte value +/// slab, so the choice never changes [`NODE_ROW_STRIDE`] (no +/// `ENVELOPE_LAYOUT_VERSION` bump — canon "registry-resolved via +/// `classid → ClassView`", never a stride change). [`Bootstrap`] is the +/// zero-fallback default: value all zero, only key + edges meaningful. +/// +/// [`Bootstrap`]: ValueSchema::Bootstrap +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)] +#[repr(u8)] +pub enum ValueSchema { + /// Empty value slab — the canon zero-fallback (key + edges only). + #[default] + Bootstrap = 0, + /// Hot self-thinking set: Meta + Qualia + Fingerprint + Energy + Plasticity + + /// EntityType. No materialised edges, no codec residues. + Cognitive = 1, + /// Cold / compressed codec stack: Fingerprint + Helix-48 + turbovec residue + + /// EntityType. No hot lifecycle columns. + Compressed = 2, + /// Every [`ValueTenant`] materialised — the densest node. + Full = 3, +} + +impl ValueSchema { + /// The presence [`FieldMask`] over [`ValueTenant`] positions for this preset. + pub const fn field_mask(self) -> FieldMask { + match self { + ValueSchema::Bootstrap => FieldMask::EMPTY, + ValueSchema::Cognitive => FieldMask::from_positions(&[ + ValueTenant::Meta as u8, + ValueTenant::Qualia as u8, + ValueTenant::Fingerprint as u8, + ValueTenant::Energy as u8, + ValueTenant::Plasticity as u8, + ValueTenant::EntityType as u8, + ]), + ValueSchema::Compressed => FieldMask::from_positions(&[ + ValueTenant::Fingerprint as u8, + ValueTenant::HelixResidue as u8, + ValueTenant::TurbovecResidue as u8, + ValueTenant::EntityType as u8, + ]), + ValueSchema::Full => FieldMask::from_positions(&[ + ValueTenant::Meta as u8, + ValueTenant::Qualia as u8, + ValueTenant::MaterializedEdges as u8, + ValueTenant::Fingerprint as u8, + ValueTenant::HelixResidue as u8, + ValueTenant::TurbovecResidue as u8, + ValueTenant::Energy as u8, + ValueTenant::Plasticity as u8, + ValueTenant::EntityType as u8, + ]), + } + } + + /// Does this preset materialise `tenant`? + #[inline] + pub const fn has(self, tenant: ValueTenant) -> bool { + self.field_mask().has(tenant as u8) + } + + /// Total bytes this preset occupies in the value slab (Σ present tenants). + pub const fn tenant_bytes(self) -> usize { + let mask = self.field_mask(); + let mut total = 0usize; + let mut i = 0usize; + while i < VALUE_TENANTS.len() { + let c = &VALUE_TENANTS[i]; + if mask.has(c.name_id as u8) { + total += c.col_bytes_per_row(); + } + i += 1; + } + total + } + + /// Every preset carves within the reserved 480-byte slab — none changes + /// [`NODE_ROW_STRIDE`], so none forces an `ENVELOPE_LAYOUT_VERSION` bump. + #[inline] + pub const fn is_layout_preserving(self) -> bool { + true + } +} + +// Compile-time canon: the densest preset fits the slab; Full covers every tenant; +// Bootstrap is empty. +const _: () = assert!(ValueSchema::Full.tenant_bytes() <= VALUE_SLAB_LEN); +const _: () = assert!(ValueSchema::Full.field_mask().count() as usize == VALUE_TENANTS.len()); +const _: () = assert!(ValueSchema::Bootstrap.field_mask().is_empty()); + /// Zero-copy [`SoaEnvelope`] wrapper over a contiguous slice of [`NodeRow`]. /// /// `NodeRow` is `#[repr(C, align(64))]` with the locked 16/16/480 byte @@ -660,4 +885,90 @@ mod tests { // verify_layout exercises that gate. assert!(pkt.verify_layout().is_ok()); } + + // ── Value-slab schema presets ──────────────────────────────────────────── + + #[test] + fn value_tenants_contiguous_within_slab() { + let mut prev_end = VALUE_SLAB_ROW_OFFSET; + for (i, c) in VALUE_TENANTS.iter().enumerate() { + assert_eq!(c.name_id as usize, i, "discriminant == index"); + assert_eq!(c.row_offset as usize, prev_end, "no gap before {c:?}"); + prev_end = c.row_offset as usize + c.col_bytes_per_row(); + } + assert!(prev_end <= NODE_ROW_STRIDE); + assert_eq!( + prev_end - VALUE_SLAB_ROW_OFFSET, + 154, + "current Full carve uses 154 of 480 B" + ); + assert!(prev_end - VALUE_SLAB_ROW_OFFSET <= VALUE_SLAB_LEN); + } + + #[test] + fn value_schema_default_is_bootstrap_empty() { + assert_eq!(ValueSchema::default(), ValueSchema::Bootstrap); + assert!(ValueSchema::Bootstrap.field_mask().is_empty()); + assert_eq!(ValueSchema::Bootstrap.tenant_bytes(), 0); + } + + #[test] + fn value_schema_full_covers_every_tenant() { + let full = ValueSchema::Full; + assert_eq!(full.field_mask().count() as usize, VALUE_TENANTS.len()); + for t in [ + ValueTenant::Meta, + ValueTenant::Qualia, + ValueTenant::MaterializedEdges, + ValueTenant::Fingerprint, + ValueTenant::HelixResidue, + ValueTenant::TurbovecResidue, + ValueTenant::Energy, + ValueTenant::Plasticity, + ValueTenant::EntityType, + ] { + assert!(full.has(t), "Full must materialise {t:?}"); + } + } + + #[test] + fn value_schema_byte_budgets_are_locked() { + assert_eq!(ValueSchema::Bootstrap.tenant_bytes(), 0); + assert_eq!(ValueSchema::Cognitive.tenant_bytes(), 58); + assert_eq!(ValueSchema::Compressed.tenant_bytes(), 98); + assert_eq!(ValueSchema::Full.tenant_bytes(), 154); + for s in [ + ValueSchema::Bootstrap, + ValueSchema::Cognitive, + ValueSchema::Compressed, + ValueSchema::Full, + ] { + assert!(s.tenant_bytes() <= VALUE_SLAB_LEN); + assert!(s.is_layout_preserving()); + } + } + + #[test] + fn value_schema_presets_carry_expected_tenants() { + // Cognitive: hot columns, no codec residues, no materialised edges. + let c = ValueSchema::Cognitive; + assert!(c.has(ValueTenant::Meta) && c.has(ValueTenant::Qualia)); + assert!(c.has(ValueTenant::Energy) && c.has(ValueTenant::EntityType)); + assert!(!c.has(ValueTenant::HelixResidue)); + assert!(!c.has(ValueTenant::TurbovecResidue)); + assert!(!c.has(ValueTenant::MaterializedEdges)); + // Compressed: codec residues, no hot lifecycle. + let z = ValueSchema::Compressed; + assert!(z.has(ValueTenant::HelixResidue) && z.has(ValueTenant::TurbovecResidue)); + assert!(z.has(ValueTenant::Fingerprint)); + assert!(!z.has(ValueTenant::Energy) && !z.has(ValueTenant::Meta)); + } + + #[test] + fn value_schema_preserves_node_stride() { + // A preset is an interpretation of the reserved value slab, never a + // stride change — same canon invariant as EdgeCodecFlavor. + assert_eq!(NODE_ROW_STRIDE, core::mem::size_of::()); + assert_eq!(VALUE_SLAB_ROW_OFFSET + VALUE_SLAB_LEN, NODE_ROW_STRIDE); + } } diff --git a/crates/lance-graph-contract/src/class_view.rs b/crates/lance-graph-contract/src/class_view.rs index 635f4701..fecf8b1e 100644 --- a/crates/lance-graph-contract/src/class_view.rs +++ b/crates/lance-graph-contract/src/class_view.rs @@ -218,6 +218,34 @@ pub trait ClassView { fn edge_codec_flavor(&self, _class: ClassId) -> crate::canonical_node::EdgeCodecFlavor { crate::canonical_node::EdgeCodecFlavor::CoarseOnly } + + /// Which value-slab schema preset this class materialises in + /// [`NodeRow::value`](crate::canonical_node::NodeRow::value). + /// + /// **TEMPORARY (POC default, 2026-06-15):** returns + /// [`ValueSchema::Full`](crate::canonical_node::ValueSchema::Full) — every + /// *unconfigured* class (incl. the default `classid 0x0000_0000`) materialises + /// the whole value slab so downstream consumers (tesseract-rs / woa-rs / + /// medcare-rs / q2) can transcode against a fully-populated `NodeRow` POC. + /// Specialisation is **opt-IN, not opt-out**: a consumer that needs to save + /// memory mints a class that overrides this to a smaller preset (`Cognitive` / + /// `Compressed` / `Bootstrap`); a consumer that needs denser/specialised data + /// mints a *separate* class. Selection only: every preset carves within the + /// reserved 480-byte value slab, so the choice never changes `NODE_ROW_STRIDE` + /// (canon "registry-resolved via `classid → ClassView`", never a stride change) + /// — flipping the default is layout-preserving and a one-line revert to + /// `Bootstrap` (the canon zero-fallback) before merge. The type-level + /// [`ValueSchema::default()`](crate::canonical_node::ValueSchema) stays + /// `Bootstrap`, so the substrate zero-fallback semantics are untouched; only + /// the class→schema *resolution* default is Full. + #[inline] + fn value_schema(&self, _class: ClassId) -> crate::canonical_node::ValueSchema { + // TEMPORARY POC default — see doc above. Revert to `ValueSchema::Bootstrap` + // (canon zero-fallback) before merge. No invention: `Full` activates the + // already-existing, already-tested 9 ValueTenants (helix-48 / turbovec / + // signed / fingerprint / …), it adds no new property. + crate::canonical_node::ValueSchema::Full + } } /// One populated field to render — the late-resolved `label` + its `predicate` key. @@ -415,4 +443,24 @@ mod tests { vec!["Total", "Tax", "Partner"] ); } + + #[test] + fn value_schema_default_is_full_temporary_poc() { + // TEMPORARY (2026-06-15 POC): the blanket ClassView default materialises the + // FULL value slab so consumers (tesseract-rs / woa-rs / medcare-rs / q2) + // transcode against a populated NodeRow. Specialisation is opt-IN (override + // to a smaller preset). When the POC phase ends, revert the default to + // `ValueSchema::Bootstrap` AND this test together. + use crate::canonical_node::{EdgeCodecFlavor, ValueSchema}; + let classes = FakeClasses::new(); + // The default class (classid 0x0000_0000) and any unconfigured class both + // resolve to Full while the POC default is active. + assert_eq!(classes.value_schema(0), ValueSchema::Full); + assert_eq!(classes.value_schema(7), ValueSchema::Full); + // The edge-codec axis is SEPARATE and untouched (still the CoarseOnly + // zero-fallback) — only the value slab flipped to Full. + assert_eq!(classes.edge_codec_flavor(0), EdgeCodecFlavor::CoarseOnly); + // The TYPE-level default is unchanged: substrate zero-fallback stays Bootstrap. + assert_eq!(ValueSchema::default(), ValueSchema::Bootstrap); + } } diff --git a/crates/lance-graph-contract/src/lib.rs b/crates/lance-graph-contract/src/lib.rs index ddfab9d2..a881e84d 100644 --- a/crates/lance-graph-contract/src/lib.rs +++ b/crates/lance-graph-contract/src/lib.rs @@ -106,7 +106,9 @@ pub mod world_map; pub mod world_model; // Re-exports for the most commonly used collapse_gate types. -pub use canonical_node::{EdgeBlock, EdgeCodecFlavor, NodeGuid, NodeRow}; +pub use canonical_node::{ + EdgeBlock, EdgeCodecFlavor, NodeGuid, NodeRow, ValueSchema, ValueTenant, VALUE_TENANTS, +}; pub use class_view::{ClassId, ClassProjection, ClassView, FieldMask, RenderRow}; pub use collapse_gate::{GateDecision, MailboxId, MergeMode}; pub use episodic_edges::{EdgeRef, EpisodicEdges64};