@@ -341,6 +341,84 @@ PR-X10 ships the ndarray-side canonical surface; jc agents pick up the
341341consolidation against it. PR-X10 is ** independent** of PR-X4 / PR-X9 / PR-Z1
342342(no file overlap), can ship concurrently from a separate branch.
343343
344+ ## Shopping-list addendum (2026-05-19 substrate-pair update)
345+
346+ The 2026-05-18 entry above (PR-X10 + jc consolidation) is the ** arithmetic**
347+ substrate. A 2026-05-19 cross-cutting design session identified the
348+ ** storage-and-contract** substrate as the missing companion piece. Two
349+ pre-sprint prompts capture it:
350+
351+ - ` .claude/knowledge/hhtl-gridlake-pre-sprint-prompt.md ` — ** PR-X1 + PR-X2**
352+ (GridLake carrier: ` MultiLaneColumn ` + ` #[derive(SoA)] ` proc-macro)
353+ - ` .claude/knowledge/hhtl-pr-x14-substrate-contract-prompt.md ` — ** PR-X14′**
354+ (` lance-graph-contract::column ` module set + new
355+ ` lance-graph-contract-bridge ` sibling crate)
356+
357+ ### Cost-of-ownership framework adopted this session
358+
359+ Cost-of-ownership is calculated only by ** how many cluttered parts a choice
360+ replaces** . By that metric the substrate-pair is the highest-leverage move
361+ in the Phase-2 arc:
362+
363+ | Adoption | Cluttered parts replaced |
364+ | ---| ---|
365+ | PR-X1 + PR-X2 (GridLake carrier) | ** 5 implicit per-consumer column-buffer copies** (Databend, Tantivy, lance-graph, sea-orm, SurrealDB each maintain their own) collapse to one |
366+ | PR-X14′ (contract + bridge) | ** 4 duplicate column-access patterns** (BindSpace ` Box<[u64]> ` , lance-graph query ` HashMap<String, RecordBatch> ` , planner ` Morsel ` placeholder enum, ` lance::Dataset.scan() ` rolled per feature) collapse to one |
367+ | Databend (future, when integrated through the contract) | ClickHouse (1 JVM/C++ service decommissioned) |
368+ | Tantivy (future, when integrated through the contract) | Elasticsearch + Lucene (1 JVM service decommissioned) |
369+ | lance-graph + ndarray-over-TiKV (existing) | JanusGraph + TinkerPop/Gremlin (2 JVM services decommissioned) |
370+
371+ ### Decisions that pinned the scope
372+
373+ Three architectural decisions narrowed the prompt's scope from earlier
374+ proposals in the session:
375+
376+ 1 . ** Skip SQL for now** . All SQL-frontend work (sea-orm column contract,
377+ sqlparser-rs standalone, PostgREST front, the Phase-3 "fusion parser"
378+ sprint) is deferred. The lance-graph SQL path keeps its `RecordBatch +
379+ DataFusion::SessionContext` pipeline unchanged.
380+
381+ 2 . ** Don't evict datafusion** . ` lance-graph/Cargo.toml ` :35-39 has hard deps
382+ on ` datafusion = "52" ` + four sibling ` datafusion-* ` crates; lance-graph
383+ upstream depends on them. PR-X14′ does NOT touch these — the datafusion
384+ 1400-module tail stays contained inside the lance-graph crate.
385+
386+ 3 . ** Use storage format as-is** . PR-X14′ reads ` lance::Dataset ` and
387+ ` arrow::RecordBatch ` as-is; it does NOT define Arrow extension types,
388+ NOT register custom Lance encoders, NOT modify schemas in place.
389+
390+ ### Decisions superseded
391+
392+ - ❌ Earlier-session proposal: PR-X14 evicts datafusion from lance-graph and
393+ builds a parsendes Fusionskraftwerk at 240ns/parse. ** Superseded** —
394+ lance-graph upstream dep makes eviction out of scope; the planner IR +
395+ Cypher nom parser + NSM/FSM parser already exist and PR-X14′ is the
396+ consolidation, not a fusion-parser sprint.
397+ - ❌ Earlier-session proposal: two new top-level crates ` gridlake-contract `
398+ + ` gridlake-bridge ` . ** Superseded** — ` lance-graph-contract ` already
399+ exists with 10+ workspace consumers and is the right home for the column
400+ module; only a sibling bridge crate is genuinely new.
401+
402+ ### Two Q-markers carried forward (plan-review savant decides at preflight)
403+
404+ - ** Q-NEW-1** (from GridLake prompt): GridLake at W2.5 prerequisite slot
405+ vs absorbed into PR-X10 as A13/A14
406+ - ** Q-NEW-2** (from PR-X14′ prompt): PR-X14′ concurrent with GridLake at
407+ W2.5 (path α, 10 workers) vs sequential at W3 (path β, 4 workers + 0.5
408+ week schedule extension)
409+
410+ ### Forbidden constraints (preserved from the prompts)
411+
412+ - PR-X14′ must NOT add ` arrow ` , ` arrow-schema ` , ` arrow-array ` , ` lance ` ,
413+ ` lancedb ` , or ` datafusion ` to ` lance-graph-contract ` 's Cargo.toml —
414+ preserves the lib.rs:1 zero-dependency invariant
415+ - PR-X14′ must NOT touch ` lance-graph/src/sql_query.rs ` ,
416+ ` lance-graph/src/sql_catalog.rs ` , or ` lance-graph/Cargo.toml ` 's
417+ datafusion deps — these are deliberately out of scope per decision (2)
418+ above
419+ - ndarray crate receives zero changes from PR-X14′ — the substrate-pair is
420+ consumer-side only
421+
344422## Cross-references
345423
346424- ` /root/.claude/uploads/.../7b0ea082-splat3d_sprint_prompt.md ` — splat3d sprint (shipped as ndarray PR #153 , 2026-05-18)
@@ -351,3 +429,5 @@ consolidation against it. PR-X10 is **independent** of PR-X4 / PR-X9 / PR-Z1
351429- ` .claude/knowledge/pr-x9-design.md ` — lazy basin-codebook storage
352430- ` .claude/knowledge/pr-z1-ogit-cognitive-bootstrap.md ` — OGIT Cognitive namespace bootstrap
353431- ` .claude/knowledge/pr-x10-linalg-core-design.md ` — ** the consolidating linalg sprint** that unblocks splat3d training + inference modules + jc Pillars simultaneously
432+ - ` .claude/knowledge/hhtl-gridlake-pre-sprint-prompt.md ` — ** PR-X1 + PR-X2** GridLake carrier (` MultiLaneColumn ` + ` #[derive(SoA)] ` ); 2026-05-19 session output, branch ` claude/gridlake-pre-sprint-prompt `
433+ - ` .claude/knowledge/hhtl-pr-x14-substrate-contract-prompt.md ` — ** PR-X14′** ` lance-graph-contract::column ` module + ` lance-graph-contract-bridge ` sibling crate; 2026-05-19 session output, same branch
0 commit comments