Skip to content

feat(contract): NodeGuid — structured 128-bit instance identity (identity-architecture Phase A)#480

Merged
AdaWorldAPI merged 3 commits into
mainfrom
claude/nice-edison-g4rhhl
Jun 9, 2026
Merged

feat(contract): NodeGuid — structured 128-bit instance identity (identity-architecture Phase A)#480
AdaWorldAPI merged 3 commits into
mainfrom
claude/nice-edison-g4rhhl

Conversation

@AdaWorldAPI

@AdaWorldAPI AdaWorldAPI commented Jun 9, 2026

Copy link
Copy Markdown
Owner

What

The workspace's first stable binary instance identity: lance_graph_contract::identity::NodeGuid([u8; 16]) — a structured UUIDv8 (RFC 9562) that formalizes + namespaces the HHTL nibble-address. This is Phase A (the keystone) of the identity architecture mapped in .claude/plans/identity-architecture-exists-vs-needs-v1.md.

Composed from existing committed scalars — nothing re-invented. An up-front cross-repo sweep (lance-graph + ndarray) confirmed the 128-bit identity space was empty (the only [u8; 16] in the contract was atoms::I4x32, a style vector). So the GUID is assembled from fields that already exist:

octet layout (big-endian):
  ns:u8 │ entity_type:u16 │ kind:u8   ← the SchemaPtr.packed convention
  ⊕ truncated NiblePath prefix (PREFIX_NIBBLES = 4)  ← routing cache
  ⊕ 22-bit shape_hash (truncated StructuralSignature) ← drift witness
  ⊕ 24-bit local                                      ← instance discriminator
  with UUIDv8 version(=8) + variant(=0b10) at their RFC-fixed positions
  + an IDENTITY_LAYOUT_VERSION stamp

The eineindeutigkeit decision (decision-1, now RESOLVED in the plan)

The class is carried two ways, bound by an enforced bijection, decided pre-production so it's baked in with zero migration debt:

  • entity_type:u16 is the canonical, exact class identity — fixed-width, no truncation.
  • NiblePath is the bijective derived view — the GUID carries only a coarse 4-nibble prefix as a routing cache (niblepath_of(entity_type) truncated). A truncated prefix cannot be the identity (two deep classes collide past it), so the exact identity must be the dense scalar; the prefix is_ancestor_of the full path (tested).
  • identity-IS-address holds (ADR-1374): entity_type IS the dense encoding of the address, bijective with NiblePath.

Full enforcement of the bijection (registry mints the unique pair + a build-time round-trip test) is Phase B — this PR lands the byte-layout half (the GUID prefix-consistency invariant + field-isolation matrix).

In this PR

  • identity.rs (new) — NodeGuid + IDENTITY_LAYOUT_VERSION, 15 tests: field-isolation matrix (write each field, assert all others unchanged), UUIDv8 version/variant gates, prefix is_ancestor_of full invariant, canonical-UUID Display.
  • hhtl::NiblePath::from_packed — the inverse of packed(), needed to derive the routing prefix.
  • 2 plan docsidentity-architecture-exists-vs-needs-v1.md (the exists-vs-needs map + phases A→H) and cognitive-write-roundtrip-substrate-v1.md.
  • Board hygiene (same arc): LATEST_STATE.md inventory entry, EPIPHANIES.mdE-IDENTITY-WHITEBOX-1, AGENT_LOG.md, decision-1 marked RESOLVED in the plan.

Gates

Gate Result
contract lib tests 599 (+15)
doctests 8 ✓ (3 ignored)
clippy -D warnings --all-targets clean
cargo fmt --check clean

Locked / invariants

  • Zero-dep — lands entirely in the zero-dependency contract crate; additive only.
  • Forward-only, no consumer wired yetNodeGuid is defined but nothing constructs it in a persisted path yet (that's Phase B/C/F), so there is no migration risk; pre-production, baked in clean.
  • I-VSA-IDENTITIES Test 0 respected — the GUID is a register key (points to content), never VSA-bundled.

Honest note for the reviewer

The feature commit incidentally swept ~20 contract files to fmt-clean. cargo fmt reformats the whole crate, and the contract crate had pre-existing fmt drift (CI only fmt-gates lance-graph + deepnsm, never the zero-dep contract). Every large diff (mul.rs / recipes.rs / savants.rs) is pure rustfmt — line-wrapping previously-over-long single-line struct literals; verified via git show -w, semantic-preserving, 599 tests green. It's benign and leaves the crate fmt-clean, but the diff is larger than the logical change. Happy to split into feat + style commits if preferred.

Not in scope (deferred to later phases)

B (registry bijection enforcement + build-time round-trip test) · C (SoaEnvelope MailboxSoA impl) · D–H (per the plan). NodeGuid is the substrate those phases build on.

https://claude.ai/code/session_014A4JuRCqKP2yNENrQ9Ha7H


Generated by Claude Code

Summary by CodeRabbit

  • New Features

    • Introduced structured identity system with NodeGuid for 128-bit UUIDv8-based node identity with composed fields (namespace, entity type, kind, path prefix, shape hash, local index).
    • Added from_packed constructor to NiblePath for reconstructing paths from their packed representation.
  • Documentation

    • Added identity architecture specification and phase-based delivery plan.
    • Added cognitive write round-trip substrate hardening specification with diagnostics and failure mode maps.

claude added 3 commits June 9, 2026 09:20
Express the cold-path write (mailbox SoA -> SPO nodes + CausalEdge64 edges)
as a codegen_spine::TripletProjection, so roundtrip_eq becomes the commit's
own gate: every commit is a substrate proof. Separates the three layers
(exact-LE members / container envelope / lossy codec) onto two witnesses
(roundtrip_eq vs rank-correlation), and decouples substrate hardening from
the [ABSENT] KausalSpec DO-enforcement runtime.

Grounded against: codegen_spine.rs, soa_envelope.rs (zero impls today),
soa_view.rs (MailboxSoaView/Owner), lance_membrane.rs (sole-writer
commit_event + CommitFilter/MembraneGate), ndarray causal_diff.rs
(NARS 10b x1023 -> truth_tolerance 1/1023).

Phase plan P0-P4 unblocked; P5 (SurrealQL read glove) BLOCKED(C) on
surrealdb fork coords.

https://claude.ai/code/session_014A4JuRCqKP2yNENrQ9Ha7H
Grounded map of the structured 128-bit identity (UUIDv8 = HHTL nibble-address
formalized) against the existing substrate, from first-hand reads + two
cross-repo sweeps.

Four findings: (1) the 128-bit identity space is empty (no committed
u128/Uuid/[u8;16]-as-id); (2) every GUID FIELD already exists as a committed
scalar -> compose, do not re-invent (SchemaPtr + NiblePath + StructuralSignature
+ EdgeRef); (3) the cross-store transport is already solved by
EntityKey(&[u8]) -- smb-bridge key_to_filter already length-branches; (4) the
cold path has no stable structured identity today (node_id:u32 + String props,
SpoStore u64 dn_hash) -- the identity fills a real gap.

6-layer exists inventory + 7 build gaps (N1-N7 unblocked, N8 surreal BLOCKED on
fork coords) + phased plan A-H. Substrate is ~80% present; the work is
composition/wiring, not green-field. One open decision: SchemaPtr.entity_type
vs NiblePath-prefix as the class carrier.

https://claude.ai/code/session_014A4JuRCqKP2yNENrQ9Ha7H
…ENTITY-1)

The workspace's first stable binary instance identity: a UUIDv8 (RFC 9562)
that formalizes + namespaces the HHTL nibble-address. Composed entirely from
existing committed scalars (the 128-bit id space was empty per the Agent A
sweep): SchemaPtr.packed convention (ns8|entity_type16|kind8) + a truncated
NiblePath routing prefix + a 22-bit shape_hash + a 24-bit local, with the
UUIDv8 version/variant at their RFC-fixed positions and a layout-version stamp.

Eineindeutigkeit (ratified): entity_type:u16 is the canonical exact class
identity; the NiblePath prefix is the bijective DERIVED view (a truncated
prefix can't be the identity -- deep classes collide past it; the prefix
is_ancestor_of the full path, tested). Five readings: resolve / route /
witness / ground-truth / dispatch-to-store (as_bytes -> EntityKey).

- new: identity.rs (NodeGuid + 15 tests: field-isolation matrix, UUIDv8
  version/variant gates, ancestor-prefix invariant, canonical-UUID Display).
- new: NiblePath::from_packed (inverse of packed()).
- 599 contract lib tests (+15), clippy -D warnings clean, fmt clean.
- board: LATEST_STATE inventory, EPIPHANIES E-IDENTITY-WHITEBOX-1, AGENT_LOG,
  decision-1 RESOLVED in the exists-vs-needs plan.

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

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Phase A of the identity architecture is now shipped: a 128-bit structured NodeGuid type encodes instance identity as a UUIDv8 with namespace, entity type, kind, truncated path prefix, shape hash, and local index. Supporting planning docs map architecture gaps and a round-trip substrate hardening spec. Extensive code formatting hygiene improvements follow across examples, tests, and SIMD pipelines.

Changes

Identity Architecture & NodeGuid Feature

Layer / File(s) Summary
Architecture Planning & Documentation
.claude/board/AGENT_LOG.md, .claude/board/EPIPHANIES.md, .claude/board/LATEST_STATE.md, .claude/plans/identity-architecture-exists-vs-needs-v1.md, .claude/plans/cognitive-write-roundtrip-substrate-v1.md
Five new planning documents establish the Phase A identity blueprint: a structured inventory of existing components vs. gaps (N1–N8), a grounded round-trip substrate hardening spec with five diagnostic maps, and updated contract state tracking.
NodeGuid Type Implementation & Tests
crates/lance-graph-contract/src/identity.rs
New 16-byte aligned NodeGuid struct encodes UUIDv8-based identity with fields for namespace, entity type, kind, truncated nibble-path prefix, shape hash, and local index. Includes new() constructor with masking, byte-level access (as_bytes/from_bytes), field accessors for all five readings (namespace, entity_type, kind, niblepath, shape_hash, local, layout_version), UUID validation, canonical Display formatting, and 20+ unit tests covering round-trip, field independence, masking saturation, ancestor validation, and byte parity.
NiblePath Inverse Constructor
crates/lance-graph-contract/src/hhtl.rs
NiblePath::from_packed(path: u64, depth: u8) -> Option<Self> reconstructs a path from its packed representation, validating depth bounds and ensuring no stray bits outside the nibble region; enables round-trip composition of NodeGuid.
Library Module & Export Wiring
crates/lance-graph-contract/src/lib.rs
Added public identity module and re-exported NodeGuid and IDENTITY_LAYOUT_VERSION constants to the crate's public API.

Code Formatting & Hygiene Refactoring

Layer / File(s) Summary
Example Code Readability
crates/lance-graph-contract/examples/cognitive_cycle.rs, crates/lance-graph-contract/examples/savant_dispatch.rs
Gate state decision logic and dispatch logging refactored into multi-line if/else branches, expanded println! formatting, and multi-line struct literals for improved code clarity.
Unit Test Assertion & Struct Formatting
crates/lance-graph-contract/src/{atoms,callcenter,counterfactual,episodic_edges,escalation,head2head,nars,pearl_junction,soa_envelope,transaction,witness_table}.rs
Widespread multi-line reformatting of assert_eq!, assert!, and struct literals across 13 modules; assertion logic, thresholds, and test behavior unchanged.
Constant Data & Recipe Formatting
crates/lance-graph-contract/src/recipes.rs, crates/lance-graph-contract/src/savants.rs
RECIPES array (34 entries) and SAVANTS roster (25 entries) reformatted from compact single-line to multi-line field-per-line layouts; all values and membership preserved.
MUL SIMD Pipeline & Scheduler Formatting
crates/lance-graph-contract/src/mul.rs, crates/lance-graph-contract/src/scheduler.rs
MUL contract's i4-scalar and batch SIMD evaluation pipeline reorganized: multiline match arms, split/expanded struct construction, SIMD intrinsics blocks (AVX-512/NEON lane operations), and wrapper batch API length assertions reformatted. Scheduler libet_offset_us computation refactored to inline if expression. All algorithmic logic, thresholds, and comparison tolerances preserved.
Import Reordering & Miscellaneous Formatting
crates/lance-graph-contract/src/plan.rs
Module-level import reordering; no behavioral changes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Poem

🐰 A GUID of identity, nested and true,
Sixteen bytes of structure, a compass so new.
From nibbles to hashes, round-trip made sound,
Phase A takes flight—the architecture is crowned!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: introduction of NodeGuid, a structured 128-bit instance identity type implementing Phase A of the identity architecture plan, which is the primary feature addition in this PR.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@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

🤖 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 1-8: Update the new AGENT_LOG.md entry for "2026-06-09 —
D-IDENTITY-1 (Phase A) + 2 cross-repo sweeps — identity-architecture" to include
the commit SHA used for this run; locate the header line and append the short or
full commit identifier after the date or outcome (so the entry contains D-ids,
commit, tests, outcome as required), ensuring the commit SHA is recorded in the
same sentence that describes the orchestration/outcome for traceability.

In @.claude/board/LATEST_STATE.md:
- Line 58: A blank line inside a blockquote is triggering MD028; fix the
blockquote continuity in .claude/board/LATEST_STATE.md by removing the empty
line inside the quoted block or ensuring the separator line also starts with '>'
so the quote remains continuous; locate the broken blockquote (the paragraph
break around the "Proposed fix" area) and either delete the blank line or prefix
it with '>' to preserve a single continuous blockquote.

In @.claude/plans/cognitive-write-roundtrip-substrate-v1.md:
- Around line 44-58: The Markdown has unlabeled fenced code blocks containing
the ASCII diagram (starting with "WRITE  (project = encode) ... roundtrip_eq:
in(s,p,o) == out(s,p,o) ... PASS ⟹ substrate sound") which triggers MD040;
update each fenced block to include an explicit language identifier (e.g.,
change ``` to ```text) so markdownlint accepts them and rendering is consistent;
locate the two unlabeled blocks around the ASCII diagram and the later block
(the one that spans the "roundtrip_eq" section) and add the same language tag to
each.

In @.claude/plans/identity-architecture-exists-vs-needs-v1.md:
- Around line 193-195: Remove the stale "One open [DECISION]: D1 vs D2
(SchemaPtr-entity_type vs NiblePath-prefix as the class carrier) —
recommendation: both (exact + routing prefix)." statement; locate the exact
sentence that begins "One open [DECISION]: D1 vs D2" and delete it or replace it
with a short canonical status line indicating the decision is resolved/landed in
Phase A to match the resolution recorded earlier (the paragraph that marks the
decision as resolved and landed). Ensure only the resolved status remains to
avoid conflicting plan state.
- Around line 50-105: The markdown has multiple tables that lack surrounding
blank lines causing MD058; for each table (the initial Types table under the top
section, and the Layer 1 through Layer 6 tables labeled "Layer 1 — edge /
handoff carriers", "Layer 2 — cold-path stores", "Layer 3 — resolution", "Layer
4 — commit + witness", "Layer 5 — cross-store transport", and "Layer 6 —
round-trip / substrate-hardening") add one blank line immediately before the
table header line (the | Type | ... |) and one blank line immediately after the
table end (after the last |---| row/data row block) so each table is separated
from surrounding text; update the blocks containing symbols like NiblePath,
SchemaPtr, EpisodicEdges64, MetadataStore, RegistryClassView, SoaEnvelope,
EntityKey, and TripletProjection to follow this spacing convention.

In `@crates/lance-graph-contract/src/hhtl.rs`:
- Around line 191-211: Add focused #[cfg(test)] unit tests next to the
NiblePath::from_packed implementation to cover its rejection and sentinel paths:
assert None is returned when depth > MAX_DEPTH, assert None is returned when
path has non-zero bits above 4*depth (e.g., pack a value with a high nibble set
while depth is smaller), and assert that from_packed(0, 0) returns
Some(NiblePath::EMPTY) (or equal to NiblePath { path:0, depth:0 }). Place tests
in a new mod tests block in the same file and reference the public constructor
NiblePath::from_packed, the MAX_DEPTH constant, and EMPTY sentinel to validate
behavior.
🪄 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: 3acaa399-3998-4a9b-919b-3b61a47af0c4

📥 Commits

Reviewing files that changed from the base of the PR and between 4d26776 and 947c1e4.

📒 Files selected for processing (29)
  • .claude/board/AGENT_LOG.md
  • .claude/board/EPIPHANIES.md
  • .claude/board/LATEST_STATE.md
  • .claude/plans/cognitive-write-roundtrip-substrate-v1.md
  • .claude/plans/identity-architecture-exists-vs-needs-v1.md
  • crates/lance-graph-contract/examples/cognitive_cycle.rs
  • crates/lance-graph-contract/examples/savant_dispatch.rs
  • crates/lance-graph-contract/src/atoms.rs
  • crates/lance-graph-contract/src/callcenter/mod.rs
  • crates/lance-graph-contract/src/callcenter/ogit_uris.rs
  • crates/lance-graph-contract/src/callcenter/role_keys.rs
  • crates/lance-graph-contract/src/cognition/advance.rs
  • crates/lance-graph-contract/src/counterfactual.rs
  • crates/lance-graph-contract/src/episodic_edges.rs
  • crates/lance-graph-contract/src/escalation.rs
  • crates/lance-graph-contract/src/head2head.rs
  • crates/lance-graph-contract/src/hhtl.rs
  • crates/lance-graph-contract/src/identity.rs
  • crates/lance-graph-contract/src/lib.rs
  • crates/lance-graph-contract/src/mul.rs
  • crates/lance-graph-contract/src/nars.rs
  • crates/lance-graph-contract/src/pearl_junction.rs
  • crates/lance-graph-contract/src/plan.rs
  • crates/lance-graph-contract/src/recipes.rs
  • crates/lance-graph-contract/src/savants.rs
  • crates/lance-graph-contract/src/scheduler.rs
  • crates/lance-graph-contract/src/soa_envelope.rs
  • crates/lance-graph-contract/src/transaction/ctx.rs
  • crates/lance-graph-contract/src/witness_table.rs

Comment on lines +1 to +8
## 2026-06-09 — D-IDENTITY-1 (Phase A) + 2 cross-repo sweeps — identity-architecture

**Orchestrator:** Opus main thread (autoattended). **Outcome:** Shipped Phase A.
- **Sweep A** (Opus general-purpose): lance-graph + ndarray identity-type inventory → the 128-bit identity space is EMPTY (only `[u8;16]` is `atoms::I4x32`, a style vector); every GUID field already exists as a committed scalar → compose-don't-reinvent.
- **Sweep B** (Opus general-purpose): MedCare-rs + smb-office-rs store keys → `EntityKey(&[u8])` already carries any-length keys (smb-bridge `key_to_filter` length-branches on Mongo+Lance); transport solved. MedCare needs one `external_ref` (or reuse DMS `sha256`); smb maps directly.
- **Phase A:** `lance_graph_contract::identity::NodeGuid` (UUIDv8, composed from SchemaPtr⊕NiblePath⊕StructuralSignature⊕local) + `NiblePath::from_packed`. 599 contract lib tests (+15), clippy `-D` clean, fmt clean.

Plans: `identity-architecture-exists-vs-needs-v1.md`, `cognitive-write-roundtrip-substrate-v1.md`. Epiphany: E-IDENTITY-WHITEBOX-1.

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 the commit SHA to the new AGENT_LOG entry for traceability.

The new run entry captures D-id/tests/outcome, but it should also include the commit identifier so the shipped scope is audit-linkable from this log entry.

As per coding guidelines, “Every agent run gets one append-only entry in AGENT_LOG.md (D-ids, commit, tests, outcome).”

🤖 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 1 - 8, Update the new AGENT_LOG.md
entry for "2026-06-09 — D-IDENTITY-1 (Phase A) + 2 cross-repo sweeps —
identity-architecture" to include the commit SHA used for this run; locate the
header line and append the short or full commit identifier after the date or
outcome (so the entry contains D-ids, commit, tests, outcome as required),
ensuring the commit SHA is recorded in the same sentence that describes the
orchestration/outcome for traceability.

Source: Coding guidelines

## Current Contract Inventory (lance-graph-contract)

> **2026-06-09 — ADDED (D-IDENTITY-1, Phase A of identity-architecture)**: `lance_graph_contract::identity::{NodeGuid([u8;16]), IDENTITY_LAYOUT_VERSION}` — the workspace's first **stable binary instance identity**: a structured 128-bit UUIDv8 (RFC 9562) = the HHTL nibble-address **formalized + namespaced**. **Composed from existing committed scalars, never re-invented** (Agent A sweep confirmed the 128-bit id space was empty): octets carry `namespace:u8 | entity_type:u16 | kind:u8` (the `SchemaPtr.packed` convention) ⊕ a truncated `NiblePath` routing prefix (`PREFIX_NIBBLES=4`) ⊕ a 22-bit `shape_hash` (truncated `StructuralSignature`) ⊕ a 24-bit `local`, with UUIDv8 version(=8)/variant(=0b10) at their RFC-fixed positions + an `IDENTITY_LAYOUT_VERSION` stamp. **Eineindeutigkeit**: `entity_type` is the canonical exact class identity; the `NiblePath` prefix is the bijective DERIVED view (a *truncated* prefix can't be the identity — deep classes collide past it; the prefix `is_ancestor_of` the full path). Five readings: resolve (`entity_type`) / route (`niblepath`) / witness (frozen bytes + merkle) / ground-truth (`shape_hash` drift) / dispatch-to-store (`as_bytes` → `EntityKey`). Also added `hhtl::NiblePath::from_packed` (inverse of `packed`). Zero-dep; 599 contract lib tests (+15: field-isolation matrix, UUIDv8 gates, ancestor-prefix invariant, Display=canonical-UUID); clippy `-D warnings` clean; fmt clean. Plans: `identity-architecture-exists-vs-needs-v1.md` (exists-vs-needs map + phases A→H), `cognitive-write-roundtrip-substrate-v1.md`. Epiphany: E-IDENTITY-WHITEBOX-1.

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

Remove the blank blockquote break that triggers MD028.

Line 58 is a blank line inside a blockquote (MD028). Keep the quote block continuous (or use > on the separator line) to avoid markdown lint warnings.

Proposed fix
-
+>
📝 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
>
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 58-58: Blank line inside blockquote

(MD028, no-blanks-blockquote)

🤖 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/LATEST_STATE.md at line 58, A blank line inside a blockquote
is triggering MD028; fix the blockquote continuity in
.claude/board/LATEST_STATE.md by removing the empty line inside the quoted block
or ensuring the separator line also starts with '>' so the quote remains
continuous; locate the broken blockquote (the paragraph break around the
"Proposed fix" area) and either delete the blank line or prefix it with '>' to
preserve a single continuous blockquote.

Source: Linters/SAST tools

Comment on lines +44 to +58
```
WRITE (project = encode) READ-BACK (decompile = decode)
Vec<Triple> Vec<Triple>
│ intern (s,p,o) → ids (dict) ▲ dict reverse: ids → (s,p,o)
│ quantize (f,c) → NARS bits │ dequantize NARS → (f,c)
▼ │
CausalEdge64 u64 + class_id u16 ──────────┘
│ lay out via MAILBOX_COLUMNS
SoaEnvelope LE bytes ── commit_event (sole-writer, tick version) ──► Lance

roundtrip_eq: in(s,p,o) == out(s,p,o) [exact, truth_tolerance ignored for identity]
in(f,c) ≈ out(f,c) [tol = 1/1023, the CausalEdge64 NARS grid]
PASS ⟹ substrate sound for this cycle | FAIL ⟹ the brittle contract, NAMED
```

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 language identifiers to fenced code blocks (MD040).

Lines 44 and 90 use unlabeled fenced blocks; add explicit language tags (for example text) to satisfy markdownlint and improve rendering consistency.

Also applies to: 90-97

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 44-44: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 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/plans/cognitive-write-roundtrip-substrate-v1.md around lines 44 -
58, The Markdown has unlabeled fenced code blocks containing the ASCII diagram
(starting with "WRITE  (project = encode) ... roundtrip_eq: in(s,p,o) ==
out(s,p,o) ... PASS ⟹ substrate sound") which triggers MD040; update each fenced
block to include an explicit language identifier (e.g., change ``` to ```text)
so markdownlint accepts them and rendering is consistent; locate the two
unlabeled blocks around the ASCII diagram and the later block (the one that
spans the "roundtrip_eq" section) and add the same language tag to each.

Source: Linters/SAST tools

Comment on lines +50 to +105
| Type | Width | Role | Status | Evidence |
|---|---|---|---|---|
| `NiblePath{path:u64,depth:u8}` | 72 | HHTL tree address (basin/child/is_ancestor_of, 16ⁿ) | **[G]** | hhtl.rs |
| `SchemaPtr{packed:u32=[ns:8\|entity_type:16\|kind:8], ctx:u32}` | 64 | schema/type pointer | **[G]** | namespace.rs:119 |
| `NamespaceId(u8)` | 8 | OGIT namespace ordinal | **[G]** | namespace.rs:24 |
| `ClassId = u16` | 16 | per-row shape discriminator ("never a content hash") | **[G]** | class_view.rs:53 |
| `EntityTypeId = u16` | 16 | per-row object-type (Palantir) | **[G]** | ontology.rs:81 |
| `FieldMask(u64)` + `inherit` | 64 | presence bitmask, parent-OR-delta | **[G]** | class_view.rs:69,136 |
| `StructuralSignature` (shape_hash) | hash | "deterministic hash over property-id set" | **[G] type / [H] live-wire** | odoo_blueprint::class_signature |
| `EdgeRef{family:u8,local:u16}` | 24 | episodic HHTL family+local address | **[G]** | episodic_edges.rs:34 |

### Layer 1 — edge / handoff carriers (the LE "sound members")
| Type | Width | Role | Status |
|---|---|---|---|
| `EpisodicEdges64(u64)` = 4×EdgeRef, MRU promote/evict, `to_le_bytes` | 64 | AriGraph episodic edges | **[G]** episodic_edges.rs |
| `CausalEdge64(u64)` (NARS 10+10 ×1023) | 64 | baton/causal edge payload | **[G]** ndarray causal_diff.rs:153 |
| Baton `(target:u16, edge:u64)` | 80 | inter-mailbox handoff | **[G]** collapse_gate.rs:235 |
| `MailboxId=u32`, `MailboxRow{mailbox_ref:u32,row_idx:u32}` | 32/64 | mailbox + row address | **[G]** |

### Layer 2 — cold-path stores (TODAY: thin + inconsistent)
| Store | Key | Status |
|---|---|---|
| `MetadataStore`: `NodeRecord{node_id:u32, label:String, properties:HashMap<String,String>}`, `EdgeRecord{source:u32,target:u32,edge_type:String}` | u32 + **STRING label/props (legacy Cypher)** | **[G]** metadata.rs:60,86 |
| `SpoStore`: `HashMap<u64 dn_hash, SpoRecord>` | u64 **content-hash** (not stable id) | **[G]** spo/store.rs:38 |
| ndarray `CogRecord{meta,cam,btree,embed}` | **no id** ("id is external dn_hash") | **[G]** cogrecord.rs:56 |
| `WitnessId(u64)` (arigraph witness) | 64 opaque handle | **[G]** witness_corpus.rs:63 |

### Layer 3 — resolution (class-from-address)
| Surface | Status |
|---|---|
| `RegistryClassView: ClassView` (fields/template/dolce_category_id) | **[G] resolve / [H] field-enum deferred** class_resolver.rs |
| `OntologyRegistry`: `resolve_uri`, `enumerate_first_with_entity_type_id(u16)`, `resolve_iri_in` | **[G]** registry.rs |

### Layer 4 — commit + witness (the membrane)
| Surface | Status |
|---|---|
| `SoaEnvelope` trait + `ColumnDescriptor` (container-LE geometry) | **[G] trait / [H] ZERO impls** soa_envelope.rs |
| `MailboxSoaView`/`MailboxSoaOwner` (read airgap + Rubicon `try_advance_phase`) | **[G]** soa_view.rs |
| `commit_event` sole-writer + `ExternalMembrane::project` + `CommitFilter`/`MembraneGate` | **[G]** lance_membrane.rs:315 |
| `CognitiveEventRow` (scalar audit event — VSA stripped) | **[G]** external_intent.rs:113 |
| `MerkleRoot(u64)` ×3 (audit/SPO/unified) + `AuditSink` (jsonl/lance) | **[G]** audit_sink/, merkle.rs |
| `SlaPolicy`, `TenantScope` | **[G] types** sla.rs |

### Layer 5 — cross-store transport (the consumer boundary)
| Surface | Status |
|---|---|
| `EntityKey<'a>(pub &'a [u8])` — opaque length-agnostic key | **[G]** repository.rs:12 |
| `EntityStore`/`EntityWriter`/`Batch` traits | **[G]** repository.rs |
| `smb-bridge`: implements both for Mongo+Lance, `key_to_filter` length-branch | **[G]** smb-bridge/mongo.rs:79, lance.rs:92 |
| MedCare-rs: MySQL i64 PKs; DMS `sha256`(NOT NULL)+`storage_key`; imports EntityKey | **[G]** dms.rs:14, graph_contract.rs:31 |
| smb-office-rs: Mongo `ObjectId`(12B) + `String` refs; actively impls repository | **[G]** base.rs:92 |

### Layer 6 — round-trip / substrate-hardening
| Surface | Status |
|---|---|
| `TripletProjection` trait + `roundtrip_eq` → `RoundTripFailure` | **[G]** codegen_spine.rs:107 |

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 markdown table spacing to clear MD058 warnings.

Lines 50, 62, 70, 78, 84, 94, and 103 need blank lines around tables per markdownlint (MD058).

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 50-50: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


[warning] 62-62: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


[warning] 70-70: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


[warning] 78-78: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


[warning] 84-84: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


[warning] 94-94: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


[warning] 103-103: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

🤖 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/plans/identity-architecture-exists-vs-needs-v1.md around lines 50 -
105, The markdown has multiple tables that lack surrounding blank lines causing
MD058; for each table (the initial Types table under the top section, and the
Layer 1 through Layer 6 tables labeled "Layer 1 — edge / handoff carriers",
"Layer 2 — cold-path stores", "Layer 3 — resolution", "Layer 4 — commit +
witness", "Layer 5 — cross-store transport", and "Layer 6 — round-trip /
substrate-hardening") add one blank line immediately before the table header
line (the | Type | ... |) and one blank line immediately after the table end
(after the last |---| row/data row block) so each table is separated from
surrounding text; update the blocks containing symbols like NiblePath,
SchemaPtr, EpisodicEdges64, MetadataStore, RegistryClassView, SoaEnvelope,
EntityKey, and TripletProjection to follow this spacing convention.

Source: Linters/SAST tools

Comment on lines +193 to +195
- **One open [DECISION]:** D1 vs D2 (SchemaPtr-entity_type vs NiblePath-prefix as
the class carrier) — recommendation: both (exact + routing prefix).

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 | ⚡ Quick win

Remove the stale “open decision” statement to avoid plan-state conflict.

Line 193 says there is “One open [DECISION]”, but Lines 158-165 already mark that decision as resolved and landed in Phase A. Keep one canonical status to prevent downstream planning drift.

🤖 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/plans/identity-architecture-exists-vs-needs-v1.md around lines 193 -
195, Remove the stale "One open [DECISION]: D1 vs D2 (SchemaPtr-entity_type vs
NiblePath-prefix as the class carrier) — recommendation: both (exact + routing
prefix)." statement; locate the exact sentence that begins "One open [DECISION]:
D1 vs D2" and delete it or replace it with a short canonical status line
indicating the decision is resolved/landed in Phase A to match the resolution
recorded earlier (the paragraph that marks the decision as resolved and landed).
Ensure only the resolved status remains to avoid conflicting plan state.

Comment on lines +191 to +211
/// Reconstruct a path from its raw packed `(path, depth)` — the inverse of
/// [`packed`](NiblePath::packed). Used by `identity::NodeGuid` to round-trip
/// the routing-prefix it stores.
///
/// Returns `None` if `depth > MAX_DEPTH`, or if `path` has bits set above the
/// `depth` nibbles (an inconsistent pack — leading nibbles must be the route,
/// trailing high bits must be zero). `from_packed(0, 0)` is [`EMPTY`](NiblePath::EMPTY).
#[must_use]
pub const fn from_packed(path: u64, depth: u8) -> Option<Self> {
if depth > MAX_DEPTH {
return None;
}
// `path` must fit in `depth` nibbles (4·depth bits); higher bits must be 0.
// At MAX_DEPTH (16 nibbles = 64 bits) the whole u64 is usable — skip the
// shift (a `>> 64` would be UB).
let used_bits = 4 * depth as u32;
if used_bits < 64 && (path >> used_bits) != 0 {
return None;
}
Some(Self { path, depth })
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add focused unit tests for from_packed edge cases.

Line 191 adds a new public constructor, but there are no direct tests here for its rejection paths (depth > MAX_DEPTH, non-zero high bits) and the (0, 0) sentinel mapping. Add focused unit tests in this module.

Proposed test additions
 #[cfg(test)]
 mod tests {
     use super::*;
     use crate::class_view::FieldMask;
+    
+    #[test]
+    fn from_packed_validates_depth_and_high_bits() {
+        assert_eq!(NiblePath::from_packed(0, 0), Some(NiblePath::EMPTY));
+        assert_eq!(NiblePath::from_packed(0x12, 2), Some(NiblePath::root(0x1).child(0x2)));
+        assert_eq!(NiblePath::from_packed(0, MAX_DEPTH + 1), None);
+        // depth=2 => only low 8 bits are allowed; high bits must be zero.
+        assert_eq!(NiblePath::from_packed(0x1_12, 2), None);
+    }
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-contract/src/hhtl.rs` around lines 191 - 211, Add focused
#[cfg(test)] unit tests next to the NiblePath::from_packed implementation to
cover its rejection and sentinel paths: assert None is returned when depth >
MAX_DEPTH, assert None is returned when path has non-zero bits above 4*depth
(e.g., pack a value with a high nibble set while depth is smaller), and assert
that from_packed(0, 0) returns Some(NiblePath::EMPTY) (or equal to NiblePath {
path:0, depth:0 }). Place tests in a new mod tests block in the same file and
reference the public constructor NiblePath::from_packed, the MAX_DEPTH constant,
and EMPTY sentinel to validate behavior.

Source: Coding guidelines

@AdaWorldAPI AdaWorldAPI merged commit 62bca5e into main Jun 9, 2026
6 checks passed
AdaWorldAPI pushed a commit that referenced this pull request Jun 9, 2026
Follow-up on merged PR #480 (D-IDENTITY-1 Phase A).

Substantive:
- hhtl: focused from_packed edge-case test — depth>MAX_DEPTH and high-bits-set
  rejection, (0,0)->EMPTY sentinel, the MAX_DEPTH boundary that exercises the
  used_bits<64 guard (avoids >>64 UB), and packed o from_packed identity.
- plan: the stale "one open DECISION" line conflicted with the RESOLVED block
  above it -> now a RESOLVED status line (decision landed in NodeGuid).
- plan: add the no-content-drift-for-existing invariant — an existing entity's
  identity is a derived function of its ontology-mapped class, so it cannot
  drift; the sole drift surface is an ontology cache not mapped from its
  authoritative source, which is exactly what the shape_hash witness guards.
- AGENT_LOG: add the commit SHA to the D-IDENTITY-1 entry (traceability).

Cosmetic (markdownlint, the two new plan docs):
- MD040: language tag on the MAP1/MAP5 fenced diagrams.
- MD058: blank lines around the Layer 0-6 inventory tables.
- Skipped MD028 in LATEST_STATE: the blank line between board entries is the
  file's append-only style; "fixing" one entry diverges it from all priors.

Tooling:
- README: native GitHub Actions status badges (Rust Tests / Style Check /
  Build). Chose native badge URLs over the marketplace ci-badges action —
  zero-config, no workflow step or write-back token, no maintenance surface.

600 contract lib tests (+1); clippy -D warnings --all-targets clean; fmt clean.

https://claude.ai/code/session_014A4JuRCqKP2yNENrQ9Ha7H
AdaWorldAPI pushed a commit that referenced this pull request Jun 9, 2026
…supervision-edge = template specialization

Cross-session convergence: a parallel OGAR/SurrealDB session pulled #480 and
independently re-derived the OGAR<->lance-graph membrane as the registry mint of
(entity_type, NiblePath) per class -- exactly DECISION-2 (OGAR mirror) from #481.

New synthesis: NiblePath::is_ancestor_of (one HHTL bit-shift on the GUID prefix)
is three relations at once -- OWL subClassOf, OTP supervision edge, and north-star
template specialization. The template hierarchy IS the routing/supervision
hierarchy IS the subclass hierarchy; no separate routing structure to maintain.

https://claude.ai/code/session_014A4JuRCqKP2yNENrQ9Ha7H
AdaWorldAPI added a commit that referenced this pull request Jun 9, 2026
chore(contract): address #480 CodeRabbit review + CI status badges
AdaWorldAPI pushed a commit that referenced this pull request Jun 11, 2026
…allization)

Crystallizes the operator-pinned canonical GUID (OGAR/CLAUDE.md) into
lance-graph's policy-side contract before it dilutes:

- The canon cited (hex dash-groups = classid-HEEL-HIP-TWIG-[basin+id];
  key(128)+value(3968)=4096; 3x4 uniform, tier = nibble >> 2; RFC 9562 =
  wrapper concern; NodeGuid #480 audited against the canon group-by-group,
  never the reverse — Phase B question: groups 3-4 yield all eight
  nibbles to HIP/TWIG).
- Policy ownership table: registry mint (Phase B), per-class
  4^4-hierarchical codebooks on the registry shelf (prefix-scoped,
  longest-prefix wins), PrefixShapeTable registration into ndarray's
  router, quorum certificate type landing in contract::quorum (the #411
  scaffold), escalation via the shipped RouteAction precedent.
- Anti-eigenvalue-theater rules contract-side: quorum certificate with
  measured-tau (I-NOISE-FLOOR-JIRAK; Pflug-10 anchors 0.9973/0.965),
  named typed metrics (no-umbrella; raw-XOR-u64 ordering is the named
  anti-pattern), escalate-never-silently-accept, ShapeId is a register
  key (I-VSA-IDENTITIES Test 0).
- Probes shared with the ndarray counterpart: ROUTE-1, QUORUM-1, PHI-1,
  PYR-1, CODEBOOK-44, HILBERT-L4 (blocker).

Board hygiene: EPIPHANIES E-CANON-GUID-1 prepended in the same commit.
Docs-only; no .rs touched.

https://claude.ai/code/session_01PBTGaPCSnnt6u3pjXpbLwY
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