Skip to content

contract: classid canon:custom half-order flip — P0 route-through + P1 CanonHigh#628

Open
AdaWorldAPI wants to merge 7 commits into
mainfrom
claude/v3-substrate-migration-review-o0yoxv
Open

contract: classid canon:custom half-order flip — P0 route-through + P1 CanonHigh#628
AdaWorldAPI wants to merge 7 commits into
mainfrom
claude/v3-substrate-migration-review-o0yoxv

Conversation

@AdaWorldAPI

@AdaWorldAPI AdaWorldAPI commented Jul 2, 2026

Copy link
Copy Markdown
Owner

What

Executes the operator-triggered classid half-order migration (plan: .claude/plans/classid-canon-custom-flip-v1.md, ruling anchors in §0).

P0 (landed first, zero behavior change): ONE flippable classid composition in ogar_codebook.rsClassidOrder { CanonLow, CanonHigh }, compose_classid / split_classid / classid_canon / classid_custom / flip_classid — with every half-read in the contract routed through it (classid_concept_domain, classid_concept, classid_app_prefix, render_classid, hhtl::from_guid_prefix, canonical_node EntityType stamps). Probes: round-trip under both orders, flip(flip(x)) == x, legacy-boundary matrix over every CODEBOOK id, no-class-collapse guard.

P1 (this PR's tip): flips CLASSID_ORDER to CanonHigh — stored classids become canon (domain:appid) HIGH, custom LOW: 0x0701_1000 (OSINT:q2), 0x0A01_1000 (Anatomy:q2), 0x0E01_1000 (Genetics:q2). Legacy pre-flip forms remain in BUILTIN_READ_MODES as documented read-only aliases (mint-forward: persisted pre-flip rows resolve forever until re-baked; retirement gated on corpus proof).

Guards honored

Base

Rebased onto main after #625 (which merged after #626/#627); OGAR lock pin already at a0c7936 (#146, OSINT contributes zero vocabulary rows).

🤖 Generated with Claude Code

https://claude.ai/code/session_01MLBnPuScZy6w9di2QEjsXM


Generated by Claude Code

Summary by CodeRabbit

  • New Features

    • Added support for a new class ID handling format, including safer splitting and recombining of class ID values.
    • Improved consistency in how tenant and path values are generated from class IDs.
  • Bug Fixes

    • Fixed incorrect class ID routing after flips so the canonical value is preserved.
    • Prevented invalid path generation when the custom portion of a class ID is present.

claude added 2 commits July 2, 2026 04:59
Co-Authored-By: Claude <noreply@anthropic.com>
…ough, zero behavior

ClassidOrder {CanonLow, CanonHigh} + CLASSID_ORDER (P0-pinned CanonLow) +
compose_classid[_with] / split_classid[_with] / classid_canon /
classid_custom / flip_classid in ogar_codebook (the module that already
owned the unnamed split — wire, don't invent).

Routed through the ONE definition (behavior-identical under CanonLow,
probed): classid_concept_domain, classid_concept, classid_app_prefix,
render_classid, hhtl::NiblePath::from_guid_prefix's custom-half-zero
guard, and the carve-matrix EntityType discriminator stamps (now
classid_canon(...) — the codex-P2 class-collapse guard; 'as u16' on a
classid is the forbidden pattern).

Probes: split-compose round-trip both orders; flip involution over all
wired + post-flip ids; the legacy-boundary matrix (every routed reader
== its direct mask for every codebook id under every prefix); the
no-class-collapse probe (post-flip canon halves 0x0701/0x0A01/0x0E01
distinct while naive 'as u16' collapses all three to 0x1000).

Gates: contract 773 w/ v2+v3 features (14 new), 759 default, doctests
green, clippy -D warnings clean, fmt clean.

Plan: classid-canon-custom-flip-v1.md P0.

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

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

Next review available in: 56 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

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 reviews.

How do review 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 refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bd75ecec-beb6-4e20-a298-d40ba7ea0a40

📥 Commits

Reviewing files that changed from the base of the PR and between 3b5aea0 and 019062a.

📒 Files selected for processing (13)
  • .claude/board/AGENT_LOG.md
  • .claude/board/EPIPHANIES.md
  • .claude/board/LATEST_STATE.md
  • .claude/board/PR_ARC_INVENTORY.md
  • .claude/board/STATUS_BOARD.md
  • crates/lance-graph-contract/Cargo.toml
  • crates/lance-graph-contract/src/canonical_node.rs
  • crates/lance-graph-contract/src/hhtl.rs
  • crates/lance-graph-contract/src/ogar_codebook.rs
  • crates/lance-graph-contract/src/rbac.rs
  • crates/lance-graph-ogar/src/actions.rs
  • crates/lance-graph-ogar/src/rbac_impl.rs
  • crates/lance-graph-rbac/src/auth.rs
📝 Walkthrough

Walkthrough

This PR introduces a ClassidOrder abstraction in ogar_codebook.rs with compose/split helpers, canon/custom half extractors, and a flip_classid function. Existing classid-dependent logic (classid_concept_domain, classid_app_prefix, classid_concept, render_classid, NiblePath::from_guid_prefix) and tenant-carve tests are migrated to use canon-half extraction instead of raw casts. Board docs record PR #627.

Changes

Classid Canon/Custom Flip Implementation

Layer / File(s) Summary
ClassidOrder abstraction and helpers
crates/lance-graph-contract/src/ogar_codebook.rs
Adds ClassidOrder enum, CLASSID_ORDER constant, compose_classid_with/split_classid_with, compose_classid/split_classid, classid_canon/classid_custom, flip_classid, plus tests for split/compose identity, flip involution, and route-through invariance.
Domain routing and rendering migration
crates/lance-graph-contract/src/ogar_codebook.rs
classid_concept_domain now routes via classid_canon; render_classid composes classid via compose_classid instead of manual bit packing; classid_app_prefix/classid_concept delegate to classid_custom/classid_canon.
NiblePath guid prefix validation
crates/lance-graph-contract/src/hhtl.rs
NiblePath::from_guid_prefix uses split_classid to extract canon/custom halves, rejecting the GUID when custom is nonzero, and uses canon as classid_lo.
Tenant-carve isolation tests
crates/lance-graph-contract/src/canonical_node.rs
OSINT-V3, FMA-V3, and CPIC-V3 tests set EntityType bytes via classid_canon instead of as u16 casts.
PR tracking documentation
.claude/board/LATEST_STATE.md, .claude/board/PR_ARC_INVENTORY.md
Adds entries for PR #627 documenting the classid canon/custom flip activation and migration plan.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Poem

A canon half, a custom half, now split with care,
No more raw casts drifting through the air.
This rabbit hops through bits so neat,
Flip and compose — the classid's complete! 🐇
Onward to the burrow, docs in tow~

🚥 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 reflects the core classid half-order flip and contract route-through changes, including the CanonHigh migration.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.

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.

@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: 3b5aea0bb1

ℹ️ 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".

Comment thread crates/lance-graph-contract/src/ogar_codebook.rs Outdated

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

🧹 Nitpick comments (1)
crates/lance-graph-contract/src/hhtl.rs (1)

296-312: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Update the v1-fold rustdoc to say “CUSTOM half,” not “high u16.”

The implementation now rejects custom != 0 from split_classid; after the order flip, that is no longer equivalent to classid >> 16 != 0. Updating the public docs prevents consumers from reintroducing the raw-mask rule.

🤖 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 296 - 312, Update the
rustdoc/comments in hhtl.rs around the v1 fold logic to refer to the CUSTOM half
from split_classid(parts.classid), not the old “high u16” wording. Make the
wording match the actual check custom != 0 in the v1-fold path so the public
documentation reflects the CanonLow order flip and avoids implying a raw classid
>> 16 mask.
🤖 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:
- Line 103: The board entry uses the wrong accessor shape for classid canon
lookup: `split_classid` returns a tuple, so `.canon` does not exist. Update the
ledger text to reference the exported accessor `classid_canon(id)` instead, so
the documented behavior matches the helper signatures in `ogar_codebook.rs` and
the row stays aligned with the implementation.

In @.claude/board/PR_ARC_INVENTORY.md:
- Around line 42-44: The PR arc entry uses non-existent symbol names, so update
the prose to match the implementation’s real API. Replace references like
CLASSID_CANON_HIGH and split_classid(id).canon with the actual identifiers
ClassidOrder::CanonHigh, classid_canon, and tuple-style split_classid(...),
keeping the board text aligned with the definitions in ogar_codebook.rs. Make
the summary machine-checkable by using the exact exported names consistently
throughout the arc entry.

In `@crates/lance-graph-contract/src/ogar_codebook.rs`:
- Around line 314-343: Add an explicit version/order gate before any
persisted-reader path uses the active CLASSID_ORDER. The issue is that
split_classid(), classid_canon(), and classid_custom() currently reinterpret
legacy classids when the layout flips. Fix by routing v1 decode paths through
split_classid_with(ClassidOrder::CanonLow, ...) or by requiring a version
byte/read-mode selector before choosing CanonHigh, and keep the gating logic
close to split_classid and the classid_* accessors so the correct order is
chosen from the blob/version instead of global state.

---

Nitpick comments:
In `@crates/lance-graph-contract/src/hhtl.rs`:
- Around line 296-312: Update the rustdoc/comments in hhtl.rs around the v1 fold
logic to refer to the CUSTOM half from split_classid(parts.classid), not the old
“high u16” wording. Make the wording match the actual check custom != 0 in the
v1-fold path so the public documentation reflects the CanonLow order flip and
avoids implying a raw classid >> 16 mask.
🪄 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: 97f76310-ecff-4e4d-8c95-1271db75b580

📥 Commits

Reviewing files that changed from the base of the PR and between 5561908 and 3b5aea0.

📒 Files selected for processing (5)
  • .claude/board/LATEST_STATE.md
  • .claude/board/PR_ARC_INVENTORY.md
  • crates/lance-graph-contract/src/canonical_node.rs
  • crates/lance-graph-contract/src/hhtl.rs
  • crates/lance-graph-contract/src/ogar_codebook.rs

Comment thread .claude/board/LATEST_STATE.md Outdated
Comment thread .claude/board/PR_ARC_INVENTORY.md
Comment thread crates/lance-graph-contract/src/ogar_codebook.rs
…om LOW)

The P1 flip of classid-canon-custom-flip-v1 (operator trigger 2026-07-02):

- CLASSID_ORDER = CanonHigh; stored classids now carry canon (domain:appid)
  in the HIGH u16, custom (marker/render prefix) in the LOW u16.
- New mint surface: CLASSID_OSINT 0x0700_0000, CLASSID_FMA 0x0A01_0000,
  CLASSID_PROJECT 0x0100_0000, CLASSID_ERP 0x0200_0000; V3 classes
  0x0701_1000 / 0x0A01_1000 / 0x0E01_1000 (OSINT + CPIC appid normalized
  to :01 = q2 per the ruling).
- Mint-forward boundary: every pre-flip stored form registered as a
  CLASSID_*_LEGACY read-only alias in BUILTIN_READ_MODES — persisted rows
  resolve until re-baked; retirement gated on corpus proof (codex P2 #627).
- hhtl::from_guid_prefix (v1 fold) accepts pure-canon classids in BOTH
  stored forms and folds them to the identical path; marked classids
  (both halves nonzero) still refuse.
- OGAR#95 reconciliation (plan P2): the app prefix IS the custom half —
  render_classid composes concept HIGH / prefix LOW (patient@Healthcare =
  0x0901_0005); the #95 table becomes the custom-half render catalogue.
- Board: EPIPHANIES E-CLASSID-FLIP-P1-LANDED, STATUS_BOARD D-CCF rows,
  AGENT_LOG fleet-inventory entry (same commit per board-hygiene rule).

Gates: contract 773 (guid-v3-tail) / 759 (default) + doctests; clippy -D
warnings; dependents green (callcenter, cognitive-shader-driver, planner).

Co-Authored-By: Claude <noreply@anthropic.com>
…rbac.rs

Follow-up on the CanonHigh flip: three sites derived classid halves outside
the one flippable composition and surfaced only when the flip landed —

- contract rbac.rs ClassGrant::permits used 'class as u16' (the codex-P2
  collapse pattern). Now routes classid_canon_compat.
- lance-graph-rbac AuthProvider::classid() hand-widened u32::from(concept).
  Now routes contract render_classid(0x0000, concept) -> 0x0B01_0000-form.
- lance-graph-ogar AUTH_*_CID / test ENCOUNTER literals in the pre-flip
  0x0000_DDCC form. Now const-composed via contract render_classid.

New: ogar_codebook::classid_canon_compat — the mint-forward CANON reader
for surfaces serving BOTH stored forms (RBAC grants, un-re-baked corpora):
active canon when plausible (>= 0x0100 && != 0x1000), legacy-order
fallback otherwise; the canon slot exactly 0x1000 (domain-0x10 root) stays
reserved-unusable until marker retirement (P4). RBAC authorizes pre-flip
persisted rows without re-bake; both-forms grant test added.

Board: EPIPHANIES E-CLASSID-COMPAT-READER (same commit).

Gates: contract 774 (guid-v3-tail), rbac 30, ogar 81; clippy; fmt.

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
claude added 2 commits July 2, 2026 06:13
Co-Authored-By: Claude <noreply@anthropic.com>
#628)

LATEST_STATE guard line now cites classid_canon(id) (split_classid returns
a tuple; .canon is not a field). PR_ARC #627 entry gets an appended dated
correction line naming ClassidOrder::CanonHigh + classid_canon(id)
(append-only honored — original lines untouched).

Co-Authored-By: Claude <noreply@anthropic.com>
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