Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .claude/board/AGENT_LOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
## 2026-06-20 (cont.¹⁵) — PR #564 codex P2 fixes (contract-source unification + build-time parity fuse)

**Main thread (Opus), autoattended.** Two codex P2 review comments on #564, both correct, both fixed:
1. **One contract source at the integration boundary** (Cargo.toml): `lance-graph` + `symbiont` path-dep `lance-graph-contract`; `lance-graph-ogar` git-dep'd it → two distinct crates when composed → `OgarClassView` would impl the git `ClassView`, not the path one. Fix: `lance-graph-ogar` now **path-deps** `../lance-graph-contract` (the canonical in-repo copy) + a `[patch."…/lance-graph"] lance-graph-contract = { path = … }` folds ogar-class-view's transitive git contract onto the SAME path copy = ONE source. Documented the cargo limitation: an in-repo workspace root (symbiont) adding this crate MUST repeat the patch (`[patch]` only applies at the root).
2. **Parity guard only ran under `#[cfg(test)]`** (lib.rs) → a downstream `cargo build` never executed it, contradicting the "fails the build on drift" claim. Fix: added a **compile-time length fuse** `parity::COUNT_FUSE` (`const _ = assert!(mirror::CODEBOOK.len() == ogar_vocab::class_ids::ALL.len())`) that fires in ANY build (cargo build included) on add/remove drift; kept the runtime `assert_codebook_parity` (full id/domain bijection, tested + callable at startup); corrected the docs to state both depths precisely (no overclaim).

Re-verified: `cargo test --manifest-path crates/lance-graph-ogar/Cargo.toml` 3/3 (the `ogar_class_view_implements_contract_class_view` test compiling PROVES one-source unification), clippy `-D warnings` + fmt clean, no "patch not used". Both threads replied + resolved. Pushed to #564.

## 2026-06-20 (cont.¹⁴) — zero-copy SoA read contract (`node_rows_from_le_bytes`) — the surrealdb "second brain" primitive

**Main thread (Opus), autoattended.** Operator: "create a contract … that ensures LE contract to the lance-graph SoA view → zero-copy symbiont; surrealdb becomes a second brain inside lance-graph." Brutal feasibility pass against real code on both sides (see EPIPHANY `E-SURREALDB-SECOND-BRAIN-IS-ZERO-COPY-IFF-FIXEDSIZEBINARY`):
- lance-graph side already zero-copy-ready: `NodeRow` `#[repr(C, align(64))]` 512B LE; `NodeRowPacket::as_le_bytes` is the WRITE cast. **Shipped the missing READ inverse:** `canonical_node::node_rows_from_le_bytes(&[u8]) -> Option<&[NodeRow]>` — checked (`len % 512`, `ptr % 64`), `None` on violation (caller copies, no UB), empty→Some(empty). Re-exported from lib.rs; +`NodeRowPacket` re-export. 2 tests (zero-copy round-trip with ptr-identity assert; rejects non-multiple + misaligned-but-correct-length window). 712 lib green, clippy `-D warnings` both configs + fmt clean.
- surrealdb side does NOT yet qualify: `.claude/lance-backend/lance/schema.rs` stores `val: DataType::Binary` (variable BinaryArray, no fixed stride / no align) → not castable. Needs `FixedSizeBinary(512)` SoA value column + deps the zero-dep contract + reads through `node_rows_from_le_bytes`. Caveat: value zero-copy iff stored UNcompressed (compressed = one decode-copy; key always zero-copy). That's the surrealdb-side plan (the lance-backend wiring), not done here.

Rides on the jirak branch (PR #564 arc — the symbiont contract surface: OGAR activation + SoA zero-copy reader). Next: the surrealdb-side FixedSizeBinary(512) SoA path plan.

## 2026-06-20 (cont.¹³) — clean separation: NEW `lance-graph-ogar` activation crate (OGAR AR surface), #563 merged

**Main thread (Opus), autoattended.** Operator: "what about clean separation — lance-graph-ontology OGIT / lance-graph-ogar OGAR" + correction "OGAR isn't just vocab, it's classes, ClassView, active-record shape" + "563 merged". Rebased jirak onto new main (ff1a3452 = merged #563, so `contract::ogar_codebook` is now ON main).

**Discovery (consult-don't-guess):** OGAR is the Active-Record Core and ALREADY speaks the contract — `ogar-class-view::OgarClassView` already `impl lance_graph_contract::ClassView` (32 promoted concepts → ObjectView/render_rows), git-depping `lance-graph-contract@main`. `ogar-vocab::Class` = the AR shape (attrs + family Associations); `canonical_concept_id == ClassId == NodeGuid.classid` low u16. So the AR bridge already exists OGAR-side; the lance-graph side just needs ACTIVATION, not a new bridge. Also: `ogar-ontology` is zero-dep; `ogar-adapter-surrealql` default = light `emit()` DDL (no surrealdb); its `surrealdb-parser` feature (the `unmap()` half, rust 1.95+) is the only heavy part.

**NEW `crates/lance-graph-ogar`** (operator chose "Full AR surface"): re-exports ogar-vocab + ogar-class-view + ogar-ontology + ogar-adapter-surrealql under stable names + `OgarClassView`/`Class` + `contract` passthrough; hosts the **parity-guard** (`parity::assert_codebook_parity`: bijective `contract::ogar_codebook::CODEBOOK ⇄ ogar_vocab::class_ids::ALL` + domain agreement) that FAILS THE BUILD on codebook drift. Features: `default = []` (light: all four crates, emit-only), `surrealql-parser` (the surrealdb parser half), `serde` passthrough. **EXCLUDED** from the workspace with its own `[workspace]` root; **git-deps OGAR@main + lance-graph-contract@main = ONE contract source** (same as ogar-class-view's) so the `impl ClassView` matches the trait the guard checks — NO `[patch]` (the symbiont alignment; a path+git mix would be two distinct contract types). This is the clean separation: `lance-graph-ontology = OGIT` (TTL spine), `lance-graph-ogar = OGAR` (AR surface), `contract` = zero-dep traits + the OGAR-absent `ogar_codebook` mirror.

**Auto-activation = Cargo presence** (no runtime detection): a build pulling `lance-graph-ogar` (golden image via symbiont, or q2/medcare) gets the REAL OGAR Class/ClassView/codebook + full `from_alias` normalizer + the drift fuse; a build without it carries the contract's zero-dep mirror + the bare `ClassView` trait (OGAR stays headless-capable — depending on the zero-dep contract is the compile-time handshake, not "needing lance-graph").

Verified: `cargo test --manifest-path crates/lance-graph-ogar/Cargo.toml` **3/3** (parity bijection ≥32 concepts, classid↔codebook-id identity, OgarClassView-is-a-ClassView); `lance-graph-contract` resolved to ONE source (git main #ff1a3452); clippy `-D warnings --all-targets` + fmt clean. Added to workspace `exclude` (next to symbiont). New PR off main (jirak). EPIPHANY `E-OGAR-IS-AR-CORE-AUTOACTIVATED-BY-CARGO-PRESENCE`; plan D-OVC-5.

## 2026-06-20 (cont.¹²) — D-OVC realign LANDED: contract classids follow OGAR 0xDDCC + ogar_codebook mirror

**Main thread (Opus), autoattended.** Operator "562 merged, Rebase" + earlier `AskUserQuestion` greenlight (realign 0xDDCC / wire-compat / FMA=Health 0x0901). Rebased the jirak branch onto new main (6075d007, post #561+#562; #562 = bridge-codebook-convergence, different files — no conflict) and executed the migration plan's D-OVC deliverables, resolving ISS-CLASSID-OGAR-DRIFT.
Expand Down
34 changes: 34 additions & 0 deletions .claude/board/EPIPHANIES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,37 @@
## 2026-06-20 — E-SURREALDB-SECOND-BRAIN-IS-ZERO-COPY-IFF-FIXEDSIZEBINARY — surrealdb (kv-lance) can become a zero-copy "second brain" inside lance-graph ONLY if it stores each node as an uncompressed `FixedSizeBinary(512)` LE blob; the contract a store satisfies is `node_rows_from_le_bytes(&[u8]) -> Option<&[NodeRow]>` (the inverse of `NodeRowPacket::as_le_bytes`), and a variable-length `Binary` column does NOT qualify

**Status:** FINDING (brutal feasibility pass, 2026-06-20; contract primitive shipped, surrealdb side planned).

Operator proposal: "a contract in surrealdb that ensures LE contract to the lance-graph SoA view → zero-copy symbiont; surrealdb becomes a second brain inside lance-graph." Verified against the real code on both sides:

**lance-graph side — already zero-copy-ready:** `NodeRow` is `#[repr(C, align(64))]`, 512 bytes (const-asserted), key(16)+edges(16)+value(480), all canon-LE. `NodeRowPacket::as_le_bytes` already casts `&[NodeRow] → &[u8]` (the WRITE path). The missing piece — the READ path — is now shipped: **`node_rows_from_le_bytes(&[u8]) -> Option<&[NodeRow]>`** (checked: `len % 512 == 0` AND `ptr % 64 == 0`, else `None` → caller copies rather than risk UB). That function IS the LE contract a backing store satisfies.

**surrealdb side — NOT zero-copy as scaffolded:** the `.claude/lance-backend` Arrow schema stores `val: DataType::Binary` (variable-length `BinaryArray` = offsets + an unaligned, non-fixed-stride value buffer). That **cannot** be cast to `&[NodeRow]`. The SoA value path needs `DataType::FixedSizeBinary(512)` (a single contiguous N×512 buffer, which arrow-rs allocates 64-byte aligned) so the column buffer IS a `&[NodeRow]` in place.

**The two honest caveats (brutal):**
1. **Zero-copy on the VALUE requires the column be UNcompressed.** A Lance-compressed `FixedSizeBinary` decodes to a contiguous buffer first — that's ONE copy (still no per-field deserialize, far better than serde, but not literally zero). The KEY (16 bytes) is always addressable zero-copy (OGAR canon: "the key is never compressed"). So: zero-copy address always; zero-copy value iff stored uncompressed.
2. **Direction of the contract:** the LE layout is OWNED by `lance-graph-contract` (`NodeRow` + `node_rows_from_le_bytes`); surrealdb SATISFIES it by depending on the **zero-dep** contract (the handshake, not the engine — OGAR-pattern) and storing `FixedSizeBinary(512)`. "Second brain" = surrealdb's kv-lance bytes ARE the SoA the cognitive shader reads in place; surrealdb adds SurrealQL + MVCC + Lance versioning over the SAME bytes, no serialize boundary.

Shipped: `node_rows_from_le_bytes` + round-trip/reject tests (712 lib green, clippy+fmt clean). Planned: surrealdb-side `FixedSizeBinary(512)` SoA value path + read-through (the `.claude/lance-backend` 12-day wiring). Cross-ref: AGENT_LOG 2026-06-20 (cont.¹⁴); `soa_envelope::SoaEnvelope`; surrealdb `.claude/lance-backend/lance/schema.rs`; OGAR canon "the GUID is the key of key-value … the key is never compressed."

## 2026-06-20 — E-OGAR-IS-AR-CORE-AUTOACTIVATED-BY-CARGO-PRESENCE — OGAR is the Active-Record Core (Class + ClassView), not "just vocab"; it already `impl`s the contract's `ClassView`, so a lance-graph-side `lance-graph-ogar` crate AUTO-ACTIVATES the real AR surface wherever it is compiled in (Cargo presence = the switch, no runtime detection), guarded against drift by a parity fuse — while OGAR stays headless-capable and the contract stays zero-dep

**Status:** FINDING (operator clean-separation lock, 2026-06-20; shipped `crates/lance-graph-ogar`).

Two corrections crystallised the design:

1. **OGAR ≠ codebook.** OGAR = *Open Graph of Active Record*: the unit is the **`Class`** (canonical concept + typed attributes + family-edge `Association`s) and its **`ClassView`**. The `u16` codebook id is ONE facet of a Class's identity (`canonical_concept_id == ClassId == NodeGuid.classid` low u16). A bridge that only carried the id would be exactly the "make OGAR stupid" failure the operator warned against.
2. **The AR bridge already exists, OGAR-side.** `ogar-class-view::OgarClassView` already `impl lance_graph_contract::ClassView` (32 promoted concepts → `ObjectView`/`render_rows`), git-depping `lance-graph-contract@main`. So OGAR already *speaks the contract*; depending on the **zero-dep** contract is the compile-time handshake, NOT "needing lance-graph" (contracts compile types, never serialize). OGAR stays fully headless.

**The clean separation (two crates, two responsibilities):**
- `lance-graph-ontology` = **OGIT** (TTL/RDF hydration — the ontology SOURCE).
- `lance-graph-ogar` = **OGAR** (re-export + activation of the full AR surface: ogar-vocab Class/codebook + ogar-class-view ClassView + ogar-ontology + ogar-adapter-surrealql).
- `lance-graph-contract` keeps the **zero-dep `ogar_codebook` mirror** as the OGAR-ABSENT baseline + the `ClassView`/`ObjectView` traits OGAR implements.

**Auto-activation = Cargo presence (no runtime detection).** A build graph that pulls `lance-graph-ogar` (golden image via symbiont, or q2/medcare) gets the REAL OGAR Class/ClassView/codebook + full `from_alias` normalizer + the **parity-guard** (`assert_codebook_parity`: bijective `mirror ⇄ ogar_vocab::class_ids::ALL` + domain agreement) that FAILS THE BUILD on drift. A build without it carries the lean mirror + the bare `ClassView` trait and never knows the difference. **One contract source** is the load-bearing constraint: `lance-graph-ogar` AND `ogar-class-view` both resolve `lance-graph-contract` to git `#main` (no `[patch]`, the symbiont alignment), so the `impl ClassView` matches the trait the guard checks (path + git copies would be two distinct types). The crate is `exclude`d from the workspace (git OGAR deps), built via `--manifest-path`.

Verified: `cargo test --manifest-path crates/lance-graph-ogar/Cargo.toml` 3/3 (parity bijection over ≥32 concepts + classid↔codebook-id identity + OgarClassView-is-a-ClassView), clippy `-D warnings` + fmt clean; resolved `lance-graph-contract` to ONE source (git main #ff1a3452 = merged #563). Cross-ref: AGENT_LOG 2026-06-20 (cont.¹³), plan `ogar-vocab-contract-codebook-migration-v1` D-OVC-5; the `from_alias`-vs-`from_canonical` split (E-... ogar_codebook mirror, #563).

## 2026-06-20 — E-UNIFORM-MORTON-TILE-PYRAMID — making every GUID tier the same size (8×u16) makes the KEY, the per-family CODEBOOK, the VALUE tile, and the PERTURBATION pyramid all the SAME 2bit×2bit 4×4 Morton-tile primitive — so one kernel (Morton + AMX 4×4 BF16 GEMM), one distance (Morton common-prefix = HHTL hop), and one codebook shape (256×256 per tier) govern the whole substrate

**Status:** FINDING (operator design lock, GUID-v2-tail, 2026-06-20).
Expand Down
Loading
Loading