Skip to content

refactor(contract): reusable facet module — content-blind 8:8 substrate + zero-cost reinterpret#614

Merged
AdaWorldAPI merged 2 commits into
mainfrom
claude/facet-module
Jun 25, 2026
Merged

refactor(contract): reusable facet module — content-blind 8:8 substrate + zero-cost reinterpret#614
AdaWorldAPI merged 2 commits into
mainfrom
claude/facet-module

Conversation

@AdaWorldAPI

@AdaWorldAPI AdaWorldAPI commented Jun 25, 2026

Copy link
Copy Markdown
Owner

What

Follow-up to #613. Extracts FacetTier / FacetCascade out of the operator-LOCKED canonical_node into a dedicated, reusable facet module — they are a content-blind reading over borrowed bytes, not part of the node layout, so this is the correct factoring. canonical_node re-exports both for the historical path; no behaviour change to the existing API.

This is the optimized reusable V3-shaped pattern that the V3 value-tenant migration builds on.

Reusable lane API (one register, four lenses)

The 16-byte facet (facet_classid(4) | 6×(8:8)) is #[repr(C, align(16))] — one 128-bit register, addressable four ways, each a single op:

lens accessor hardware op
row (u32×4) rows(), row_match_mask() vpcmpeqd + vmovmskps
tile (u16×8) .tiers, hi_chain/lo_chain vpcmpeqw / pshufb
prefix (bit, LCP) prefix_distance / shared_prefix_tiles vpxor + tzcnt (granularity-free)
nibble (Morton) FacetTier::morton GFNI (AVX-512)
register as_u128 / from_u128 vmovdqu

Row 0 is the facet_classid ({domain}{schema}); rows 1–3 are the cascade pairs (HEEL:HIP / TWIG:LEAF / family:identity). Transpose-native for AoS→SoA batch sweeps.

Zero-cost reinterpret

as_bytes / ref_from_bytes are SAFETY-commented reinterprets (mirroring node_rows_from_le_bytes). Verified in asm: as_bytes lowers to mov rax, rdi — a literal no-op — and reading a field through it is a single load. So a &FacetCascade held over the slab reads every field/lane with zero decode.

Content-blind: only the consumer projects meaning (part_of:is_a / 256:256 palette centroid / group:member / column:row / concatenated u16 …); every reading amortizes to one 2bit×2bit Morton tile cascade.

Tests / gates

Additive, zero-dep. 741 lib tests (default + guid-v3-tail), clippy -D warnings + fmt clean. Lab-test write-up deferred. Board: LATEST_STATE Contract Inventory entry.

🤖 Generated with Claude Code

https://claude.ai/code/session_01TzqvDqbFRzyx17EkLKBoZF


Generated by Claude Code

Summary by CodeRabbit

  • New Features
    • Added a new 16-byte facet representation with reusable helpers for byte, integer, and lane-based views.
    • Introduced fast prefix, distance, and row-match checks for comparing facet values.
    • Added zero-copy byte reinterpretation helpers for aligned data, improving inspection and reuse of facet records.

… + zero-cost reinterpret

Follow-up to #613. FacetTier/FacetCascade are a content-blind *reading*, not part of
the operator-LOCKED node layout, so they belong in their own module rather than
canonical_node. Extracted to src/facet.rs; canonical_node re-exports both for the
historical path. No behaviour change to the existing API.

Rounded out the reusable lane API (the one-register / four-lane design):
- as_u128 / from_u128   single-register (128-bit) view
- rows()                the 4 dword rows: {domain}{schema} / HEEL:HIP / TWIG:LEAF /
                        family:identity (vpcmpeqd lane)
- prefix_distance / shared_prefix_tiles
                        the granularity-free LCP redout (vpxor + tzcnt; 8:8 vs nibble
                        is a free >> on the count, measured)
- row_match_mask        which of the 4 rows match (vpcmpeqd + vmovmskps)
- as_bytes / ref_from_bytes
                        ZERO-COST reinterpret (repr(C, align(16))): as_bytes lowers to
                        `mov rax, rdi` (a literal no-op, verified in asm), so a
                        &FacetCascade over the slab reads fields/lanes with no decode.
                        ref_from_bytes is the checked-aligned borrow (mirrors
                        node_rows_from_le_bytes; None if unaligned).

repr C -> C, align(16) (0 padding; size stays 16) makes the facet an explicit 128-bit
register value (aligned SIMD loads + the no-op reinterpret).

Board: LATEST_STATE Contract Inventory entry. Lab-test write-up deferred.
741 lib tests green (default + guid-v3-tail), clippy -D warnings + fmt clean.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TzqvDqbFRzyx17EkLKBoZF
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@AdaWorldAPI, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 40 minutes and 32 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5febba5b-c3dd-4a39-9677-cf022b44c7b9

📥 Commits

Reviewing files that changed from the base of the PR and between 3612316 and f8becf2.

📒 Files selected for processing (1)
  • .claude/board/LATEST_STATE.md
📝 Walkthrough

Walkthrough

The PR adds a public facet module in lance-graph-contract, moves FacetTier and FacetCascade into it, re-exports them from canonical_node, and adds byte, u128, row, chain, prefix, and match helpers with tests.

Changes

Facet module extraction

Layer / File(s) Summary
Public facet surface
crates/lance-graph-contract/src/lib.rs, crates/lance-graph-contract/src/canonical_node.rs, .claude/board/LATEST_STATE.md
facet is exported publicly, canonical_node re-exports FacetTier and FacetCascade, and the board entry records the split.
Facet layout and byte views
crates/lance-graph-contract/src/facet.rs
FacetTier and FacetCascade define the 16-byte layout and expose byte, u128, row, and chain views.
Locality helpers
crates/lance-graph-contract/src/facet.rs
FacetCascade adds shared-prefix distance helpers and a row-match mask.
Tests and cleanup
crates/lance-graph-contract/src/facet.rs, crates/lance-graph-contract/src/canonical_node.rs
Unit tests cover the new conversions, views, and helpers, and the old canonical-node test is removed.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

I hopped through bytes with twitchy nose,
In facet burrows, the structure grows.
Four lanes of rows, a u128 glow,
Prefixes dance in tidy flow.
🐰 The contract squeaks: “All systems go!”

🚥 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 summarizes the main refactor: extracting a reusable facet module with zero-cost byte reinterpretation.
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.


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.

@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: 1

🤖 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/LATEST_STATE.md:
- Around line 143-144: The blockquote in LATEST_STATE.md is broken by an
unquoted blank line, causing the entry to split and trigger MD028. Keep the
inventory note contiguous by either removing the blank line or turning it into a
quoted blank line so the quoted section remains a single block. Refer to the
Markdown block starting with the `2026-06-25 — MODULARIZED` entry and ensure the
`>` prefix is preserved consistently.
🪄 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: 7b97c2ea-2f4f-4a72-92ae-c0882f52a4f1

📥 Commits

Reviewing files that changed from the base of the PR and between 6136eb5 and 3612316.

📒 Files selected for processing (4)
  • .claude/board/LATEST_STATE.md
  • crates/lance-graph-contract/src/canonical_node.rs
  • crates/lance-graph-contract/src/facet.rs
  • crates/lance-graph-contract/src/lib.rs

Comment thread .claude/board/LATEST_STATE.md Outdated
CodeRabbit flagged MD028 on #614 — the blank line between the new facet
entry and the #613 entry breaks the blockquote. Quote it (`>`) so the two
entries stay in one blockquote, the fix CodeRabbit suggested.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TzqvDqbFRzyx17EkLKBoZF
AdaWorldAPI pushed a commit that referenced this pull request Jun 25, 2026
Same MD028 fix as #614: quote (`>`) the blank line between the new Phase-1
entry and the #613 entry so they stay one blockquote. Preempts the
identical CodeRabbit nit on this PR.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TzqvDqbFRzyx17EkLKBoZF
@AdaWorldAPI AdaWorldAPI merged commit f686d3a into main Jun 25, 2026
6 checks passed
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