From cbd3f757db5402730f22b309d38925a4d0502919 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 18 Sep 2026 20:19:06 +0000 Subject: [PATCH 1/2] board: record PR #1248 merged (a2a51012) -- arc entry + LATEST_STATE Post-merge hygiene for #1248 (NodeRow::edges is byte-backed). Prepends the PR_ARC_INVENTORY entry (Added / Retyped / Doctrine / Locked / Source-breaking / Deferred / Review / CI / Confidence) and the LATEST_STATE merged-PR entry that regrades the 2026-09-18 (2) contract-inventory delta from in-PR to on-main. Hygiene-only: no type, plan, deliverable, epiphany or code. Per the termination clause this PR itself owes no arc entry. Post-checks: both ledgers grew (7372->7438, 4440->4460; zero deleted lines); citation-decay --since a2a51012: 0 new; supersession index regenerated after the board writes, byte-identical. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01HScwwezRdMxFfTs3WLG19d --- .claude/board/LATEST_STATE.md | 20 ++++++++++ .claude/board/PR_ARC_INVENTORY.md | 66 +++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/.claude/board/LATEST_STATE.md b/.claude/board/LATEST_STATE.md index b0a4ce9bd..4e181f681 100644 --- a/.claude/board/LATEST_STATE.md +++ b/.claude/board/LATEST_STATE.md @@ -1,3 +1,23 @@ +## 2026-09-18 (3) — PR #1248 merged (`a2a51012`): `NodeRow::edges` is `EdgeFacet([u8; 16])` on `main` — no field of the 512-byte row is a native-endian integer + +The entry below dated 2026-09-18 (2) describes what is now on `main`, not +what is in PR. Read it as shipped. + +- **On `main`:** `EdgeFacet`, `pub type EdgeBlock = EdgeFacet`, the + two-superpower falsifier, the corrected SAFETY comments, the narrowed + `target_endian` guard, and a running doctest on the alias verifying the + migration `edges.facet().facet_classid`. +- **Source-breaking for field access through `EdgeBlock`** (`facet_classid` + / `tiers` / inherent methods are gone from the alias) — a compile error, + never a silent reinterpretation. Documented on the alias; NOT versioned: + `lance-graph-contract` is `0.1.0`, unpublished, the stable-API phase is + Room 5 PREP. CodeRabbit accepted this and recorded it as a repo learning. +- **Unchanged after this PR:** `ISS-EDGE-BLOCK-WAS-A-SECOND-TYPE-FOR-THE-SAME-FACET` + (readers splitting at 12 remain a reading for the ClassView to decide); + `TD-JC-CLIPPY-RED-ON-BASE-2` (`main` still clippy-red in `crates/jc`, the + two-line fix is written up and awaits its own PR). +- Full record: `PR_ARC_INVENTORY.md` 2026-09-18 #1248. + ## 2026-09-18 (2) — CONTRACT INVENTORY DELTA: `EdgeFacet([u8; 16])` — `NodeRow::edges` is byte-backed, so no field of the 512-byte row is a native-endian integer any more - **Added:** `lance_graph_contract::canonical_node::EdgeFacet` — diff --git a/.claude/board/PR_ARC_INVENTORY.md b/.claude/board/PR_ARC_INVENTORY.md index 85ae62647..ed701f9b9 100644 --- a/.claude/board/PR_ARC_INVENTORY.md +++ b/.claude/board/PR_ARC_INVENTORY.md @@ -1,3 +1,69 @@ +## 2026-09-18 — lance-graph PR #1248 (merged `a2a51012`, branch `claude/great-pascal-k96kok`) — `NodeRow::edges` is byte-backed: bytes are stored, integers are projected + +- **Added:** `lance_graph_contract::canonical_node::EdgeFacet` — + `#[repr(C, align(16))]` over `[u8; 16]`, the exact mirror of `NodeGuid`, + with `as_bytes` / `as_bytes_mut` / `from_bytes` / `to_bytes` / `facet()` + and `From`/`Into` against `FacetCascade`. `pub type EdgeBlock = EdgeFacet` + keeps every call site compiling. Falsifier + `edges_store_bytes_verbatim_and_project_the_integer_little_endian` asserts + BOTH superpowers at once: the stored bytes are verbatim (endian-free) AND + `facet().facet_classid` decodes `0xDEAD_BEEF` little-endian. Disable-run + red-then-green (byte-swap in `from_bytes` fails it on "stored bytes are + verbatim"). A running doctest on the `EdgeBlock` alias verifies the + migration `edges.facet().facet_classid` compiles. +- **Retyped:** `NodeRow::edges` from `FacetCascade` to `EdgeFacet`. All three + `NodeRow` fields are now byte arrays (`[u8;16] | [u8;16] | [u8;480]`), so the + 512-byte stored image contains no native-endian integer and `as_le_bytes` is + byte-identical across targets by construction. Byte positions, + `NODE_ROW_STRIDE`, `ENVELOPE_LAYOUT_VERSION`, `node_rows_from_le_bytes` + unchanged. +- **Doctrine (operator, 2026-09-18):** byte-agnosticism is the STORAGE + superpower; little-endian is the COMPUTE superpower. The failure has one + shape: *storing a projection*. `EPIPHANIES.md` + `E-BYTES-ARE-STORED-INTEGERS-ARE-PROJECTED-1` carries the three-site census + (`NodeGuid` obeyed, `AttentionFocusFacet` obeyed, `NodeRow::edges` violated) + and the reusable pattern *byte-backed newtype + `.facet()` projection*. +- **Locked:** the `target_endian = "little"` guard on `FacetCascade` STAYS, + narrowed. #1246's arc entry said byte-backing `edges` would retire it + entirely — wrong, and the code said so: `FacetCascade::as_bytes` is a + reinterpret BY DESIGN (the 1.72 ns byte-chain LCP hot path), so the + `reinterpret == encode` identity is still assumed. The guard's blast radius + is now a value in flight, never a row at rest. Both `canonical_node.rs` + SAFETY comments corrected in place; the one that called `EdgeBlock` "the one + field that is not" a byte array is struck, not reworded. +- **Source-breaking, documented, not versioned:** `EdgeBlock` no longer + exposes `FacetCascade`'s `facet_classid` / `tiers` or inherent methods — + callers doing field access through the alias get a compile error (the loud + failure; `I-LEGACY-API-FEATURE-GATED` governs SILENT semantic change and + does not reach this). No in-tree consumer affected (every site is + `default()` / byte access / equality / `Copy`); `lance-graph-java`'s + `lgj-abi` — the one named out-of-repo consumer of `canonical_node` — imports + `EdgeCodecFlavor` and never the block type. No SemVer bump: the crate is + `0.1.0`, unpublished, and the stable-API phase is Room 5 PREP + (`docs/SUBSTRATE-ENDGAME-RUNTIME-VIEW.md`), not a contract in force. +- **Deferred / named, not built:** readers that still split the 16 bytes at + 12 on their own authority (`ISS-EDGE-BLOCK-WAS-A-SECOND-TYPE-FOR-THE-SAME-FACET` + — a READING, for the ClassView to decide; byte-backing neither fixes nor + worsens it); `mask_set_range_under`; the planner-side ordering witness. +- **Review:** CodeRabbit raised one Major — the alias change is a breaking + API change, version it. Half accepted (the break is real → migration note + + compile-verified doctest, `adba78bf`), half declined (SemVer bump — premise + wrong in tense; compatibility shim — would restore the stored projection the + PR removes). CodeRabbit accepted both declines by name, withdrew the finding, + dropped Merge Risk Moderate → Minimal, and recorded a repo learning (pre-1.0 + unpublished contract crate: intentional source-breaking changes need a + compile-verified migration path, not a major bump or a shim). Cursor Bugbot + did not run (usage cap). +- **CI:** green on all eight rows at `adba78bf`. Struck from the PR body in + place: the claim that the full workspace build was "blocked in this + container by a missing `protoc`" — the block was self-inflicted + (`protobuf-compiler` not installed); with it installed, + `cargo check --workspace --all-targets` passed locally in 2m 26s. +- **Confidence:** HIGH that the stored image is endian-free by construction + (three byte-array fields, `const` size asserts, falsifier + disable-run). + MEDIUM on "no out-of-tree consumer breaks": in-tree and `lance-graph-java` + verified by reading; other AdaWorldAPI consumers not checked from here. + ## 2026-09-18 — lance-graph PR #1246 (merged `568965e9`, branch `claude/great-pascal-k96kok`) — `EdgeBlock` becomes `FacetCascade`, `Pred::Range` joins the mask-risc IR, and every `.0.0` exact pin floats - **Added:** `Pred::Range { lo: u32, hi: u32 }` + `ExecError::RangeOutOfBounds` From 08891b9ebfcc73d0a9242a63280374ac1823d20a Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 18 Sep 2026 23:55:00 +0000 Subject: [PATCH 2/2] board: narrow the EdgeBlock alias compatibility claim (CodeRabbit, #1249) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The entry said the alias "keeps every call site compiling". Verified against the source: EdgeFacet is a byte newtype (as_bytes / as_bytes_mut / from_bytes / to_bytes / facet(), plus From/Into), so FacetCascade's public facet_classid and tiers fields — and any method not on EdgeFacet — do not resolve through the alias. The in-tree call sites survive because they use default(), byte access, equality and Copy; that is what the claim should have said. Restated as: the alias keeps the IN-TREE call sites compiling, and the narrower surface is the point of the retype rather than an oversight — an out-of-tree caller reaching for a FacetCascade field gets a compile error and names the projection (edges.facet().facet_classid), which is already covered under Source-breaking-documented-not-versioned. Wording only; no type, code or doctrine change. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01HScwwezRdMxFfTs3WLG19d --- .claude/board/PR_ARC_INVENTORY.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.claude/board/PR_ARC_INVENTORY.md b/.claude/board/PR_ARC_INVENTORY.md index ed701f9b9..f89355e49 100644 --- a/.claude/board/PR_ARC_INVENTORY.md +++ b/.claude/board/PR_ARC_INVENTORY.md @@ -4,7 +4,15 @@ `#[repr(C, align(16))]` over `[u8; 16]`, the exact mirror of `NodeGuid`, with `as_bytes` / `as_bytes_mut` / `from_bytes` / `to_bytes` / `facet()` and `From`/`Into` against `FacetCascade`. `pub type EdgeBlock = EdgeFacet` - keeps every call site compiling. Falsifier + keeps the in-tree call sites compiling — and only those: they use + `default()`, byte access, equality and `Copy`, all of which `EdgeFacet` + carries. **It is NOT a drop-in for `FacetCascade`'s whole surface**, which is + the point of the retype, not an oversight: `EdgeFacet` deliberately exposes + bytes, so `FacetCascade`'s public `facet_classid` / `tiers` fields and any + method not on `EdgeFacet` do not resolve through the alias. An out-of-tree + caller reaching for one gets a compile error and names the projection + instead (`edges.facet().facet_classid`) — see Source-breaking below. + Falsifier `edges_store_bytes_verbatim_and_project_the_integer_little_endian` asserts BOTH superpowers at once: the stored bytes are verbatim (endian-free) AND `facet().facet_classid` decodes `0xDEAD_BEEF` little-endian. Disable-run