Skip to content

contract: resolve ISS-V1-TAIL-RESIDUE — un-gate mint_for, default-on guid-v3-tail, aiwar mints V3#663

Merged
AdaWorldAPI merged 2 commits into
mainfrom
claude/v3-substrate-migration-review-o0yoxv
Jul 8, 2026
Merged

contract: resolve ISS-V1-TAIL-RESIDUE — un-gate mint_for, default-on guid-v3-tail, aiwar mints V3#663
AdaWorldAPI merged 2 commits into
mainfrom
claude/v3-substrate-migration-review-o0yoxv

Conversation

@AdaWorldAPI

@AdaWorldAPI AdaWorldAPI commented Jul 7, 2026

Copy link
Copy Markdown
Owner

What

Resolves ISS-V1-TAIL-RESIDUE — the V1→V3 GUID-tail migration for the two production mint sites, plus the substrate wiring that unblocks it.

Changes (2 commits)

44c67d12 — un-gate + default-on + route

  • canonical_node.rsmint_for moved to an unconditional impl NodeGuid: V1 arm always available, V2/V3 arms feature-gated with a dead V1 fallback so --no-default-features still compiles.
  • Cargo.tomldefault = ["guid-v3-tail"].
  • ocr.rs + aiwar.rs — route through mint_for(classid_read_mode(c).tail_variant, …); no hardcoded NodeGuid::new left.
  • .claude/commands/v3-audit.md — check feat(graph): add SPO triple store with bitmap ANN, TruthGate, semirin… #6 forbids NodeGuid::new( in non-test production code.

4bc25ba2 — complete the aiwar V3 flip

  • soa_graph.rsOSINT_GOTHAM.classidCLASSID_OSINT_V3 (cfg-selected, V1 fallback for --no-default-features); the node() test helper mints via mint_for.
  • aiwar.rs — mints the real CLASSID_OSINT_V3 in every normal build.

Corrected diagnosis (recorded in ISSUES.md)

Commit 1 had claimed the aiwar V3 flip was blocked because project_snapshot reads family via the V1 family() accessor. That was wrong. soa_graph's read path is already tail-aware (family_of/identity_of route through the classid's tail_variantfamily_v2/identity_v2 for V3; a test proves it). The actual blocker was a one-line domain-spec pin — OSINT_GOTHAM.classid = CLASSID_OSINT (V1) — and project_snapshot filters rows by exact classid, so V3-minted rows were dropped. Consumers were V3-ready; the straggler was the domain constant. Commit 2 fixes it.

Verification

  • Default build (V3): 854 contract lib tests green.
  • --no-default-features (V1 fallback): 840 green.
  • Downstream lance-graph + lance-graph-planner check clean; fmt + clippy clean.

Follow-up (separate, non-blocking)

CLASSID_OSINT (V1, 0x0700_0000) stays a registered legacy alias — retirement is corpus-proof-gated (W6), not part of this issue.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Enabled tail-aware GUID minting by default for graph contracts.
    • OSINT Gotham now follows the correct registered tail/class layout based on feature configuration.
  • Bug Fixes

    • Production node key construction now routes through the registered tail-aware minting flow instead of hardcoded ID construction.
    • Added a production audit check to flag legacy minting patterns that bypass the tail registry.
    • Updated tests and key field masking to match the expected V3 layout when enabled.

… mints

Executes the structural half of ISS-V1-TAIL-RESIDUE (operator ruling
2026-07-04, "default-on guid-v3-tail now so production mints route through
mint_for in every build").

- canonical_node.rs: `mint_for` moved to an unconditional `impl NodeGuid` —
  V1 arm always available; V2/V3 arms feature-gated (`guid-v2-tail`) with a
  dead V1 fallback so `--no-default-features` still compiles.
- Cargo.toml: `default = ["guid-v3-tail"]` — every normal build has the V3
  mint path.
- ocr.rs + aiwar.rs: route through `mint_for(classid_read_mode(c).tail_variant,
  …)` instead of hardcoded `NodeGuid::new`. ocr is classid-param-driven (V3-
  ready). aiwar stays on the V1 `CLASSID_OSINT` (see below), behavior-preserving.
- .claude/commands/v3-audit.md: check #6 forbids `NodeGuid::new(` in non-test
  production code (mechanical guard).

Discovered blocker (documented, deferred): flipping aiwar to `CLASSID_OSINT_V3`
broke `projects_to_family_node_graph` — the V3 tail puts `family` at bytes
12..14 (u16) but `soa_graph::project_snapshot` reads it via the V1 `family()`
u24 accessor. So aiwar's V3-classid flip is now gated on making that consumer
tail-aware (I-LEGACY-API-FEATURE-GATED), not on the feature gate the issue
originally named. ISSUES.md carries the progress + remaining work.

Verification: 854 contract lib tests green (default); `--no-default-features`
compiles; `lance-graph` + `lance-graph-planner` check clean (default-on
propagates safely); fmt + clippy clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MLBnPuScZy6w9di2QEjsXM
@cursor

cursor Bot commented Jul 7, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_ce8a3e4a-1ac6-4c8c-8921-6c21a7586a7a)

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR makes NodeGuid::mint_for unconditional, enables guid-v3-tail by default, routes OCR and AIWAR key minting through tail-aware paths, updates OSINT classid handling and tests, adds a production mint audit check, and records the migration status in the issues board.

Changes

V1-tail-residue migration

Layer / File(s) Summary
Unconditional mint_for and default feature
crates/lance-graph-contract/src/canonical_node.rs, crates/lance-graph-contract/Cargo.toml
mint_for now compiles unconditionally with TailVariant dispatch and fallback behavior, and guid-v3-tail is enabled by default.
ocr.rs mint routing
crates/lance-graph-contract/src/ocr.rs
LayoutBlock::to_node_row now mints the NodeRow key through mint_for using classid_read_mode(classid).tail_variant.
OSINT classid gating and tail-aware tests
crates/lance-graph-contract/src/aiwar.rs, crates/lance-graph-contract/src/soa_graph.rs
OSINT classids now vary by feature flag, minting goes through mint_for with the resolved tail variant, and the related tests/helpers follow the same classid and layout rules.
Audit check and progress log
.claude/commands/v3-audit.md, .claude/board/ISSUES.md
Adds a grep-based production NodeGuid::new( forbid check and records the resolved V1-tail residue entry in the issues log.

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

Possibly related PRs

Poem

I’m a rabbit with a tidy hop,
tail-aware minting doesn’t stop.
V3 wakes up by default now, hooray,
and stray new( calls hop away.
🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title accurately captures the main changes: un-gating mint_for, defaulting guid-v3-tail on, and flipping aiwar to V3 minting.
✨ 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.

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

Caution

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

⚠️ Outside diff range comments (1)
crates/lance-graph-contract/src/aiwar.rs (1)

112-125: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Clarify the V3 note in crates/lance-graph-contract/src/aiwar.rs:112-125: mint_for does not narrow family/identity automatically; the V2/V3 arm asserts both fit in 16 bits and panics otherwise, so the & 0x00FF_FFFF masks must be tightened if this path ever flips.

🤖 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/aiwar.rs` around lines 112 - 125, The
`NodeGuid::mint_for` call in `aiwar.rs` is annotated as if V3 would
automatically narrow `family` and `identity`, but the `V2/V3` path actually
asserts 16-bit fit and will panic if those values exceed it. Update the comment
and the masking logic around the `mint_for` invocation so it reflects the real
behavior, and tighten the `fam`/`identity` masks to 16 bits if this path can
ever switch to V3.
🧹 Nitpick comments (2)
crates/lance-graph-contract/src/ocr.rs (1)

104-132: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Redundant classid_read_mode(classid) lookup.

classid_read_mode(classid) is invoked twice — once at Line 105 for .value_schema and again at Line 124 for .tail_variant — for the same classid within the same call. Since ReadMode appears to carry both fields, cache the result once and reuse it.

♻️ Proposed refactor
     pub fn to_node_row(&self, classid: u32, identity: u32) -> NodeRow {
-        let schema = classid_read_mode(classid).value_schema;
+        let mode = classid_read_mode(classid);
+        let schema = mode.value_schema;
         let mut value = [0u8; VALUE_SLAB_LEN];
@@
             key: NodeGuid::mint_for(
-                classid_read_mode(classid).tail_variant,
+                mode.tail_variant,
                 classid,
🤖 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/ocr.rs` around lines 104 - 132, The
to_node_row method is doing the same classid_read_mode(classid) lookup twice for
one call. Cache the returned ReadMode once at the start of to_node_row, then
reuse its value_schema and tail_variant fields when building the NodeRow. This
keeps the logic in to_node_row unchanged while removing the redundant lookup.
crates/lance-graph-contract/src/aiwar.rs (1)

75-131: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Hoist classid_read_mode(osint_classid) out of the per-row closure.

osint_classid is loop-invariant (fixed at Line 81), but classid_read_mode(osint_classid).tail_variant (Line 117) is re-resolved inside .map() on every row. Hoist it once before the .map() call to avoid a redundant lookup per graph node.

♻️ Proposed refactor
     let view = AiwarClassView::from_graph(graph);
     let ids = graph.all_node_ids();
+    let tail_variant = classid_read_mode(osint_classid).tail_variant;
     let fam_of =
         |id: &str| -> Option<u32> { graph.node(id).and_then(|n| view.family_of(&n.label)) };
     ids.iter()
         .enumerate()
         .map(|(i, id)| {
@@
                 key: NodeGuid::mint_for(
-                    classid_read_mode(osint_classid).tail_variant,
+                    tail_variant,
                     osint_classid,
🤖 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/aiwar.rs` around lines 75 - 131, The per-row
closure in the `ids.iter().enumerate().map(...)` pipeline is re-resolving
`classid_read_mode(osint_classid).tail_variant` for every `NodeRow`, even though
`osint_classid` is ثابت and invariant. Hoist the
`classid_read_mode(osint_classid)` result (or at least its `tail_variant`) once
before the `.map()` call in `aiwar.rs`, then reuse that value inside
`NodeGuid::mint_for` so the lookup happens only once per batch instead of once
per node.
🤖 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.

Outside diff comments:
In `@crates/lance-graph-contract/src/aiwar.rs`:
- Around line 112-125: The `NodeGuid::mint_for` call in `aiwar.rs` is annotated
as if V3 would automatically narrow `family` and `identity`, but the `V2/V3`
path actually asserts 16-bit fit and will panic if those values exceed it.
Update the comment and the masking logic around the `mint_for` invocation so it
reflects the real behavior, and tighten the `fam`/`identity` masks to 16 bits if
this path can ever switch to V3.

---

Nitpick comments:
In `@crates/lance-graph-contract/src/aiwar.rs`:
- Around line 75-131: The per-row closure in the
`ids.iter().enumerate().map(...)` pipeline is re-resolving
`classid_read_mode(osint_classid).tail_variant` for every `NodeRow`, even though
`osint_classid` is ثابت and invariant. Hoist the
`classid_read_mode(osint_classid)` result (or at least its `tail_variant`) once
before the `.map()` call in `aiwar.rs`, then reuse that value inside
`NodeGuid::mint_for` so the lookup happens only once per batch instead of once
per node.

In `@crates/lance-graph-contract/src/ocr.rs`:
- Around line 104-132: The to_node_row method is doing the same
classid_read_mode(classid) lookup twice for one call. Cache the returned
ReadMode once at the start of to_node_row, then reuse its value_schema and
tail_variant fields when building the NodeRow. This keeps the logic in
to_node_row unchanged while removing the redundant lookup.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5b4fb986-befb-4ad7-ba34-da9ccfeae001

📥 Commits

Reviewing files that changed from the base of the PR and between bcf3a63 and 44c67d1.

📒 Files selected for processing (6)
  • .claude/board/ISSUES.md
  • .claude/commands/v3-audit.md
  • crates/lance-graph-contract/Cargo.toml
  • crates/lance-graph-contract/src/aiwar.rs
  • crates/lance-graph-contract/src/canonical_node.rs
  • crates/lance-graph-contract/src/ocr.rs

…AIL-RESIDUE resolved)

Completes the migration: aiwar now mints the real V3 `CLASSID_OSINT_V3` in every
normal build (V1 fallback only under `--no-default-features`).

The mid-work diagnosis in the prior commit was WRONG and is corrected here.
`soa_graph`'s read path is already tail-aware (`family_of`/`identity_of` route
through `classid_read_mode(...).tail_variant` → `family_v2`/`identity_v2` for V3;
proven by `v3_rows_decode_family_and_identity_via_tail_variant`). The actual
blocker was a one-line domain-spec pin: `OSINT_GOTHAM.classid = CLASSID_OSINT`
(V1), and `project_snapshot` filters rows by EXACT classid, so V3-minted aiwar
rows were dropped (empty snapshot). Consumers were V3-ready; the straggler was
the domain constant.

- soa_graph.rs: `OSINT_GOTHAM.classid` -> `CLASSID_OSINT_V3` (via a cfg-selected
  `OSINT_GOTHAM_CLASSID`, V1 fallback for `--no-default-features`). The `node()`
  test helper mints via `mint_for` so its rows carry the domain's tail layout.
- aiwar.rs: mint `CLASSID_OSINT_V3` (cfg fallback), u16 masks; test asserts the
  V3 classid.
- ISSUES.md: ISS-V1-TAIL-RESIDUE marked RESOLVED with the corrected diagnosis.

Verification: default build 854 lib tests green (V3), `--no-default-features`
840 green (V1 fallback), fmt + clippy clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MLBnPuScZy6w9di2QEjsXM
@cursor

cursor Bot commented Jul 8, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_355a4716-ab6d-46ed-9488-c48dcfc9927c)

@AdaWorldAPI AdaWorldAPI changed the title contract: un-gate mint_for + default-on guid-v3-tail; route ocr/aiwar mints contract: resolve ISS-V1-TAIL-RESIDUE — un-gate mint_for, default-on guid-v3-tail, aiwar mints V3 Jul 8, 2026
@AdaWorldAPI AdaWorldAPI merged commit 9a79920 into main Jul 8, 2026
7 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