diff --git a/.claude/board/EPIPHANIES.md b/.claude/board/EPIPHANIES.md index 7fe35cffc..1cd552fd9 100644 --- a/.claude/board/EPIPHANIES.md +++ b/.claude/board/EPIPHANIES.md @@ -309,6 +309,156 @@ and a supervision corpus sized from the label is oversized by exactly the rows where the source labelled but did not fill. Cross-ref: `.claude/plans/dismech-causality-v3-v1.md` §3a; `E-DISMECH-CORPUS-CENSUS-1`. +## 2026-08-21 — E-V4-IS-THE-100-PERCENT-TIER-V3-UNCHANGED-1 — operator ruling: V4 is a SIBLING for lossless/special-need coverage, not a successor + +**Status:** RULING `[operator]` — explicit in-session decision, verbatim below. +**Confidence:** the ruling is authoritative; the CONSEQUENCES I draw from it are +marked separately and several are open questions, not inferences to act on. + +**The ruling, verbatim (operator, 2026-08-21):** +> *"Meine Auffassung ist, V4 ist für R2IL 100% coverage und andere Special +> needs. V3 wie bisher."* +> ("V4 is for R2IL 100% coverage and other special needs. V3 as before.") + +**What it settles.** V4 is **real and additive** — a sibling tier for workloads +requiring lossless / 100 % coverage, NOT a replacement for V3. **V3 is +explicitly unchanged** ("wie bisher"). The two coexist; V4 serves what V3's +deliberately projective design does not. + +**Storno — this corrects my own entry from earlier today.** +`E-R2IL-VARNODEFACET-IS-A-G3-CARVING-AND-0xC4-WOULD-BIRTH-A-CLASS-INTO-IT-1` +argued the "V4" label "should not be adopted" on three grounds. Regraded, not +deleted: +1. *"reverses the ratified no-V4 verdict"* — **superseded.** The plan's + `:112` verdict ("V3 is sufficient. No V4.") was a session verdict; this is + an operator ruling, and rulings are frozen while verdicts are revisable. + The plan's §22.5 stop condition is now SUPERSEDED, not violated. The plan + text needs the correction appended. +2. *"V4 already denotes the dialectic-engine V4 field-search slice"* — + **STANDS as a hygiene item only**, downgraded from architecture objection. + `E-DIA-V4-FIELD-SEARCH-LOOP-1` is a plan V-slice ordinal in a different + subsystem; the two are contextually separable but a future session grepping + "V4" will hit both. Disambiguation owed (suggest: "V4 tier" vs "V4 slice"). +3. *"implies V3-superseded"* — **WRONG, and the ruling says so directly.** + "V3 wie bisher" is the explicit denial. This was my strongest objection and + it was the one built on an assumption the operator did not share. + +**Consequence for the G3 carving question — the frame changes, and this is the +part worth reading twice.** §3a's *"new classes MUST NOT be born into G1–G3"* +is a **V3** rule. If R2IL is a V4 tenant, §3a does not govern it, and the whole +carving question I posed — re-carve / named-exception / defer — was posed +inside the wrong frame. `VarnodeFacet`'s 3×32 density is then not a V3 +violation needing an exception; it is **the reason R2IL is V4 in the first +place**. [MY INFERENCE, not the operator's words — flagged as such.] + +**Consequence for `E-ADDRESS-FROM-THE-THING-NOT-THE-ACCIDENT-1` — its own +falsifier is PARTIALLY triggered.** That entry pre-registered: *"if a gate is +legitimately cleared by a fix that leaves the address derived from layout … +this entry is scoped down to the other instance."* The ruling does not say +"G3 is correct for R2IL" — it relocates R2IL to a tier whose carving discipline +is not yet stated. So the spatial instance is **suspended, not refuted**, +pending V4's actual layout. The temporal instance (F-ORD) is untouched and +still stands on its own measurement. Scoping down now would be premature; +scoping down later may be correct. + +**What the ruling does NOT say — open, do not invent answers:** +- **V4's layout.** Facet width, carving discipline, whether rails apply at all, + whether the 512-byte row stride is reused. Unknown. +- **Where V4 lives.** Contract crate? Separate module? A ClassView read-mode? + Unknown. +- **What "andere Special needs" enumerates.** R2IL is one named tenant; the + set is open. +- **How a reader routes V3 vs V4.** By classid? By domain byte (0xC4 is + already the R2IL destination)? By an explicit tier discriminator? Unknown — + and this is the question that most affects whether existing readers break. +- **Whether the `0xC4` mint is a V3 mint or a V4 mint.** Given the ruling, it + is presumably V4 — but the domain enum lives in the V3-shaped + `ogar_codebook` mirror, so the interaction needs stating. + +**Cross-refs:** the two entries this corrects/suspends (both 2026-08-21), +`le-contract.md` §3 (L1–L8) + §3a (G1–G3), ruff plan +`r2il-behavioral-ir-v1.md` `:112` + §22.5 (both now superseded, correction +owed in-repo), `ogar_codebook.rs:112-117` (0xC4 BinaryLifting), +`E-DIA-V4-FIELD-SEARCH-LOOP-1` (the name collision), +`E-V3-FACET-4-PLUS-12` (the V3 lock that stays untouched). + +**⊘ STORNO 2026-08-21 (operator correction, same day) — objection 2 above is +RETRACTED; there is no name collision and no disambiguation is owed.** +`dialectic-engine-v1.md`'s `V0…V5` are **integration-plan STEPS, like its own +`S1…S11`** — §4 is literally headed "Build order", and `V4` there is one stage +("the 64k SIMT lowering … only after V0–V3 green at small scale"), the fifth of +six. A step ordinal and a substrate tier are not two meanings of one label +competing for a namespace; they are two independent counters that never address +the same kind of thing. `E-DIA-V4-FIELD-SEARCH-LOOP-1` inherits the STEP +meaning — it names a finding from that stage — so it was never evidence of a +tier collision either. **Nothing should be renamed**, and a future session must +not read line 30's "disambiguation owed" as a live item; acting on it would +rewrite a correct plan to resolve a conflict that does not exist. What this +leaves: all three of my objections to the V4 label are now retracted, two as +superseded by the ruling and this one as simply mistaken about what the source +document says. The G3 reframing (below) and the five open questions are +unaffected — they never rested on this point. + +## 2026-08-21 — E-ADDRESS-FROM-THE-THING-NOT-THE-ACCIDENT-1 — the two blocked gates are one failure on two axes + +**Status:** SYNTHESIS / CONJECTURE — my cross-reading of two independently +authored, independently measured docs. **Not an operator ruling and not a new +rule**; both constituent findings are separately graded FINDING and stand on +their own if this framing is rejected. **Confidence:** the two instances are +High (source-read, measured); the UNIFICATION is Medium — it is a lens, and +its value is that it makes one test serve two gates. + +**The one sentence.** *An address must be derived from what the thing IS, +never from the accident of how it was laid out or when it showed up.* + +**Two gates are currently blocked, in two different repos, by two different +sessions, and they are the same failure rotated 90°:** + +| | SPATIAL — the carving | TEMPORAL — the landing | +|---|---|---| +| where | ruff `VarnodeFacet` / PR3 `0xC4` mint | lance-graph-java GridLake / F-ORD | +| the accident | a **flat contiguous register** (3×32, G3) — no byte axis, so no rail exists to address it by | a key **minted from completion order** (`collect_casts` mints `stream_position`) — so identity encodes *when*, not *what* | +| the symptom | ClassView cannot project rails; `group_of` is not a shift; saturates silently with no cascade spill | same work, two runs, two publication identities — measured hashes 2604999916736672513 vs 4858955943411201665 | +| the doc's own exit | "**cosine-replacement** palette256 (L4)" — content-derived addressing (`le-contract.md` §3a) | "**identity-derived** or otherwise deterministic" — required property #1 (correction spec §12) | + +**The tell that this is convergence, not my imposition:** the two docs were +written by different sessions for different subsystems and neither cites the +other, yet both name their exit with the same word-family — *cosine-**replacement*** +(derive the address from content) and *identity-**derived*** (derive the key +from identity). Nobody coordinated that. + +**The test, usable at either gate, in one question:** +> If I re-ran this with the bytes laid out differently, or the workers +> finishing in a different order, would the address change? +> +> **Yes → the address is coming from the accident.** No → it comes from the +> thing. + +**What this does NOT license.** It does not decide either gate. Specifically: +(a) it does not say `VarnodeFacet` must re-carve — a varnode genuinely needs +64 bits of offset plus a size, `6×(8:8)` cannot hold that, and the +`identity_quad` G2 precedent (`E-IDENTITY-QUAD-4X24-RATIFIED-PERMANENT-1`) +exists precisely so a permanent honest wide resident can be **named** rather +than hidden; (b) it does not prescribe F-ORD's fix mechanism, which A2/A3 +deliberately left unprescribed (four candidates, per-workload). The lens +sharpens the question; the operator still answers it. + +**Falsifier — what would retire this entry.** If a gate is legitimately +cleared by a fix that leaves the address derived from layout or schedule (e.g. +an operator ruling that a G3 carving is permanently correct for R2IL *because* +of its density, or an F-ORD resolution that canonicalises arrival order as +semantically meaningful), then the "accident" framing is wrong for that +instance and this entry is scoped down to the other one — or dropped. Two +instances is a pattern, not a law; a third independent instance would raise +confidence, a counter-example would end it. + +**Cross-refs:** `E-R2IL-VARNODEFACET-IS-A-G3-CARVING-AND-0xC4-WOULD-BIRTH-A-CLASS-INTO-IT-1` +(the spatial instance, same day), `le-contract.md` §3a G1–G3 + the L4 exit, +`E-IDENTITY-QUAD-4X24-RATIFIED-PERMANENT-1` (the named-exception precedent), +lance-graph-java `.claude/plans/mask-native-navigation-correction-v1.md` §12 +(F-ORD/F-LAND split, the five frozen landing-key properties) + the Lotus +F-ORD defect pin, `ogar_codebook.rs:112-117` (the 0xC4 destination). + ## 2026-08-21 — E-ABBREVIATION-GREP-MANUFACTURED-AN-ABSENCE-1 — I reported a shipped 15-module subsystem as non-existent because `fn .*ppr` matches `approx`, and a `head` limit hid the real hits **Status:** FINDING (self-inflicted, caught by the operator pointing at @@ -579,6 +729,119 @@ field the schema clearly uses is a claim about the reader, not the corpus** — the same rule this board already states for null probe results, applied to counting rather than to timing. Reading three raw blocks cost thirty seconds and moved the answer by a factor of 622. +## 2026-08-21 — E-R2IL-VARNODEFACET-IS-A-G3-CARVING-AND-0xC4-WOULD-BIRTH-A-CLASS-INTO-IT-1 + +**Status:** FINDING (measured at file:line this session, after rebasing +`claude/ruff-r2il-lancegraph-3tdt8d` onto `main` @ `8a93423`). +**Confidence:** High for the layout arithmetic and the §3a rule text (both +read from source); the CONSEQUENCE is a gate question for PR3, deliberately +not pre-decided here. + +**The finding.** `ruff_r2il::facet::VarnodeFacet` (`facet.rs:36-48`) carves its +16 bytes as `classid: u32` + `offset_lo: u32` + `offset_hi: u32` + `size: u32`. +The 12-byte payload is therefore **3 × 32-bit contiguous = exactly `le-contract.md` +§3a's G3 "wide-quad"** (`:82`, `96 ✓`) — the axis-LESS grace carving, not the +axis-grouped `3×(8:8:8:8)` L6/`CascadeShape::G3D4` shape. It carries no rail: +there is no `X:Y` byte pair anywhere in it. + +Today this is invisible and legal: `PROVISIONAL_R2IL_VARNODE = 0x0000` +(`facet.rs:21`) puts every varnode in the **default class** — the CANON +zero-fallback ladder's "no prefix routing (dormant)" state, which is not a +minted class at all. + +**Why the mint changes its status.** `lance_graph_contract::ogar_codebook` +already names the destination in source (`ogar_codebook.rs:112-117`): *"`0xC4XX` +— Binary lifting … the R2IL container concepts mint here in the ruff PR3 arc, +**replacing `PROVISIONAL_R2IL_VARNODE = 0x0000`**"*. The moment that mint lands, +the facet stops being the dormant default and becomes a **real, addressed class +whose payload is G3** — and §3a is explicit (`le-contract.md:104`): *"New classes +MUST NOT be born into G1–G3; the waiting room is not a destination."* + +So PR3 as currently specified would, without a deliberate decision, do the one +thing §3a names. Three legible resolutions, none prescribed here: +(a) re-carve the payload onto a rail shape before minting (e.g. the L4 +`6×(u8:u8)` reading, which would make space/offset/size rail-addressable); +(b) mint and take a **named ratified exception**, the way +`ISS-IDENTITY-QUAD-WIDE-CARVING-HOME` did for `identity_quad` in G2 (operator, +2026-08-17) — that precedent exists precisely for a permanent, honest resident; +(c) keep `0x0000` and defer the mint until the carving question is settled. +The honest-cost accounting §3a already demands applies either way: a 64-bit +varnode offset genuinely needs 64 bits, so (a) is a real design question about +whether offset belongs in the facet at all, not a mechanical re-slice. + +**Two things this session checked that are NOT defects, recorded so they are +not re-investigated:** + +1. **The ruff SPO intake arms do not use the R2IL/r2sleigh format — correctly.** + `ruff_{cpp,csharp,python,ruby,sqlalchemy}_spo` depend on `ruff_spo_triplet` + only; none depends on `r2il`/`r2ssa`/`ruff_r2il`. That is the plan's two-arm + split (`ruff/.claude/plans/r2il-behavioral-ir-v1.md:320`): structural + (AST → `ModelGraph` → `expand()` → `Vec`) beside behavioral + (machine code → R2IL/SSA), converging only at OGAR/ClassView. Feeding R2IL + into an AST harvest would be the "backdoor opcode vocabulary" the plan + forbids at `:335`. Consistent with this board's own line 9347. +2. **`ruff_spo_address` having zero in-ruff dependents is not dead code.** It is + consumed CROSS-REPO by OGAR `ogar-from-ruff` (`Cargo.toml:35`, a git dep on + ruff `main`; `mint.rs:35` imports `{Facet, Mint, mint_with_classid}`). The + in-ruff dependent count is the wrong measurement for a producer crate. + +**Correction of this session's own prior statement (storno).** Earlier this +session I reported PR3's home as an OPEN question — "slot in `ogar_codebook` +versus a new `ogar-r2il` crate, your call" — and leaned slot. That was wrong on +the facts available: the decision was already made and landed. `BinaryLifting` +(`0xC4`) is in the mirrored `ConceptDomain` enum on both sides, is pinned by +`reserved_empty_domains_agree_across_the_mirror`, and +`E-OGAR-CODEBOOK-MIRROR-DOMAIN-DRIFT-SYNCED-1` (2026-08-18) already states *"the +R2IL container-concept mints under 0xC4 arrive with the ruff arc's PR3 and will +rebase trivially on this."* No `ogar-r2il` crate was ever proposed anywhere +(zero hits across `ruff/` and `OGAR/`). **The lesson is the process one:** the +finding was reachable only by reading the board AFTER the rebase — I formed a +conclusion from the ruff tree alone and presented a settled decision as open. +Rebase, then read EPIPHANIES/plans, THEN conclude. + +**⚠ NAMING — a sibling session is calling `ruff_r2il` "V4"; the INSIGHT is +right and the LABEL is wrong, and they must not be collapsed into each other.** +Reported mid-session: *"another session called `ruff_r2il` V4, just because the +IR format is way denser from the perspective of a compiler substrate."* The +density observation is **correct and is the same fact as this entry's finding** +— R2IL's address space genuinely is denser than a rail shape can express (a +varnode needs a 64-bit offset plus a size; `6×(u8:u8)` cannot hold that), which +is exactly WHY `VarnodeFacet` ended up carved as G3. Two sessions reached one +fact from opposite sides. Preserve that. + +The LABEL collides three ways and should not be adopted: + +1. **It reverses a ratified verdict without falsifying it.** The r2il plan's own + `:112` reads *"Verdict: V3 is sufficient. **No V4.** The hypothesis stands + un-falsified"*, restated as stop condition §22.5 (`:397`, "no V4; variable + arity already routed upstream"). Nothing measured since has falsified it — + PR2's oracle went the other way, reconstructing 35,946 op sites with zero + mismatches *through V3 routes*. A version bump needs a falsifier, not a + density impression. +2. **"V4" already denotes something else here.** `E-DIA-V4-FIELD-SEARCH-LOOP-1` + (2026-07-23) is the dialectic-engine's **V4 foveated field-search slice** — a + plan V-slice number in `dialectic-engine-v1.md`, an unrelated subsystem. A + second meaning on the same token divides the search surface for every future + session, which is the duplicate-id failure this board already fights. +3. **It implies V3-superseded, which no ruling supports.** V3 is a LAYOUT canon + (4+12 content-blind facet, 512-byte row, classid canon-high). Density is not + a property of the canon; it is a property of ONE CLASS's carving choice + *inside* it. That is precisely what §3a's G-carvings and the `identity_quad` + named exception exist to express. + +**The honest reframing:** R2IL is not a new substrate version — it is a **dense +class whose carving question is open** (the three options above). If the density +is genuinely permanent and irreducible, the sanctioned vocabulary for saying so +is a **named ratified G3 exception** in the `ISS-IDENTITY-QUAD-WIDE-CARVING-HOME` +mould, not a version number. Route the disagreement to the operator as a carving +ruling; do not let either session settle it by naming. + +**Cross-refs:** `le-contract.md` §3a (G1–G3 + the `identity_quad` named +exception), `E-IDENTITY-QUAD-4X24-RATIFIED-PERMANENT-1` (the exception +precedent), `E-OGAR-CODEBOOK-MIRROR-DOMAIN-DRIFT-SYNCED-1` (the 0xC4 sync), +`E-V3-FACET-4-PLUS-12`, `ogar_codebook.rs:112-117`, ruff +`crates/ruff_r2il/src/facet.rs:21,36-48`, ruff plan `r2il-behavioral-ir-v1.md` +PR3 + O5. ## 2026-08-20 — E-DISMECH-CORPUS-CENSUS-1 — the DisMech corpus measured: 87.2 MB of strings, of which the entire causal semantics is bits + codebook ordinals diff --git a/.claude/board/ISSUES.md b/.claude/board/ISSUES.md index 8a3c94c1f..113bd9052 100644 --- a/.claude/board/ISSUES.md +++ b/.claude/board/ISSUES.md @@ -1,5 +1,42 @@ # Issues Log — Open + Resolved (double-entry, append-only) +## ISS-CAUSAL-EDGE-CARRIES-SEVEN-PRE-EXISTING-CLIPPY-FINDINGS (2026-08-22) — OPEN + +`crates/causal-edge` is workspace-EXCLUDED but a path-dep of `lance-graph`, +`lance-graph-planner`, `cognitive-shader-driver` and `sigma-tier-router`, so +its LIB compiles inside gated builds while its TESTS ran nowhere but on a +developer machine. #981 landed a `#[test]` there and #982 lands two +falsifiers there; none of them could ever have gone red in CI. + +**Fixed in the same PR that files this:** a `cargo test --manifest-path +crates/causal-edge/Cargo.toml` step in `rust-test.yml` (75 green, measured on +the pinned 1.97.1) and a `cargo fmt … -- --check` step in `style.yml` (clean +today). + +**Deliberately NOT gated: clippy.** `cargo clippy --manifest-path +crates/causal-edge/Cargo.toml --all-targets -- -D warnings` returns **7 +errors**, all pre-existing and none in the file #982 touches: + +``` +src/edge.rs:118, :120, :200, :685, :743, :748, :835 +src/tables.rs:37 +src/v2_layout_tests.rs:20 +``` + +(identical-if-blocks ×1, too-many-arguments ×2, wildcard-covers-any ×1, +collapsible-if ×2, doc-list-item-without-indentation ×1) + +Gating them in this PR would fail it for defects it did not introduce. They +need their own pass. Until then this crate has a test gate and a format gate +but no lint gate, and that asymmetry is deliberate and recorded here rather +than left to be rediscovered. + +Context: `EPIPHANIES.md` +`E-THE-GATE-IS-A-HAND-MAINTAINED-ALLOWLIST-NOT-THE-WORKSPACE-1` — no workflow +runs `--workspace`, so every gate is a hand-maintained allowlist; nine +workspace members plus this excluded crate were reached by nothing. + + ## ISS-HYDRATE-ENV-READER-IS-A-SECOND-COPY-OF-DEV-S3-ENV (2026-08-17) — OPEN, deliberate-with-a-named-exit `crates/lance-graph-hydrate/src/env.rs` reproduces diff --git a/.claude/board/STATUS_BOARD.md b/.claude/board/STATUS_BOARD.md index 1b3bf62d3..c603b08fc 100644 --- a/.claude/board/STATUS_BOARD.md +++ b/.claude/board/STATUS_BOARD.md @@ -57,7 +57,7 @@ the rest. | D-ACR-0 | Audit `attention_mask.rs`/`attention_mask_actor.rs`: residue carrier, or a name collision? Report only | **Shipped** 2026-08-21 — `.claude/ATTENTION_MASK_AUDIT_2026_08_21.md`. Verdict **EXISTS-UNCALLED** + a name collision: the shipped type is a *rename register file* (`causaledge64-mailbox-rename-soa-v1.md` §4), not a residue carrier | recorded EXISTS-UNCALLED (0 callers workspace-wide + 3 sibling repos); piece E regraded — not a basis for D-ACR-1 | | D-ACR-1 | `RowFocusMask` — the one missing primitive (S3.1b names it; no crate contains it) | **Shipped** 2026-08-21 — `contract::attention_facet`. Basis: **reuse** `FacetCascade` + `CascadeShape::G6D2`, zero new bytes; `FocusAxis` is content-blind (`Axis0..Axis5`), composition is **prefix containment**, never bit-OR; explicit `depth` outside the 12 bytes (`NiblePath` precedent) | can-fire AND can-stay-silent on non-trivial input — **both green**, plus a not-a-blind-OR negative and a 1000-entry container (no `FieldMask` 64 / `WideFieldMask` 256 cap inherited) | | D-ACR-7 | The 59..63 reading contract (§3b): name per `(classid, rail)` which lens applies and which witness carrier discriminates evidence-kind. Acceptance: tactic sampling filters on `delta_conf` capability (14/34), never on `maturity().is_production()` (31/34) | **Shipped** 2026-08-21 — `contract::band_reading` + `ClassView::band_reading` + the G10b gate test in `causal-edge`. Spec RATIFIED same day via 5+3 council (`.claude/plans/dacr7-band-reading-contract-v1.md`; **3×BLOCK(P0) raised, 3 resolved in Phase 4, none argued away**). Scope covers BOTH carriers (CE64 bits 59-63 + `CausalEdgeV3` bytes [8]/[9]); `EdgeProvenance::V3Register` is a caller ASSERTION because `from_v1` drops provenance — unstated ⇒ `Unknown` ⇒ refuse. L1 split shipped: declaration lookup TOTAL, raw-bit projection FALLIBLE | G1 (1207, +13), G2, G3′, G4′, G5a, G5b, G6 (14 admitted / 20 rejected against the real `all_kernels()`, ≠ the 31 production count), G7′, G8, G9, G10b — all green | -| D-ACR-3 | The one-way invariant as a test: no ontology-owned write traces to a patient-tagged read through ANY call path (corrected from write-authorization-only after CodeRabbit found a session-derived value can flow to the ontology owner via a shared parameter/return, then be written as the owner's own act) | Queued — gates on D-ACR-1 | a write whose call graph includes a session-tagged read is the bug, even if the write itself is authored by the ontology owner | +| D-ACR-3 | The one-way invariant as a test: no ontology-owned write traces to a patient-tagged read through ANY call path (corrected from write-authorization-only after CodeRabbit found a session-derived value can flow to the ontology owner via a shared parameter/return, then be written as the owner's own act) | **Queued — the D-ACR-1 gate cleared, but a SECOND blocker was found 2026-08-21: the write path it must guard does not exist.** `SoaEnvelope` has ONE production implementor (`NodeRowPacket`, `canonical_node.rs:1540`; the other two are test types) and `mailbox_owner()` has **zero callers outside its own module**. There is no ontology-owned write to trace TO and no session-tagged read to trace FROM, so the test would assert something no code can violate — the exact shape the falsifiability rule forbids (*"what input would make this fail? If none exists, delete or rewrite it"*). Same finding shape as D-ACR-0's EXISTS-UNCALLED. Gates on a real write path, not on D-ACR-1 | a write whose call graph includes a session-tagged read is the bug, even if the write itself is authored by the ontology owner | | D-ACR-2 | Mint the Rung-ladder rail | Queued — gates on operator mint decision (HTT §8 Q3) | `rail_carving` gains its first non-default consumer | | D-ACR-4 | Second-order row at the same address, separate table | Queued | a rung-2 read reconstructs where rung-1 looked, on a fixture with an independent answer | | D-ACR-5 | 64k lowering | **BLOCKED** — dialectic V4's own gate (V0–V3 green at small scale) | — | diff --git a/.github/workflows/rust-test.yml b/.github/workflows/rust-test.yml index 99bff13d6..5bc4ee160 100644 --- a/.github/workflows/rust-test.yml +++ b/.github/workflows/rust-test.yml @@ -165,6 +165,24 @@ jobs: # what this step ran before, so it cannot lose coverage. - name: Run supervisor tests (W2b real-owner probes + #879 cycle driver) run: cargo test --manifest-path crates/lance-graph-supervisor/Cargo.toml --features supervisor,cycle-driver + # causal-edge: workspace-EXCLUDED, but a path-dep of lance-graph, + # lance-graph-planner, cognitive-shader-driver and sigma-tier-router — so + # its LIB already compiles inside gated builds while its TESTS ran + # nowhere but on a developer machine. #981 landed a #[test] here and this + # PR lands two falsifiers here; none of them could ever have gone red in + # CI. Same "blind gate" closed above for deepnsm / supervisor / + # bgz-tensor, one crate at a time. + # + # Verified locally before landing: 75 passed, 0 failed. + # + # Deliberately TESTS ONLY. A `clippy -D warnings` step would be red on + # arrival: the crate carries 7 pre-existing findings, all in edge.rs / + # tables.rs / v2_layout_tests.rs and NONE in the edge_v3.rs this PR + # touches. Gating them here would fail this PR for defects it did not + # introduce; they are recorded in ISSUES + # ISS-CAUSAL-EDGE-CARRIES-SEVEN-PRE-EXISTING-CLIPPY-FINDINGS instead. + - name: Run causal-edge tests (workspace-excluded, previously ungated) + run: cargo test --manifest-path crates/causal-edge/Cargo.toml # bgz-tensor: workspace-EXCLUDED metric-algebraic codec crate (deps the # ndarray sibling checked out above + in-repo holograph). None of the # steps above reach it, so its 207 lib tests — including the V3 diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index 822030aa8..7e076072a 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -148,6 +148,12 @@ jobs: components: rustfmt - name: Check formatting (lance-graph) run: cargo fmt --manifest-path crates/lance-graph/Cargo.toml -- --check + # causal-edge: workspace-excluded, so `cargo fmt --all` never reaches it. + # It is rustfmt-clean today (verified before adding this step); the check + # keeps it that way. Its clippy debt is NOT gated here — see the + # rust-test.yml step for why. + - name: Rustfmt causal-edge (workspace-excluded, previously ungated) + run: cargo fmt --manifest-path crates/causal-edge/Cargo.toml -- --check # deepnsm is a standalone, workspace-excluded codec crate, so # `cargo fmt --all` never reaches it. It was brought to a rustfmt-clean # baseline in this PR; check it explicitly so it can't silently drift. diff --git a/crates/causal-edge/src/edge_v3.rs b/crates/causal-edge/src/edge_v3.rs index ab42c64f9..68187ddb2 100644 --- a/crates/causal-edge/src/edge_v3.rs +++ b/crates/causal-edge/src/edge_v3.rs @@ -114,6 +114,11 @@ impl CausalEdgeV3 { /// /// **Not lifted:** the deprecated v2 `temporal` (not valid CE64-v2 state; /// V3's TE is an independent producer-set offset). + /// + /// **Provenance:** copying the v2 tail (`w_slot`/`truth`/`spare`) ASSERTS + /// that its producer stamped it deliberately. When you do not know that, + /// use [`Self::from_v1_tail_unstated`] — see its doc for why the signature + /// alone cannot tell the two cases apart (D-ACR-7 BLOCK-1). pub fn from_v1(e: CausalEdge64, target: u16) -> Self { let mut p = [0u8; 12]; p[0] = e.frequency_u8(); @@ -140,6 +145,42 @@ impl CausalEdgeV3 { Self { payload: p } } + /// Lift a [`CausalEdge64`] whose v2 tail is **UNSTATED** — bytes `[8]`/`[9]` + /// are zeroed instead of copied. + /// + /// # Why this exists (D-ACR-7 BLOCK-1) + /// + /// [`Self::from_v1`] copies `w_slot`/`truth`/`spare` raw. Under the **v1** + /// layout that is provably safe: those accessors are documented zero stubs + /// (`edge.rs`, `truth_raw` and `spare` return `0`), so the copy writes + /// zeros anyway. Under **v2** they read real bits — and nothing in the + /// signature says whether a producer deliberately stamped them or whether + /// they are residue from a source that never meant anything by them. + /// + /// The reading contract that consumes these bits + /// (`lance_graph_contract::band_reading`) resolves that gap by making + /// provenance a **caller assertion**: unstated means refuse. This + /// constructor is that assertion's honest half on the WRITE side — a lift + /// that declines to claim the tail. A consumer then reads the zero-fallback + /// (`Trust` / band `Absent`) rather than a plausible wrong ordinal. + /// + /// **Pick by what you know**, not by convenience: + /// + /// | you know | use | + /// |---|---| + /// | the producer stamped the tail | [`Self::from_v1`] | + /// | you do not know, or the source predates the stamp | **this** | + /// + /// Every other field is lifted exactly as [`Self::from_v1`] lifts it. + /// Note that [`Self::rehydrate`] on the result is therefore **not** a + /// bit-exact round trip of the source: the tail was deliberately dropped. + pub fn from_v1_tail_unstated(e: CausalEdge64, target: u16) -> Self { + let mut v3 = Self::from_v1(e, target); + v3.payload[8] = 0; + v3.payload[9] = 0; + v3 + } + /// NARS frequency (u8, `f = val/255`) — byte 0. pub fn frequency(&self) -> u8 { self.payload[0] @@ -757,4 +798,76 @@ mod tests { assert_eq!(vz.truth_raw(), 0); assert_eq!(vz.spare_raw(), 0); } + + /// D-ACR-7 BLOCK-1, write side: the unstated lift DROPS the tail while the + /// plain lift CLAIMS it. Two-sided by construction — a constructor that + /// zeroed unconditionally, or one that never differed from `from_v1`, + /// would carry exactly as much information as no constructor at all. + #[cfg(feature = "causal-edge-v2-layout")] + #[test] + fn from_v1_tail_unstated_drops_what_from_v1_claims() { + use crate::layout::{CausalTopology, ReasoningBand}; + + // A source whose tail is NON-ZERO — without this the two lifts agree + // trivially and the test proves nothing. + let e = sample_edges()[0] + .with_w_slot(0x2A) + .with_topology(CausalTopology::Unknown) + .with_reasoning_band(ReasoningBand::Transcendent); + assert_ne!( + (e.truth_raw(), e.spare()), + (0, 0), + "fixture must have a tail" + ); + + let claimed = CausalEdgeV3::from_v1(e, 7); + let unstated = CausalEdgeV3::from_v1_tail_unstated(e, 7); + + // CLAIMS: the tail survives, ordinal for ordinal. + assert_eq!(claimed.truth_raw(), e.truth_raw()); + assert_eq!(claimed.spare_raw(), e.spare()); + assert_eq!(claimed.w_slot(), e.w_slot() & 0x3F); + + // DECLINES: the tail is zero, so a consumer reads the zero-fallback + // rather than an ordinal nobody vouched for. + assert_eq!( + unstated.truth_raw(), + 0, + "unstated lift must not claim truth" + ); + assert_eq!( + unstated.spare_raw(), + 0, + "unstated lift must not claim a band" + ); + assert_eq!(unstated.w_slot(), 0, "the whole tail is dropped, not half"); + + // And ONLY the tail differs — every other lifted field is identical. + let (a, b) = (claimed.to_le_bytes(), unstated.to_le_bytes()); + assert_eq!(a[..8], b[..8], "bytes 0..8 must be untouched by the choice"); + assert_eq!( + a[10..], + b[10..], + "bytes 10.. must be untouched by the choice" + ); + assert_ne!( + a[8..10], + b[8..10], + "and the tail bytes must be what differs" + ); + } + + /// The can-stay-silent half: on a source whose tail is ALREADY zero the two + /// lifts are byte-identical. The constructor is a declaration about + /// provenance, never an unconditional mutation. + #[cfg(feature = "causal-edge-v2-layout")] + #[test] + fn on_a_zero_tail_the_two_lifts_agree() { + let z = sample_edges()[1]; + assert_eq!((z.truth_raw(), z.spare()), (0, 0)); + assert_eq!( + CausalEdgeV3::from_v1(z, 7).to_le_bytes(), + CausalEdgeV3::from_v1_tail_unstated(z, 7).to_le_bytes(), + ); + } } diff --git a/docs/architecture/S3-0-EXACT-LITERAL-AUDIT.md b/docs/architecture/S3-0-EXACT-LITERAL-AUDIT.md new file mode 100644 index 000000000..88d121736 --- /dev/null +++ b/docs/architecture/S3-0-EXACT-LITERAL-AUDIT.md @@ -0,0 +1,308 @@ +# S3.0 audit — why PR #973 was closed, and what replaces it + +> **Status:** AUDIT (operator-directed, 2026-08-20). Written BEFORE any +> replacement code, per the reset brief. #973 is closed and is **not** to be +> reopened or continued; this note is the record of why, so the failure stays +> visible rather than being smoothed into "an earlier design iteration". + +--- + +## 1. The exact claim in #973 that was wrong + +#973 measured, correctly: + +```text +domain + S + P + O = 4 × u16 = 64 bits = 16 nibbles = NiblePath::MAX_DEPTH +``` + +and then concluded, **incorrectly**: + +> therefore the exact literal cannot itself live in HHTL, because no path depth +> is left for evidence below it — so identity must be separated from HHTL +> routing, and HHTL retained only as a lossy prefix projection. + +**The measurement is fine. The inference is rejected.** It silently promoted + +- a limit of **one concrete sequential representation** (`NiblePath`: a `u64` + carved 16-ary, `FAN_OUT = 16`, `MAX_DEPTH = 16`, `child()` shifting left 4) + +into + +- a limit of **HHTL itself** as hierarchy / locality / exact-addressing + substrate. + +`NiblePath::MAX_DEPTH` is a property of that carving. It is not the +dimensionality of HHTL, and it says nothing about whether orthogonal facets can +be keyed by the same exact address. + +The second, subtler error rode along with it: treating a **Morton / prefix** +view as inherently lossy. Truncation is lossy. Interleaving is not. + +--- + +## 2. The measured evidence that contradicts it + +Six items. The first two are in the **same crate #973 modified**; the third is +a finding **this session measured and reported itself**. Any one of them +falsifies the inference. + +### 2.1 `RAIL_MAX_DEPTH = 24` — in `lance-graph-contract`, one file away + +`crates/lance-graph-contract/src/rail_geometry.rs:50-55`: + +```rust +pub const RAIL_PAIR_LEVELS: usize = 6; // levels per interleaved-pair register +pub const RAIL_SLAB_LEVELS: usize = 12; // levels per axis-slab register +/// Maximum addressable depth: a slab register plus its continuation. +pub const RAIL_MAX_DEPTH: usize = 2 * RAIL_SLAB_LEVELS; // = 24 +``` + +with `RailCarving::AxisSlab { reg, cont: Option }` — *"twelve contiguous +level bytes at `reg`, with an optional (possibly discontiguous) **continuation** +register of twelve more."* + +**The contract crate declares the canonical maximum addressable depth as 24 +levels via a continuation register.** #973 asserted a hard ceiling of 16 +nibbles by reading `NiblePath::MAX_DEPTH` — a different type, in a different +module of the same crate — and never checked the rail geometry that owns the +question. + +### 2.2 The canonical tenant is `FacetCascade`, and it is already coded + +`crates/lance-graph-contract/src/facet.rs`: `FacetTier { lo, hi }` (2 B) + +`FacetCascade { facet_classid: u32, tiers: [FacetTier; 6] }` = **4 + 12 = 16 B**, +size-asserted. Operator ruling, 2026-08-20: *"HHTL is the canonical 6×2×8bit +tenant for SoA identity. Period."* The module's own doc gives the rule: + +> The substrate is **ALWAYS 8:8** … only the CONSUMER projects meaning onto the +> bytes … The producer bakes in nothing. + +Re-carvings are already an algebra — `CascadeShape::{G6D2, G4D3, G3D4}`, +"byte-for-byte the same 12-unit register". **`G4D3` is the 4×24 reading**, which +is MedCare-rs's special case (operator, same session). + +### 2.3 THE SHARPEST ONE — this session already measured the continuation, and said so + +On 2026-08-19, working the Zipper/DN thread (session tasks *"Zipper/DN +precedent archaeology"* and *"Phase 1: logical DN across base+continuation"*, +both completed), the operator scoped it: + +> *"a hierarchy path deeper than 12 can be represented as a continuation; the +> full logical DN can be reconstructed; `parent()` is truncation by one +> position; `ancestor()` is prefix containment; depths 16–18 round-trip"* + +and **this session reported back, in its own words**: + +> *"`read()` does exactly the concatenation — `p[..12]` from the slab, `p[12..]` +> from the continuation slab. **So the logical DN across base+continuation +> already exists and is already assembled.**"* + +**#973 then claimed that depth past the 16-nibble mark makes the exact literal +unrepresentable in HHTL.** That is not a forgotten repo precedent from months +ago — it is a **direct contradiction of a measurement this session made and +published hours earlier**. This is the single most damning item and it belongs +at the top of the record. + +### 2.4 The primitive layer was declared COMPLETE — by the operator, in session + +2026-08-20T00:53Z: + +> Facet bytes · `hi_chain` / `lo_chain` (2 × 6-level readings) · +> `shared_prefix_tiles` (XOR + TZCNT prefix length) · `row_match_mask` (4-bit +> equality mask) · distance/group helpers. +> **"So there is no missing HHTL operation and no reason to invent an ndarray +> helper, gather path, or extra mask algebra."** + +and 00:46Z: *"The split is already implemented as a no-op as part of the **2× 6×2×8bit +cast** for one CPU cycle."* All four primitives are present in `facet.rs` +(`hi_chain` :211, `lo_chain` :220, `shared_prefix_tiles` :255, `row_match_mask`). + +### 2.5 `E-WORDNET-MAKES-THE-4-ARY-ADDRESS-SEMANTIC-1` (PR #875) + +FINDING, 5/5 gates green on real WordNet 3.1 (82,192 noun synsets): the `@` +hypernym relation is used **as the HHTL address** — it encodes structure rather +than discovering it (W1 +0.494 real vs −0.036 shuffled; W3 out-of-cell band +0.763 vs 0.031 random = **24.71×**). W4, verbatim: + +> `NiblePath` (`FAN_OUT = 16`, the shipped router) can express exactly two +> levels in a byte; inside one top nibble it sees a single undifferentiated +> bucket. The 4-ary address splits that same population into two rungs that +> differ by 2.47 WordNet hops. **That is real structure the current router is +> blind to.** + +The repo had already **measured** that `NiblePath`'s carving is one carving +among others. #973 took the shipped router's ceiling for the substrate's. +PR #876 (`PROBE-HHTL-INTAKE-BLINDNESS`) is the paired caution: a null produced +by an intake limitation must not be reported as a property of the address. + +### 2.6 OSM / WebMercator and Bible Rosetta — coordinate-plus-facets + +- **OSM:** OGAR `MERCATOR-HHTL-HELIX-MAP.md` §1 + OGAR `CLAUDE.md` — *"domains + bind the axes (**OSM: literal x/y**; semantic: PQ subspace pairs)"*; a tier is + a 256×256 tile, canon "one byte per axis per tier" = exactly the `8:8` pair. + + > **⊘ I OVER-CLAIMED THIS ROW — corrected by a read-only audit, and the + > overclaim is the same failure mode this document exists to record.** An + > earlier revision ended this bullet: *"Exact Cartesian coordinates are an + > exact HHTL address, **in a shipped domain**."* **False.** Measured: + > `MERCATOR-HHTL-HELIX-MAP.md:5` sets the legend *"`[G]` = in code, `[H]` = + > design"* and **§1 at `:17` is graded `[H]`**; its round-trip falsifier + > (`:94-96`) is **unrun**. `ogar-osm/src/lib.rs:212-296` declares + > `GEO_V3_FACET` — a **byte-position table**; grep for lon/lat/mercator/ + > morton/zoom math in that crate returns **zero hits**. The cited reader is a + > stub: `ndarray/crates/cesium/src/esri_crs.rs:285` `inverse_mercator` is + > `unimplemented!("scaffold only")`; `osm_pbf.rs:12` *"this file is + > **D-OSM-1** — the stub"*. `OGAR/docs/DISCOVERY-MAP.md:222` grades `D-OSM` + > **`H` / `IDEA` / queued**. + > + > **What OSM actually establishes:** the binding of Cartesian axes to HHTL + > tiers is DECLARED as a byte schema and minted as classids — not computed, + > and nothing hydrated. It still refutes #973's inference (nothing anywhere + > treats the address plane as unable to hold a Cartesian point), but it is a + > **design precedent, not a shipped one**. Citing it as shipped was + > strengthening a receipt to fit an argument — the reflex that produced #973, + > repeated inside the document written to record it. + +- **Rosetta:** `.claude/plans/rosetta-codebook-convergence-v1.md` — *"The verse + address is a frozen external key … the exact sentence in ALL translations + lands in [the same row]"*, while WordNet synsets supply a separate + language-neutral semantic coordinate. One absolute coordinate roots orthogonal + coordinate systems; language lane, clause index, sense and qualia vary as + **facets**, never as nibbles appended below the verse. + + > **⊘ SAME CORRECTION, SAME DIRECTION.** That plan's own status line (`:3`) + > is **PROPOSED (doc-only)**; the verse row is deliverable `D-RCC-2` + > (`:108-114`), and no verse-identity type exists in `crates/`. The book row's + > real state is the operator's point exactly: **the address exists, the + > concept field does not.** A book is a HORIZONTAL STREAM of addressed + > sentences; concepts are the VERTICAL axis and are not materialized as SoA + > at HEEL/HIP. Reasoning is what has to hydrate them. + +### 2.7 MedCare-rs: FMA anatomy IS the HHTL address, in production + +Operator, 2026-08-20: *"MedCare-rs is using FMA anatomy 70k nodes 4 Mio vercels +as HHTL"* — and, separately, *"MedCare-rs using 4×24 as a special case"* +(= `CascadeShape::G4D3`, the same 12-unit register re-carved 4 groups × 3 +levels). + +This is the WordNet result (§2.5) again, in a second domain and **in a shipped +consumer**: a real ontology — the Foundational Model of Anatomy — is not +*routed by* HHTL, it **is** the HHTL address, at 70k nodes and ~4 M vertices. +Two independent domains, two different carvings (4-ary semantic in #875, 4×24 +here), one substrate. + +It also makes the #973 inference untenable on its own terms: a 70k-node anatomy +addressed at 4×24 is precisely the case that a 16-nibble ceiling would have +declared impossible, and it is running. + +> **⊘ MORTON IS NOT PART OF THIS — AND REACHING FOR IT WAS THE SAME MISTAKE +> AGAIN (operator, 2026-08-20: "No SoA ever was allowed to use Morton", "No NARS +> ever residing in Morton", "Nobody fucking asked you to hallucinate Morton").** +> The Stage-3 brief mentioned Morton **only** to deny the premise *"Morton +> implies lossy"*. An earlier draft of THIS audit turned that denial into a +> component to build — a second instance of the same failure mode, inside the +> document written to correct the first. Morton exists here as a SIMD nibble +> lens (`FacetTier::morton`, GFNI) and in non-SoA spatial probes. It is not the +> SoA identity substrate, no NARS state resides in it, and S3.0 must not contain +> it. + +## 3. What code from #973 is still mathematically valid + +Salvageable, after re-interpretation: + +| #973 artefact | verdict | +|---|---| +| four canonical `u16` components; exact component equality; no hash, no tolerance, no learned assignment | **valid** | +| reversible fixed-width packing (`as_u64` / `to_le_bytes` and inverses) | **valid** | +| `const _: () = assert!(size_of == 8)` as the structural guard that no evidence/confidence/source/version field can be added | **valid, and worth keeping** — it makes falsifiers 7–10 compile-time | +| the component-isolation matrix from a non-zero baseline | **valid** | +| the injectivity sweep and the "three sources → one literal" test | **valid** | +| the `E-A-DISABLE-THAT-DOES-NOT-BIND-IS-NOT-A-DISABLE-2` method finding | **valid, unrelated to the error** | + +Invalid and removed: + +| #973 artefact | verdict | +|---|---| +| the "identity is outside HHTL" framing | **rejected** | +| `E-THE-LITERAL-CANNOT-LIVE-IN-THE-PATH-IT-ROOTS-1` | **retracted** (never merged — #973 closed unmerged, so nothing on `main` needs editing) | +| `routing_prefix_is_not_identity` **as the architectural headline** | **demoted** — it is a fact about *truncation*, not a discovery about HHTL | +| the `LITERAL_PATH_NIBBLES == MAX_DEPTH` assert read as a budget *impossibility* | **re-read** as one carving's capacity, nothing more | +| the name `CausalLiteral` | **renamed** — see §4 | + +--- + +## 4. Terminology and types — and the type that already exists + +**The canonical carrier is not to be re-minted.** Operator ruling, 2026-08-20: +*"HHTL is the canonical 6×2×8bit tenant for SoA identity. Period."* That tenant +is already CODED, in this crate: + +`lance_graph_contract::facet` — +`FacetTier { lo, hi }` (2 B) + `FacetCascade { facet_classid: u32, tiers: [FacetTier; 6] }` += **4 + 12 = 16 B**, one 128-bit register, with `const _` size asserts. Its own +module doc states the governing rule: + +> The substrate is **ALWAYS 8:8** (each tier is two opaque bytes `hi:lo`); only +> the CONSUMER projects meaning onto the bytes … The producer bakes in nothing +> (AGI-as-glove: the SoA is content-blind, the reader interprets). + +and the re-carvings are already an algebra — `CascadeShape::{G6D2, G4D3, G3D4}`, +"byte-for-byte the same 12-unit register". **`G4D3` (4 groups × 3 levels) is the +4×24 reading**, which is the MedCare-rs special case (operator, same session), +and OGAR's grace-carving amendment lists `G2 4×u24` in the same family. + +Consequences for S3.0: + +- **No new packed identity type.** `ExactLiteralAddr` is a *reading* over the + canonical facet, not a parallel 4×`u16` container. Minting one would be the + ruling-E anti-pattern (*"a container minted to avoid completing the address + transition"*) — the same mistake in a new costume. +- **`CausalLiteral` → exact literal, generic.** Causality is a predicate family + above identity, never inside it: `ASSOCIATED_WITH`, `PART_OF`, + `INTERACTS_WITH`, `CAUSES`, `MEDIATES`, `PREVENTS`, `SUPPORTS`, + `CONTRADICTS` all address through the same substrate. +- **No Morton anywhere in this path** (§2.3 fence). +- **`routing_prefix` → a locality/cohort *truncation*,** demoted from headline; + the facet already ships `prefix_distance` (LCP) for that job, so a new prefix + API may not be needed at all. + +## 5. Replacement invariants + +```text + ExactLiteralAddr (D, S, P, O) + one immutable Cartesian point + = the exact HHTL literal address + │ + ┌──────────┬──────────┼──────────┬──────────┐ + ▼ ▼ ▼ ▼ ▼ + ontology concept CausalMeta Epistemic BasinSet / + coordinate coordinate Meta EntropyWork +``` + +1. Identity is the four canonical axes. Exact, reversible, no hash, no + tolerance, no learned assignment. +2. The address is **inside** HHTL — it is a reading over the canonical + `6×(8:8)` facet tenant (`FacetCascade`), not a parallel container beside it. +3. Evidence, Meta, basins, qualifications and receipts are **orthogonal facets + keyed by** the address. They are never appended as extra nibbles, and they + never change the address. +4. Truncating the locality view is coarse **by choice**; that is a property of + truncation, not of the substrate. +5. Causality is a predicate family above the literal, never inside identity. +6. A local V3 `u16` target is a tenant-local proxy and never the absolute + address. + +--- + +## 6. The process finding + +The failure was **not** "we tried a reasonable architecture and later found a +better one." It was: *a new local derivation ignored already-measured substrate +facts and confidently promoted its incomplete premise into an architectural +impossibility* — in a repository that contained the counterexample in three +domains and a passing test named `morton_roundtrip_is_identity`. + +Recorded as `E-A-LOCAL-DERIVATION-CANNOT-OVERRULE-A-MEASURED-COUNTEREXAMPLE-1`. +The operative rule: **when a local derivation concludes "X is impossible", +that is a claim about the whole substrate and requires a search for +counterexamples before it is written down — not merely a correct calculation.**