Skip to content

feat: 4-task unblock-cascade — NiblePath::from_guid_prefix + MailboxSoaOwner impl + LanceVersionScheduler + SurrealMailboxView (D-PG-6)#507

Merged
AdaWorldAPI merged 3 commits into
mainfrom
claude/odoo-savant-reasoners
Jun 16, 2026
Merged

feat: 4-task unblock-cascade — NiblePath::from_guid_prefix + MailboxSoaOwner impl + LanceVersionScheduler + SurrealMailboxView (D-PG-6)#507
AdaWorldAPI merged 3 commits into
mainfrom
claude/odoo-savant-reasoners

Conversation

@AdaWorldAPI

@AdaWorldAPI AdaWorldAPI commented Jun 16, 2026

Copy link
Copy Markdown
Owner

What

Four tasks from the shortest-unblocking-path list surfaced after PR #497#501 + the AdaWorldAPI/surrealdb fork bump (lance/lance-index =7.0.0, lancedb =0.30.0, ndarray exact-rev). All four meet at the single contract trait MailboxSoaView, so the cascade closes in one commit (E-UNBLOCK-CASCADE-1).

Each task was a named-but-unwritten consumer of contract scaffolding that already shipped — nothing here duplicates main (verified: none of the four symbols exist on main, on jolly-cori-clnf9, or on wonderful-hawking-lodtql; the source cherry-pick commit 463d71b is not an ancestor of main).

The four tasks

3 — NiblePath::{from_guid_prefix, prefix} (zero-dep, foundational)

Ontology-side keystone follow-up of #498's classid → ReadMode LE contract. The 20-nibble classid(8) | HEEL(4) | HIP(4) | TWIG(4) prefix overflows the 16-nibble MAX_DEPTH; the deterministic fold drops the canon-reserved high u16 of classid (root-first pack classid_lo(4) | HEEL(4) | HIP(4) | TWIG(4)), returning None when the fold would be lossy (callers never get a silent collision). prefix(d) is the O(1) single-shot ancestor view: prefix(d).is_ancestor_of(self) holds for every d ≤ self.depth — the routing-cache view of a deeper class path. Solves identity-architecture v1 §3 P-SCOPE-CLASSIFY.

crates/lance-graph-contract/src/hhtl.rs+7 tests, contract lib 632 green

2 — impl MailboxSoaView + MailboxSoaOwner for MailboxSoA<N>

Cherry-pick of jolly-cori-clnf9::463d71b (integrated-cognitive-planner-v1 §2 Seam #3). Adds the pub phase: KanbanColumn field + zero-copy repr(transparent) slice impls (edges_raw/meta_raw) + the in-RAM Rubicon driving-loop test. The contract spine (#437/#439) now drives an actual loop end-to-end — no surreal, no ractor bus needed for the in-process case.

crates/cognitive-shader-driver/src/mailbox_soa.rs+1 driving-loop test, driver lib 86 green

1 — LanceVersionScheduler over VersionedGraph::versions()

D-MBX-9-IN core impl — the Lance-backed implementor the contract trait's own docstring names as unwritten (scheduler.rs:20 "lands in a buildable downstream crate"). Generic over the inner VersionScheduler<S = NextPhaseScheduler>; exposes drive_once / drive_at_latest / current_dataset_version. Closes E-SUBSTRATE-IS-THE-SCHEDULER's OUT-direction. Stays propose-not-dispose (R1): the returned KanbanMove is for the caller's MailboxSoaOwner::try_advance_phase to apply.

crates/lance-graph/src/graph/scheduler.rs (new) — +5 tests, real on-disk tempdir Lance (no mocks)

4 — SurrealMailboxView (D-PG-6 contract slice)

Read-only MailboxSoaView adapter a SurrealQL projection populates via from_columns(...) — pure zero-copy borrow over the kv-lance scan buffers. Imports MailboxSoaView but NOT MailboxSoaOwner (compile-time enforcement of kanban.rs:1-21 "surreal=project-read-only, callcenter=commit"). read_via_kv_lance() returns the new typed SurrealContainerError::BlockedColdBuild until the surrealdb fork dep in Cargo.toml is uncommented — kept off by default to spare contributors the ~10 min cold surrealdb build. The contract surface is available today; the integration is one Cargo.toml uncomment + a SurrealQL projection body.

crates/surreal_container/src/view.rs (new) + lib.rs + Cargo.toml+4 tests

What this unblocks

  • D-MBX-9-IN-impl → SHIPPED (the contract trait now has a Lance-backed implementor)
  • integrated-cognitive-planner-v1 §2 Seam Claude/review lance graph architecture i6 t kf #3 → in-tree (the in-RAM loop, previously only on the unmerged jolly branch)
  • D-PG-6 (Rubicon kanban VIEW) → contract slice SHIPPED; impl-side gated on the BlockedColdBuild flip-on
  • identity-architecture v1 §3 P-SCOPE-CLASSIFY → solved (deterministic, ancestor-preserving, test-falsifiable)

Tests + lint

Crate Tests
lance-graph-contract 632 (+7 hhtl)
cognitive-shader-driver 86 (+1 driving-loop)
lance-graph::graph::scheduler 5 (new, real Lance tempdir)
surreal_container::view 4 (new)

All clippy -D warnings clean on the new files. Pre-existing lints in lance-graph-ontology / lance-graph-planner / ndarray_bridge.rs are out of session scope.

Board hygiene (mandatory rule — same commit)

  • LATEST_STATE.md — Contract Inventory PREPEND for the new types
  • EPIPHANIES.mdE-UNBLOCK-CASCADE-1 (three independent landings converge on one trait surface)
  • AGENT_LOG.md — task-by-task entry with test counts

11 files, +1,257 / −18. Rebased clean on 74e04cc (post #505/#506).

https://claude.ai/code/session_01Xzyc27Nx3f8WC5KzwfWfjx


Generated by Claude Code

Summary by CodeRabbit

  • New Features

    • Added NiblePath routing helpers (prefix(), from_guid_prefix())
    • Introduced LanceVersionScheduler for graph version management
    • New SurrealMailboxView read-only adapter for mailbox data
    • Added VersionedGraph::base_path() accessor
    • Extended mailbox phase lifecycle tracking
  • Refactor

    • Extensive code reorganization and formatting improvements
  • Documentation

    • Updated internal project status tracking

…oaOwner cherry-pick + LanceVersionScheduler + SurrealMailboxView (D-PG-6)

Lands four tasks from the shortest-unblocking-path list surfaced after
PR #497-#501 + the AdaWorldAPI/surrealdb fork bump (lance/lance-index =7.0.0,
lancedb =0.30.0, ndarray exact-rev). All four meet at the single contract
trait `MailboxSoaView`, closing the cascade in one commit (E-UNBLOCK-CASCADE-1).

## Task 3 — `NiblePath::{from_guid_prefix, prefix}` (zero-dep, foundational)

Ontology-side keystone follow-up of PR #498's `classid → ReadMode` LE contract.
The 20-nibble `classid(8) | HEEL(4) | HIP(4) | TWIG(4)` prefix overflows the
16-nibble MAX_DEPTH: the deterministic fold drops the canon-reserved high u16
of classid (root-first pack: `classid_lo(4) | HEEL(4) | HIP(4) | TWIG(4)`),
returning None when the fold would be lossy. `prefix(d)` is the O(1) ancestor
view; `prefix(d).is_ancestor_of(self)` holds for every d ≤ self.depth (the
routing-cache view of a deeper class path).

  +7 tests in `hhtl::tests`; contract lib 619 → 632 green.

## Task 2 — `impl MailboxSoaView + MailboxSoaOwner for MailboxSoA<N>`

Cherry-pick of jolly-cori-clnf9 commit 463d71b (integrated-cognitive-planner-v1
§2 Seam #3, +149 LOC). Adds `pub phase: KanbanColumn` field + zero-copy
repr(transparent) slice impls (edges_raw, meta_raw) + the in-RAM Rubicon
driving-loop test (`test_in_ram_driving_loop_walks_rubicon_to_commit`). The
contract spine (#437/#439) now drives an actual loop end-to-end — no surreal,
no ractor bus needed for the in-process case.

  +1 driving-loop test; cognitive-shader-driver lib 85 → 86 green.

## Task 1 — `LanceVersionScheduler` over `VersionedGraph::versions()`

D-MBX-9-IN core impl (the CI-gated twin of the contract slice shipped 2026-05-31).
Lives in `crates/lance-graph/src/graph/scheduler.rs`. Wraps a `VersionedGraph` +
inner `VersionScheduler<S = NextPhaseScheduler>` and exposes:

- `drive_once(view, exec)`           — read current Lance version, lower to a move
- `drive_at_latest(view, exec)`      — fold `versions().last()` into a move
- `current_dataset_version()`        — typed `DatasetVersion` over nodes head

Closes `E-SUBSTRATE-IS-THE-SCHEDULER`'s OUT-direction end-to-end. The OUT
direction stays propose-not-dispose (R1): returned `KanbanMove` is for the
caller's `MailboxSoaOwner::try_advance_phase` to apply.

  +5 tests with real on-disk tempdir Lance (no mocks).

## Task 4 — `SurrealMailboxView<'a>` (D-PG-6 contract slice)

Read-only `MailboxSoaView` adapter the SurrealQL projection populates via
`from_columns(...)` — pure zero-copy borrow over the kv-lance scan's byte
buffers. Imports `MailboxSoaView` but NOT `MailboxSoaOwner` (compile-time
enforcement of `kanban.rs:1-21` "surreal=project-read-only, callcenter=commit").

`read_via_kv_lance()` returns the new typed `SurrealContainerError::BlockedColdBuild`
until the surrealdb fork dep in `Cargo.toml` is uncommented — kept off by default
to avoid the ~10 min cold surrealdb build for contributors who don't need it.
The contract surface is available today; the integration is one Cargo.toml edit
+ a SurrealQL projection body in `view.rs`.

  +4 tests; new `lance-graph-contract` dep in surreal_container/Cargo.toml;
  BLOCKED(C) marker flipped to RESOLVED.

## What this unblocks

- **D-MBX-9-IN-impl** — SHIPPED (the contract trait now has a Lance-backed implementor).
- **D-MBX-A6-P3** — still queued, BUT Seam #3 (the in-RAM loop) is now in-tree;
  a downstream session can wire the emit-side without depending on the unmerged
  jolly branch.
- **D-PG-6 (Rubicon kanban VIEW)** — contract slice SHIPPED; impl-side gated on
  `BlockedColdBuild` flip-on (one Cargo.toml uncomment + projection body).
- **Identity-architecture v1 §3 P-SCOPE-CLASSIFY** — solved (the bijection-width
  fix is deterministic + ancestor-preserving + falsifiable by tests).

## Tests + clippy

- lance-graph-contract:   **632** (+7 hhtl)
- cognitive-shader-driver: **86** (+1 driving-loop)
- lance-graph::scheduler:  **5** (new module, real Lance tempdir)
- surreal_container::view: **4** (new module)

All clippy `-D warnings` clean on the new files. Pre-existing lints in
lance-graph-ontology / lance-graph-planner / ndarray_bridge.rs are out of
session scope.

## Board hygiene (mandatory rule)

- LATEST_STATE.md — Contract Inventory PREPEND for the new types.
- EPIPHANIES.md — E-UNBLOCK-CASCADE-1: three independent landings converge on
  one trait surface, closing four queued deliverables in one commit.
- AGENT_LOG.md — task-by-task summary with test counts.

https://claude.ai/code/session_01Xzyc27Nx3f8WC5KzwfWfjx
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds #[repr(transparent)] to CausalEdge64 enabling safe slice reinterpretation, introduces NiblePath::prefix and from_guid_prefix routing helpers, wires phase: KanbanColumn and MailboxSoaView/MailboxSoaOwner trait impls into MailboxSoA, adds a LanceVersionScheduler that reads Lance dataset head versions to produce KanbanMove proposals, and introduces a SurrealMailboxView read-only adapter with a stubbed read_via_kv_lance. A broad cargo fmt pass is applied across cognitive-shader-driver.

Changes

Unblock-cascade: layout safety, NiblePath routing, mailbox lifecycle, Lance scheduler, Surreal view

Layer / File(s) Summary
CausalEdge64 #[repr(transparent)] layout safety
crates/causal-edge/src/edge.rs, crates/causal-edge/src/layout.rs, crates/causal-edge/src/v2_layout_tests.rs
CausalEdge64 gains #[repr(transparent)] with documentation asserting the guaranteed u64-identical layout. InferenceType::from_mantissa is rewritten with explicit sign-extension branching. Layout constants are reformatted and v2 round-trip tests are updated with multi-line assertions.
NiblePath::prefix and from_guid_prefix routing helpers
crates/lance-graph-contract/src/hhtl.rs
Adds two pub const fn methods: prefix(depth) for O(1) ancestor-path extraction and from_guid_prefix(guid) for a deterministic 20→16 nibble fold from a NodeGuid. New tests cover depth boundaries, None on lossy folds, bijection invariants, and routing-prefix ancestor relationships.
MailboxSoA phase field, MailboxSoaView/MailboxSoaOwner impls, reinterpret-cast accessors
crates/cognitive-shader-driver/src/mailbox_soa.rs, crates/cognitive-shader-driver/src/lib.rs
Adds pub(crate) phase: KanbanColumn (initialized to Planning). Implements MailboxSoaView with unsafe edges_raw()/meta_raw() slice reinterpret casts guarded by compile-time size/alignment asserts, and MailboxSoaOwner::advance_phase that produces a KanbanMove with a Libet anchor for the Planning→CognitiveWork transition. New tests drive the full Rubicon phase loop and verify reinterpret-cast pointer identity.
LanceVersionScheduler: Lance head version → KanbanMove
crates/lance-graph/src/graph/versioned.rs, crates/lance-graph/src/graph/mod.rs, crates/lance-graph/src/graph/scheduler.rs
Adds VersionedGraph::base_path(). Introduces LanceVersionScheduler<S> with drive_once (reads nodes dataset head) and drive_at_latest (polls all versions, picks latest), both delegating to an inner VersionScheduler policy to produce Option<KanbanMove>. Tokio tests use in-memory Lance commits to verify version tracking, phase transitions, and ExecTarget threading.
SurrealMailboxView read adapter and BlockedColdBuild error
crates/surreal_container/src/view.rs, crates/surreal_container/src/lib.rs, crates/surreal_container/Cargo.toml
Adds SurrealContainerError::BlockedColdBuild, a test-only SurrealStore::test_placeholder(), and pub mod view. SurrealMailboxView<'a> is a zero-copy lifetime-borrowing struct implementing MailboxSoaView via from_columns (enforces equal-length column slices). read_via_kv_lance is a stub returning BlockedColdBuild. Cargo.toml comments updated with resolved fork pin.
cargo fmt sweep across cognitive-shader-driver
crates/cognitive-shader-driver/src/*, crates/cognitive-shader-driver/tests/*, crates/cognitive-shader-driver/examples/*, crates/cognitive-shader-driver/build.rs
Broad rustfmt-only pass across all cognitive-shader-driver source files. No logic, signatures, constant values, or control flow changed. Includes driver.rs, engine_bridge.rs, serve.rs, sigma_rosetta.rs, wire.rs, grpc.rs, bindspace.rs, and ~20 other files.
Board documentation
.claude/board/AGENT_LOG.md, .claude/board/EPIPHANIES.md, .claude/board/LATEST_STATE.md
New 2026-06-16 entries recording the 8-agent review fleet results (P0 layout safety fix, P1 fmt-check correction), the E-UNBLOCK-CASCADE-1 epiphany, and the 4-task unblock-cascade status summary.

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant LanceVersionScheduler
  participant VersionedGraph
  participant MailboxSoaView
  participant VersionScheduler
  Caller->>LanceVersionScheduler: drive_once(view, exec)
  LanceVersionScheduler->>VersionedGraph: open nodes.lance dataset
  VersionedGraph-->>LanceVersionScheduler: DatasetVersion
  LanceVersionScheduler->>MailboxSoaView: phase(), w_slot(), current_cycle()
  MailboxSoaView-->>LanceVersionScheduler: KanbanColumn, metadata
  LanceVersionScheduler->>VersionScheduler: on_version(view, version, exec)
  VersionScheduler-->>LanceVersionScheduler: Option<KanbanMove>
  LanceVersionScheduler-->>Caller: Ok(Option<KanbanMove>)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • AdaWorldAPI/lance-graph#437: Introduced the MailboxSoaView/MailboxSoaOwner contract traits, KanbanColumn, and KanbanMove that this PR wires into MailboxSoA and SurrealMailboxView.
  • AdaWorldAPI/lance-graph#427: Added the thoughtspace columns to MailboxSoA<const N> that this PR extends with the phase: KanbanColumn field and zero-copy reinterpret-cast view accessors.
  • AdaWorldAPI/lance-graph#480: Extended NiblePath with from_packed, which this PR builds on to implement from_guid_prefix via a delegate call to from_packed.

Poem

🐇 A nibble folds neatly, a repr is set true,
The phase leaps from Planning to work that is new,
A scheduler reads Lance and proposes a move,
The Surreal view borrows—zero-copy, smooth groove!
fmt swept through the codebase like morning dew,
Now every bit-layout is safe to pass through! ✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8017ca19a5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// `[u64; N]`. The pointer is non-null, aligned, and valid for `N` `u64`
// reads; the returned slice borrows `&self`, so it cannot outlive the
// backing array. Zero-copy — never clones the store (R1).
unsafe { core::slice::from_raw_parts(self.edges.as_ptr() as *const u64, N) }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add a repr guarantee before casting edge storage

When any consumer calls MailboxSoaView::edges_raw() on a real mailbox, this unsafe cast relies on CausalEdge64 having the exact layout of u64, but in the reviewed tree crates/causal-edge/src/edge.rs defines it as a plain tuple struct without #[repr(transparent)]. That makes the zero-copy slice reinterpretation unsound under Rust's layout rules; add the repr guarantee to CausalEdge64 or avoid the raw slice cast.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved on the current tip (c181fec4). CausalEdge64 now carries #[repr(transparent)] over u64 (crates/causal-edge/src/edge.rs:156), edges_raw() / meta_raw() document the SAFETY invariant against it, and test_edges_raw_meta_raw_reinterpret_round_trips asserts the reinterpret is bit-exact and zero-copy (same backing pointer). The unsound cast you flagged is now sound by construction.

/// Mutated only via [`MailboxSoaOwner::advance_phase`] /
/// [`MailboxSoaOwner::try_advance_phase`]; starts at
/// [`KanbanColumn::Planning`].
pub phase: KanbanColumn,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Make the lifecycle phase non-public

Because phase is a public field, any downstream crate holding a MailboxSoA<N> can assign an arbitrary KanbanColumn directly, bypassing MailboxSoaOwner::try_advance_phase, the lifecycle DAG check, and the KanbanMove emission that this change is trying to centralize. If the phase is meant to be mutated only through the owner trait, keep this field private or expose only checked setters.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in c181fec4. You're right — the field doc claimed "mutated only via the owner trait" but pub left that as documentation, not enforcement.

Changed pub phasepub(crate) phase, so a downstream crate can no longer assign a KanbanColumn directly and bypass try_advance_phase (the lifecycle-DAG check) + the KanbanMove emission.

Verified safe across cargo check --workspace --all-targets (exits 0):

  • the only writer is the in-crate impl MailboxSoaOwner for MailboxSoA<N>::advance_phase; pub(crate) keeps that compiling;
  • the soa_view.rs write is on the FakeSoa test double, not MailboxSoA;
  • no external crate reads the field directly — reads go through the unchanged MailboxSoaView::phase() getter.

mailbox_soa lib tests (12) + soa_view tests (3) green.

// — format!("{:?}", graph) yields `VersionedGraph { base_path: "..." }`.
// Parse out the quoted value. This is the cheapest read-only path
// until VersionedGraph exposes `pub fn base_path(&self) -> &str`.
let dbg = format!("{:?}", self.graph);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use a real base-path accessor instead of parsing Debug

When VersionedGraph::local is constructed with a path containing characters that Debug escapes, such as a quote in a Unix filename, this parser reads the formatted debug string rather than the original path and drive_once opens the wrong nodes.lance path. VersionedGraph already exposes current_version()/versions() using the real private base_path, so this method should call that API or add a proper accessor instead of depending on Debug output.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved on the current tip (c181fec4). scheduler.rs now reads the dataset path through a real VersionedGraph::base_path() accessor (format!("{}/nodes.lance", self.graph.base_path())) — the Debug-scraping path was removed, so a quote (or any Debug-escaped char) in a filename no longer misdirects drive_once.

claude added 2 commits June 16, 2026 09:13
…rds + fmt + asserts

8-agent review fleet (5 specialists + PP-13/15/16 hardeners) against the
4-task unblock-cascade (PR #507): zero REJECT, but two real defects all four
green test suites missed.

P0 — incomplete cherry-pick (PP-16 root cause). Task 2 cherry-picked
463d71b's mailbox_soa.rs half (+149) but dropped its causal-edge/src/edge.rs
half (+6: #[repr(transparent)] on CausalEdge64). The SAFETY comments cited a
repr the type didn't carry — sound on today's rustc by newtype-layout
coincidence, unsound by the letter, invisible to CI.

P1 — fmt --check overclaim (PP-13). The 4-task entry said "clippy/fmt clean"
but only clippy had been run; cargo fmt --check failed on PR-added lines.

Fixes:
- FIX-A: restore #[repr(transparent)] + doc on CausalEdge64 (edge.rs:148-156);
  add const _ size/align guards at edges_raw/meta_raw cast sites; corrected
  both SAFETY comments.
- FIX-B: cargo fmt across all 5 touched crates; fmt --check exit 0.
- FIX-C (PP-15): SurrealMailboxView::from_columns debug_assert_eq! ->
  assert_eq! (release-build OOB closed); + from_columns_rejects_ragged_projection panic test.
- FIX-D: pub fn base_path() on VersionedGraph; deleted format!("{:?}")
  Debug-scrape (embedded-quote truncation hazard).
- FIX-E (PP-13): test_edges_raw_meta_raw_reinterpret_round_trips — the
  unsafe cast had ZERO coverage; now bit-exact round-trip + pointer-identity
  asserted.
- FIX-F/H (P2 docs): hhtl bijection 0..=16 -> 1..=16; drive_at_latest scope
  note + versions().last() upstream-pagination caveat tying ascending-sort
  assumption to the lance =7.0.0 pin.

Process lesson -> EPIPHANIES E-CHERRYPICK-SPANS-CRATES-1 (queued).

Board hygiene: AGENT_LOG.md prepended in same commit (this commit), per the
mandatory rule — no retroactive cleanup.

https://claude.ai/code/session_01Xzyc27Nx3f8WC5KzwfWfjx
…er-enforced (#507 review)

Codex P2: MailboxSoA.phase was `pub`, so a downstream crate could assign an
arbitrary KanbanColumn directly, bypassing MailboxSoaOwner::try_advance_phase
(the lifecycle-DAG check) and the KanbanMove emission this change centralizes.
The field doc already claims "mutated only via the owner trait" — but `pub`
left that as documentation, not enforcement.

Change `pub phase` -> `pub(crate) phase`. Verified safe across the whole
workspace (cargo check --workspace --all-targets exits 0):
  - the only writer is the in-crate impl MailboxSoaOwner for MailboxSoA<N>
    (advance_phase, mailbox_soa.rs); pub(crate) keeps that working.
  - the soa_view.rs write is on the FakeSoa test double, not MailboxSoA.
  - no external crate reads the field directly; reads go through the
    MailboxSoaView::phase() getter, which is unchanged.
mailbox_soa lib tests (12) + soa_view tests (3) green.

https://claude.ai/code/session_01VysoWJ6vsyg3wEGc5v7T5v
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{"name":"HttpError","status":500,"request":{"method":"PATCH","url":"https://api.github.com/repos/AdaWorldAPI/lance-graph/issues/comments/4716536382","headers":{"accept":"application/vnd.github.v3+json","user-agent":"octokit.js/0.0.0-development octokit-core.js/7.0.6 Node.js/24","authorization":"token [REDACTED]","content-type":"application/json; charset=utf-8"},"body":{"body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- review_stack_entry_start -->\n\n[![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/AdaWorldAPI/lance-graph/pull/507?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)\n\n<!-- review_stack_entry_end -->\n<!-- This is an auto-generated comment: review in progress by coderabbit.ai -->\n\n> [!NOTE]\n> Currently processing new changes in this PR. This may take a few minutes, please wait...\n> \n> <details>\n> <summary>⚙️ Run configuration</summary>\n> \n> **Configuration used**: Organization UI\n> \n> **Review profile**: CHILL\n> \n> **Plan**: Pro Plus\n> \n> **Run ID**: `c9292c9a-d8f3-4426-b583-a284e33e6c5a`\n> \n> </details>\n> \n> <details>\n> <summary>📥 Commits</summary>\n> \n> Reviewing files that changed from the base of the PR and between 74e04cc9c283912ccbb7d915c813163bed25e911 and c181fec4428e7776d6eec9e25a9b2acafb1e9ad6.\n> \n> </details>\n> \n> <details>\n> <summary>⛔ Files ignored due to path filters (1)</summary>\n> \n> * `Cargo.lock` is excluded by `!**/*.lock`\n> \n> </details>\n> \n> <details>\n> <summary>📒 Files selected for processing (40)</summary>\n> \n> * `.claude/board/AGENT_LOG.md`\n> * `.claude/board/EPIPHANIES.md`\n> * `.claude/board/LATEST_STATE.md`\n> * `crates/causal-edge/src/edge.rs`\n> * `crates/causal-edge/src/layout.rs`\n> * `crates/causal-edge/src/v2_layout_tests.rs`\n> * `crates/cognitive-shader-driver/build.rs`\n> * `crates/cognitive-shader-driver/examples/villager_ai.rs`\n> * `crates/cognitive-shader-driver/src/attention_mask.rs`\n> * `crates/cognitive-shader-driver/src/attention_mask_actor.rs`\n> * `crates/cognitive-shader-driver/src/auto_detect.rs`\n> * `crates/cognitive-shader-driver/src/auto_style.rs`\n> * `crates/cognitive-shader-driver/src/bin/grpc.rs`\n> * `crates/cognitive-shader-driver/src/bin/serve.rs`\n> * `crates/cognitive-shader-driver/src/bindspace.rs`\n> * `crates/cognitive-shader-driver/src/codec_bridge.rs`\n> * `crates/cognitive-shader-driver/src/codec_kernel_cache.rs`\n> * `crates/cognitive-shader-driver/src/codec_research.rs`\n> * `crates/cognitive-shader-driver/src/cypher_bridge.rs`\n> * `crates/cognitive-shader-driver/src/decode_kernel.rs`\n> * `crates/cognitive-shader-driver/src/driver.rs`\n> * `crates/cognitive-shader-driver/src/engine_bridge.rs`\n> * `crates/cognitive-shader-driver/src/grpc.rs`\n> * `crates/cognitive-shader-driver/src/lib.rs`\n> * `crates/cognitive-shader-driver/src/mailbox_soa.rs`\n> * `crates/cognitive-shader-driver/src/planner_bridge.rs`\n> * `crates/cognitive-shader-driver/src/rotation_kernel.rs`\n> * `crates/cognitive-shader-driver/src/serve.rs`\n> * `crates/cognitive-shader-driver/src/sigma_rosetta.rs`\n> * `crates/cognitive-shader-driver/src/token_agreement.rs`\n> * `crates/cognitive-shader-driver/src/wire.rs`\n> * `crates/cognitive-shader-driver/tests/busdto_bridge_test.rs`\n> * `crates/cognitive-shader-driver/tests/end_to_end.rs`\n> * `crates/lance-graph-contract/src/hhtl.rs`\n> * `crates/lance-graph/src/graph/mod.rs`\n> * `crates/lance-graph/src/graph/scheduler.rs`\n> * `crates/lance-graph/src/graph/versioned.rs`\n> * `crates/surreal_container/Cargo.toml`\n> * `crates/surreal_container/src/lib.rs`\n> * `crates/surreal_container/src/view.rs`\n> \n> </details>\n> \n> ```ascii\n>  _________________________________________________\n> < Undefined behavior is my favorite horror genre. >\n>  -------------------------------------------------\n>   \\\n>    \\   \\\n>         \\ /\\\n>         ( )\n>       .( o ).\n> ```\n\n<!-- end of auto-generated comment: review in progress by coderabbit.ai -->\n\n<!-- finishing_touch_checkbox_start -->\n\n<details>\n<summary>✨ Finishing Touches</summary>\n\n<details>\n<summary>📝 Generate docstrings</summary>\n\n- [ ] <!-- {\"checkboxId\": \"7962f53c-55bc-4827-bfbf-6a18da830691\"} --> Create stacked PR\n- [ ] <!-- {\"checkboxId\": \"3e1879ae-f29b-4d0d-8e06-d12b7ba33d98\"} --> Commit on current branch\n\n</details>\n\n</details>\n\n<!-- finishing_touch_checkbox_end -->\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=AdaWorldAPI/lance-graph&utm_content=507)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->"},"request":{"retryCount":3,"signal":{},"retries":3,"retryAfter":16}}}

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/surreal_container/Cargo.toml (1)

42-59: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add explicit crates.io provenance rationale for active dependencies.

This manifest still has active crates.io dependencies without explicit rationale for why they are not AdaWorldAPI forks. Please document that rationale inline (or wire fork coordinates where a fork exists), per repo policy.

Suggested patch shape
 [dependencies]
+# crates.io rationale:
+# - lance/lancedb/tokio/futures/snafu are used from crates.io because
+#   [explicit repo-approved reason here].
+# - If an AdaWorldAPI fork exists for any of these, replace with fork coords
+#   (git URL + branch/tag or [patch.crates-io]).
 lance-graph-contract = { path = "../lance-graph-contract" }

 lance    = "=7.0.0"
 lancedb  = { version = "=0.30.0", optional = true, default-features = false }
 tokio    = { version = "1", features = ["rt-multi-thread", "macros"] }
 futures  = "0.3"
 snafu    = "0.8"

As per coding guidelines, **/Cargo.toml: “Every Cargo.toml must have a comment explaining why crates.io dependencies (if any) are NOT AdaWorldAPI forks, and every fork dependency must reference its fork source (git URL, branch, or [patch.crates-io]).”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/surreal_container/Cargo.toml` around lines 42 - 59, The active
crates.io dependencies in this Cargo.toml file (lance, lancedb, tokio, futures,
and snafu) are missing inline comments explaining why they are not AdaWorldAPI
forks or when forks exist. Add explicit rationale comments above or alongside
each of these dependencies to document why they remain on crates.io, following
the same pattern as the existing comment block for the commented-out surrealdb
fork dependency. Per repo policy, every crates.io dependency must have an
associated comment clarifying the decision to use the published version rather
than a fork.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.claude/board/AGENT_LOG.md:
- Around line 10-18: The AGENT_LOG.md file contains conflicting statements about
the repository state: the "Fixes applied" section header claims the fixes are in
a new commit, but the "Disk verification this turn" note states all changes are
uncommitted. Clarify the wording to accurately reflect the actual state — either
update the "Fixes applied" header and descriptions to indicate these are
staged/uncommitted changes awaiting decision, or update the "Disk verification"
note to confirm committed status. Ensure both sections describe the same
repository state consistently so readers understand whether the 34 modified
files with +2841/-1100 changes are committed to the branch or still in the
working directory.

In @.claude/board/EPIPHANIES.md:
- Around line 11-23: The current wording in the "The find" section conflates
NiblePath::from_guid_prefix with the MailboxSoaView trait surface, overstating
their coupling. NiblePath is not an implementation of MailboxSoaView and is
actually part of separate work. Reword the section to clarify that the actual
trait surface convergence point involves only MailboxSoA<N> and
SurrealMailboxView as implementations of MailboxSoaView/MailboxSoaOwner, while
NiblePath::{from_guid_prefix, prefix} is separate work that should be called out
as Task 3 independently adding that ontology-side keystone. Restructure the
bullet points so the three items listed correspond to distinct task boundaries
rather than all appearing to converge on the single trait surface.

In `@crates/cognitive-shader-driver/src/mailbox_soa.rs`:
- Around line 424-429: The libet_offset_us assignment in the mailbox_soa.rs file
gates on both the source and destination columns, but the contract
implementation only gates on the destination column. Remove the from ==
KanbanColumn::Planning condition from the if statement for libet_offset_us so
that it only checks to == KanbanColumn::CognitiveWork. This ensures that the
-550_000 offset is applied whenever entering CognitiveWork from any column,
matching the contract semantics and preventing divergence when new edges to
CognitiveWork are introduced.

In `@crates/lance-graph/src/graph/scheduler.rs`:
- Around line 75-80: The documentation comment for the LanceVersionScheduler
constructor contains an incorrect unit specification for the Libet anchor. The
comment currently states the anchor as -550 µs (microseconds), but the actual
canonical offset is -550 milliseconds (or -550_000 microseconds). Update the doc
comment text to correctly specify -550 ms instead of -550 µs to ensure accurate
timing documentation and prevent confusion.

In `@crates/lance-graph/src/graph/versioned.rs`:
- Around line 142-149: The newly exposed public method `base_path()` lacks a
direct unit test to verify its contract. Add a focused unit test in a
`#[cfg(test)]` module within this file that verifies the `base_path()` method
returns the expected base path value. The test should create a VersionedGraph
instance with a known base path and assert that calling `base_path()` returns
that value correctly.

In `@crates/surreal_container/src/view.rs`:
- Around line 218-221: The function `read_via_kv_lance` returns
`SurrealMailboxView<'static>`, but this contradicts the zero-copy design of the
struct which is intended to work with borrowed slices. Change the return type
lifetime from `'static` to an appropriate lifetime parameter (such as `'a`) that
reflects the borrowed nature of the data the view wraps. This aligns the
function signature with the struct's design intent for zero-copy borrowed data
access.

---

Outside diff comments:
In `@crates/surreal_container/Cargo.toml`:
- Around line 42-59: The active crates.io dependencies in this Cargo.toml file
(lance, lancedb, tokio, futures, and snafu) are missing inline comments
explaining why they are not AdaWorldAPI forks or when forks exist. Add explicit
rationale comments above or alongside each of these dependencies to document why
they remain on crates.io, following the same pattern as the existing comment
block for the commented-out surrealdb fork dependency. Per repo policy, every
crates.io dependency must have an associated comment clarifying the decision to
use the published version rather than a fork.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c9292c9a-d8f3-4426-b583-a284e33e6c5a

📥 Commits

Reviewing files that changed from the base of the PR and between 74e04cc and c181fec.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (40)
  • .claude/board/AGENT_LOG.md
  • .claude/board/EPIPHANIES.md
  • .claude/board/LATEST_STATE.md
  • crates/causal-edge/src/edge.rs
  • crates/causal-edge/src/layout.rs
  • crates/causal-edge/src/v2_layout_tests.rs
  • crates/cognitive-shader-driver/build.rs
  • crates/cognitive-shader-driver/examples/villager_ai.rs
  • crates/cognitive-shader-driver/src/attention_mask.rs
  • crates/cognitive-shader-driver/src/attention_mask_actor.rs
  • crates/cognitive-shader-driver/src/auto_detect.rs
  • crates/cognitive-shader-driver/src/auto_style.rs
  • crates/cognitive-shader-driver/src/bin/grpc.rs
  • crates/cognitive-shader-driver/src/bin/serve.rs
  • crates/cognitive-shader-driver/src/bindspace.rs
  • crates/cognitive-shader-driver/src/codec_bridge.rs
  • crates/cognitive-shader-driver/src/codec_kernel_cache.rs
  • crates/cognitive-shader-driver/src/codec_research.rs
  • crates/cognitive-shader-driver/src/cypher_bridge.rs
  • crates/cognitive-shader-driver/src/decode_kernel.rs
  • crates/cognitive-shader-driver/src/driver.rs
  • crates/cognitive-shader-driver/src/engine_bridge.rs
  • crates/cognitive-shader-driver/src/grpc.rs
  • crates/cognitive-shader-driver/src/lib.rs
  • crates/cognitive-shader-driver/src/mailbox_soa.rs
  • crates/cognitive-shader-driver/src/planner_bridge.rs
  • crates/cognitive-shader-driver/src/rotation_kernel.rs
  • crates/cognitive-shader-driver/src/serve.rs
  • crates/cognitive-shader-driver/src/sigma_rosetta.rs
  • crates/cognitive-shader-driver/src/token_agreement.rs
  • crates/cognitive-shader-driver/src/wire.rs
  • crates/cognitive-shader-driver/tests/busdto_bridge_test.rs
  • crates/cognitive-shader-driver/tests/end_to_end.rs
  • crates/lance-graph-contract/src/hhtl.rs
  • crates/lance-graph/src/graph/mod.rs
  • crates/lance-graph/src/graph/scheduler.rs
  • crates/lance-graph/src/graph/versioned.rs
  • crates/surreal_container/Cargo.toml
  • crates/surreal_container/src/lib.rs
  • crates/surreal_container/src/view.rs

Comment on lines +10 to +18
**Fixes applied (new commit on the same branch — preserves review history):**
- **FIX-A (P0):** restored the dropped enabler — `#[repr(transparent)]` + doc on `CausalEdge64` (`causal-edge/src/edge.rs:148-156`); added `const _` size/align guards at the `edges_raw`/`meta_raw` cast sites (compile-error on any layout regression); corrected both SAFETY comments.
- **FIX-B (P1):** ran `cargo fmt` on all 5 touched crates; `fmt --check` now exits 0.
- **FIX-C (P1, PP-15):** `SurrealMailboxView::from_columns` `debug_assert_eq!` → `assert_eq!` (the column-length invariant now fails loudly in ALL profiles — closes a release-build OOB where a ragged kv-lance projection → `n_rows() > entity_type().len()` → `SoaWavePrimer::project` indexes out of bounds). + `from_columns_rejects_ragged_projection` panic test.
- **FIX-D (P1, 4 agents):** `pub fn base_path()` on `VersionedGraph`; deleted the `format!("{:?}")` Debug-scrape in `scheduler.rs` (embedded-quote truncation hazard).
- **FIX-E (PP-13):** `test_edges_raw_meta_raw_reinterpret_round_trips` — the unsafe cast had ZERO coverage; now bit-exact round-trip + pointer-identity asserted.
- **FIX-F/H (P2 docs):** `hhtl` bijection doc `0..=16` → `1..=16` (prefix(0)=EMPTY is ancestor of nothing); `drive_at_latest` scope note (version-agnostic policies only) + `versions().last()` upstream-pagination caveat tying the ascending-sort assumption to the lance =7.0.0 pin.

**Disk verification this turn:** `git diff` confirms FIX-A landed (`#[repr(transparent)]` on `CausalEdge64` at `edge.rs:156`, `const _:` size/align guards at both cast sites in `mailbox_soa.rs`, `test_edges_raw_meta_raw_reinterpret_round_trips` at `mailbox_soa.rs:716`, `from_columns_rejects_ragged_projection` at `surreal_container/src/view.rs:257`). 34 files modified, +2841/-1100 — all uncommitted, awaits operator decision.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clarify the commit/status wording.

This section says the fixes were applied in a new commit, but the disk-verification note then says the branch is “all uncommitted.” Those states conflict; please distinguish committed fixes from any remaining unstaged drift so the log reflects the actual repo state.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/board/AGENT_LOG.md around lines 10 - 18, The AGENT_LOG.md file
contains conflicting statements about the repository state: the "Fixes applied"
section header claims the fixes are in a new commit, but the "Disk verification
this turn" note states all changes are uncommitted. Clarify the wording to
accurately reflect the actual state — either update the "Fixes applied" header
and descriptions to indicate these are staged/uncommitted changes awaiting
decision, or update the "Disk verification" note to confirm committed status.
Ensure both sections describe the same repository state consistently so readers
understand whether the 34 modified files with +2841/-1100 changes are committed
to the branch or still in the working directory.

Comment on lines +11 to +23
**The find.** All three meet at exactly **one trait surface**: `lance_graph_contract::soa_view::MailboxSoaView`. Each landing made a DIFFERENT impl viable on the same boundary:
- **`MailboxSoA<N>` (cognitive)** — the in-process owner+view, so the Rubicon loop runs in-RAM (was only on `jolly`).
- **`SurrealMailboxView<'a>` (surreal-side view)** — D-PG-6's read glove, now buildable end-to-end via the fork's `kv-lance` backend.
- **`NiblePath::from_guid_prefix`** — the ontology-side keystone follow-up of #498's `classid → ReadMode` LazyLock: a deterministic 20→16 nibble fold that satisfies the routing-prefix `is_ancestor_of` invariant the LE contract names.

`LanceVersionScheduler` (D-MBX-9-IN core impl) sits one layer up and consumes ANY `V: MailboxSoaView` — so a single OUT-direction wrapper drives all three impls without case-splitting. The trait's read-only-by-design (`MailboxSoaView` has no mutator method) is the structural enforcement of `kanban.rs:1-21`'s "surreal=project-read-only, callcenter=commit" ruling; the SurrealQL adapter NOT importing `MailboxSoaOwner` is the compile-time tripwire if a future drift tries to mutate through the projection.

**Why this matters.** Four "still BLOCKED" rows from the most recent unblock-list synthesis (last sync turn) all collapse onto a SINGLE commit, because the substrate already had the shape — only three independent dep/code landings had to converge. The pattern:
- Substrate trait designed once + multiple implementors (no `Box<dyn>` in hot paths — generic `V: MailboxSoaView` everywhere).
- Read-only-by-trait-design = compile-time enforcement of the architectural ruling (no need for a runtime "you can't write through this" guard).
- A typed `BlockedColdBuild` error variant lets a heavy dep wire-up (surrealdb cold build) be deferred without breaking the contract-side adapter — the surface ships, the integrator flips it on in their branch.

**Lesson.** When three plans cite the same trait surface as their unblock dependency, the first session that lands ANY one of the implementors should ALSO ship the trait-impl shape for the others (even as a stub returning a typed error). This collapses N independent post-unblock follow-ups into 1 commit's worth of trait engineering. The cost is ~50 LOC of stub + a typed error variant; the benefit is N − 1 fewer post-merge commits per queued plan.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Separate the NiblePath work from the mailbox seam.

NiblePath::from_guid_prefix is not part of the MailboxSoaView/MailboxSoaOwner seam, so the current "one trait surface" framing overstates the coupling. As written, it reads like Task 3 collapses into the mailbox-view commit, which is not what the diff shows.

Suggested rewording
- **The find.** All three meet at exactly **one trait surface**: `lance_graph_contract::soa_view::MailboxSoaView`.
+ **The find.** The mailbox/view work converges on `lance_graph_contract::soa_view::MailboxSoaView`; `NiblePath::from_guid_prefix` is an adjacent routing follow-up, not part of that seam.

Based on learnings: Task 3 adds NiblePath::{from_guid_prefix, prefix}, while Task 2 adds MailboxSoaView/MailboxSoaOwner and Task 4 adds SurrealMailboxView.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/board/EPIPHANIES.md around lines 11 - 23, The current wording in the
"The find" section conflates NiblePath::from_guid_prefix with the MailboxSoaView
trait surface, overstating their coupling. NiblePath is not an implementation of
MailboxSoaView and is actually part of separate work. Reword the section to
clarify that the actual trait surface convergence point involves only
MailboxSoA<N> and SurrealMailboxView as implementations of
MailboxSoaView/MailboxSoaOwner, while NiblePath::{from_guid_prefix, prefix} is
separate work that should be called out as Task 3 independently adding that
ontology-side keystone. Restructure the bullet points so the three items listed
correspond to distinct task boundaries rather than all appearing to converge on
the single trait surface.

Comment on lines +424 to +429
libet_offset_us: if from == KanbanColumn::Planning && to == KanbanColumn::CognitiveWork
{
-550_000
} else {
0
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify current and contract-side Libet offset condition sites.
rg -n -C3 "libet_offset_us|CognitiveWork" crates/cognitive-shader-driver/src/mailbox_soa.rs crates/lance-graph-contract/src/soa_view.rs

Repository: AdaWorldAPI/lance-graph

Length of output: 5433


Remove the from condition from libet_offset_us gate to match contract semantics.

The Libet offset should trigger whenever entering CognitiveWork, not only when entering from Planning. The contract-side implementation (lance-graph-contract/src/soa_view.rs:196) gates solely on to == KanbanColumn::CognitiveWork, but the driver gates on both from == KanbanColumn::Planning && to == KanbanColumn::CognitiveWork. If additional valid edges to CognitiveWork are introduced, the driver will fail to apply the offset, diverging from contract behavior.

Suggested fix
-            libet_offset_us: if from == KanbanColumn::Planning && to == KanbanColumn::CognitiveWork
-            {
+            libet_offset_us: if to == KanbanColumn::CognitiveWork {
                 -550_000
             } else {
                 0
             },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
libet_offset_us: if from == KanbanColumn::Planning && to == KanbanColumn::CognitiveWork
{
-550_000
} else {
0
},
libet_offset_us: if to == KanbanColumn::CognitiveWork {
-550_000
} else {
0
},
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/cognitive-shader-driver/src/mailbox_soa.rs` around lines 424 - 429,
The libet_offset_us assignment in the mailbox_soa.rs file gates on both the
source and destination columns, but the contract implementation only gates on
the destination column. Remove the from == KanbanColumn::Planning condition from
the if statement for libet_offset_us so that it only checks to ==
KanbanColumn::CognitiveWork. This ensures that the -550_000 offset is applied
whenever entering CognitiveWork from any column, matching the contract semantics
and preventing divergence when new edges to CognitiveWork are introduced.

Comment on lines +75 to +80
/// Construct a `LanceVersionScheduler` with the canonical forward-arc
/// reference [`NextPhaseScheduler`]: every tick proposes
/// `Planning → CognitiveWork → Evaluation → Commit`, halting at the
/// absorbing column. The `-550 µs` Libet anchor stamps the
/// `Planning → CognitiveWork` crossing — the same convention
/// `MailboxSoa<N>::advance_phase` uses.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix Libet anchor unit in docs.

Line 78 states -550 µs, but the canonical move offset is -550_000 microseconds (-550 ms). Please align the doc text to prevent timing confusion.

Suggested patch
-    /// absorbing column. The `-550 µs` Libet anchor stamps the
+    /// absorbing column. The `-550_000 µs` (`-550 ms`) Libet anchor stamps the
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/// Construct a `LanceVersionScheduler` with the canonical forward-arc
/// reference [`NextPhaseScheduler`]: every tick proposes
/// `Planning → CognitiveWork → Evaluation → Commit`, halting at the
/// absorbing column. The `-550 µs` Libet anchor stamps the
/// `Planning → CognitiveWork` crossing — the same convention
/// `MailboxSoa<N>::advance_phase` uses.
/// Construct a `LanceVersionScheduler` with the canonical forward-arc
/// reference [`NextPhaseScheduler`]: every tick proposes
/// `Planning → CognitiveWork → Evaluation → Commit`, halting at the
/// absorbing column. The `-550_000 µs` (`-550 ms`) Libet anchor stamps the
/// `Planning → CognitiveWork` crossing — the same convention
/// `MailboxSoa<N>::advance_phase` uses.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/lance-graph/src/graph/scheduler.rs` around lines 75 - 80, The
documentation comment for the LanceVersionScheduler constructor contains an
incorrect unit specification for the Libet anchor. The comment currently states
the anchor as -550 µs (microseconds), but the actual canonical offset is -550
milliseconds (or -550_000 microseconds). Update the doc comment text to
correctly specify -550 ms instead of -550 µs to ensure accurate timing
documentation and prevent confusion.

Comment on lines +142 to +149
/// The base directory or URI this graph is rooted at (local path, `s3://`,
/// `az://`, `gs://`). The per-dataset paths (`nodes.lance`, `edges.lance`,
/// …) are this suffixed by their dataset name. Exposed so downstream
/// crates (e.g. `graph::scheduler::LanceVersionScheduler`) can derive a
/// dataset path without scraping the `Debug` representation.
pub fn base_path(&self) -> &str {
&self.base_path
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a focused unit test for the new public accessor.

base_path() is newly exposed API surface; please add a direct assertion for it in this module’s tests to lock the contract explicitly.

Suggested patch
 #[test]
 fn test_versioned_graph_paths() {
     let g = VersionedGraph::local("/tmp/test-graph");
+    assert_eq!(g.base_path(), "/tmp/test-graph");
     assert_eq!(g.nodes_path(), "/tmp/test-graph/nodes.lance");
     assert_eq!(g.edges_path(), "/tmp/test-graph/edges.lance");
     assert_eq!(g.fingerprints_path(), "/tmp/test-graph/fingerprints.lance");
 }

As per coding guidelines, crates/**/*.rs: “Add Rust unit tests alongside implementations via #[cfg(test)] modules; prefer focused scenarios over broad integration tests.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/lance-graph/src/graph/versioned.rs` around lines 142 - 149, The newly
exposed public method `base_path()` lacks a direct unit test to verify its
contract. Add a focused unit test in a `#[cfg(test)]` module within this file
that verifies the `base_path()` method returns the expected base path value. The
test should create a VersionedGraph instance with a known base path and assert
that calling `base_path()` returns that value correctly.

Source: Coding guidelines

Comment on lines +218 to +221
pub async fn read_via_kv_lance(
_store: &crate::SurrealStore,
_mailbox_id: MailboxId,
) -> Result<SurrealMailboxView<'static>, SurrealContainerError> {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify current signature and all call sites before changing lifetime bounds.
rg -n -C2 "pub async fn read_via_kv_lance|SurrealMailboxView<'static>" crates/surreal_container/src/view.rs
rg -n -C2 "read_via_kv_lance\\("

Repository: AdaWorldAPI/lance-graph

Length of output: 2440


🏁 Script executed:

# Find SurrealMailboxView definition
rg -n "struct SurrealMailboxView|pub struct SurrealMailboxView" crates/surreal_container/

Repository: AdaWorldAPI/lance-graph

Length of output: 143


🏁 Script executed:

# Get full context of read_via_kv_lance implementation
sed -n '216,240p' crates/surreal_container/src/view.rs

Repository: AdaWorldAPI/lance-graph

Length of output: 1166


🏁 Script executed:

# Find all usages of read_via_kv_lance
rg -n "read_via_kv_lance" crates/

Repository: AdaWorldAPI/lance-graph

Length of output: 1012


🏁 Script executed:

# Check module-level documentation for design intent
head -n 100 crates/surreal_container/src/view.rs

Repository: AdaWorldAPI/lance-graph

Length of output: 4817


read_via_kv_lance return lifetime contradicts zero-copy design intent.

SurrealMailboxView<'a> is explicitly designed for borrowed slices over projection byte buffers (module docs lines 25-81), but the function signature returns SurrealMailboxView<'static>. This forces static lifetime constraints that would prevent the zero-copy implementation once the stub is filled in. Align the function signature with the struct design:

Fix
-pub async fn read_via_kv_lance(
-    _store: &crate::SurrealStore,
+pub async fn read_via_kv_lance<'a>(
+    _store: &'a crate::SurrealStore,
     _mailbox_id: MailboxId,
-) -> Result<SurrealMailboxView<'static>, SurrealContainerError> {
+) -> Result<SurrealMailboxView<'a>, SurrealContainerError> {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/surreal_container/src/view.rs` around lines 218 - 221, The function
`read_via_kv_lance` returns `SurrealMailboxView<'static>`, but this contradicts
the zero-copy design of the struct which is intended to work with borrowed
slices. Change the return type lifetime from `'static` to an appropriate
lifetime parameter (such as `'a`) that reflects the borrowed nature of the data
the view wraps. This aligns the function signature with the struct's design
intent for zero-copy borrowed data access.

@AdaWorldAPI AdaWorldAPI merged commit 0c6ef02 into main Jun 16, 2026
6 checks passed
AdaWorldAPI pushed a commit that referenced this pull request Jun 16, 2026
…D-CI-COVERAGE-MOLD-1)

The `test` job has begun hitting the same disk/RSS link cliff already
mitigated on `test-with-coverage` (b56bb2c): `ld terminated with signal 7
[Bus error]` + an LLVM crash at the `cargo test --no-run` link step of
test_sql_query / intervene_counterfactual.

Root cause is link-footprint growth, NOT a logic break (a layout break would
fail an assertion, not SIGBUS at link). PR #507 (0c6ef02, +4055 lines across
causal-edge ce64-v2 layout + cognitive-shader-driver MailboxSoaOwner /
SurrealMailboxView) grew the integration-test object set enough to tip the
previously-marginal `test`-job link over the same ceiling. It surfaced on the
first full-workspace CI run after #507 (the intervening PRs are
root-excluded crates, so their CI never linked the post-#507 tree).

Fix: give the `test` job a job-level RUSTFLAGS with `-C debuginfo=0` (parity
with the coverage job). debuginfo carries no value in CI (no debugger is
attached); dropping it cut the coverage job's per-binary link ~930 MB -> ~252 MB
(-73%, measured in b56bb2c) and relieves both the mold/GNU-ld RSS and the disk
ceiling. mold is already installed on this job. Side effect: the job gets its
own Swatinem cache key (first run repopulates).

This is a fence (buys headroom), not a root reduction of #507's legitimate
codegen — documented as such in the TD-CI-COVERAGE-MOLD-1 ledger addendum,
including the secular-growth caveat and the separate (warns-not-fails)
intervene_counterfactual.rs deprecated-API debt.
AdaWorldAPI pushed a commit that referenced this pull request Jun 16, 2026
#511)

Addresses the open review findings on the merged #511:

- examples/calibrate.rs: guard degenerate grids up front. `k = 24.min(m)` is 0
  when m==0, so `m / k` panics (divide by zero); `eigenvector(1)` / `m - 1` also
  break on n<2. Exit cleanly with a message instead. (CodeRabbit Major)
- src/hhtl.rs: basin_lambda2 asserts keys.len() == grid.n. A mismatched slice
  silently produced wrong basin groupings + lambda2; fail fast at the API
  boundary. (CodeRabbit Major)
- .claude/board/TECH_DEBT.md: reflow the wrapped `#507` so it is not parsed as
  an ATX heading (markdownlint MD018). (CodeRabbit Minor)

Already-fixed before merge (no change needed): Codex P2 — `infight` is 4-bit
(columns.rs `spec("infight", 4, ...)`, the certified width per the §10 note).
Deferred: the TECH_DEBT.md append-only addendum-placement nit (CodeRabbit Major)
is a board-hygiene reorganization, left to a focused governance pass rather than
churned inside a code-fix PR.

Gates: fmt + clippy -D warnings + test green (75 lib tests) on the standalone
perturbation-sim crate.

https://claude.ai/code/session_016b33swuXE23hKtqxsHu9p1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants