From 1263c27bd37b5fd0d8fe59922bfb1c716671046f Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 18 Jun 2026 19:12:52 +0000 Subject: [PATCH 1/6] =?UTF-8?q?docs(epiphany):=20E-GUID-IS-THE-GRAPH=20?= =?UTF-8?q?=E2=80=94=20the=20substrate=20is=20already=20a=20graph;=20GUID-?= =?UTF-8?q?key=3Dnode,=20EdgeBlock-slot=3Dedge,=20traversal=3Dprefix-route?= =?UTF-8?q?+slot-deref?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Grounding for the q2-rewire session. The GUID IS the key: a node is its 16-byte NodeGuid, the key prerenders (classid->ClassView, HEEL/HIP/TWIG-> cascade, family->basin, identity->instance) zero-value-decode. Edges are key-references (EdgeBlock slot byte -> neighbor local_key). So Cypher traversal is prefix-route + edge-slot deref off the key alone, no new layer. Two inversions corrected: SurrealQL is egress (ExecTarget::SurrealQl), not a Cypher front-end; kanban is the mailbox lifecycle that DISPATCHES a traversal, not the traversal itself. Minimal real wiring = a Backend::MailboxSoa router variant resolving key->row + following edge slots. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01CcpLeEC3XK8Eye53GKBVvi --- .claude/board/EPIPHANIES.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/.claude/board/EPIPHANIES.md b/.claude/board/EPIPHANIES.md index b18d72de..48e4809e 100644 --- a/.claude/board/EPIPHANIES.md +++ b/.claude/board/EPIPHANIES.md @@ -1,3 +1,28 @@ +## 2026-06-18 — E-GUID-IS-THE-GRAPH — the substrate IS a graph already: GUID-key = node, EdgeBlock-slot = edge, traversal = prefix-route + slot-deref, all zero-value-decode; SurrealQL is egress, kanban dispatches + +**Status:** FINDING (grounded in shipped `canonical_node.rs` / `soa_view.rs` / `kanban.rs` / planner polyglot strategies). Written to stop the q2-rewire session from hallucinating a node/edge/Cypher layer that already exists. + +**The spine — the GUID is the key (canon, CLAUDE.md CANON + OGAR P0):** a node IS its 16-byte `NodeGuid`. There is no "node table with a guid column" and nothing to "expose" — the key is the address and the prerender: +- `classid (0..4) → ClassView` (type/class/method-resolution), +- `HEEL/HIP/TWIG (4..10) → cascade tier` (HHTL routing), +- `family (10..13) → basin`, `identity (13..16) → instance`; `local_key()` = bytes 10..16. +All of that resolves **off the key alone, zero value decode** ("the key prerenders nodes — in any way — with zero value decode"). The `MailboxSoaView` columns (`energy`/`edges_raw`/`meta_raw`/`entity_type`/`class_id`/content·topic·angle planes) are the **value side** — "everything the key isn't" (deferred 480 B, Lance-compressible). You never look up a row's GUID; the GUID is how you addressed the row. + +**Edges are key-references, not blobs:** an `EdgeBlock` slot is one byte = a basin-local index that resolves to a neighbor's `local_key`. Two coexisting representations: `EdgeBlock` (12 in-family + 4 out-family adjacency-of-keys, in the canonical `NodeRow`) and `edges_raw() -> &[u64]` (`CausalEdge64`, the causal/W-slot variant on the view). Both are references. + +**Therefore the substrate is ALREADY a graph — traversal needs no new layer:** +- `MATCH (n:Person)` → classid prefix binds `ClassView` (a prefix route on the key). +- `(a)-[r]->(b)` → dereference an `EdgeBlock` slot (byte → neighbor `local_key`). +- Both happen on keys, zero value decode — that is the entire point of GUID-as-key: routing + prerender never touch the compressed value. + +**Two corrections to the q2 framing (what it got inverted):** +1. **SurrealQL is EGRESS, not a Cypher/Gremlin front-end.** Front-end parsers are Cypher/Gremlin/SPARQL/GQL → one planner IR. SurrealQL appears only as `ExecTarget::SurrealQl` (lower the parsed plan, run in substrate) + `ogar-adapter-surrealql` schema registration (`DEFINE TABLE`/`knowable_from`). Flow is `Cypher → IR → (optionally) ExecTarget::SurrealQl`, never "SurrealQL adapter as Cypher." (The "DLL AST adapter" phrasing is the OGAR C++→Rust codegen subsystem — a third, unrelated thing.) +2. **Kanban is the mailbox LIFECYCLE, not the traversal.** `KanbanColumn` = `Planning→CognitiveWork→Evaluation→Commit` (+`Plan`/`Prune`), the Rubicon cycle of ONE mailbox (`phase()`, `try_advance_phase`, `KanbanMove`). A traversal is **dispatched as** the `CognitiveWork` action via `ExecTarget` — fine read as *dispatched-within*, wrong read as *kanban-transition = edge-hop*. "16k" is the `Vsa16kF32` fingerprint width (16384 bits/row), a different axis from a `MailboxSoA` row-count. + +**The minimal real wiring (no new layer):** the only missing piece for Cypher-over-the-canonical-substrate is a `Backend::MailboxSoa` variant in `graph_router` whose scan resolves **key → row** (`from_guid_prefix` / `local_key()`) and follows `EdgeBlock`/`edges_raw` slots. Not a guid value-column; not a SurrealQL front-end; not a kanban-as-traversal. Just: route on the key, deref the edge slot. Cross-refs: `canonical_node::{NodeGuid, EdgeBlock, NodeRow}`, `soa_view::MailboxSoaView`, `kanban::{KanbanColumn, ExecTarget}`, planner `strategy/{cypher,gremlin,sparql,gql}_parse.rs`, `E-OGAR-ROUTER-ENCODER` (the key-prefix router is the same address machinery). + +--- + ## 2026-06-18 — E-PERTURBATION-CASCADE-IS-COMPUTE-DAG — the electricity cascade crate is `compute_dag` already running on a real physical field, and it ships the Weyl bound that certifies the incremental recompute **Status:** FINDING (mechanism mapping; no dependency added). The `crates/perturbation-sim` outage simulator is the physical instance of the SAME topological recompute `ClassView::compute_dag` + `compute_dag_topo_order` + `write_row` express abstractly. Doc-level join only (`crates/perturbation-sim/COMPUTE_DAG_MAPPING.md`); the crate stays zero-dep / workspace-excluded — no `lance-graph-contract` import. Grounds: `E-CHESS-TENSOR-PROVEN`, `E-EXCEL-SHADER-PROJECTION`, `E-OGAR-ROUTER-ENCODER`, `probe-excel-compute-dag-v1`. From d31b968ab244509b2b652484fac0687d16b8df2e Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 18 Jun 2026 19:16:54 +0000 Subject: [PATCH 2/6] =?UTF-8?q?docs(epiphany):=20E-CYPHER-IS-THE-KANBAN-AS?= =?UTF-8?q?T=20=E2=80=94=20a=20kanban=20board=20is=20a=20graph,=20so=20Cyp?= =?UTF-8?q?her=20is=20its=20AST;=20board-ops=20+=20ontology-traversal=20+?= =?UTF-8?q?=20thinking-styles=20+=20SurrealQL=20egress=20are=20ONE=20AST?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A kanban board IS a graph: card=GUID node, column/phase=state, move=edge rewrite, dependency=edge, WIP=count constraint, transition rules=graph schema. Cypher is the AST for graph patterns, so Cypher is the board's native query/mutation language. The planner already shares one AST across Cypher/Gremlin/SPARQL/GQL front-ends + SurrealQL adapter/egress + thinking-style dispatch + kanban phases - odoo's ontology traversal through the SurrealQL AST adapter is the existence proof. These are one AST seen from four sides, not four subsystems. Refines E-GUID-IS-THE-GRAPH correction #2 (the lifecycle state-machine IS a graph; "kanban is not traversal" was a false dichotomy). Scope: "Cypher is the AST" = surface lowering to the shared IR/SurrealQL AST, not a claim the nom parser emits SurrealQL today (DataFusion now; SurrealQL lowering is the lite-unified gate #540). Wiring = Backend::MailboxSoa router variant + Cypher->SurrealQL lowering behind lite-unified. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01CcpLeEC3XK8Eye53GKBVvi --- .claude/board/EPIPHANIES.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/.claude/board/EPIPHANIES.md b/.claude/board/EPIPHANIES.md index 48e4809e..ec1cbb28 100644 --- a/.claude/board/EPIPHANIES.md +++ b/.claude/board/EPIPHANIES.md @@ -1,3 +1,30 @@ +## 2026-06-18 — E-CYPHER-IS-THE-KANBAN-AST — a kanban board IS a graph, so Cypher is its AST; board-ops + ontology-traversal + thinking-style dispatch + SurrealQL egress collapse to ONE shared AST + +**Status:** FINDING (convergence; odoo is the existence proof — ontology traversal already runs through the SurrealQL AST adapter). Refines `E-GUID-IS-THE-GRAPH` correction #2: "kanban is lifecycle, not traversal" was a false dichotomy — the lifecycle state-machine IS a graph, and that's the whole point. + +**The collapse:** a kanban board is a graph, full stop — +- **card → GUID node** (`E-GUID-IS-THE-GRAPH`), +- **column / phase → state** (a `Column` node the card has an `:IN` edge to, or a `classid`/property), +- **move → edge rewrite** (`(c)-[:IN]->(Doing)` ⇒ `(c)-[:IN]->(Done)`), +- **dependency / blocks → edge**, **WIP limit → a count constraint** (a Cypher `MATCH … RETURN count` guard), **swimlane → basin/label**. +- the Rubicon transition rules (`KanbanColumn::can_transition_to`) **ARE the graph schema** (which edges are legal). + +So the board's queries and mutations are graph patterns, and **Cypher is the AST for graph patterns**. Driving the board with Cypher is not a metaphor — it is the board's native query/mutation language. + +**Why it's the obvious move (the four-into-one):** the planner already holds all the pieces, and they share one AST/IR — +1. **Cypher/Gremlin/SPARQL/GQL → one planner IR** (front-end parsers). +2. **SurrealQL AST** = the shared adapter/egress hub that IR lowers into and the substrate runs (`ExecTarget::SurrealQl` + `ogar-adapter-surrealql`). odoo's **ontology traversal already goes through this adapter** — the existence proof. +3. **Thinking styles + MUL** dispatch over that IR (planner `thinking/`, 12 styles, NARS, sigma chain). +4. **Kanban phases** (`KanbanColumn`) are the lifecycle the cards move through. + +These are not four subsystems to be bridged — they are **one AST seen from four sides**: Cypher is the surface syntax, SurrealQL is the adapter/egress, thinking-styles are the planner layer over it, kanban is the board the patterns mutate. **Cypher AS the kanban-board AST unifies them.** Not doing so means re-expressing board moves in a second language while the graph AST sits right there — the dumb path. + +**Concretely:** a board move = a Cypher mutation → planner IR → thinking-style/MUL plan → `ExecTarget::SurrealQl` (or `Native`/`Jit`) over the GUID-keyed substrate; a board query (cards in a column, blocked cards, WIP count) = a Cypher `MATCH` → prefix-route on `classid` + `EdgeBlock`-slot deref, zero-value-decode (`E-GUID-IS-THE-GRAPH`). The `KanbanColumn` lifecycle is the *mailbox cognitive-cycle* instantiation of the same structure; an odoo project board / woa work-order board / q2 case board are *domain* instantiations — **same AST, same substrate, different `classid` + edge schema.** + +**Scope guard (truth-architect):** "Cypher is the AST" = Cypher is the surface that lowers to the shared IR/SurrealQL AST — NOT a claim that the core's nom Cypher parser already emits SurrealQL (it lowers to DataFusion today; the SurrealQL lowering is the `lite-unified` gate #540, default-OFF, process-not-switch). The unification is the architecture; the wiring is the `Backend::MailboxSoa` router variant + the Cypher→SurrealQL lowering behind `lite-unified`. Cross-refs: `E-GUID-IS-THE-GRAPH`, `E-AR-DO-WIRING` (ontology→DO consumers), `lite-unified-surrealql-lance-v1`, planner `thinking/` + `strategy/cypher_parse.rs`, `kanban::{KanbanColumn, ExecTarget}`. + +--- + ## 2026-06-18 — E-GUID-IS-THE-GRAPH — the substrate IS a graph already: GUID-key = node, EdgeBlock-slot = edge, traversal = prefix-route + slot-deref, all zero-value-decode; SurrealQL is egress, kanban dispatches **Status:** FINDING (grounded in shipped `canonical_node.rs` / `soa_view.rs` / `kanban.rs` / planner polyglot strategies). Written to stop the q2-rewire session from hallucinating a node/edge/Cypher layer that already exists. From 8809ec5af3be8d1da947046f07e6e00c7e205253 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 18 Jun 2026 19:20:53 +0000 Subject: [PATCH 3/6] =?UTF-8?q?docs(plan):=20cypher-kanban-ast-unification?= =?UTF-8?q?-v1=20=E2=80=94=20Cypher=20IS=20the=20kanban-board=20AST;=20fou?= =?UTF-8?q?r=20subsystems=20=E2=86=92=20one=20AST?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Captures the E-GUID-IS-THE-GRAPH + E-CYPHER-IS-THE-KANBAN-AST unification before it dilutes, and sequences the q2-rewire wiring: Inc0 Backend::MailboxSoa router variant (key->row, EdgeBlock-slot deref, zero-value-decode), Inc1 Cypher-> SurrealQL lowering behind lite-unified (#540, default-OFF), Inc2 kanban-board- as-Cypher, Inc3 q2 consumer. Gates F1-F5; datafusion stays default. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01CcpLeEC3XK8Eye53GKBVvi --- .claude/board/INTEGRATION_PLANS.md | 10 ++ .../plans/cypher-kanban-ast-unification-v1.md | 107 ++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 .claude/plans/cypher-kanban-ast-unification-v1.md diff --git a/.claude/board/INTEGRATION_PLANS.md b/.claude/board/INTEGRATION_PLANS.md index e28f22c9..51c2c7fd 100644 --- a/.claude/board/INTEGRATION_PLANS.md +++ b/.claude/board/INTEGRATION_PLANS.md @@ -1,3 +1,13 @@ +## 2026-06-18 — cypher-kanban-ast-unification-v1 (Cypher IS the kanban-board AST; the GUID-keyed substrate IS the graph; four subsystems → one AST) + +**Status:** PLAN (pre-5+3-council). **Plan file:** `.claude/plans/cypher-kanban-ast-unification-v1.md`. Grounded by `E-GUID-IS-THE-GRAPH` + `E-CYPHER-IS-THE-KANBAN-AST`; odoo ontology-traversal-through-SurrealQL-AST = existence proof. +**Thesis:** a kanban board is a graph (card=GUID node, column/phase=state, move=edge rewrite, dep=edge, WIP=count guard, `can_transition_to`=schema), so Cypher is its AST; the planner already shares ONE IR across Cypher/Gremlin/SPARQL/GQL front-ends + SurrealQL adapter/egress + thinking-styles/MUL + kanban phases — one AST seen from four sides. +- **Inc 0:** `Backend::MailboxSoa` router variant — key→row via `from_guid_prefix`/`local_key`, edge = `EdgeBlock`-slot deref; `MATCH (n:Label)` = classid prefix-route, `(a)-[r]->(b)` = slot-deref, zero-value-decode. **Inc 1:** Cypher→SurrealQL lowering behind `lite-unified` (#540, default-OFF). **Inc 2:** kanban-board-as-Cypher over the GUID substrate. **Inc 3:** q2 consumer (domain classid+edge schema; consumes lance-graph, never substitutes). +- **Gates:** F1 backend parity vs DataFusion · F2 zero-value-decode 1-hop · F3 illegal-move rejected at plan time · F4 `lite-unified`-OFF byte-identical · F5 no new layer. +**Scope line:** "Cypher is the AST" = surface lowering to the shared IR/SurrealQL AST, NOT the nom parser emitting SurrealQL today. datafusion NOT deprecated. **Repos:** lance-graph (router + planner) + q2 (consumer). Branch `claude/q2-substrate-grounding`. + +--- + ## 2026-06-18 — probe-excel-compute-dag-v1 (land ClassView::compute_dag on the 2-axis grid; the NNUE-incremental existence proof) **Status:** CONJECTURE / probe scope. **Plan file:** `.claude/plans/probe-excel-compute-dag-v1.md`. Grounded by `E-CHESS-TENSOR-PROVEN` + `E-EXCEL-SHADER-PROJECTION` + `E-OGAR-ROUTER-ENCODER`. diff --git a/.claude/plans/cypher-kanban-ast-unification-v1.md b/.claude/plans/cypher-kanban-ast-unification-v1.md new file mode 100644 index 00000000..3232d464 --- /dev/null +++ b/.claude/plans/cypher-kanban-ast-unification-v1.md @@ -0,0 +1,107 @@ +# cypher-kanban-ast-unification-v1 — Cypher IS the kanban-board AST; the GUID-keyed substrate IS the graph; four subsystems collapse to one + +> **Status:** PLAN (pre-5+3-council). Captures the unification from +> `E-GUID-IS-THE-GRAPH` + `E-CYPHER-IS-THE-KANBAN-AST` before it dilutes, +> and sequences the q2-rewire wiring. **datafusion stays the default query +> engine; the SurrealQL lowering rides the `lite-unified` gate (#540, +> default-OFF) — process, not switch.** + +## The thesis (one AST, four sides) + +A kanban board is a graph. The GUID is the key. Therefore Cypher — the AST for +graph patterns — is the board's native query/mutation language, and the planner +already shares **one IR/AST** across all four sides: + +| Side | Surface | Already shipped | +|---|---|---| +| **Query language** | Cypher / Gremlin / SPARQL / GQL → one IR | planner `strategy/{cypher,gremlin,sparql,gql}_parse.rs` | +| **Adapter / egress** | SurrealQL AST (`DEFINE`/traversal) | `ExecTarget::SurrealQl` + `ogar-adapter-surrealql`; odoo ontology traversal = existence proof | +| **Planner layer** | thinking-styles + MUL over the IR | planner `thinking/` (12 styles, NARS, sigma chain), `mul/` | +| **Board** | kanban phases the cards move through | `kanban::{KanbanColumn, ExecTarget}` | + +Board ⇄ graph mapping (no new types): +- **card → GUID node** (`NodeGuid` key; `classid→ClassView`, `local_key`=family++identity) +- **column / phase → state** (a `Column` node via `:IN` edge, or a `classid`/property) +- **move → edge rewrite** (`(c)-[:IN]->(Doing)` ⇒ `(c)-[:IN]->(Done)`) +- **dependency / blocks → edge**; **WIP limit → a Cypher `count` guard**; **swimlane → basin/label** +- **`KanbanColumn::can_transition_to` → the graph schema** (which edges are legal) + +The `KanbanColumn` cognitive cycle is the *mailbox* instantiation; an odoo project +board / woa work-order board / q2 case board are *domain* instantiations — +**same AST, same substrate, different `classid` + edge schema.** + +## What's already true (no work) + +- **The substrate is the graph** (`E-GUID-IS-THE-GRAPH`): node = `NodeGuid` key, + edge = `EdgeBlock` slot (byte → neighbor `local_key`) or `CausalEdge64`, + traversal = prefix-route + slot-deref, zero value decode. +- **Cypher parses** (core nom parser, 44 tests: node + relationship patterns, + var-length `*1..2`, WHERE/RETURN/etc). +- **The polyglot front-ends → one IR**; **thinking-styles + MUL** plan over it; + **`ExecTarget::SurrealQl`** is the egress. +- **odoo ontology traversal already runs through the SurrealQL AST adapter** — + the existence proof that Cypher/ontology-over-SurrealQL works. + +## The gap (what this plan wires) — additive, layout-preserving + +### Inc 0 — `Backend::MailboxSoa` router variant +`graph_router::Backend` gains a `MailboxSoa` variant whose scan: +- resolves **key → row** via `NodeGuid::{from_guid_prefix, local_key}` (no guid + value-column — the key IS the address), +- follows edges by **`EdgeBlock` slot deref** (byte → neighbor `local_key`) and/or + `MailboxSoaView::edges_raw` (`CausalEdge64`), +- a Cypher `MATCH (n:Label)` lowers to a **classid prefix route**; `(a)-[r]->(b)` + to an **edge-slot deref** — both zero-value-decode. +Additive to the existing 3-backend router (DataFusion / Blasgraph / Palette); no +`NodeRow`/stride/`ENVELOPE_LAYOUT_VERSION` change. + +### Inc 1 — Cypher → SurrealQL lowering behind `lite-unified` (default-OFF) +The board's mutations/queries lower to SurrealQL (`ExecTarget::SurrealQl`) **only +under `lite-unified`**; datafusion stays the default. This is the egress side of +the AST, gated per the #540 process-not-switch invariant. + +### Inc 2 — kanban-board-as-Cypher over the GUID substrate +Express board ops as Cypher patterns dispatched through the planner with +thinking-styles/MUL: a move = a Cypher edge-rewrite → IR → style/MUL plan → +`ExecTarget`; a query (cards-in-column / blocked / WIP-count) = a Cypher `MATCH`. +The transition-legality (`KanbanColumn::can_transition_to`) is the schema guard. + +### Inc 3 — q2 consumer wiring (the rewire) +q2 (Palantir-Gotham/neo4j-aspiring) cases = a **domain `classid` + edge schema** +over the same substrate + AST. q2 depends on lance-graph as the hot path (NOT a +substitute — `.claude/rules/architectural-compliance.md`); its board/case +traversal is Cypher over `Backend::MailboxSoa`. + +## Falsification gates + +- **F1 (router):** a Cypher `MATCH (n:Label)` over `Backend::MailboxSoa` returns + the same node set as the DataFusion backend on the same data (backend parity). +- **F2 (zero-decode):** a 1-hop traversal touches only key + `EdgeBlock` bytes, + never the 480 B value slab (assert via a value-access counter / borrow check). +- **F3 (board legality):** an illegal kanban move (`!can_transition_to`) is + rejected at plan time, not after the edge rewrite. +- **F4 (gate isolation):** with `lite-unified` OFF, behaviour is byte-identical to + today (datafusion path); the SurrealQL lowering is unreachable. +- **F5 (no new layer):** the unification adds ONE router variant + ONE lowering + path behind a flag — no new node/edge type, no second object model, no + kanban-as-traversal type. + +## Scope guards (truth-architect) + +- "Cypher is the kanban AST" = Cypher is the **surface** that lowers to the shared + IR/SurrealQL AST — NOT a claim the nom parser emits SurrealQL today (it lowers + to DataFusion; SurrealQL lowering is Inc 1 behind `lite-unified`). +- **datafusion is NOT deprecated** (#540). The router gains a backend; it does not + lose one. +- No measured-perf claim without a bench (F1 is a correctness/parity gate, not a + speed gate). +- The mailbox-`KanbanColumn` lifecycle and a domain board are the SAME structure; + do NOT fork a second kanban type per domain — vary `classid` + edge schema. + +## Cross-refs +`E-GUID-IS-THE-GRAPH`, `E-CYPHER-IS-THE-KANBAN-AST`, `E-AR-DO-WIRING` +(ontology→DO consumers), `lite-unified-surrealql-lance-v1` (#540 gate), +`canonical_node::{NodeGuid, EdgeBlock, NodeRow}`, `soa_view::MailboxSoaView`, +`kanban::{KanbanColumn, ExecTarget}`, planner `thinking/` + +`strategy/cypher_parse.rs`, `graph_router::Backend`, +`.claude/rules/architectural-compliance.md` (q2 must consume, not substitute). From dd731bda3b4b419298010f1cde127260df435131 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 18 Jun 2026 19:31:41 +0000 Subject: [PATCH 4/6] feat(contract)+docs: E-OGAR-IS-FOUNDRY capstone + 5+3 council corrections + the key->row baton MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Foundry/Gotham reduces to "write the OGAR class schema + inheritance"; every other layer is generic machinery over it: ontology=classid->ClassView+inheritance, AR behavior=DO/THINK (ActionDef vs MethodSig), pipelines=compute_dag, apps=Jinja-over-classes (class_id->ontology seam), query=Cypher<->SurrealQL one IR. Captured as E-OGAR-IS-FOUNDRY. 5+3 council on cypher-kanban-ast-unification-v1 (8/8): core thesis SOUND (StepDomain::Kanban exists; 4 polyglot parsers already share one PlanInput IR). Corrections applied: - CATCH-CRITICAL (baton-auditor): MailboxSoaView had no key->row resolver. Added row_for_local_key(local_key) -> Option as a deferred-binding default-None method (matches the qualia/episodic_witness deferral pattern). +1 test, clippy clean. - from_guid_prefix is on NiblePath (hhtl.rs:262), not NodeGuid — corrected in the epiphany + plan. - "odoo existence proof" downgraded FINDING->CONJECTURE (tagged const + classify, not a running traversal); ogar-adapter-surrealql is not a crate (surreal_container stub, BLOCKED(C)). - headline demoted "four sides of one AST" -> "one IR, four relationships". - resequenced: first shippable = Inc0+F1/F2 on the Native path; Inc1 Cypher->SurrealQL is dependency-on lite-unified OQ-LU-2, not a duplicate. Three ripple boundaries pinned. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01CcpLeEC3XK8Eye53GKBVvi --- .claude/board/EPIPHANIES.md | 23 ++++++++++++++ .../plans/cypher-kanban-ast-unification-v1.md | 17 ++++++++++ crates/lance-graph-contract/src/soa_view.rs | 31 +++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/.claude/board/EPIPHANIES.md b/.claude/board/EPIPHANIES.md index ec1cbb28..acc340e2 100644 --- a/.claude/board/EPIPHANIES.md +++ b/.claude/board/EPIPHANIES.md @@ -1,5 +1,28 @@ +## 2026-06-18 — E-OGAR-IS-FOUNDRY — being Palantir Foundry / Gotham reduces to "write the OGAR class schema + inheritance"; everything else (traversal, query, pipelines, actions, low-code apps) is generic machinery over it via the shared AST + +**Status:** FINDING (capstone; operator-stated). The platform-level reading of the whole arc: Foundry/Gotham is not a platform to rebuild — it is an **OGAR class-schema-inheritance exercise**, because every other Foundry/Gotham layer is already generic machinery the workspace ships, parameterized only by `classid`. + +**The reduction (each Foundry/Gotham layer → an OGAR primitive already in code):** + +| Foundry / Gotham layer | OGAR primitive | Shipped surface | +|---|---|---| +| **Ontology** (object types + links) | OGAR **class schema + inheritance** | `classid → ClassView`; `effective_actions` / effective-methods = inheritance | +| **Objects + links** | GUID node + `EdgeBlock` edge | `E-GUID-IS-THE-GRAPH` (key=node, slot=edge, zero-value-decode) | +| **AR object behavior** | **DO vs THINK = Active Record** | THINK = `ClassView`/`MethodSig` (fields+methods, read/compute); DO = `ActionDef`/`ActionInvocation` (actions, gated RBAC→state-guard→MUL) | +| **Pipelines / transforms** | `compute_dag` topological recompute | `ClassView::compute_dag` + `compute_dag_topo_order` (`E-EXCEL`/`E-CHESS`/`E-PERTURBATION`) | +| **Apps / low-code / dashboards** | **Jinja/templates over OGAR classes** | `soa_view.rs:57` — `class_id → OGIT ontology → "label inheritance, column projection, jinja templates"` resolve one layer up | +| **Query / traversal surface** | **Cypher ⇄ SurrealQL, one shared AST** | `E-CYPHER-IS-THE-KANBAN-AST`; polyglot parsers → one `PlanInput` IR; SurrealQL is egress | + +**The headline:** AR-shaped DO/THINK objects + the shared Cypher/SurrealQL AST mean **any low-code or Jinja template runs over OGAR classes** without bespoke per-app wiring — the template binds to the class's fields (THINK) and actions (DO), the AST traverses/queries/mutates them, `compute_dag` recomputes derived fields, the DO-arm gate authorizes writes. So a vertical (medical / work-orders / intelligence cases / project boards) = *write its OGAR classes + inheritance*, and the platform behaviors fall out. That is the Foundry-aspiring superpower: the reduction of "build a platform" to "declare a schema." + +**Scope guard (truth-architect, carried from the 5+3 on the sibling plan):** "everything else is shipped" is the *architecture*, not "all wired today." The honest gaps the council found: (a) `ogar-adapter-surrealql` is NOT a crate — the nearest is `surreal_container::SurrealStore` (a `BLOCKED(C)` stub); the Cypher→SurrealQL lowering rides `lite-unified` (#540, default-OFF). (b) the "odoo ontology traversal already runs through SurrealQL" claim is a tagged `const ActionDef` + `classify_odoo` classification, **not** a running end-to-end traversal — CONJECTURE, not FINDING, until an `ExecTarget::SurrealQl` executor arm exists. (c) Jinja-over-classes is the `class_id→ontology` seam (real hook) + `lance-graph-ontology` resolution — the template *engine* binding is not yet a shipped path. The reduction is the doctrine; the wiring is the `cypher-kanban-ast-unification-v1` increments. Cross-refs: `E-CYPHER-IS-THE-KANBAN-AST`, `E-GUID-IS-THE-GRAPH`, `E-AR-DO-WIRING` (DO/THINK arms), `cypher-kanban-ast-unification-v1`, `canonical_node`/`class_view`/`action`/`soa_view`. + +--- + ## 2026-06-18 — E-CYPHER-IS-THE-KANBAN-AST — a kanban board IS a graph, so Cypher is its AST; board-ops + ontology-traversal + thinking-style dispatch + SurrealQL egress collapse to ONE shared AST +**Council correction (2026-06-18, 5+3 on `cypher-kanban-ast-unification-v1`):** three legs of this entry were over-stated and are hereby qualified (the CORE — board-is-graph, Cypher-is-graph-AST — stands; convergence-architect confirmed 3 of 4 sides share one shipped `PlanInput` IR): **(1)** "one AST seen from four sides" → say **"one IR, four *relationships*"** (surface = Cypher; egress = SurrealQL; planner-layer = thinking-styles; mutated = board) — they are *is* / *lowers-to* / *plans-over* / *is-mutated-by*, not one identity (dilution-collapse-sentinel). **(2)** "odoo ontology traversal already runs through the SurrealQL AST adapter — existence proof" is **CONJECTURE, not FINDING**: it is a tagged `const ActionDef`(`ExecTarget::SurrealQl`) + `classify_odoo`, with NO executor arm and NO Cypher→SurrealQL lowering in source; `ogar-adapter-surrealql` is not a crate (truth-architect + runtime-archaeologist). **(3)** `from_guid_prefix` lives on **`NiblePath`** (`hhtl.rs:262`), NOT `NodeGuid`; and the wiring is **blocked CATCH-CRITICAL** until `MailboxSoaView` gains a key→row resolver (`row_for_local_key`, now added default-`None`) — the View had only `n_rows`, no way back from the canon address to a row (baton-handoff-auditor). Preserve the distinction `E-GUID` correction #2 drew: mailbox-cycle `KanbanColumn` phase-advance (traversal *dispatched-within* `CognitiveWork`) ≠ domain-board column move (an edge-rewrite) — same AST surface, two semantics (ripple-architect). + **Status:** FINDING (convergence; odoo is the existence proof — ontology traversal already runs through the SurrealQL AST adapter). Refines `E-GUID-IS-THE-GRAPH` correction #2: "kanban is lifecycle, not traversal" was a false dichotomy — the lifecycle state-machine IS a graph, and that's the whole point. **The collapse:** a kanban board is a graph, full stop — diff --git a/.claude/plans/cypher-kanban-ast-unification-v1.md b/.claude/plans/cypher-kanban-ast-unification-v1.md index 3232d464..ccbc5cc2 100644 --- a/.claude/plans/cypher-kanban-ast-unification-v1.md +++ b/.claude/plans/cypher-kanban-ast-unification-v1.md @@ -105,3 +105,20 @@ traversal is Cypher over `Backend::MailboxSoa`. `kanban::{KanbanColumn, ExecTarget}`, planner `thinking/` + `strategy/cypher_parse.rs`, `graph_router::Backend`, `.claude/rules/architectural-compliance.md` (q2 must consume, not substitute). + +--- + +## 5+3 Council verdict (2026-06-18) — revisions applied + +8/8 reported. Core thesis **SOUND** (convergence: `StepDomain::Kanban` exists; all 4 polyglot parsers already return one `PlanInput`/`QueryFeatures` IR — 3 of 4 sides are genuinely one IR). Revisions: + +1. **Headline demoted** (dilution-sentinel): "four sides of one AST" → **"one IR, four *relationships*"** (surface=Cypher / egress=SurrealQL / planner-layer=styles / mutated=board). +2. **CATCH-CRITICAL fixed first** (baton-auditor): `MailboxSoaView` had no key→row resolver — added `row_for_local_key(local_key) -> Option` default-`None` (deferred binding). `from_guid_prefix` is on **`NiblePath`** (`hhtl.rs:262`), not `NodeGuid` — Inc 0 routes via `NiblePath::from_guid_prefix(&guid)` + `NodeGuid::local_key` + `MailboxSoaView::row_for_local_key`. +3. **Resequenced** (integration-lead): **first shippable = Inc 0 + F1/F2 ALONE**, on the DataFusion-default `ExecTarget::Native` path — zero SurrealQL, zero `lite-unified`, zero q2 coupling. **Inc 1 (Cypher→SurrealQL) is a *dependency-on* `lite-unified-v1`'s OQ-LU-2, NOT a duplicate deliverable** (the two plans were claiming the same lowering). +4. **Three boundaries to pin before Inc 0 lands** (ripple-architect): + - **(b) edge-representation is `classid`-resolved, not query-guessed:** a relationship-type binds to `EdgeBlock` (adjacency) XOR `CausalEdge64` (causal) via the class's `EdgeCodecFlavor`/`ReadMode` — the router must not pick by availability. + - **(a) domain-board transition schema ≠ `KanbanColumn`:** a domain board's legal moves resolve via `classid → ClassView`, NOT `KanbanColumn::can_transition_to` (that encodes the *mailbox* Rubicon DAG only). Same graph shape, different transition algebra. + - **(d) board mutation routes through the DO arm:** a move = `ActionInvocation` through the commit gate (def-match→RBAC→state-guard→MUL), NOT a raw `MATCH…SET` edge-rewrite — otherwise WIP/permission/MUL guards are bypassed. Add F6: an illegal move fails at plan time for ALL guard classes, not just Rubicon legality. +5. **Status downgrades** (truth-architect + archaeologist): the "odoo existence proof" is a tagged `const` + `classify_odoo`, NOT a running traversal → CONJECTURE; "zero-value-decode" (F2) is design-intent until the value-access counter exists; `ogar-adapter-surrealql` is not a crate (it's `surreal_container::SurrealStore`, a `BLOCKED(C)` stub). + +**Net first increment (this PR):** the `row_for_local_key` deferred-binding contract method (the named dropped baton) — additive, zero-dep, testable now. `Backend::MailboxSoa` (Inc 0 proper) follows once the three boundaries above are pinned. diff --git a/crates/lance-graph-contract/src/soa_view.rs b/crates/lance-graph-contract/src/soa_view.rs index b488575d..6a8e6dc8 100644 --- a/crates/lance-graph-contract/src/soa_view.rs +++ b/crates/lance-graph-contract/src/soa_view.rs @@ -68,6 +68,26 @@ pub trait MailboxSoaView { self.entity_type()[row] } + /// Resolve a canonical [`NodeGuid::local_key`](crate::canonical_node::NodeGuid::local_key) + /// (bytes 10..16 = family++identity, the basin-local discriminator) to a row + /// index in this view — the **key→row baton** a `Backend::MailboxSoa` graph + /// router needs to land a Cypher `MATCH`/edge-slot deref on the GUID-keyed + /// substrate (`cypher-kanban-ast-unification-v1` Inc 0; the baton-handoff-auditor's + /// CATCH-CRITICAL — the View previously exposed only `n_rows`, with no way to go + /// from the canon address back to a row). + /// + /// **Default = `None` (zero-fallback, deferred binding).** A view that has NOT + /// materialized a per-row key index returns `None` for every key — the same + /// deferred-accessor discipline as `qualia` / `episodic_witness` below: the + /// resolver contract is declared here so the router signature can name it, and an + /// owner that stores keys (the in-RAM `MailboxSoA`, once it carries a `local_key` + /// column) overrides this. Until then a consumer that gets `None` falls back to + /// the positional `(mailbox_id, row)` address, never a wrong row. + #[inline] + fn row_for_local_key(&self, _local_key: u64) -> Option { + None + } + // NOTE (follow-up): the qualia column (`QualiaI4_16D`) accessor is intentionally omitted — // add `fn qualia(&self) -> &[crate::qualia::QualiaI4_16D]` when the first consumer // (planner strategy selection) needs it; keep the read surface minimal until then. @@ -232,6 +252,17 @@ mod tests { assert_eq!(soa.w_slot(), 7); } + #[test] + fn row_for_local_key_defaults_to_none_until_a_key_index_is_materialized() { + // Deferred-binding default: a view with no per-row key column resolves + // every local_key to None — the consumer falls back to the positional + // (mailbox_id, row) address, never a wrong row. The Backend::MailboxSoa + // router can name this baton; an owner that stores keys overrides it. + let soa = sample(); + assert_eq!(soa.row_for_local_key(0), None); + assert_eq!(soa.row_for_local_key(u64::MAX), None); + } + #[test] fn owner_advances_phase_and_sets_libet_anchor() { let mut soa = sample(); From 31571a5de5f7162d9b2ecd6089ff7da517da9d30 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 18 Jun 2026 19:45:29 +0000 Subject: [PATCH 5/6] docs(plan): align Inc 0 / Inc 2 / thesis / F3 with the 5+3 verdict (one contract) PR #542 review: the body sections still named the pre-verdict contract while the verdict below corrected it. Brought onto one contract: - Inc 0 key->row: NiblePath::from_guid_prefix(&guid) + NodeGuid::local_key + MailboxSoaView::row_for_local_key (from_guid_prefix is on NiblePath, not NodeGuid). - Inc 0 edge-rep: classid-resolved (EdgeCodecFlavor) EdgeBlock XOR CausalEdge64, never guessed by availability (verdict 4b). - thesis + Inc 2 legality: mailbox-cycle = KanbanColumn::can_transition_to; domain-board = classid->ClassView; board mutation routes through the DO-arm commit gate, not raw MATCH...SET (verdict 4a/4d). - F3 folds in the all-guard-classes gate (was F6 in the verdict). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01CcpLeEC3XK8Eye53GKBVvi --- .../plans/cypher-kanban-ast-unification-v1.md | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/.claude/plans/cypher-kanban-ast-unification-v1.md b/.claude/plans/cypher-kanban-ast-unification-v1.md index ccbc5cc2..02701177 100644 --- a/.claude/plans/cypher-kanban-ast-unification-v1.md +++ b/.claude/plans/cypher-kanban-ast-unification-v1.md @@ -24,7 +24,9 @@ Board ⇄ graph mapping (no new types): - **column / phase → state** (a `Column` node via `:IN` edge, or a `classid`/property) - **move → edge rewrite** (`(c)-[:IN]->(Doing)` ⇒ `(c)-[:IN]->(Done)`) - **dependency / blocks → edge**; **WIP limit → a Cypher `count` guard**; **swimlane → basin/label** -- **`KanbanColumn::can_transition_to` → the graph schema** (which edges are legal) +- **legal moves → the graph schema:** mailbox-lifecycle legality stays with + `KanbanColumn::can_transition_to`; domain-board legality resolves via + `classid → ClassView` (NOT `KanbanColumn` — see verdict §4a) The `KanbanColumn` cognitive cycle is the *mailbox* instantiation; an odoo project board / woa work-order board / q2 case board are *domain* instantiations — @@ -46,10 +48,13 @@ board / woa work-order board / q2 case board are *domain* instantiations — ### Inc 0 — `Backend::MailboxSoa` router variant `graph_router::Backend` gains a `MailboxSoa` variant whose scan: -- resolves **key → row** via `NodeGuid::{from_guid_prefix, local_key}` (no guid - value-column — the key IS the address), -- follows edges by **`EdgeBlock` slot deref** (byte → neighbor `local_key`) and/or - `MailboxSoaView::edges_raw` (`CausalEdge64`), +- resolves **key → row** via `NiblePath::from_guid_prefix(&guid)` + `NodeGuid::local_key` + + `MailboxSoaView::row_for_local_key` (no guid value-column — the key IS the address; + `from_guid_prefix` is on `NiblePath`, not `NodeGuid` — see verdict §2), +- follows edges via the **`classid`-resolved** representation (verdict §4b) — + `EdgeBlock` slot deref (adjacency, byte → neighbor `local_key`) **XOR** + `MailboxSoaView::edges_raw` (`CausalEdge64`, causal), selected by the class's + `EdgeCodecFlavor`/`ReadMode`, never guessed by availability, - a Cypher `MATCH (n:Label)` lowers to a **classid prefix route**; `(a)-[r]->(b)` to an **edge-slot deref** — both zero-value-decode. Additive to the existing 3-backend router (DataFusion / Blasgraph / Palette); no @@ -62,9 +67,11 @@ the AST, gated per the #540 process-not-switch invariant. ### Inc 2 — kanban-board-as-Cypher over the GUID substrate Express board ops as Cypher patterns dispatched through the planner with -thinking-styles/MUL: a move = a Cypher edge-rewrite → IR → style/MUL plan → -`ExecTarget`; a query (cards-in-column / blocked / WIP-count) = a Cypher `MATCH`. -The transition-legality (`KanbanColumn::can_transition_to`) is the schema guard. +thinking-styles/MUL: a move = a Cypher edge-rewrite **routed through the DO arm** +(`ActionInvocation` commit gate: def-match → RBAC → state-guard → MUL — NOT a raw +`MATCH…SET`, see verdict §4d); a query (cards-in-column / blocked / WIP-count) = +a Cypher `MATCH`. Legality is `classid → ClassView`-resolved for a domain board; +`KanbanColumn::can_transition_to` governs only the mailbox cognitive cycle. ### Inc 3 — q2 consumer wiring (the rewire) q2 (Palantir-Gotham/neo4j-aspiring) cases = a **domain `classid` + edge schema** @@ -78,8 +85,11 @@ traversal is Cypher over `Backend::MailboxSoa`. the same node set as the DataFusion backend on the same data (backend parity). - **F2 (zero-decode):** a 1-hop traversal touches only key + `EdgeBlock` bytes, never the 480 B value slab (assert via a value-access counter / borrow check). -- **F3 (board legality):** an illegal kanban move (`!can_transition_to`) is - rejected at plan time, not after the edge rewrite. +- **F3 (board legality, all guard classes — was F6 in the verdict):** an illegal + domain-board move (rejected by the `classid → ClassView` schema) **and** any + DO-arm guard failure (RBAC / state-guard / MUL) are rejected at plan time, not + after the edge rewrite. (Mailbox-cycle legality is the separate + `KanbanColumn::can_transition_to` check.) - **F4 (gate isolation):** with `lite-unified` OFF, behaviour is byte-identical to today (datafusion path); the SurrealQL lowering is unreachable. - **F5 (no new layer):** the unification adds ONE router variant + ONE lowering From ebe9aa7fbe3d31ef33e24526c2dec10d436d04fa Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 18 Jun 2026 19:46:54 +0000 Subject: [PATCH 6/6] =?UTF-8?q?docs(plan):=20soften=20the=20odoo=20claim?= =?UTF-8?q?=20to=20CONJECTURE=20in=20the=20body=20(match=20verdict=20?= =?UTF-8?q?=C2=A75)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #542 review: lines 18 + 42-43 still asserted "odoo ontology traversal already runs / the existence proof" as fact while the verdict downgraded it. Body now says: convergent-but-unwired signal (tagged const ActionDef + classify_odoo, no executor arm, no Cypher->SurrealQL lowering); ogar-adapter-surrealql is not a crate (surreal_container stub). Plan and verdict now agree. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01CcpLeEC3XK8Eye53GKBVvi --- .claude/plans/cypher-kanban-ast-unification-v1.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.claude/plans/cypher-kanban-ast-unification-v1.md b/.claude/plans/cypher-kanban-ast-unification-v1.md index 02701177..ad9d215b 100644 --- a/.claude/plans/cypher-kanban-ast-unification-v1.md +++ b/.claude/plans/cypher-kanban-ast-unification-v1.md @@ -15,7 +15,7 @@ already shares **one IR/AST** across all four sides: | Side | Surface | Already shipped | |---|---|---| | **Query language** | Cypher / Gremlin / SPARQL / GQL → one IR | planner `strategy/{cypher,gremlin,sparql,gql}_parse.rs` | -| **Adapter / egress** | SurrealQL AST (`DEFINE`/traversal) | `ExecTarget::SurrealQl` + `ogar-adapter-surrealql`; odoo ontology traversal = existence proof | +| **Adapter / egress** | SurrealQL AST (`DEFINE`/traversal) | `ExecTarget::SurrealQl` enum tag only (no lowering yet; `ogar-adapter-surrealql` is NOT a crate — nearest is `surreal_container::SurrealStore`, a `BLOCKED(C)` stub); odoo path = CONJECTURE, see verdict §5 | | **Planner layer** | thinking-styles + MUL over the IR | planner `thinking/` (12 styles, NARS, sigma chain), `mul/` | | **Board** | kanban phases the cards move through | `kanban::{KanbanColumn, ExecTarget}` | @@ -41,8 +41,11 @@ board / woa work-order board / q2 case board are *domain* instantiations — var-length `*1..2`, WHERE/RETURN/etc). - **The polyglot front-ends → one IR**; **thinking-styles + MUL** plan over it; **`ExecTarget::SurrealQl`** is the egress. -- **odoo ontology traversal already runs through the SurrealQL AST adapter** — - the existence proof that Cypher/ontology-over-SurrealQL works. +- **odoo ontology work suggests the Cypher/ontology-over-SurrealQL path** — but + this is **CONJECTURE, not a proof** (verdict §5): what ships is a tagged + `const ActionDef`(`ExecTarget::SurrealQl`) + `classify_odoo` classification, with + NO executor arm and NO Cypher→SurrealQL lowering in source yet. Treat as a + convergent-but-unwired signal, not a running traversal. ## The gap (what this plan wires) — additive, layout-preserving