From 08b64d301d6a861e9c8ff9093110dcb821e5de67 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 5 Sep 2026 15:47:28 +0000 Subject: [PATCH 1/9] =?UTF-8?q?plan:=20open-ideas-fetch-v1=20=E2=80=94=20t?= =?UTF-8?q?hree=20stale=20idea=20cards=20re-derived=20from=20the=20tree?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Planning only; no code. Three Open cards fetched from an 82-day-stale IDEAS.md, and each was wrong about its own blocker when read against the current tree: - policy_hash_v1: the blocker is the UDF body, not registration. The UDF is bound as an object inside the Expr (policy.rs:137) and executes without any by-name lookup — register_vsa_udfs has zero callers and its UDFs still run. invoke_with_args just returns NotImplemented. The hash family + key source is the operator's decision (D-OIF-1-DEC); unkeyed FNV-64 is recommended against. - Σ-propagation "hardware backends": mis-shaped for a 2×2 f64 kernel (12 mul + 6 add); AMX tiles are 16×16 and MKL dgemm costs more than the flops. The lever is F64x8 batching with bit identity to the scalar kernel, as consumer code in jc — no ndarray change. And ewa_sandwich( has zero production call expressions (every "caller" is a doc comment), so the kernel ships only paired with the hop re-quantization probe that decides whether apply_edges may advance sigma[row]. - Σ sidecar: the 1-byte index already shipped as a SoA column (mailbox_soa.rs:133, bindspace.rs:58). The codebook it indexes is claimed to live in three places and exists in none: every production row carries sigma = 0, "first centroid" of a codebook with no centroids. Two provenance stories (fitted vs declared) and two viability numbers (R²=0.9949 vs ρ=0.9973) ride on the same claim. D-OIF-0..6 on STATUS_BOARD; three operator decisions gate the workers (D-OIF-1-DEC / 2-DEC / 5-DEC). §7 carries the per-D Sonnet briefs; §8 lists the structural claims execution must confirm. IDEAS.md gains four entries and three in-place status flips carrying the MEASURED blocker with a date. Both board gates green; the citation gate fired four times on my own citations first (nearest-symbol anchor rule) and was satisfied by fixing the citing lines, not the rule. Supersession index regenerated last. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01DCfrD5y19cvFc4AoyydXYv --- .claude/board/EPIPHANIES.md | 27 ++++ .claude/board/IDEAS.md | 38 ++++- .claude/board/INTEGRATION_PLANS.md | 32 +++++ .claude/board/STATUS_BOARD.md | 10 ++ .claude/board/SUPERSESSION-INDEX.md | 9 +- .claude/plans/open-ideas-fetch-v1.md | 208 +++++++++++++++++++++++++++ 6 files changed, 317 insertions(+), 7 deletions(-) create mode 100644 .claude/plans/open-ideas-fetch-v1.md diff --git a/.claude/board/EPIPHANIES.md b/.claude/board/EPIPHANIES.md index fb07bf6a2..81081bd0d 100644 --- a/.claude/board/EPIPHANIES.md +++ b/.claude/board/EPIPHANIES.md @@ -1,3 +1,30 @@ +## 2026-09-05 — E-A-COLUMN-OF-INDICES-INTO-A-CODEBOOK-THAT-DOES-NOT-EXIST-1 — three stale idea cards, each wrong about its own blocker + +**Status:** FINDING (structural — grep + read of the current tree; nothing compiled). Plan: `.claude/plans/open-ideas-fetch-v1.md`. +**Confidence:** High on every "exists / does not exist / has N callers" claim below; each carries file:line. + +Fetching the three highest-value Open cards from an 82-day-stale `IDEAS.md` produced the same shape three times: **the card names a blocker that is not the blocker.** + +| card | named blocker | measured blocker | +|---|---|---| +| `IDEA-POLICY-HASH-UDF` | "UDF registration" | the **body** — the UDF is bound as an object in the `Expr` (`policy.rs:137`) and executes without by-name registration (`register_vsa_udfs` has zero callers and its UDFs still run); `invoke_with_args` simply returns `NotImplemented` | +| `IDEA-B1-HARDWARE-BACKENDS` | "waits on ndarray AMX/MKL" | the **shape** — a 2×2 f64 sandwich has no 16×16 tile mapping; and `ewa_sandwich(` has **zero production call expressions** (all four "callers" are doc comments), so any faster kernel is a home without a consumer | +| `IDEA-CAUSAL-EDGE-TENSOR-SIDECAR` | "design the 9-byte sidecar" | it **shipped**, as a SoA column (`mailbox_soa.rs:125-133`, `bindspace.rs:54-58`) — the card never learned; what is missing is the **codebook** the column indexes | + +### The sharp one + +Every production row carries `sigma = 0`, documented as "untrained / first centroid" (`bindspace.rs:54`). The `SigmaCodebook` those bytes index is claimed to live in the contract (`sigma_propagation.rs:73`), in `lance-graph-cognitive` (`contract/src/splat.rs:308`), and to be built offline by `jc` (`arm-discovery/aerial/codebook.rs:16`). `grep -rn SigmaCodebook crates/` returns the two doc lines and nothing else; `lance-graph-cognitive/src` has zero hits; `jc` holds the *viability probe* and no builder. **Three claimed homes, zero implementations, one live column of references into them.** Its writers are the write-shim loop (`backing.rs:310`) and one test that writes `9`; its readers are two examples that dump the byte. + +Two further inconsistencies ride on the same claim: the σ provenance is written two incompatible ways — *fitted* by k-means (`sigma_codebook_probe.rs`) vs *declared* from the typed value's `(PropertyKind, Marking, SemanticType)` tuple (`sigma_propagation.rs:74-77`) — and two viability numbers are cited for one probe: `R²=0.9949` (`bindspace.rs:39,57`) vs `ρ=0.9973` (`arm-discovery/src/lib.rs:13`), where the probe computes R² (`:317`) and `0.9973` is elsewhere the 3σ constant and an unrelated Spearman band. + +### The generalizable rule + +**A ledger entry's stated blocker decays faster than its stated goal.** The goal ("hash the column", "propagate Σ faster", "index Σ per edge") survived 4 months; every *mechanism* claim attached to it was stale. So: before acting on an idea card, re-derive its blocker from the tree — the cost is a grep, the alternative is building registration that was never missing, hardware backends for a 3-scalar kernel, or a second projection of a byte that already has a column. The `IDEAS.md` "Status" field should carry the *measured* blocker with a date, and the plan re-derivation is the entry, not a preamble to it. + +Also recorded, because it changes what is owed: an unkeyed 64-bit hash of an identifier column is a lookup table wearing a redaction's name — the v1 target named in `policy.rs:275` ("FNV-64") is the option the plan recommends against (`D-OIF-1-DEC`). + +Cross-ref: `E-A-RULED-HOME-NEEDS-A-FIRST-CONSUMER-OR-IT-IS-A-VACANCY-1` (the batched kernel's sequencing); `I-VSA-IDENTITIES` (indices, not content — why the column is right and the sidecar was wrong); `E-A-GATE-INHERITS-THE-BLIND-SPOT-OF-WHOEVER-WROTE-IT-1` (the same day's other instance of a written mechanism outliving its truth). + ## 2026-09-05 — E-NXG-18 — the ladder's top band must BE the universe, or the histogram loses rows silently **Status:** FINDING (PROBE-NXG-ROLL-1 falsified its own first run). diff --git a/.claude/board/IDEAS.md b/.claude/board/IDEAS.md index 5d869181d..faf31534c 100644 --- a/.claude/board/IDEAS.md +++ b/.claude/board/IDEAS.md @@ -87,6 +87,38 @@ Agents filter by `@`-mention or domain to see what's theirs. (Prepend new ideas here with today's date. Format:) +## 2026-09-05 — Σ-propagation: the batched `F64x8` kernel is the real lever; AMX/MKL was the wrong shape for a 2×2 + +`[P2 @savant-architect @sentinel-qa domain:codec D-OIF-4 D-OIF-5]` + +Re-derived from the tree while fetching `IDEA-B1-HARDWARE-BACKENDS`. The kernel is 2×2 f64 (`sigma_propagation.rs:210-227`, 12 mul + 6 add); an AMX tile is 16×16 bf16/int8 and an MKL `dgemm` call costs more than the 18 flops. `F64x8` carries non-FMA `Mul`/`Add` on all four backends (`simd_avx512.rs:446-448`), so eight edges per instruction with **bit identity** to the scalar kernel is reachable as plain consumer code in `jc` — no ndarray change. The catch that decides sequencing: `ewa_sandwich(` has **zero production call expressions** outside `jc` + the contract; every "caller" is a doc comment. So the kernel ships only paired with the hop re-quantization probe that decides whether `MailboxSoA::apply_edges` may advance `sigma[row]`. Plan: `open-ideas-fetch-v1.md` §3. + +**Status:** Open — In plan (`D-OIF-4`, `D-OIF-5`); `D-OIF-5-DEC` (where an edge's `M` comes from — the `CausalEdge64` v2 spare is 3 bits) is the operator's. + +## 2026-09-05 — The σ column indexes a codebook that exists in three doc comments and zero crates + +`[P1 @truth-architect @integration-lead domain:codec D-OIF-0 D-OIF-2 D-OIF-3]` + +`BindSpace.fingerprints.sigma` (`bindspace.rs:54-58`) and `MailboxSoA.sigma` (`mailbox_soa.rs:125-133`) shipped the 1-byte index the `IDEA-CAUSAL-EDGE-TENSOR-SIDECAR` card was still designing. The `SigmaCodebook` it references is claimed to live in the contract (`sigma_propagation.rs:73`), in `lance-graph-cognitive` (`contract/src/splat.rs:308`), and to be built offline by `jc` (`arm-discovery/aerial/codebook.rs:16`) — `grep -rn SigmaCodebook crates/` finds only the two doc lines. Every production row carries `sigma = 0`, "first centroid" of a codebook with no centroids. Two provenance stories coexist — fitted (k-means, `sigma_codebook_probe.rs`) vs declared (typed-value tuple, `sigma_propagation.rs:74-77`) — and two viability numbers are cited for one claim (`R²=0.9949` vs `ρ=0.9973`). Plan: `open-ideas-fetch-v1.md` §4. + +**Status:** Open — In plan (`D-OIF-0` re-runs the probe; `D-OIF-2` the type + builder; `D-OIF-3` the first real writer). `D-OIF-2-DEC` (fitted vs declared) is the operator's. + +## 2026-09-05 — `ndarray::simd::ternlog` ⋂ the §14 voxel cube: the "other 18 cells" are one named immediate each + +`[P2 @simd-savant @kernel-membrane-warden domain:mask]` + +lance-graph-java's `mask-risc-lowering-v1.md` §14 prices a 3-state × 3-tier voxel cube as 9 built primitives with "the other 18 cells ANDs of three". `ndarray::simd::ternlog::{AND3, AND2_ANDNOT, AND_ANDNOT2, …}` (ndarray #299 arc, parity-tested over all 256 immediates on six backends) makes each of those cells ONE instruction with a NAME. Partly realized already: `lance-graph-planner/examples/probe_nxg_hist_1.rs:51-136` calls `mask_ternlog::` / `` by name (E-NXG-2/3). What is still open: (a) §14's arithmetic assumes cell = 3 ANDs — restate it as 1 ternlog and re-price; (b) `ogar_loco::TERNLOG = FnIndex(0x86)` still has no consumer, and the immediate byte IS the call value — the lowering from a §14 cell to a loco call is a table, not code. Interacts with `D-MRL-G2` (mask spans the class's rows or all rows), which is the operator's. + +**Status:** Open (research; blocked on `D-MRL-G2`). + +## 2026-09-05 — Citations should carry the path the decay gate can resolve, or the gate sees 7 % of them + +`[P2 @doctrine-keeper domain:board]` + +The `citation-decay` gate (#1168/#1170) measured **2314 citations / 37 OK / 124 DECAYED / 2153 UNVERIFIABLE** — 93 % unverifiable because the house style cites bare basenames (`policy.rs:137`) that no scanner can resolve to a file. The gate is honest about it (unverifiable never fails). Two possible remedies, neither taken yet: (1) a convention — cite `crate/path.rs:LINE` for anything under `crates/`, basename-only allowed inside a plan that names its crate once in a header; (2) a resolver in the gate that tries `**/` and treats a UNIQUE hit as resolvable, a non-unique one as unverifiable. (2) needs no behaviour change from writers and is measurable (how many of the 2153 become OK vs DECAYED). Recommend (2) first, then decide (1) on the numbers. + +**Status:** Open. + ## 2026-06-15 — Research synergy: CLAM residue ladder ⋂ knee/hip attractor basins (HHTL cascade in REVERSE, fine→coarse ascent) `[P3 @cascade-architect @savant-research domain:codec]` @@ -1061,7 +1093,7 @@ bgz17 crate as the substrate. ### IDEA-B1-HARDWARE-BACKENDS — AMX/MKL hardware backends for sigma_propagation (PR #322) -**Status:** Open 2026-05-05 +**Status:** Reshaped 2026-09-05 — AMX/MKL rejected for the 2×2 kernel (shape mismatch); superseded by the `F64x8` batched kernel, plan `open-ideas-fetch-v1.md` §3 (`D-OIF-4`/`D-OIF-5`) **Priority:** P3 **Source:** PR #322 explicit "What this PR does NOT do" **Author's words:** "No hardware backends (AMX/MKL via ndarray #119/#121). That's B1.5 follow-up." @@ -1125,7 +1157,7 @@ bgz17 crate as the substrate. ### IDEA-CAUSAL-EDGE-TENSOR-SIDECAR — CausalEdgeTensor as 9-byte sidecar (CausalEdge64 + 1 byte Σ index) (PR #288) -**Status:** Open 2026-05-05 +**Status:** Implemented-in-part 2026-09-05 — the 1-byte index shipped as a SoA column (`mailbox_soa.rs:133`, `bindspace.rs:58`), NOT as a sidecar; the codebook it indexes is OPEN, plan `open-ideas-fetch-v1.md` §4 (`D-OIF-2`/`D-OIF-3`) **Priority:** P2 **Source:** PR #288 (sigma codebook probe conclusion) **Author's words:** "Mit diesem Probe-Resultat kann jetzt `CausalEdgeTensor`-Variante als 9-Byte-Sidecar (`CausalEdge64` + 1 Byte Σ-Codebook-Index) entworfen werden, ODER äquivalent über Schemasidecar Block 14/15. Caller-Wahl, beide architektonisch tragbar." @@ -1161,7 +1193,7 @@ bgz17 crate as the substrate. ### IDEA-POLICY-HASH-UDF — policy_hash_v1 UDF registration (PR #301) -**Status:** Open 2026-05-05 +**Status:** In plan 2026-09-05 — blocker is the UDF body, not registration (`policy.rs:137` binds the object); plan `open-ideas-fetch-v1.md` §2 (`D-OIF-1`, decision `D-OIF-1-DEC`) **Priority:** P2 **Source:** PR #301 **Author's words:** "`NotYetWiredHashUdf` binds at plan time, returns `NotImplemented('policy_hash_v1 UDF not yet registered')` at execute. Plans build; execution fails loud." diff --git a/.claude/board/INTEGRATION_PLANS.md b/.claude/board/INTEGRATION_PLANS.md index 473d62c6e..6f8c38d17 100644 --- a/.claude/board/INTEGRATION_PLANS.md +++ b/.claude/board/INTEGRATION_PLANS.md @@ -1,3 +1,35 @@ +## 2026-09-05 — `open-ideas-fetch-v1` (MEASURED, planning-only — three decisions gate the workers) + +`.claude/plans/open-ideas-fetch-v1.md`. Three Open cards fetched from an +82-day-stale `IDEAS.md` and re-derived from the current tree; **each card +was wrong about its own blocker** (`E-A-COLUMN-OF-INDICES-INTO-A-CODEBOOK-THAT-DOES-NOT-EXIST-1`). + +- **`policy_hash_v1`** — the blocker is the UDF body, not registration + (`policy.rs:137` binds the object into the `Expr`; `register_vsa_udfs` has + zero callers and its UDFs still execute). `D-OIF-1`; the hash family + key + source is `D-OIF-1-DEC` (recommendation: keyed SipHash-1-3 in-crate, key + bound at rewriter construction; unkeyed FNV-64 recommended against). +- **Σ-propagation "hardware backends"** — mis-shaped for a 2×2 f64 kernel; + the lever is `F64x8` batching with bit identity to the scalar kernel, as + consumer code in `jc` (no ndarray change). Zero production call sites + exist, so the kernel ships only paired with the hop re-quantization probe. + `D-OIF-4` + `D-OIF-5`; the edge-`M` source is `D-OIF-5-DEC`. +- **Σ sidecar** — already shipped as a SoA column; the **codebook** the + column indexes exists in three doc comments and zero crates. `D-OIF-0` + (re-run the viability probe, reconcile 0.9949 vs 0.9973), `D-OIF-2` (type + in the contract, builder in `jc`, instance in `cognitive-shader-driver`, no + digest pin), `D-OIF-3` (first real writer); provenance is `D-OIF-2-DEC`. +- **`D-OIF-6`** — the ledger itself: four new entries + three status flips, + shipped in this PR. + +Rejected on record (§5): AMX/MKL for 2×2; the 9-byte sidecar and Block +14/15 (superseded); the in-`u64` index (3 spare bits); an IDEAS-staleness CI +gate (fires on legitimate quiet). §8 lists the four structural claims that +execution must confirm before they are believed. §7 carries the per-D Sonnet +briefs; nothing is dispatched until the three decisions land. + +**Status:** PLANNED — halted for operator decisions D-OIF-1-DEC / 2-DEC / 5-DEC. + ## 2026-09-05 — `bindspace-mailbox-soa-wiring-v1` (MEASURED, ready-to-execute) `.claude/plans/bindspace-mailbox-soa-wiring-v1.md`. The BindSpace → MailboxSoA diff --git a/.claude/board/STATUS_BOARD.md b/.claude/board/STATUS_BOARD.md index 151625c10..81921359b 100644 --- a/.claude/board/STATUS_BOARD.md +++ b/.claude/board/STATUS_BOARD.md @@ -15,6 +15,16 @@ records against itself. | D-id | deliverable | status | |---|---|---| +| D-OIF-0 | Re-run `cargo run -p jc --example sigma_probe` on the current tree; record R², verdict, and reconcile the `R²=0.9949` (`bindspace.rs:39`) vs `ρ=0.9973` (`arm-discovery/lib.rs:13`) citations to their sources. Orchestrator-run, no worker. Falsifier: the recorded number is the probe's own printed R², not either citation | Queued (plan `open-ideas-fetch-v1` §4.3) | +| D-OIF-1 | `policy_hash_v1` gets a body: `PolicyHashUdf` (renamed from `NotYetWiredHashUdf`, `policy.rs:279`) with real `invoke_with_args` over Array/Scalar, NULL→NULL, typed byte views, loud `NotImplemented` for unsupported types; `.claude/patterns.md:89` (`NotYetWiredHashUdf`) renamed in the same commit. Gates G1–G8 (§2.4), each disable-named. Falsifier: executing a Hash-masked scan over a 3-row `MemTable` returns 3 distinct non-null `UInt64` | Queued (blocked on D-OIF-1-DEC) | +| D-OIF-1-DEC | **Operator decision:** hash family + key source — A unkeyed FNV-1a-64 (PR #301's stated target; recommended AGAINST: enumerable on identifier columns) / **B keyed SipHash-1-3, 128-bit key, in-crate, key bound at rewriter construction (recommended)** / C SHA-256-64 (`sha2` dep). See plan §2.2 | Decision — operator | +| D-OIF-2 | `SigmaCodebook([Spd2; 256])` TYPE in the zero-dep contract (`from_le_bytes`/`to_le_bytes`, `entry`, `nearest` via the affine-invariant metric, all-SPD boundary check on load per `sigma_propagation.rs:108`); k-means BUILDER/EMITTER in `jc` (float to build); loaded INSTANCE homed in `cognitive-shader-driver` beside the column it serves. Tag + content invariants, **no digest pin**. Gates G1–G4 (§4.4) | Queued (blocked on D-OIF-2-DEC) | +| D-OIF-2-DEC | **Operator decision:** σ provenance — *fitted* (k-means over observed Σ, `sigma_codebook_probe.rs`) vs *declared* (typed-value tuple lookup, `sigma_propagation.rs:74-77`). Recommendation: fitted entries, declared as write-time fallback only. See plan §4.2 | Decision — operator | +| D-OIF-3 | First writer of a non-zero σ at the ingest path that today calls `BackingStoreWrite::set_sigma` with a constant (`backing.rs:310`). Falsifier: ≥2 distinct Σ shapes in → ≥2 distinct non-zero σ (can-fire); identical shapes in → one value (stay-silent) | Queued (blocked on D-OIF-2) | +| D-OIF-4 | `ewa_sandwich_x8` + slice driver in `crates/jc` over `ndarray::simd::F64x8` `Mul`/`Add` (**never `mul_add`**), same 12-mul/6-add order per lane as `ewa_sandwich.rs:185-199`. Gates: bit identity (`to_bits`) vs the scalar contract kernel on 1000 pairs incl. the tail path; bench pinned AFTER measurement (§3.5). Ships only paired with D-OIF-5 (zero production callers today — `E-A-RULED-HOME-…-VACANCY-1`) | Queued (plan §3) | +| D-OIF-5 | Hop re-quantization probe (jc pillar): for n ∈ {1,2,4,8,16}, ≥1000 seeded paths, `log_norm_growth` exact vs re-quantized-to-k=256-per-hop, against `pillar_5plus_bound(n)` with the existing 1.75× slack (`sigma_propagation.rs:268-285`). PASS at every n = σ-advance in `apply_edges` is sound; any FAIL = shelved with the number. Arm 1 on the probe's own codebook, arm 2 on D-OIF-2's | Queued (plan §3.4) | +| D-OIF-5-DEC | **Operator decision:** where an edge's `M` comes from for σ-advance — `CausalEdge64` v2 spare is 3 bits (`edge.rs:557`), so not a per-edge 256-index; candidates: the source row's own σ, or a per-edge-class M. Wiring into `apply_edges` (`mailbox_soa.rs:348`) is gated on this AND on D-OIF-5 PASS | Decision — operator | +| D-OIF-6 | `IDEAS.md` hygiene: four new Open entries (F64x8 lever / the missing codebook / ternlog ⋂ §14 / citation resolvability) + three in-place Status flips on the fetched cards, each carrying the MEASURED blocker with a date | Shipped (this PR) | | D-BSW-0 | Put the feature under CI in **BOTH** configurations — `--features mailbox-thoughtspace` AND `--features with-engine,mailbox-thoughtspace` (plan §4 M0). One job is NOT the deliverable: `dispatch_busdto` and `busdto_bridge_test.rs` are `with-engine`-gated (`engine_bridge.rs:280`), so a mailbox-only job compiles neither and stays green while the paired configuration breaks. Today the 4 `w2_differential` bit-identity tests and every `BackingStoreWrite` Mailbox arm have ZERO coverage. Precedent `rust-test.yml:158-173`. Falsifier: test count strictly increases in each configuration and the 4 tests appear by name | Queued (plan `bindspace-mailbox-soa-wiring-v1` §4) | | D-BSW-1 | Wire `BackingStoreWrite` (`backing.rs:164-314`, 9 methods, both arms real) into the driver write path — it has zero callers outside its own test module. Adds a caller, not a capability | Queued (blocked on D-BSW-0) | | D-BSW-2 | Route the production BindSpace writers through the shim — **eight sites, not five**: `engine_bridge` `write_qualia_observed:490` / `write_qualia_17d:548` (direct), `persist_cycle:784` (edge+meta; cycle write is the documented loss), `ingest_codebook_indices:58` (composed last); plus the three `serve.rs` handlers `encode_handler:607` (direct `set_content`), `:139` and `:639` (via `Arc::get_mut`). `dispatch_busdto:281` is **excluded pending a decision** — its `qualia_f32` tenant has no MailboxSoA equivalent (plan §4). All eight must land BEFORE D-BSW-3 or dispatch reads the mailbox while `/v1/shader/encode` writes the singleton | Queued (blocked on D-BSW-1) | diff --git a/.claude/board/SUPERSESSION-INDEX.md b/.claude/board/SUPERSESSION-INDEX.md index 361bad1aa..9d9398004 100644 --- a/.claude/board/SUPERSESSION-INDEX.md +++ b/.claude/board/SUPERSESSION-INDEX.md @@ -14,7 +14,7 @@ ## What this table says **`BindSpace` is the shape of the problem.** Marked RETIRE, and simultaneously the -most-referenced symbol here: **68 crate files, 46 plans, 41 of them blind.** +most-referenced symbol here: **68 crate files, 47 plans, 42 of them blind.** That is a programme, not a cleanup. **`GateState` is the sharpest case: 1 plan names it and *every one* is blind.** @@ -60,11 +60,11 @@ coverage instead. | `GateState` | REPURPOSE | — | 14 | 1 | 1 | | `MergeMode` | REPURPOSE | — | 8 | 13 | 12 | | `ResonanceDto` | REPURPOSE | `PerturbationDto` | 2 | 12 | 7 | -| `BindSpace` | RETIRE | — | 68 | 46 | 41 | +| `BindSpace` | RETIRE | — | 68 | 47 | 42 | | `CollapseGateEmission` | RETIRE | — | 5 | 13 | 12 | | `ThinkingStyle` | RETIRE-toward-contract | — | 51 | 28 | 24 | -## Table 2 — plans naming a ruled symbol without citing the ruling (73) +## Table 2 — plans naming a ruled symbol without citing the ruling (74) Route is **mechanical triage, not a verdict**: `ARCHIVE?` = the plan's own status says it shipped; `RESCOPE` = it targets a symbol marked RETIRE; `READ` = neither signal fires @@ -142,6 +142,7 @@ a licence to act on it. | **RESCOPE** | `lf-integration-mapping-v1` | `BindSpace` | Active (2026-04-25) | 0/0 | | **RESCOPE** | `lite-unified-surrealql-lance-v1` | `BindSpace` | CONJECTURE / design. **Test via feature gate | 0/0 | | **RESCOPE** | `ogit-cascade-supabase-callcenter-v1` | `BindSpace` | plan, not implementation. | 0/16 | +| **RESCOPE** | `open-ideas-fetch-v1` | `BindSpace` | MEASURED / ready-to-execute — PLANNING ONLY | 2/10 | | **RESCOPE** | `q2-foundry-integration-v1` | `BindSpace` | Proposed (2026-04-24) | 0/0 | | **RESCOPE** | `reliability-checklist-arc-v1` | `ThinkingStyle` | PROPOSAL / possibility menu (2026-05-30). NO | 3/3 | | **RESCOPE** | `singleton-to-snapshot-nudge-v1` | `BindSpace` | PROPOSAL | 1/12 | @@ -154,6 +155,6 @@ a licence to act on it. | **RESCOPE** | `unified-soa-rubikon-integration-v1` | `BindSpace` | — | 8/8 | - **ARCHIVE?**: 0 -- **RESCOPE**: 55 +- **RESCOPE**: 56 - **READ**: 18 - ruled symbols tracked: 14 diff --git a/.claude/plans/open-ideas-fetch-v1.md b/.claude/plans/open-ideas-fetch-v1.md new file mode 100644 index 000000000..a559703df --- /dev/null +++ b/.claude/plans/open-ideas-fetch-v1.md @@ -0,0 +1,208 @@ +# Open-ideas fetch — three stale cards re-derived from the tree (v1) + +> **Status:** MEASURED / ready-to-execute — PLANNING ONLY in this PR. Every +> claim below carries file:line from a read of the CURRENT tree (origin/main +> `ac9148f7`, #1171, plus the FF to `afeb0458`). NOT COMPILED, NOT RUN — no +> `cargo` was invoked; every "exists / is wired / has callers" statement is +> structural (grep + read), and §8 names the ones that must be confirmed by +> execution before they are believed. +> +> **READ BY:** the orchestrator that dispatches the Sonnet workers (§7 carries +> the per-D briefs), anyone touching `lance-graph-callcenter::policy`, +> `sigma_propagation`, the `MailboxSoA.sigma` column, or `crates/jc`. +> +> **Origin:** `IDEAS.md` had gone 82 days without an entry (newest 2026-06-15) +> while ~900 PRs merged. Three of its Open cards were picked as the highest +> value; **each one changed shape on contact with the tree**, which is the +> reason this plan exists rather than three direct PRs. +> +> **Confidence:** HIGH on the census; LOW-to-none on anything marked +> DECISION — those are the operator's, stated with a recommendation and +> deliberately not taken. + +## 0. The three headline corrections + +| card (IDEAS.md) | what the card says | what the tree says | +|---|---|---| +| `IDEA-POLICY-HASH-UDF` (`:1162`) | "policy_hash_v1 UDF **registration**" | Registration is not the blocker. The UDF is bound as an `Arc` **object inside the `Expr`** (`policy.rs:137`), and DataFusion executes the embedded object without any by-name lookup — proof: `register_vsa_udfs` (`vsa_udfs.rs:574`) has **zero callers** in the tree and its UDFs still execute in tests. The blocker is the **body**: `invoke_with_args` returns `NotImplemented` (`policy.rs:~330`). | +| `IDEA-B1-HARDWARE-BACKENDS` (`:1062`) | "AMX/MKL backends for sigma_propagation, waits on ndarray #119/#121" | The kernel is a **2×2 f64** sandwich — three scalars, 12 mul + 6 add (`sigma_propagation.rs:210-227`). An AMX tile is 16×16 bf16/int8; an MKL `dgemm` call costs more than the 18 flops it would do. The idea is **mis-shaped for its own kernel**. The real lever is vertical batching — `F64x8` (8 edges/instruction), whose `Mul`/`Add` already exist on every backend. AND: `ewa_sandwich(` has **zero production call expressions** outside `jc` + the contract (grep, §3.2) — every "caller" is a doc-comment mention. | +| `IDEA-CAUSAL-EDGE-TENSOR-SIDECAR` (`:1126`) | "design a 9-byte sidecar (`CausalEdge64` + 1 byte Σ index) OR Block 14/15" | **The 1-byte index already shipped, as a SoA column** — `BindSpace.fingerprints.sigma: Box<[u8]>` (`bindspace.rs:54-58`), `MailboxSoA.sigma: [u8; N]` (`mailbox_soa.rs:125-133`), `set_sigma` (`:670`), `BackingStoreWrite::set_sigma` both arms (`backing.rs:253-257`). Neither the sidecar nor Block 14/15 is live. **What does NOT exist is the codebook the index points at** — §4. | + +## 1. Frozen decisions this plan inherits (cited, not re-derived) + +- **Zero-dep contract.** `lance-graph-contract/Cargo.toml` `[dependencies]` is empty by design and says why (a path dep there broke every CI invocation, 2026-07-07). Nothing in this plan adds a dependency to it. +- **All SIMD from `ndarray::simd`** (`simd-savant`; W1a consumer contract, ndarray `.claude/knowledge/vertical-simd-consumer-contract.md`). Consumer code composes typed wrappers; it never writes intrinsics. +- **Bit identity between the jc kernel and the contract copy is CI law** — `jc::ewa_sandwich::tests::the_contract_copy_matches_the_certified_kernel_bit_for_bit` (`ewa_sandwich.rs:~425`, 1000 sampled SPD pairs, `to_bits()`, no tolerance; `jc-proof.yml`). Any batched kernel joins that law or does not land. +- **Internal head pins are absolutely and permanently prohibited** (MedCare-rs `CLAUDE.md`, operator 2026-08-30). A frozen codebook artifact gets a **tag + content invariants**, never a digest gate. +- **Indices, not content** (`I-VSA-IDENTITIES`; `mailbox_soa.rs:128-131`): the codebook stays shared/cold; rows carry the 1-byte reference. +- **The falsifiability rule** (`CLAUDE.md`): every guard needs a can-fire AND a can-stay-silent test on non-trivial inputs; a threshold needs an inertness test; a doc claim is not a behaviour. +- **Sonnet workers: edit-only, no `cargo`, no `git`, disjoint files; the orchestrator compiles once** (`agent-cargo-hygiene.md`; `sonnet-worker-guardrails.md` §1 pasted verbatim into every brief). + +## 2. D-OIF-1 — `policy_hash_v1`: give the UDF a body + +### 2.1 Evidence + +- `crates/lance-graph-callcenter/src/policy.rs:120-140` — `mask_expr` binds `NotYetWiredHashUdf::new()` as an `Arc` inside a `ScalarFunction` expr. +- `:262-335` — the impl: `Signature::any(1, Volatility::Immutable)`, `return_type = UInt64` (already fixed so downstream schemas are stable), `invoke_with_args → Err(NotImplemented("policy_hash_v1 UDF not yet registered — see PR-F1b"))`. The header comment names **FNV-64 as the v1 target**. +- Feature gate: `auth-rls-lite = ["auth-jwt", "query-lite"]`, `query-lite = ["dep:datafusion", "dep:arrow"]` (`Cargo.toml` `[features]`). `datafusion` WITHOUT default features. +- Existing test `redaction_mode_hash_binds_not_yet_wired_udf` (`:598-620`) asserts **plan text only** (`contains("policy_hash_v1")`, `!contains("***REDACTED***")`). It stays green after the fix and is therefore **not** a falsifier of the body. New tests must EXECUTE the plan. +- Execution pattern in this crate: `graph_table.rs:196-229` — `#[tokio::test]`, `MemTable::try_new`, `ctx.register_table`, `df.collect().await`, under `#[cfg(feature = "query")]`. Policy tests today build plans against an **empty** `MemTable` (`policy.rs:530`). `tokio` is already a dev-dep with `rt-multi-thread` + `macros`. +- Array-vs-Scalar handling to copy: `vsa_udfs.rs:88-89` (unwrap) and `:201-204` (length resolution). +- Live docs naming the type: `.claude/patterns.md:89` (`NotYetWiredHashUdf`) — a live inventory, **update in the same commit**. `PR_ARC_INVENTORY.md:5734` and `LATEST_STATE.md:2753` are append-only history — leave. + +### 2.2 DECISION D-OIF-1-DEC — hash family and key (operator's; recommendation stated) + +| option | what | verdict | +|---|---|---| +| A — FNV-1a-64, unkeyed | what PR #301 named as "v1 target" | **Do not ship as the default.** A masked column is by definition an identifier; unkeyed 64-bit hashing of a low-entropy identifier is reversible by enumeration. It would *look* redacted in every plan and be a lookup table in practice. | +| B — **keyed SipHash-1-3, 128-bit key, in-crate** | ~60 LOC, zero new dependency, deterministic across Rust versions (std's `DefaultHasher` is SipHash-1-3 but **explicitly not stable across releases** and unkeyed — unusable for a persisted pseudonym) | **Recommended.** Same input + same key → same hash (joins still work); different key → different pseudonym space (a deployment's masked values are useless elsewhere). | +| C — SHA-256 truncated to 64 | needs `sha2` (crates.io, no fork) | Acceptable, one more dep for no property B lacks at this width. | + +**Key source (part of the decision):** the key must be **bound at rewriter construction**, never read from the environment inside the UDF (the UDF is `Immutable` and must be a pure function of its inputs). Proposed shape: `ColumnMaskRewriter { registry, actor_role, hash_key: [u8; 16] }`; `mask_expr` becomes a method and builds `PolicyHashUdf::new(self.hash_key)`. The **membrane** (the caller that already holds `actor_role`) supplies the key from its own config. Two rewriters, two keys, is the falsifier that proves the key is load-bearing. + +### 2.3 Deliverable + +- `PolicyHashUdf` (rename; `NotYetWiredHashUdf` is now a false name) in `policy.rs`, same `Signature`/`return_type`, `invoke_with_args` implemented over `ColumnarValue::{Array, Scalar}`: + - NULL → NULL (Arrow null propagation), never the hash of an empty string. + - Hashed byte view per type: `Utf8`/`LargeUtf8`/`Utf8View` (UTF-8 bytes), `Binary`/`LargeBinary`/`BinaryView` (bytes), `Boolean` (one byte), `Int8..Int64`/`UInt8..UInt64` (little-endian bytes of the widened `i64`/`u64` — so `Int32(5)` and `Int64(5)` hash equal; document it), `Float32`/`Float64` (IEEE bits of the `f64` widening; `-0.0 ≠ 0.0` — document it), `Date32/64`, `Timestamp(*)` (the underlying integer's bytes). + - Any other type → `DataFusionError::NotImplemented` naming the type — **loud, and enumerated in the doc comment**, never a silent constant. +- `policy_hash_udf(key) -> Arc` + `register_policy_udfs(ctx, key)` for SQL-text callers, mirroring `register_vsa_udfs` — a convenience, **not** the deliverable (see §0). +- `.claude/patterns.md:89` (`NotYetWiredHashUdf`) updated to the new name. + +### 2.4 Pre-registered gates (each red-then-green; the disable is named) + +| # | assertion | non-trivial input | disable that must turn it red | +|---|---|---|---| +| G1 | executing a Hash-masked scan over a `MemTable` with ≥3 real rows returns `UInt64`, non-null for non-null inputs | 3 distinct strings | restore `Err(NotImplemented)` | +| G2 | determinism: two separate `SessionContext`s + two rewriters with the SAME key give identical column values | same 3 strings | perturb the key in one rewriter | +| G3 | discrimination: 3 distinct inputs → 3 distinct hashes; and the two equal inputs among 4 → equal hashes | `["a","b","a","c"]` | return a constant | +| G4 | key is load-bearing: two rewriters with DIFFERENT keys give different values for the same input | same string | ignore the key in `invoke` | +| G5 | NULL → NULL; the null count of the output equals the null count of the input | a column with 2 nulls of 5 | hash `""` for nulls | +| G6 | an unsupported type fails LOUD at execute with the type in the message (can-fire); a supported type does NOT (stay-silent) | `List` vs `Utf8` | make the fallback return `0` | +| G7 | the old `:598` test still passes unchanged (plan text) — proves the rewrite site did not move | as-is | n/a (regression) | +| G8 | `cargo clippy -p lance-graph-callcenter --features auth-rls-lite -- -D warnings` clean; `cargo test -p lance-graph-callcenter --features auth-rls-lite` green | — | — | + +**§8 caveat feeding G1:** `DataFrame::collect()` under `query-lite` (datafusion without default features) is **assumed** to compile — the physical planner is core, `sql` is not needed. If it does not, the execution tests move under `#[cfg(feature = "auth-rls")]` (`= query`) and the plan says so; that is a scope note, not a failure. + +## 3. D-OIF-4 / D-OIF-5 — Σ-propagation: the batched kernel and the hop probe + +### 3.1 Why "hardware backends" is the wrong shape + +- Kernel: `Spd2 { a, b, c }` f64 (`sigma_propagation.rs:113-117`); `ewa_sandwich` = 8 products for `P = M·Σ`, 8 for `R = P·Mᵀ`, then `b = 0.5·(r01 + r10)` (`:210-227`). Byte-identical copy in `jc/src/ewa_sandwich.rs:185-199`. +- AMX: `hpc/amx_matmul.rs` exposes 16×16 tiles (`tile_dpbusd`, `tile_dpbf16ps`, `:288-359`); `simd_amx.rs` exposes u8×i8 VNNI dot/matvec. Neither has a 2×2 f64 shape. MKL `dgemm` on 2×2 is dominated by call overhead. **Rejected for this kernel** — recorded, not deferred. +- The 3×3 analogue exists as a jc probe (`ewa_sandwich_3d.rs`, `Spd3`, `:378`); the n×n idea is `IDEA-PILLAR5PLUS-HIGHER-DIM-SPD`. AMX becomes plausible only at ≥16×16 in **bf16**, and bf16 rounding on the SPD cone can lose PSD — that is its own falsifier and **out of scope** here. + +### 3.2 The real lever, and the real gap + +- `F64x8` carries `Add`/`Mul` on **every** backend with no FMA in the path: AVX-512 `impl_bin_op!(F64x8, Mul, mul, _mm512_mul_pd)` (`simd_avx512.rs:446-448`), AVX2 (`simd_avx2.rs:973-987`), NEON (`simd_neon.rs:1019-1047`), scalar via `impl_float_type!(F64x8, f64, 8, …)` (`simd_scalar.rs:510`). `mul_add` exists (`:376`) and **must not be used** — it would break bit identity with the scalar kernel. +- So the batched kernel is ordinary consumer code over typed wrappers: 8 edges per lane-op, same 12-mul/6-add order per lane. **No ndarray change is needed; the STOP rule is not triggered.** +- **Home:** `crates/jc` (deps `ndarray`, `Cargo.toml:21`, "MANDATORY"). Not the contract (zero-dep). Name: `ewa_sandwich_x8(m: &[Spd2; 8], sigma: &[Spd2; 8]) -> [Spd2; 8]` plus a slice driver `ewa_sandwich_batch(m: &[Spd2], sigma: &[Spd2], out: &mut [Spd2])` handling the tail with the scalar kernel. +- **The gap that decides the sequencing:** `grep -rn "ewa_sandwich(" crates/` outside `jc/` and `sigma_propagation.rs` returns **nothing**. The four files that mention it — `cognitive-shader-driver/src/bindspace.rs:41`, `mailbox_soa.rs:129`, `perturbation-sim/src/splat.rs:19`, `lance-graph-arm-discovery/src/aerial/codebook.rs:16` — do so in **doc comments**. A faster kernel for a function nobody calls is `E-A-RULED-HOME-NEEDS-A-FIRST-CONSUMER-OR-IT-IS-A-VACANCY-1` verbatim. Therefore D-OIF-4 ships **only paired with D-OIF-5**, whose result decides whether the first consumer (§3.3) is sound. + +### 3.3 The named first consumer (NOT built in this plan) + +`MailboxSoA::apply_edges` (`mailbox_soa.rs:348-372`) receives `(row, CausalEdge64)` deliveries and today updates only `energy[row]` and `plasticity_counter[row]`; `sigma[row]` is never advanced. The contract's own planned use-site is "B4 shader-driver-sigma-propagate … propagate `sigma_path = ewa_sandwich(...)` along the resonance chain" (`sigma_propagation.rs:78-80`). With a codebook (§4), one hop is: `Σ' = sandwich(M, codebook[sigma[row]])`, then `sigma[row] = nearest(codebook, Σ')`. Two things block wiring it, and this plan does not pretend otherwise: + +1. **Where `M` comes from.** A `CausalEdge64` carries no matrix; its v2 spare is **3 bits** (`edge.rs:194, 557` — bits 61-63), so it cannot carry a 256-entry index. Candidates: the *source* row's own `sigma` (M = codebook[σ_src]), or a per-edge-class M. **DECISION D-OIF-5-DEC, operator's.** +2. **Whether re-quantizing to k=256 after every hop keeps concentration.** That is D-OIF-5. + +### 3.4 D-OIF-5 — the hop re-quantization probe (jc) + +Pre-registered: for hop depth `n ∈ {1, 2, 4, 8, 16}`, over ≥1000 seeded paths, compare `log_norm_growth(seed, Σ_n)` (`sigma_propagation.rs:254`) for (i) exact propagation and (ii) propagation with nearest-codebook re-quantization after each hop, against `pillar_5plus_bound(n)` (`:274-285`) with the existing **1.75×** PASS slack (`:268-272`). **PASS** = re-quantized growth stays inside the slack at every `n` tested. **FAIL** at any `n` = σ-advance in `apply_edges` is unsound at that depth and the consumer is shelved with the number. First arm runs on the probe's own k-means codebook (`sigma_codebook_probe.rs`, `N_EDGES=10_000, K=256, 100 iters, SEED` fixed at `:49-52`) so it does not wait on D-OIF-2's artifact; second arm re-runs on the real codebook when it exists. + +### 3.5 D-OIF-4 gates + +| # | assertion | disable | +|---|---|---| +| G1 | `ewa_sandwich_x8` is **bit-identical** (`to_bits`) to the scalar contract `ewa_sandwich` on 1000 sampled SPD pairs incl. non-zero off-diagonals (the existing test's anti-vacuity guard) | replace one `*` + `+` with `mul_add` | +| G2 | the slice driver's tail path (len % 8 ≠ 0) is bit-identical too | drop the tail loop | +| G3 | a bench (`jc/examples`) prints ns/edge for scalar vs x8 at N = 65 536; the number is **pinned after measurement**, never predicted | — | +| G4 | `jc-proof.yml` still green (the certified kernel is untouched) | — | + +## 4. D-OIF-0 / D-OIF-2 / D-OIF-3 — the Σ codebook that three files point at and none holds + +### 4.1 The finding + +Every σ byte in the substrate is an index into a codebook that **does not exist**: + +- `sigma_propagation.rs:73` — "indexing into a 256-entry static `SigmaCodebook` of `Spd2`". +- `contract/src/splat.rs:308` — "The full SigmaCodebook lives in **lance-graph-cognitive**". +- `arm-discovery/src/aerial/codebook.rs:16-19` — "built and certified **offline by `crates/jc`**". +- `grep -rn SigmaCodebook crates/` → those two doc lines. `crates/lance-graph-cognitive/src` → zero hits. `jc` has the **viability probe** (`sigma_codebook_probe.rs`) and no builder/emitter. + +Three claimed homes, zero implementations. The column's writers: `backing.rs:310` (write-shim loop) and one test (`:347`, writes `9`). Readers: two planner examples dumping the byte (`blw_tenant.rs:190`, `blw_rows.rs:289`). Every production row has `sigma = 0`, documented as "untrained / first centroid" (`bindspace.rs:54`) of a codebook with no centroids. + +**Two numbers, one claim.** `bindspace.rs:39,57` cite "R²=0.9949 at k=256 (#288)". `arm-discovery/src/lib.rs:13` and `codebook.rs:18` cite "ρ=0.9973". The probe computes **R² in log-Euclidean space** (`sigma_codebook_probe.rs:27, 317`, PASS ≥ 0.99). `0.9973` appears elsewhere as the 3σ coverage constant and the ADC-cosine Spearman band (`probe_adc_cosine_head_to_head.rs:6`) — a different quantity. D-OIF-0 settles which number the codebook claim actually rests on. + +### 4.2 Two provenance stories for σ — DECISION D-OIF-2-DEC (operator's) + +| story | where it is written | what it implies | +|---|---|---| +| **Fitted** — σ = nearest of 256 k-means centroids over observed Σ | `sigma_codebook_probe.rs` (Lloyd's, affine-invariant Riemannian metric, R² gate) | needs a per-row observed Σ at write time; the codebook is trained once, offline, in jc (float to build, index to use — the CAM-PQ doctrine, `codebook.rs:19-22`) | +| **Declared** — σ = lookup from the typed value's `(PropertyKind, Marking, SemanticType)` + value range | `sigma_propagation.rs:74-77` ("B3 transcode-sigma-assignment") | needs a mapping table, not k-means; the "codebook" is authored, and the R² probe is irrelevant to it | + +They are not compatible as the *same* v1. Recommendation: **fitted** for the entries, **declared** only as the assignment *fallback* when no Σ is observable at write time — but that is a design choice with consequences for every consumer, so it is stated and not taken. + +### 4.3 D-OIF-0 — re-run the viability probe on the current tree (first, cheap, unconditional) + +`cargo run -p jc --example sigma_probe` (the `[[example]] sigma_probe`, `jc/Cargo.toml`). Record R², the PASS verdict, and the recommendation string it prints (`sigma_codebook_probe.rs:342-360`) in `AGENT_LOG` + this plan's §9. Reconcile 0.9949 vs 0.9973 in one sentence with the source of each. ~seconds of compute; no decision depends on skipping it. + +### 4.4 D-OIF-2 — the codebook TYPE (contract) + BUILDER/EMITTER (jc) + INSTANCE home + +- **Type, in the contract (zero-dep, LE law):** `SigmaCodebook([Spd2; 256])`, `from_le_bytes(&[u8; 256·24])` / `to_le_bytes`, `entry(u8) -> &Spd2`, `nearest(&Spd2) -> u8` (affine-invariant metric via the existing `Spd2::{log_spd, sqrt, pow, eig}` `:130-176`), and a **boundary check** on load — every entry `is_spd(eps)` (`:187`), per the module's own contract that SPD is checked "at boundaries (codebook load, runtime gate)" (`:108-109`). 6 KiB. +- **Builder, in jc:** the k-means the probe already runs, refactored so the emitter writes the frozen table (float to build). Emits **LE bytes + a tag**. **No digest pin, no digest gate** — identity = `K == 256` ∧ all-SPD ∧ `det > 0` ∧ the tag. The operator law on internal pins is absolute. +- **Instance home:** the contract carries the TYPE; the loaded INSTANCE must live where files can be read and where `set_sigma` is called — `cognitive-shader-driver` (owner of `MailboxSoA.sigma`), **not** `lance-graph-cognitive` (which the splat proxy names but which holds nothing). Recommendation only; the crate that owns the column should own the loader. +- Gates: G1 `from_le_bytes(to_le_bytes(cb)) == cb` bit-exact; G2 a non-SPD entry is **refused** at load (can-fire) and a valid table is not (stay-silent); G3 `nearest` returns the entry's own index for each of the 256 entries (identity), and a perturbed entry returns its unperturbed neighbour (discrimination); G4 the emitted table from the probe's fixed SEED is byte-stable across two runs (determinism). + +### 4.5 D-OIF-3 — the first writer of a non-zero σ (gated on D-OIF-2-DEC) + +Whichever provenance the decision picks, the first writer is the ingest/write path that today calls `BackingStoreWrite::set_sigma` in its loop (`backing.rs:310`) with a constant. Falsifier: after ingesting a batch with ≥2 genuinely different Σ shapes, `sigma` holds ≥2 distinct non-zero values (can-fire) and a batch of identical shapes holds one (stay-silent). **Not built until the decision lands**; the plan carries both shapes' one-line specs so the brief is a paste. + +## 5. What this plan REJECTS, with the reason on record + +| item | verdict | why | +|---|---|---| +| AMX / MKL for the 2×2 sandwich | rejected | shape mismatch: 3 scalars vs 16×16 tiles; call overhead ≫ 18 flops (§3.1) | +| 9-byte `CausalEdge64 + u8` sidecar | superseded | the u8 landed as a SoA column (§0); a second projection of the same byte is `SECOND-PROJECTION` | +| SchemaSidecar Block 14/15 | superseded | same | +| Σ index inside the `u64` | impossible | v2 spare is 3 bits (`edge.rs:557`) | +| wiring σ-advance into `apply_edges` | deferred, gated | needs D-OIF-5 PASS **and** D-OIF-5-DEC (the M source) | +| bf16 ≥16×16 SPD on AMX | out of scope | own falsifier (PSD under bf16 rounding) — file it as an idea, do not build | +| a CI gate on IDEAS.md staleness | rejected | a ledger that is legitimately quiet would fail it — a gate that fires on quiet carries no information (`E-ANTI-EIGENVALUE-…`). A dated census line in `LATEST_STATE` instead. | + +## 6. Sequencing + +``` +D-OIF-0 probe re-run (jc, seconds) ── unconditional, first +D-OIF-1 policy_hash_v1 body ── independent; needs D-OIF-1-DEC (hash + key) +D-OIF-4 ewa_sandwich_x8 (jc) ┐ +D-OIF-5 hop re-quant probe ┘ paired ── D-OIF-5 arm 1 needs no artifact +D-OIF-2 SigmaCodebook type + builder + home ── needs D-OIF-2-DEC (fitted vs declared) +D-OIF-3 first σ writer ── needs D-OIF-2 + D-OIF-2-DEC +D-OIF-6 IDEAS ledger: 4 entries + 3 flips ── THIS PR +``` + +Three decisions stand between the plan and the workers: **D-OIF-1-DEC**, **D-OIF-2-DEC**, **D-OIF-5-DEC**. D-OIF-0, D-OIF-4, D-OIF-5 (arm 1) and D-OIF-6 need none. + +## 7. Worker briefs (Sonnet, edit-only; the orchestrator compiles once) + +Every brief starts with `sonnet-worker-guardrails.md` §1 **verbatim**, then: *Read `.claude/board/AGENT_LOG.md` first; do NOT write it — leave your record in your own tag-file. Do NOT run `cargo` or `git`. Do not claim it compiles or that tests pass — you did not run them. Your file scope is exactly the files named; another worker owns everything else.* + +- **W-1 (D-OIF-1)** — files: `.claude/patterns.md:89` (`NotYetWiredHashUdf`), `crates/lance-graph-callcenter/src/policy.rs`. Spec: §2.3 + the decided hash/key from D-OIF-1-DEC. Tests: §2.4 G1-G7 as `#[tokio::test]` under `auth-rls-lite`, each with its disable named in a comment. STOP if `DataFrame::collect` does not resolve under `query-lite` — report, do not change features. +- **W-4 (D-OIF-4)** — files: `crates/jc/src/ewa_sandwich.rs` (append only below the existing kernel), `crates/jc/examples/ewa_sandwich_bench.rs` (new). Spec: §3.2; **no `mul_add`, ever**; same op order per lane as `:185-199`. Tests: §3.5 G1-G2 with the disable named. STOP if any test needs a tolerance — that is a bug, not a tolerance. +- **W-5 (D-OIF-5)** — files: `crates/jc/src/sigma_hop_requant_probe.rs` (new), `crates/jc/src/lib.rs` (one `pub mod` line + one pillar-table entry, `lib.rs:150-185` shape). Spec: §3.4. Output: the table `n → (exact growth, requantized growth, bound, PASS/FAIL)` printed by `prove`. +- **W-2 (D-OIF-2, after D-OIF-2-DEC)** — files: `crates/lance-graph-contract/src/sigma_propagation.rs` (type + loader + boundary check, zero deps), `crates/jc/src/sigma_codebook_probe.rs` (emitter arm). Spec: §4.4, gates G1-G4. +- **W-0 (D-OIF-0)** — no edits: the orchestrator runs `cargo run -p jc --example sigma_probe` itself and records the result (§4.3). Not a worker task. + +Orchestrator gates after the fleet lands: `cargo fmt -p `, `cargo clippy -p --all-targets -- -D warnings` per touched crate (`-p`, never `--all` — `tesseract-rs`'s lesson), `cargo test -p ` with the feature sets named above, plus the two board gates and `supersession_index.py` regenerated LAST. + +## 8. Claims in this plan that are STRUCTURAL and must be confirmed by execution + +1. `DataFrame::collect()` compiles under `query-lite` (datafusion sans default features). Fallback named in §2.4. +2. `F64x8` `Mul`/`Add` are non-FMA on **all four** backends — read from `impl_bin_op!` (AVX-512) and the operator impls (AVX2/NEON); the scalar macro body was not read line-by-line. G1 of §3.5 is what proves it. +3. `cargo run -p jc --example sigma_probe` runs on the default feature set (it is not `required-features`-gated in `Cargo.toml:44-56`; `goursat_substrate_probe` is). +4. The probe's k-means codebook is exposable to D-OIF-5 arm 1 without a public API change — if not, W-5 gets a one-line `pub(crate)` accessor in `sigma_codebook_probe.rs` and its scope grows by that file. + +## 9. Results ledger (append as they land) + +- D-OIF-0: _(not yet run)_ From f12feba01d685fc1c209e6d54a6e74ed15dc6675 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 5 Sep 2026 16:21:21 +0000 Subject: [PATCH 2/9] open-ideas-fetch-v1: address CodeRabbit round 1 on #1185 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - §3.4 D-OIF-5 re-stated to mirror the certified comparison shape (CV reduction, tightness ≤ 1.75, PASS = synthetic-model evidence only) - D-OIF-7 / W-7 owns the SigmaCodebook instance in cognitive-shader-driver - EPIPHANIES confidence line narrowed to the grep census with full-path citations; Deliverables line names every D-OIF id (index 11/11) - STATUS_BOARD D-OIF-5 reworded, D-OIF-7 row added; INTEGRATION_PLANS names W-7; fence tagged `text` (MD040) - SUPERSESSION-INDEX regenerated last Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01DCfrD5y19cvFc4AoyydXYv --- .claude/board/EPIPHANIES.md | 3 ++- .claude/board/INTEGRATION_PLANS.md | 2 +- .claude/board/STATUS_BOARD.md | 3 ++- .claude/board/SUPERSESSION-INDEX.md | 2 +- .claude/plans/open-ideas-fetch-v1.md | 15 ++++++++++++--- 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/.claude/board/EPIPHANIES.md b/.claude/board/EPIPHANIES.md index 28b42904c..0dee06710 100644 --- a/.claude/board/EPIPHANIES.md +++ b/.claude/board/EPIPHANIES.md @@ -1,7 +1,8 @@ ## 2026-09-05 — E-A-COLUMN-OF-INDICES-INTO-A-CODEBOOK-THAT-DOES-NOT-EXIST-1 — three stale idea cards, each wrong about its own blocker **Status:** FINDING (structural — grep + read of the current tree; nothing compiled). Plan: `.claude/plans/open-ideas-fetch-v1.md`. -**Confidence:** High on every "exists / does not exist / has N callers" claim below; each carries file:line. +**Confidence:** High. Existence and absence claims carry file:line. Caller/reader counts are **grep censuses**, stated as such with their scope: `crates/lance-graph-callcenter/src/vsa_udfs.rs:574` (`register_vsa_udfs`) has zero call sites outside its definition across `crates/**/*.rs`; `ewa_sandwich(` has zero call expressions outside `crates/jc/` and `sigma_propagation.rs`; the only σ writers are `crates/cognitive-shader-driver/src/backing.rs:310` (`set_sigma`, the shim loop) and `crates/cognitive-shader-driver/src/backing.rs:347` (`set_sigma`, a test); the only σ readers are `crates/lance-graph-planner/examples/blw_tenant.rs:190` (`o.sigma[row]`) and `crates/lance-graph-planner/examples/blw_rows.rs:289` (`o.sigma[row]`). Nothing compiled. +**Deliverables (plan `open-ideas-fetch-v1`):** `D-OIF-0` `D-OIF-1` `D-OIF-1-DEC` `D-OIF-2` `D-OIF-2-DEC` `D-OIF-3` `D-OIF-4` `D-OIF-5` `D-OIF-5-DEC` `D-OIF-6` `D-OIF-7`. Fetching the three highest-value Open cards from an 82-day-stale `IDEAS.md` produced the same shape three times: **the card names a blocker that is not the blocker.** diff --git a/.claude/board/INTEGRATION_PLANS.md b/.claude/board/INTEGRATION_PLANS.md index 5468948c7..98994cb9c 100644 --- a/.claude/board/INTEGRATION_PLANS.md +++ b/.claude/board/INTEGRATION_PLANS.md @@ -18,7 +18,7 @@ was wrong about its own blocker** (`E-A-COLUMN-OF-INDICES-INTO-A-CODEBOOK-THAT-D column indexes exists in three doc comments and zero crates. `D-OIF-0` (re-run the viability probe, reconcile 0.9949 vs 0.9973), `D-OIF-2` (type in the contract, builder in `jc`, instance in `cognitive-shader-driver`, no - digest pin), `D-OIF-3` (first real writer); provenance is `D-OIF-2-DEC`. + digest pin), `D-OIF-3` (first real writer), `D-OIF-7` (the loaded instance + loader in `cognitive-shader-driver`, worker W-7); provenance is `D-OIF-2-DEC`. - **`D-OIF-6`** — the ledger itself: four new entries + three status flips, shipped in this PR. diff --git a/.claude/board/STATUS_BOARD.md b/.claude/board/STATUS_BOARD.md index e4302d820..c4a28c247 100644 --- a/.claude/board/STATUS_BOARD.md +++ b/.claude/board/STATUS_BOARD.md @@ -42,9 +42,10 @@ records against itself. | D-OIF-2-DEC | **Operator decision:** σ provenance — *fitted* (k-means over observed Σ, `sigma_codebook_probe.rs`) vs *declared* (typed-value tuple lookup, `sigma_propagation.rs:74-77`). Recommendation: fitted entries, declared as write-time fallback only. See plan §4.2 | Decision — operator | | D-OIF-3 | First writer of a non-zero σ at the ingest path that today calls `BackingStoreWrite::set_sigma` with a constant (`backing.rs:310`). Falsifier: ≥2 distinct Σ shapes in → ≥2 distinct non-zero σ (can-fire); identical shapes in → one value (stay-silent) | Queued (blocked on D-OIF-2) | | D-OIF-4 | `ewa_sandwich_x8` + slice driver in `crates/jc` over `ndarray::simd::F64x8` `Mul`/`Add` (**never `mul_add`**), same 12-mul/6-add order per lane as `ewa_sandwich.rs:185-199`. Gates: bit identity (`to_bits`) vs the scalar contract kernel on 1000 pairs incl. the tail path; bench pinned AFTER measurement (§3.5). Ships only paired with D-OIF-5 (zero production callers today — `E-A-RULED-HOME-…-VACANCY-1`) | Queued (plan §3) | -| D-OIF-5 | Hop re-quantization probe (jc pillar): for n ∈ {1,2,4,8,16}, ≥1000 seeded paths, `log_norm_growth` exact vs re-quantized-to-k=256-per-hop, against `pillar_5plus_bound(n)` with the existing 1.75× slack (`sigma_propagation.rs:268-285`). PASS at every n = σ-advance in `apply_edges` is sound; any FAIL = shelved with the number. Arm 1 on the probe's own codebook, arm 2 on D-OIF-2's | Queued (plan §3.4) | +| D-OIF-5 | Hop re-quantization probe (jc pillar): for n ∈ {1,2,4,8,16}, ≥1000 seeded paths, `log_norm_growth` exact vs re-quantized-to-k=256-per-hop, against `pillar_5plus_bound(n)` with the existing 1.75× slack (`sigma_propagation.rs:268-285`). reduction mirrors the certified `ewa_sandwich::prove` (`ewa_sandwich.rs:325-343`): per depth/arm, CV of `‖log Σ_n‖²_F` across paths, tightness = CV / bound, PASS if ≤ 1.75 — NOT a direct comparison of `log_norm_growth` (an absolute Δ) against the bound (a CV). PASS = evidence for the measured synthetic model only, not proof `apply_edges` is sound; wiring σ-advance needs its own implementation + consumer tests and D-OIF-5-DEC. Arm 1 on the probe's own codebook, arm 2 on D-OIF-2/7's | Queued (plan §3.4) | | D-OIF-5-DEC | **Operator decision:** where an edge's `M` comes from for σ-advance — `CausalEdge64` v2 spare is 3 bits (`edge.rs:557`), so not a per-edge 256-index; candidates: the source row's own σ, or a per-edge-class M. Wiring into `apply_edges` (`mailbox_soa.rs:348`) is gated on this AND on D-OIF-5 PASS | Decision — operator | | D-OIF-6 | `IDEAS.md` hygiene: four new Open entries (F64x8 lever / the missing codebook / ternlog ⋂ §14 / citation resolvability) + three in-place Status flips on the fetched cards, each carrying the MEASURED blocker with a date | Shipped (this PR) | +| D-OIF-7 | The loaded `SigmaCodebook` INSTANCE + loader in `cognitive-shader-driver` (`sigma_codebook.rs`, new; owner W-7): read LE bytes + tag, construct through the contract type's boundary SPD check, expose to the driver. Gates: refuses a non-SPD table (can-fire) / accepts a valid one (stay-silent); byte-stable across two loads; tag mismatch fires. Does not touch `mailbox_soa.rs`/`backing.rs` | Queued (blocked on D-OIF-2) | | D-BSW-0 | Put the feature under CI in **BOTH** configurations — `--features mailbox-thoughtspace` AND `--features with-engine,mailbox-thoughtspace` (plan §4 M0). One job is NOT the deliverable: `dispatch_busdto` and `busdto_bridge_test.rs` are `with-engine`-gated (`engine_bridge.rs:280`), so a mailbox-only job compiles neither and stays green while the paired configuration breaks. Today the 4 `w2_differential` bit-identity tests and every `BackingStoreWrite` Mailbox arm have ZERO coverage. Precedent `rust-test.yml:158-173`. Falsifier: test count strictly increases in each configuration and the 4 tests appear by name | Queued (plan `bindspace-mailbox-soa-wiring-v1` §4) | | D-BSW-1 | Wire `BackingStoreWrite` (`backing.rs:164-314`, 9 methods, both arms real) into the driver write path — it has zero callers outside its own test module. Adds a caller, not a capability | Queued (blocked on D-BSW-0) | | D-BSW-2 | Route the production BindSpace writers through the shim — **eight sites, not five**: `engine_bridge` `write_qualia_observed:490` / `write_qualia_17d:548` (direct), `persist_cycle:784` (edge+meta; cycle write is the documented loss), `ingest_codebook_indices:58` (composed last); plus the three `serve.rs` handlers `encode_handler:607` (direct `set_content`), `:139` and `:639` (via `Arc::get_mut`). `dispatch_busdto:281` **wires — tenant TBD by probe** (⊘ regraded 2026-09-05 from "excluded pending a decision" by operator ruling R2, `E-EVERYTHING-WIRES-TO-SOA-V3-CE64-IS-ALU-LEGACY-1`): its 16-dim `qualia_f32` has no f32 VECTOR tenant on MailboxSoA (only the scalar `energy: [f32;N]`, `mailbox_soa.rs:66`); candidates are `QualiaI4_16D` via `set_qualia` or `atoms.rs` `I4x32/I4x64`, chosen by a D-MTS-6-proxy quantization probe pre-registered before its first run (plan §4). All eight must land BEFORE D-BSW-3 or dispatch reads the mailbox while `/v1/shader/encode` writes the singleton | Queued (blocked on D-BSW-1) | diff --git a/.claude/board/SUPERSESSION-INDEX.md b/.claude/board/SUPERSESSION-INDEX.md index edc90ab98..297ab1459 100644 --- a/.claude/board/SUPERSESSION-INDEX.md +++ b/.claude/board/SUPERSESSION-INDEX.md @@ -142,7 +142,7 @@ a licence to act on it. | **RESCOPE** | `lf-integration-mapping-v1` | `BindSpace` | Active (2026-04-25) | 0/0 | | **RESCOPE** | `lite-unified-surrealql-lance-v1` | `BindSpace` | CONJECTURE / design. **Test via feature gate | 0/0 | | **RESCOPE** | `ogit-cascade-supabase-callcenter-v1` | `BindSpace` | plan, not implementation. | 0/16 | -| **RESCOPE** | `open-ideas-fetch-v1` | `BindSpace` | MEASURED / ready-to-execute — PLANNING ONLY | 2/10 | +| **RESCOPE** | `open-ideas-fetch-v1` | `BindSpace` | MEASURED / ready-to-execute — PLANNING ONLY | 11/11 | | **RESCOPE** | `q2-foundry-integration-v1` | `BindSpace` | Proposed (2026-04-24) | 0/0 | | **RESCOPE** | `reliability-checklist-arc-v1` | `ThinkingStyle` | PROPOSAL / possibility menu (2026-05-30). NO | 3/3 | | **RESCOPE** | `singleton-to-snapshot-nudge-v1` | `BindSpace` | PROPOSAL | 1/12 | diff --git a/.claude/plans/open-ideas-fetch-v1.md b/.claude/plans/open-ideas-fetch-v1.md index a559703df..2834141d5 100644 --- a/.claude/plans/open-ideas-fetch-v1.md +++ b/.claude/plans/open-ideas-fetch-v1.md @@ -108,7 +108,14 @@ ### 3.4 D-OIF-5 — the hop re-quantization probe (jc) -Pre-registered: for hop depth `n ∈ {1, 2, 4, 8, 16}`, over ≥1000 seeded paths, compare `log_norm_growth(seed, Σ_n)` (`sigma_propagation.rs:254`) for (i) exact propagation and (ii) propagation with nearest-codebook re-quantization after each hop, against `pillar_5plus_bound(n)` (`:274-285`) with the existing **1.75×** PASS slack (`:268-272`). **PASS** = re-quantized growth stays inside the slack at every `n` tested. **FAIL** at any `n` = σ-advance in `apply_edges` is unsound at that depth and the consumer is shelved with the number. First arm runs on the probe's own k-means codebook (`sigma_codebook_probe.rs`, `N_EDGES=10_000, K=256, 100 iters, SEED` fixed at `:49-52`) so it does not wait on D-OIF-2's artifact; second arm re-runs on the real codebook when it exists. +Pre-registered, and **mirrored on the certified comparison** (`crates/jc/src/ewa_sandwich.rs:294-343`, `cv_measured` / `cv_tightness`) — not a new gate shape: + +- **Hop-matrix source:** the SAME seeded generator the certified pillar uses (`ewa_sandwich.rs:95` Box-Muller, `:215` random rotation θ; SplitMix64 state, seed fixed) — one `M` per hop per path. +- **Paths:** `N_PATHS ≥ 1000` per depth, `n ∈ {1, 2, 4, 8, 16}`, seed Σ as in the pillar. +- **Two arms per path:** (i) exact — `Σ_k = ewa_sandwich(M_k, Σ_{k-1})`; (ii) re-quantized — after every hop, `Σ_k ← codebook[nearest(codebook, Σ_k)]` with `nearest` in the affine-invariant metric `d(A,B) = ‖log(B^-½·A·B^-½)‖_F` (the probe's own metric, `sigma_codebook_probe.rs:24`). +- **Reduction (the part the first draft got wrong):** `log_norm_growth` returns an ABSOLUTE change in `‖log Σ‖²_F` (`sigma_propagation.rs:254`) while `pillar_5plus_bound(n)` returns a **coefficient of variation** (`:274-285`); they are not comparable directly. So, exactly as `ewa_sandwich::prove` does: per depth and per arm, take `‖log(Σ_n)‖²_F` over all paths, compute `mean` and `std`, `cv_measured = std / mean`, `tightness = cv_measured / pillar_5plus_bound(n)`, **PASS if `tightness ≤ 1.75`** (`ewa_sandwich.rs:325-343`). Report both arms' tightness and their ratio (does re-quantization widen concentration, and by how much). +- **Verdict semantics:** PASS on arm (ii) at every `n` is **evidence that re-quantization preserves concentration in THIS synthetic model** — it is not proof that `MailboxSoA::apply_edges` is sound. Wiring σ-advance into `apply_edges` stays its own deliverable with its own implementation and consumer tests, outside this plan, and still needs `D-OIF-5-DEC`. Any FAIL at depth `n` shelves that consumer with the number. +- **Arms by artifact:** arm 1 runs on the probe's own k-means codebook (`sigma_codebook_probe.rs`, `N_EDGES=10_000, K=256, 100 iters, SEED` fixed at `:49-52`), so it does not wait on D-OIF-2; arm 2 re-runs on the real codebook once D-OIF-2/D-OIF-7 exist. ### 3.5 D-OIF-4 gates @@ -151,7 +158,7 @@ They are not compatible as the *same* v1. Recommendation: **fitted** for the ent - **Type, in the contract (zero-dep, LE law):** `SigmaCodebook([Spd2; 256])`, `from_le_bytes(&[u8; 256·24])` / `to_le_bytes`, `entry(u8) -> &Spd2`, `nearest(&Spd2) -> u8` (affine-invariant metric via the existing `Spd2::{log_spd, sqrt, pow, eig}` `:130-176`), and a **boundary check** on load — every entry `is_spd(eps)` (`:187`), per the module's own contract that SPD is checked "at boundaries (codebook load, runtime gate)" (`:108-109`). 6 KiB. - **Builder, in jc:** the k-means the probe already runs, refactored so the emitter writes the frozen table (float to build). Emits **LE bytes + a tag**. **No digest pin, no digest gate** — identity = `K == 256` ∧ all-SPD ∧ `det > 0` ∧ the tag. The operator law on internal pins is absolute. -- **Instance home:** the contract carries the TYPE; the loaded INSTANCE must live where files can be read and where `set_sigma` is called — `cognitive-shader-driver` (owner of `MailboxSoA.sigma`), **not** `lance-graph-cognitive` (which the splat proxy names but which holds nothing). Recommendation only; the crate that owns the column should own the loader. +- **Instance home:** the contract carries the TYPE; the loaded INSTANCE must live where files can be read and where `set_sigma` is called — `cognitive-shader-driver` (owner of `MailboxSoA.sigma`), **not** `lance-graph-cognitive` (which the splat proxy names but which holds nothing). Recommendation only; the crate that owns the column should own the loader. **Owner: W-7 / `D-OIF-7` (§7) — not W-2**, whose scope is the contract type and the `jc` builder only. - Gates: G1 `from_le_bytes(to_le_bytes(cb)) == cb` bit-exact; G2 a non-SPD entry is **refused** at load (can-fire) and a valid table is not (stay-silent); G3 `nearest` returns the entry's own index for each of the 256 entries (identity), and a perturbed entry returns its unperturbed neighbour (discrimination); G4 the emitted table from the probe's fixed SEED is byte-stable across two runs (determinism). ### 4.5 D-OIF-3 — the first writer of a non-zero σ (gated on D-OIF-2-DEC) @@ -172,13 +179,14 @@ Whichever provenance the decision picks, the first writer is the ingest/write pa ## 6. Sequencing -``` +```text D-OIF-0 probe re-run (jc, seconds) ── unconditional, first D-OIF-1 policy_hash_v1 body ── independent; needs D-OIF-1-DEC (hash + key) D-OIF-4 ewa_sandwich_x8 (jc) ┐ D-OIF-5 hop re-quant probe ┘ paired ── D-OIF-5 arm 1 needs no artifact D-OIF-2 SigmaCodebook type + builder + home ── needs D-OIF-2-DEC (fitted vs declared) D-OIF-3 first σ writer ── needs D-OIF-2 + D-OIF-2-DEC +D-OIF-7 loaded instance + loader (cognitive-shader-driver) ── needs D-OIF-2; W-7 D-OIF-6 IDEAS ledger: 4 entries + 3 flips ── THIS PR ``` @@ -192,6 +200,7 @@ Every brief starts with `sonnet-worker-guardrails.md` §1 **verbatim**, then: *R - **W-4 (D-OIF-4)** — files: `crates/jc/src/ewa_sandwich.rs` (append only below the existing kernel), `crates/jc/examples/ewa_sandwich_bench.rs` (new). Spec: §3.2; **no `mul_add`, ever**; same op order per lane as `:185-199`. Tests: §3.5 G1-G2 with the disable named. STOP if any test needs a tolerance — that is a bug, not a tolerance. - **W-5 (D-OIF-5)** — files: `crates/jc/src/sigma_hop_requant_probe.rs` (new), `crates/jc/src/lib.rs` (one `pub mod` line + one pillar-table entry, `lib.rs:150-185` shape). Spec: §3.4. Output: the table `n → (exact growth, requantized growth, bound, PASS/FAIL)` printed by `prove`. - **W-2 (D-OIF-2, after D-OIF-2-DEC)** — files: `crates/lance-graph-contract/src/sigma_propagation.rs` (type + loader + boundary check, zero deps), `crates/jc/src/sigma_codebook_probe.rs` (emitter arm). Spec: §4.4, gates G1-G4. +- **W-7 (D-OIF-7, after D-OIF-2)** — files: `crates/cognitive-shader-driver/src/sigma_codebook.rs` (new — the loaded INSTANCE: read LE bytes + tag, construct the contract `SigmaCodebook` through its boundary SPD check, expose `&'static`/`Arc` access to the driver), `crates/cognitive-shader-driver/src/lib.rs` (one `pub mod` line). Spec: §4.4 "Instance home". Gates: G2 (a non-SPD table is REFUSED at load; a valid one is not) and G4 (byte-stable across two loads) re-run THROUGH the loader, plus a can-fire/stay-silent pair on tag mismatch. Does NOT touch `mailbox_soa.rs` or `backing.rs` — the first writer is D-OIF-3's. - **W-0 (D-OIF-0)** — no edits: the orchestrator runs `cargo run -p jc --example sigma_probe` itself and records the result (§4.3). Not a worker task. Orchestrator gates after the fleet lands: `cargo fmt -p `, `cargo clippy -p --all-targets -- -D warnings` per touched crate (`-p`, never `--all` — `tesseract-rs`'s lesson), `cargo test -p ` with the feature sets named above, plus the two board gates and `supersession_index.py` regenerated LAST. From f14968697d032f7641d827ce87790c485a834b4b Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 5 Sep 2026 16:31:43 +0000 Subject: [PATCH 3/9] =?UTF-8?q?open-ideas-fetch-v1:=20D-OIF-1=20re-derived?= =?UTF-8?q?=20=E2=80=94=20ruling=20A,=20policy=5Fhash=5Fv1=20SUPERSEDED?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit W0 architecture census (four read-only tracers; Dockerfile claim verified directly). The DataFusion column-masking path has no deployed consumer: ColumnMaskRewriter's only constructor is MedCare patient.rs:150 under the default-off lance-phase2-rbac feature no Dockerfile enables, behind ?source=lance, with a decoder stub that returns None; and the rewriter redacts above the scan (policy.rs:210), never pruning the projection. Operator ruling 2026-09-05: planning migrates to ogar-loco/ogar-r2il, DataFusion is out, existing code gets a grace period, nothing new. - plan §2 rewritten: tree verdict, obligation table, remove/retain/regrade cone, layer audit (Rubicon holds: SoA-owned checked one-way crossing, no actor survives), stale-prose list; W-1 withdrawn; D-OIF-1-DEC withdrawn - STATUS_BOARD D-OIF-1 → Superseded (retirement), D-OIF-1-DEC → Withdrawn - IDEAS.md IDEA-POLICY-HASH-UDF status → Superseded - EPIPHANIES: E-THE-UNFINISHED-FUNCTION-WAS-NOT-THE-DEBT-1 — field-level authorization has no enforced owner on any production path; the rewriter was a storage-layer patch for an authorization-layer hole - LATEST_STATE dated correction (commit_via/OgarRbac: types exist, zero callers); v3 mailbox-kanban-model / COMPONENT-MAP / write-on-behalf regraded in place (KanbanActor deleted 2026-08-05) - SUPERSESSION-INDEX regenerated last No code changed. No hash chosen. No deletion. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01DCfrD5y19cvFc4AoyydXYv --- .claude/board/EPIPHANIES.md | 22 ++++ .claude/board/IDEAS.md | 2 +- .claude/board/INTEGRATION_PLANS.md | 14 +-- .claude/board/LATEST_STATE.md | 2 + .claude/board/STATUS_BOARD.md | 4 +- .claude/board/SUPERSESSION-INDEX.md | 9 +- .claude/plans/open-ideas-fetch-v1.md | 101 ++++++++++++------- .claude/v3/COMPONENT-MAP.md | 2 +- .claude/v3/knowledge/mailbox-kanban-model.md | 2 +- .claude/v3/knowledge/write-on-behalf.md | 2 +- 10 files changed, 104 insertions(+), 56 deletions(-) diff --git a/.claude/board/EPIPHANIES.md b/.claude/board/EPIPHANIES.md index 0dee06710..d6186e175 100644 --- a/.claude/board/EPIPHANIES.md +++ b/.claude/board/EPIPHANIES.md @@ -1,3 +1,25 @@ +## 2026-09-05 — E-THE-UNFINISHED-FUNCTION-WAS-NOT-THE-DEBT-1 — the execution model that needed `policy_hash_v1` never reached a binary, and neither has its replacement + +**Status:** FINDING (W0 production census, four read-only tracers + orchestrator verification of the contested fact; nothing compiled). Plan: `.claude/plans/open-ideas-fetch-v1.md` §2 (ruling A). Operator ruling the same day: planning migrates to `ogar-loco` / `ogar-r2il`; DataFusion is out; what exists gets a grace period; nothing new migrates to it. +**Confidence:** High for every existence/absence/caller claim (each carries `file:line`; "production" was traced to a binary or axum handler, never inferred from `pub mod`, a feature flag, a registration helper, a test or a comment). The Dockerfile claim was verified by the orchestrator directly, not taken from a tracer. +**Deliverables:** `D-OIF-1` (regraded Superseded) `D-OIF-1-DEC` (withdrawn). + +**The card said "registration". The first re-derivation said "the body". Both were one abstraction generation behind.** The question was never *which hash* — it was *whether anything still executes the plan that would call it*. Measured: + +- `ColumnMaskRewriter` has one non-test constructor in seven repos, `MedCare-rs/crates/medcare-server/src/routes/patient.rs:150`, behind `#[cfg(feature = "lance-phase2-rbac")]` (`:85`) and `?source=lance` (`:52-53`). The feature is default-off (`Cargo.toml:215`) and **no Dockerfile enables it** (`docker/Dockerfile.railway:175` etc. build `lance-phase2,reasoning`). Its decoder `record_batch_to_patient` (`:200-211`) returns `None` unconditionally. No user has ever received a masked row. +- The rewriter is post-hoc by construction: `rewrite_plan` (`callcenter/src/policy.rs:210`) substitutes expressions above the scan and never writes `TableScan.projection` (`:226-241` only reads it). The forbidden column is materialized from Lance, then overwritten — the exact shape the projection invariant forbids. +- `RedactionMode::Hash` (`policy.rs:130-140`) binds a UDF whose `invoke` is `Err(NotImplemented)` (`:339`); `register_vsa_udfs` (`vsa_udfs.rs:574`) has zero callers anywhere. + +**The half that keeps this from being a tidy retirement story:** the canonical replacement is also unenforced. `lance-graph-rbac::authorize()` / `authorize_scoped()` (`authorize.rs:66,182`), `contract::ClassRbac` (`rbac.rs:143`), `ActionInvocation::commit_via` (`action.rs:327`) and `lance-graph-ogar::OgarRbac` (`rbac_impl.rs:38`) have **zero non-test callers**; `effective_mask` is not an identifier in any `.rs`; there is no `ogar-rbac` crate (`ogar-auth` is password/TOTP only). The one real `surface ∩ role` fail-closed projection (`a2ui-server/src/project.rs:70-83`) lives in a crate with no binary and no dependent. MedCare's live gate is the entity-string `Policy` returning an `AccessDecision` with no mask (`patient.rs:280`); its column projection (`views/project.rs:229`) is a **view** mask with no role operand. And the one mask fold that exists, `authorize_scoped` (`authorize.rs:190-216`), returns `FieldMask::FULL` on non-Allow — fail-open in the mask value. + +**So the sentence that is earned is narrower than the one proposed.** Not "the model that needed the function had disappeared" — it never arrived. **The unfinished function was not the debt. The debt is that field-level authorization has no enforced owner on any production path, and the DataFusion rewriter was a second, wrong-layer answer to that vacancy — a storage/query-layer patch for an authorization-layer hole.** Finishing the function would have made the wrong layer *look* finished. + +**What holds, so it is not dragged into the retirement:** the Rubicon lifecycle is SoA-owned and checked — `Planning → CognitiveWork` is a one-way edge in `KanbanColumn`'s DAG (`kanban.rs:98-106`), consulted by `try_advance_phase` (`soa_view.rs:314`) with no mutation on refusal (`:329-346`); `KanbanActor` is a tombstone (`kanban_actor.rs:1-27`); no `Baton` type, no `CollapseGateEmission`, no `CommitHook` exists. RBAC holds no Kanban state; lifecycle code makes no authorization decision; `ogar-loco`/`ogar-r2il` contain no authorization vocabulary. Three v3 docs still name the deleted actor as owner — regraded in place this PR. + +**Rule extracted:** before giving an unfinished function a body, trace the *plan* that would execute it to a binary. A `cfg(feature)` that no Dockerfile sets, a decoder that returns `None`, and a registration helper with no caller are three independent proofs of the same thing, and any one of them ends the "which algorithm" discussion before it starts. "Superseded" is not a verdict about the code; it is a verdict about whether anything reaches it. + +--- + ## 2026-09-05 — E-A-COLUMN-OF-INDICES-INTO-A-CODEBOOK-THAT-DOES-NOT-EXIST-1 — three stale idea cards, each wrong about its own blocker **Status:** FINDING (structural — grep + read of the current tree; nothing compiled). Plan: `.claude/plans/open-ideas-fetch-v1.md`. diff --git a/.claude/board/IDEAS.md b/.claude/board/IDEAS.md index faf31534c..23098a6f5 100644 --- a/.claude/board/IDEAS.md +++ b/.claude/board/IDEAS.md @@ -1193,7 +1193,7 @@ bgz17 crate as the substrate. ### IDEA-POLICY-HASH-UDF — policy_hash_v1 UDF registration (PR #301) -**Status:** In plan 2026-09-05 — blocker is the UDF body, not registration (`policy.rs:137` binds the object); plan `open-ideas-fetch-v1.md` §2 (`D-OIF-1`, decision `D-OIF-1-DEC`) +**Status:** Superseded 2026-09-05 (ruling A) — the DataFusion masking path has no deployed consumer and the operator ruled DataFusion out of planning; retirement plan in `open-ideas-fetch-v1.md` §2 (`D-OIF-1`); `D-OIF-1-DEC` withdrawn **Priority:** P2 **Source:** PR #301 **Author's words:** "`NotYetWiredHashUdf` binds at plan time, returns `NotImplemented('policy_hash_v1 UDF not yet registered')` at execute. Plans build; execution fails loud." diff --git a/.claude/board/INTEGRATION_PLANS.md b/.claude/board/INTEGRATION_PLANS.md index 98994cb9c..52faeaa70 100644 --- a/.claude/board/INTEGRATION_PLANS.md +++ b/.claude/board/INTEGRATION_PLANS.md @@ -4,11 +4,13 @@ 82-day-stale `IDEAS.md` and re-derived from the current tree; **each card was wrong about its own blocker** (`E-A-COLUMN-OF-INDICES-INTO-A-CODEBOOK-THAT-DOES-NOT-EXIST-1`). -- **`policy_hash_v1`** — the blocker is the UDF body, not registration - (`policy.rs:137` binds the object into the `Expr`; `register_vsa_udfs` has - zero callers and its UDFs still execute). `D-OIF-1`; the hash family + key - source is `D-OIF-1-DEC` (recommendation: keyed SipHash-1-3 in-crate, key - bound at rewriter construction; unkeyed FNV-64 recommended against). +- **`policy_hash_v1`** — first re-derived as "the blocker is the body, not + registration"; **superseded the same day by ruling A (plan §2, W0 census):** + the DataFusion masking path has no deployed consumer and redacts above the + scan, and the operator ruled DataFusion out of planning (grace period for + what exists, nothing new). `D-OIF-1` is a retirement plan; `D-OIF-1-DEC` + withdrawn. The field-level obligation's canonical owner (`ClassRbac × + ClassView × WideFieldMask`) is itself unenforced — recorded, not rebuilt. - **Σ-propagation "hardware backends"** — mis-shaped for a 2×2 f64 kernel; the lever is `F64x8` batching with bit identity to the scalar kernel, as consumer code in `jc` (no ndarray change). Zero production call sites @@ -28,7 +30,7 @@ gate (fires on legitimate quiet). §8 lists the four structural claims that execution must confirm before they are believed. §7 carries the per-D Sonnet briefs; nothing is dispatched until the three decisions land. -**Status:** PLANNED — halted for operator decisions D-OIF-1-DEC / 2-DEC / 5-DEC. +**Status:** PLANNED — halted for operator decisions D-OIF-2-DEC / 5-DEC (D-OIF-1-DEC withdrawn, ruling A). ## lance-convergence-staged-migration-v1 (2026-09-05) — MEASURED, stages 0–1 ready, stage 3 PROBE-GATED `.claude/plans/lance-convergence-staged-migration-v1.md`. The staged lance diff --git a/.claude/board/LATEST_STATE.md b/.claude/board/LATEST_STATE.md index 412f25232..311cca44a 100644 --- a/.claude/board/LATEST_STATE.md +++ b/.claude/board/LATEST_STATE.md @@ -2384,6 +2384,8 @@ Paired mirror of OGAR `2c8836f` (two-sided COUNT_FUSE: `lance-graph-ogar` compil --- +> **Correction 2026-09-05 (W0 census, PR #1185 plan §2.5):** the entry below lists `commit_via` / `OgarRbac` / `graph-flow-action::dispatch_via` and "`impl ClassRbac for OgarClassView`" as shipped enforcement. The types exist; **no non-test caller of `commit_via`, `OgarRbac`, `authorize()` or `authorize_scoped()` exists in any repo on disk**, `rs-graph-llm` is not on disk, and `ogar-class-view/src/lib.rs:399` implements `ClassView` only (the RBAC bridge is the separate newtype `OgarRbac`, `rbac_impl.rs:38`, axes 2-4 unimplemented per its own comment `:74-76`). Field-level authorization (`classview_mask ∧ role_mask`) is UNENFORCED on every production path; recorded as the missing implementation on the canonical `ClassRbac × ClassView × WideFieldMask` path (OGAR `DISCOVERY-MAP.md:1581-1584`). The retired DataFusion masking path is not its replacement. + ## 2026-06-23 — IN PR (`claude/medcare-bridge-lance-graph-wmx76z`) — ActionHandler⟷RBAC⟷orchestration spine `contract::rbac`: `ScopeSpec` (axis-3 Copy token) + `ClassRbac` §4 default methods (`roles_reaching`/`row_scope`/`field_mask`; backward-compat, probe green). `contract::class_view::FieldMask::union`. `contract::action::ActionInvocation::commit_via` (no-admin-bypass convergence of the inline gate). `lance-graph-rbac::{authorize_scoped, ScopedDecision}` (§5 two-stage). `lance-graph-ogar::{OgarRbac, GrantSource}` (Q5 local newtype, §6 evaporation seam). rs-graph-llm: `graph-flow-kanban::{run_cycle, CycleOutcome}` + `graph-flow-action::dispatch_via`. Plan: integration-actionhandler-rbac-orchestration-v1. diff --git a/.claude/board/STATUS_BOARD.md b/.claude/board/STATUS_BOARD.md index c4a28c247..89161c778 100644 --- a/.claude/board/STATUS_BOARD.md +++ b/.claude/board/STATUS_BOARD.md @@ -36,8 +36,8 @@ records against itself. | D-id | deliverable | status | |---|---|---| | D-OIF-0 | Re-run `cargo run -p jc --example sigma_probe` on the current tree; record R², verdict, and reconcile the `R²=0.9949` (`bindspace.rs:39`) vs `ρ=0.9973` (`arm-discovery/lib.rs:13`) citations to their sources. Orchestrator-run, no worker. Falsifier: the recorded number is the probe's own printed R², not either citation | Queued (plan `open-ideas-fetch-v1` §4.3) | -| D-OIF-1 | `policy_hash_v1` gets a body: `PolicyHashUdf` (renamed from `NotYetWiredHashUdf`, `policy.rs:279`) with real `invoke_with_args` over Array/Scalar, NULL→NULL, typed byte views, loud `NotImplemented` for unsupported types; `.claude/patterns.md:89` (`NotYetWiredHashUdf`) renamed in the same commit. Gates G1–G8 (§2.4), each disable-named. Falsifier: executing a Hash-masked scan over a 3-row `MemTable` returns 3 distinct non-null `UInt64` | Queued (blocked on D-OIF-1-DEC) | -| D-OIF-1-DEC | **Operator decision:** hash family + key source — A unkeyed FNV-1a-64 (PR #301's stated target; recommended AGAINST: enumerable on identifier columns) / **B keyed SipHash-1-3, 128-bit key, in-crate, key bound at rewriter construction (recommended)** / C SHA-256-64 (`sha2` dep). See plan §2.2 | Decision — operator | +| D-OIF-1 | `policy_hash_v1` — **RULING A, SUPERSEDED (2026-09-05 W0 census, plan §2)**: the DataFusion masking path has no deployed consumer (`ColumnMaskRewriter`'s only constructor is MedCare `patient.rs:150` under default-off `lance-phase2-rbac`, no Dockerfile enables it, decoder stub returns `None`) and redacts above the scan (`policy.rs:210`); operator ruled DataFusion out of planning. Becomes a retirement plan: first removal PR = `RedactionMode::Hash` + `NotYetWiredHashUdf` only; the rest of `policy.rs`/`rls.rs` is grace-period, frozen | Superseded — retirement, no worker | +| D-OIF-1-DEC | ~~hash family + key~~ — **WITHDRAWN 2026-09-05** (ruling A): no hash is chosen because no hash is built; the obligation's canonical owner is `ClassRbac × ClassView × WideFieldMask`, itself unenforced (zero callers of `authorize`/`authorize_scoped`/`commit_via`/`OgarRbac`; `effective_mask` not an identifier) — recorded as the missing implementation on the canonical path, not resurrected on DataFusion | Withdrawn | | D-OIF-2 | `SigmaCodebook([Spd2; 256])` TYPE in the zero-dep contract (`from_le_bytes`/`to_le_bytes`, `entry`, `nearest` via the affine-invariant metric, all-SPD boundary check on load per `sigma_propagation.rs:108`); k-means BUILDER/EMITTER in `jc` (float to build); loaded INSTANCE homed in `cognitive-shader-driver` beside the column it serves. Tag + content invariants, **no digest pin**. Gates G1–G4 (§4.4) | Queued (blocked on D-OIF-2-DEC) | | D-OIF-2-DEC | **Operator decision:** σ provenance — *fitted* (k-means over observed Σ, `sigma_codebook_probe.rs`) vs *declared* (typed-value tuple lookup, `sigma_propagation.rs:74-77`). Recommendation: fitted entries, declared as write-time fallback only. See plan §4.2 | Decision — operator | | D-OIF-3 | First writer of a non-zero σ at the ingest path that today calls `BackingStoreWrite::set_sigma` with a constant (`backing.rs:310`). Falsifier: ≥2 distinct Σ shapes in → ≥2 distinct non-zero σ (can-fire); identical shapes in → one value (stay-silent) | Queued (blocked on D-OIF-2) | diff --git a/.claude/board/SUPERSESSION-INDEX.md b/.claude/board/SUPERSESSION-INDEX.md index 297ab1459..1f4f8aaf5 100644 --- a/.claude/board/SUPERSESSION-INDEX.md +++ b/.claude/board/SUPERSESSION-INDEX.md @@ -14,7 +14,7 @@ ## What this table says **`BindSpace` is the shape of the problem.** Marked RETIRE, and simultaneously the -most-referenced symbol here: **68 crate files, 47 plans, 42 of them blind.** +most-referenced symbol here: **68 crate files, 47 plans, 41 of them blind.** That is a programme, not a cleanup. **`GateState` is the sharpest case: 1 plan names it and *every one* is blind.** @@ -60,11 +60,11 @@ coverage instead. | `GateState` | REPURPOSE | — | 14 | 1 | 1 | | `MergeMode` | REPURPOSE | — | 8 | 13 | 12 | | `ResonanceDto` | REPURPOSE | `PerturbationDto` | 2 | 12 | 7 | -| `BindSpace` | RETIRE | — | 68 | 47 | 42 | +| `BindSpace` | RETIRE | — | 68 | 47 | 41 | | `CollapseGateEmission` | RETIRE | — | 5 | 13 | 12 | | `ThinkingStyle` | RETIRE-toward-contract | — | 51 | 28 | 24 | -## Table 2 — plans naming a ruled symbol without citing the ruling (74) +## Table 2 — plans naming a ruled symbol without citing the ruling (73) Route is **mechanical triage, not a verdict**: `ARCHIVE?` = the plan's own status says it shipped; `RESCOPE` = it targets a symbol marked RETIRE; `READ` = neither signal fires @@ -142,7 +142,6 @@ a licence to act on it. | **RESCOPE** | `lf-integration-mapping-v1` | `BindSpace` | Active (2026-04-25) | 0/0 | | **RESCOPE** | `lite-unified-surrealql-lance-v1` | `BindSpace` | CONJECTURE / design. **Test via feature gate | 0/0 | | **RESCOPE** | `ogit-cascade-supabase-callcenter-v1` | `BindSpace` | plan, not implementation. | 0/16 | -| **RESCOPE** | `open-ideas-fetch-v1` | `BindSpace` | MEASURED / ready-to-execute — PLANNING ONLY | 11/11 | | **RESCOPE** | `q2-foundry-integration-v1` | `BindSpace` | Proposed (2026-04-24) | 0/0 | | **RESCOPE** | `reliability-checklist-arc-v1` | `ThinkingStyle` | PROPOSAL / possibility menu (2026-05-30). NO | 3/3 | | **RESCOPE** | `singleton-to-snapshot-nudge-v1` | `BindSpace` | PROPOSAL | 1/12 | @@ -155,6 +154,6 @@ a licence to act on it. | **RESCOPE** | `unified-soa-rubikon-integration-v1` | `BindSpace` | — | 8/8 | - **ARCHIVE?**: 0 -- **RESCOPE**: 56 +- **RESCOPE**: 55 - **READ**: 18 - ruled symbols tracked: 14 diff --git a/.claude/plans/open-ideas-fetch-v1.md b/.claude/plans/open-ideas-fetch-v1.md index 2834141d5..78341672d 100644 --- a/.claude/plans/open-ideas-fetch-v1.md +++ b/.claude/plans/open-ideas-fetch-v1.md @@ -24,7 +24,7 @@ | card (IDEAS.md) | what the card says | what the tree says | |---|---|---| -| `IDEA-POLICY-HASH-UDF` (`:1162`) | "policy_hash_v1 UDF **registration**" | Registration is not the blocker. The UDF is bound as an `Arc` **object inside the `Expr`** (`policy.rs:137`), and DataFusion executes the embedded object without any by-name lookup — proof: `register_vsa_udfs` (`vsa_udfs.rs:574`) has **zero callers** in the tree and its UDFs still execute in tests. The blocker is the **body**: `invoke_with_args` returns `NotImplemented` (`policy.rs:~330`). | +| `IDEA-POLICY-HASH-UDF` (`:1162`) | "policy_hash_v1 UDF **registration**" | Registration is not the blocker. The UDF is bound as an `Arc` **object inside the `Expr`** (`policy.rs:137`), and DataFusion executes the embedded object without any by-name lookup — proof: `register_vsa_udfs` (`vsa_udfs.rs:574`) has **zero callers** in the tree and its UDFs still execute in tests. The blocker is the **body**: `invoke_with_args` returns `NotImplemented` (`policy.rs:~330`). **Superseded the same day (§2, W0 census): the body was never the blocker either — the DataFusion masking path has no deployed consumer, and the operator ruled DataFusion out of planning. Ruling A: retire.** | | `IDEA-B1-HARDWARE-BACKENDS` (`:1062`) | "AMX/MKL backends for sigma_propagation, waits on ndarray #119/#121" | The kernel is a **2×2 f64** sandwich — three scalars, 12 mul + 6 add (`sigma_propagation.rs:210-227`). An AMX tile is 16×16 bf16/int8; an MKL `dgemm` call costs more than the 18 flops it would do. The idea is **mis-shaped for its own kernel**. The real lever is vertical batching — `F64x8` (8 edges/instruction), whose `Mul`/`Add` already exist on every backend. AND: `ewa_sandwich(` has **zero production call expressions** outside `jc` + the contract (grep, §3.2) — every "caller" is a doc-comment mention. | | `IDEA-CAUSAL-EDGE-TENSOR-SIDECAR` (`:1126`) | "design a 9-byte sidecar (`CausalEdge64` + 1 byte Σ index) OR Block 14/15" | **The 1-byte index already shipped, as a SoA column** — `BindSpace.fingerprints.sigma: Box<[u8]>` (`bindspace.rs:54-58`), `MailboxSoA.sigma: [u8; N]` (`mailbox_soa.rs:125-133`), `set_sigma` (`:670`), `BackingStoreWrite::set_sigma` both arms (`backing.rs:253-257`). Neither the sidecar nor Block 14/15 is live. **What does NOT exist is the codebook the index points at** — §4. | @@ -38,51 +38,74 @@ - **The falsifiability rule** (`CLAUDE.md`): every guard needs a can-fire AND a can-stay-silent test on non-trivial inputs; a threshold needs an inertness test; a doc claim is not a behaviour. - **Sonnet workers: edit-only, no `cargo`, no `git`, disjoint files; the orchestrator compiles once** (`agent-cargo-hygiene.md`; `sonnet-worker-guardrails.md` §1 pasted verbatim into every brief). -## 2. D-OIF-1 — `policy_hash_v1`: give the UDF a body +## 2. D-OIF-1 — `policy_hash_v1`: RULING A, SUPERSEDED — a retirement plan, not a crypto task -### 2.1 Evidence +> **Re-derived 2026-09-05 (W0 architecture census, four read-only Opus tracers + orchestrator verification).** +> The previous §2 asked "which hash?". That question was one abstraction generation behind: it assumed the DataFusion policy-rewriter execution model still owned field-level authorization. The census below shows it never reached a binary, and the operator ruled the same day: **"every planning is in migration to ogar-loco and ogar-r2il; DataFusion is out of the picture; what exists gets a grace period; nothing new will migrate to it."** A hash body for `policy_hash_v1` is *new* work on the DataFusion path and is barred by that ruling regardless of the census. No hash family is chosen; `D-OIF-1-DEC` is **withdrawn**. -- `crates/lance-graph-callcenter/src/policy.rs:120-140` — `mask_expr` binds `NotYetWiredHashUdf::new()` as an `Arc` inside a `ScalarFunction` expr. -- `:262-335` — the impl: `Signature::any(1, Volatility::Immutable)`, `return_type = UInt64` (already fixed so downstream schemas are stable), `invoke_with_args → Err(NotImplemented("policy_hash_v1 UDF not yet registered — see PR-F1b"))`. The header comment names **FNV-64 as the v1 target**. -- Feature gate: `auth-rls-lite = ["auth-jwt", "query-lite"]`, `query-lite = ["dep:datafusion", "dep:arrow"]` (`Cargo.toml` `[features]`). `datafusion` WITHOUT default features. -- Existing test `redaction_mode_hash_binds_not_yet_wired_udf` (`:598-620`) asserts **plan text only** (`contains("policy_hash_v1")`, `!contains("***REDACTED***")`). It stays green after the fix and is therefore **not** a falsifier of the body. New tests must EXECUTE the plan. -- Execution pattern in this crate: `graph_table.rs:196-229` — `#[tokio::test]`, `MemTable::try_new`, `ctx.register_table`, `df.collect().await`, under `#[cfg(feature = "query")]`. Policy tests today build plans against an **empty** `MemTable` (`policy.rs:530`). `tokio` is already a dev-dep with `rt-multi-thread` + `macros`. -- Array-vs-Scalar handling to copy: `vsa_udfs.rs:88-89` (unwrap) and `:201-204` (length resolution). -- Live docs naming the type: `.claude/patterns.md:89` (`NotYetWiredHashUdf`) — a live inventory, **update in the same commit**. `PR_ARC_INVENTORY.md:5734` and `LATEST_STATE.md:2753` are append-only history — leave. +### 2.1 Tree verdict (production census; "production" = a real call chain from a binary / server handler, never `pub mod`, a feature flag, a registration helper, a test, or a doc comment) -### 2.2 DECISION D-OIF-1-DEC — hash family and key (operator's; recommendation stated) +1. `ColumnMaskRewriter` has exactly one non-test constructor in all seven repos: `MedCare-rs/crates/medcare-server/src/routes/patient.rs:150`, inside `get_one_via_lance` (`:85`, `#[cfg(feature = "lance-phase2-rbac")]`), reached only for `?source=lance` (`:52-53`). +2. `lance-phase2-rbac` is default-off (`medcare-server/Cargo.toml:215` `default = []`) and **no Dockerfile enables it** (`docker/Dockerfile.railway:175`, `Dockerfile.railway.OCR:49`, `Dockerfile.reasoning` all build `lance-phase2,reasoning`). +3. Even when compiled, the path's row decoder `record_batch_to_patient` (`patient.rs:200-211`) is a stub that logs and returns `None`; the handler 500s. No user has ever received a masked row from this path. +4. The rewriter redacts **above the scan**: `rewrite_plan` (`policy.rs:210`) maps expressions and `recompute_schema`s; `TableScan.projection` is never written (`extract_table_name` `:226-241` only reads it). The forbidden column is scanned from Lance, materialized, then overwritten — post-hoc redaction, the exact anti-pattern the invariant forbids. +5. `RedactionMode::Hash` (`policy.rs:130-140`) binds `NotYetWiredHashUdf`; any plan containing it fails at execute with `NotImplemented` (`:339`). `policy_hash_v1` has no implementation and no `register_udf` anywhere. `register_vsa_udfs` (`vsa_udfs.rs:574`) has zero callers in all repos. +6. `PolicyRewriter` (`policy.rs:56`) has one impl and `dyn PolicyRewriter` appears nowhere — a one-impl indirection, not a policy VM. +7. The replacement path is **also not enforced**: `lance-graph-rbac::authorize()`/`authorize_scoped()` (`authorize.rs:66,182`), `contract::ClassRbac` (`rbac.rs:143`), `ActionInvocation::commit_via` (`action.rs:327`) and `lance-graph-ogar::OgarRbac` (`rbac_impl.rs:38`) have **zero non-test callers**. `effective_mask` is not an identifier in any `.rs` file. There is no `ogar-rbac` crate; `ogar-auth` is authentication only (password/TOTP). +8. MedCare's live authorization is entity-string keyed: `patient.rs:280 bridge.authorize_read("Patient", …)` → `lance-graph-rbac::policy::Policy` → `AccessDecision`. No mask reaches it. Field projection in production is `views/project.rs:229` (`WideFieldMask::from_positions` from a **view** spec, no role operand) — a view mask, not RBAC. +9. The only genuine `surface ∩ role` fail-closed projection is `a2ui-server/src/project.rs:70-83` (`WideFieldMask::intersect`, `NoRoleGrant` on empty role) — and `a2ui-server` has no `[[bin]]`, no `main`, and no dependent crate. +10. Rubicon/Kanban: no actor/controller survives (`kanban_actor.rs:1-27` tombstone: "All of it is DELETED"); the crossing `Planning → CognitiveWork` is a checked one-way edge (`kanban.rs:98-106`, `can_transition_to` consulted by `try_advance_phase` `soa_view.rs:314`, no mutation on refusal `:329-346`). `try_advance_phase` has one non-test caller (`cycle_driver.rs:560`) that is itself reached only from tests/examples. RBAC code holds no Kanban state; lifecycle code makes no authorization decision; loco/r2il make no authorization decision. -| option | what | verdict | -|---|---|---| -| A — FNV-1a-64, unkeyed | what PR #301 named as "v1 target" | **Do not ship as the default.** A masked column is by definition an identifier; unkeyed 64-bit hashing of a low-entropy identifier is reversible by enumeration. It would *look* redacted in every plan and be a lookup table in practice. | -| B — **keyed SipHash-1-3, 128-bit key, in-crate** | ~60 LOC, zero new dependency, deterministic across Rust versions (std's `DefaultHasher` is SipHash-1-3 but **explicitly not stable across releases** and unkeyed — unusable for a persisted pseudonym) | **Recommended.** Same input + same key → same hash (joins still work); different key → different pseudonym space (a deployment's masked values are useless elsewhere). | -| C — SHA-256 truncated to 64 | needs `sha2` (crates.io, no fork) | Acceptable, one more dep for no property B lacks at this width. | +**So:** the invariant «forbidden fields absent from the authorized projection, not materialized and masked by a UDF» is *violated by the only field-level mechanism that was ever written* (item 4) and *satisfied by nothing that is deployed* (items 7–9). The invariant «a Rubicon transition is an SoA-owned mutation, not an actor command» **holds** in code (item 10) and is contradicted only by stale prose (§2.5). -**Key source (part of the decision):** the key must be **bound at rewriter construction**, never read from the environment inside the UDF (the UDF is `Immutable` and must be a pure function of its inputs). Proposed shape: `ColumnMaskRewriter { registry, actor_role, hash_key: [u8; 16] }`; `mask_expr` becomes a method and builds `PolicyHashUdf::new(self.hash_key)`. The **membrane** (the caller that already holds `actor_role`) supplies the key from its own config. Two rewriters, two keys, is the falsifier that proves the key is load-bearing. +### 2.2 Obligation table -### 2.3 Deliverable +| old obligation | current owner | production evidence | action | +|---|---|---|---| +| `policy_hash_v1` UDF body (`IDEA-POLICY-HASH-UDF`, PR #301) | none — the DataFusion policy path | items 1–5: no deployed consumer; execute → `NotImplemented` | **RETIRE.** No body, no hash choice. `D-OIF-1-DEC` withdrawn | +| `RedactionMode::Hash` | same | binds a UDF that cannot execute | **REMOVE with the cone** (§2.3) — a landmine, not a mode | +| `NotYetWiredHashUdf` / `policy_hash_v1` | same | `policy.rs:279-339`, zero registrations | **REMOVE with the cone** | +| `ColumnMaskRewriter` / `ColumnMaskRegistry` / `RedactionMode::{Null,Constant,Truncate}` / `PolicyRewriter` / `PolicyKind` | same (`policy.rs`) | one gated, undeployed, stub-terminated MedCare caller | **GRACE PERIOD** (operator ruling): retained as-is, regraded SUPERSEDED, frozen — no new work, no new callers. Removal is its own PR once MedCare's `lance-phase2-rbac` feature is retired (`patient.rs:85-211`, `state.rs` `column_mask_registry`/`rls_registry`/`session_context`, `medcare-analytics::column_mask_bridge`) | +| `RlsRewriter` (`rls.rs`) | same | same single caller (`patient.rs:146`) | **GRACE PERIOD**, same cone, same condition. Not a policy VM: a tenant predicate — but on the retired path | +| `register_vsa_udfs` (`vsa_udfs.rs:574`) | none | zero callers, any repo | **REMOVE** candidate; separate from the policy cone (it is `query`-gated, not `auth-rls-lite`). Not touched in this PR | +| DataFusion RLS / optimizer-rule registration | `patient.rs:146-150` only | the only `with_optimizer_rule` in any repo | **GRACE PERIOD** with the MedCare feature | +| `unified_bridge.rs` `authorize_{read,write,act}` | `lance-graph-callcenter` | live: `patient.rs:280` | **RETAIN.** Entity-level allow/deny before SQL; never touches a plan | +| Field-level authorization (the obligation `policy_hash_v1` was one arm of) | **VACANCY** on the canonical path: `ClassRbac × ClassView × WideFieldMask` | items 7–9 | **RECORD as the missing implementation** on the canonical OGAR/ClassView path (OGAR already says so: `DISCOVERY-MAP.md:1581-1584`, `DOCIR-COMPOSITION-GROUNDING.md:75`, `PROBE-OGAR-RBAC-AUTHORIZE`). Not resurrected on DataFusion. Not built in this plan | +| `authorize_scoped` mask fold | `lance-graph-rbac/authorize.rs:199-216` | zero callers; folds a **union** over roles and returns `FieldMask::FULL` on non-Allow (`:190-196`) — fails OPEN in the mask | **REGRADE** to "TRANSPORT ONLY, fail-open in the mask value" — a design defect to fix on the canonical path, not evidence for the old one | +| Rubicon lifecycle | `MailboxSoaOwner::try_advance_phase` + `KanbanColumn` DAG | item 10 | **RETAIN**, no change. Prose corrections only (§2.5) | +| Thinking/planning | `ogar-loco` (one live consumer: `medcare-cohorts/ddx_loco.rs` ← `views/zugfolge.rs:534`); `ogar-r2il` (probe/test only); planner `thinking/`,`mul/`,`strategy/` linked into medcare-server but uncalled | no DataFusion UDF or rule performs reasoning on any production path (`datafusion_planner/udf.rs:130-663` is vector/hamming distance only) | hypothesis **confirmed for DataFusion** (it never owned reasoning in production); **partially confirmed for loco/r2il** (loco live, r2il probe-only). Nothing to move | + +### 2.3 Remove / retain / regrade (exact) + +- **REMOVE now (this arc, own PR, after grace-period sign-off):** nothing is deleted in #1185. The *first* removal PR is scoped to the dead-by-construction pieces only — `RedactionMode::Hash` + `NotYetWiredHashUdf` + the `policy_hash_v1` name (`policy.rs:130-140, 262-339`) and the test `redaction_mode_hash_binds_not_yet_wired_udf` (`:598-620`) — because they cannot execute today and no grace-period consumer can depend on them. Disable-run: removing the variant must break exactly that test and nothing else. +- **GRACE PERIOD (frozen, regraded SUPERSEDED, no new callers):** `policy.rs` remainder (`PolicyRewriter`, `PolicyKind`, `ColumnMaskRegistry`, `ColumnMaskPolicy`, `ColumnMaskRewriter`, `RedactionMode::{Null,Constant,Truncate}`), `rls.rs`, the `lib.rs:114-125` / `:93-99` gates, feature `auth-rls-lite`; MedCare `patient.rs:52-54, 85-211`, `state.rs` `column_mask_registry` / `rls_registry` / `session_context` / `build_session_context`, `medcare-analytics/src/column_mask_bridge.rs`. Removal condition: MedCare retires `lance-phase2-rbac` (its own private-repo PR) — then the callcenter cone falls in one PR. +- **RETAIN, untouched:** `lance-graph-python/src/graph.rs` (`SessionContext` `:1208,:1518`), `lance-graph-catalog/src/{connector,table_reader}.rs`, `holograph/src/storage.rs`, `callcenter/src/{graph_table,filter_expr,lance_membrane,unified_bridge}.rs`, `callcenter/src/bin/audit_verify.rs` + `audit.rs` (Lance dataset open), `lance-graph-planner/src/optimize/` (an in-house `OptimizerRule` trait of the same name, unrelated), MedCare `views/project.rs` + `medcare-rbac`, `tesseract-paperless/src/store.rs`. These are storage/query translation over Lance — the grace-period storage layer, not the policy VM. +- **REGRADE (board):** `IDEA-POLICY-HASH-UDF` → Superseded; `D-OIF-1` → Superseded (retirement plan); `D-OIF-1-DEC` → Withdrawn; `LATEST_STATE.md:2389,2393` claims (see §2.5) get a dated correction line, not an edit. + +### 2.4 Layer audit (Rubicon / Heckhausen vocabulary) + +| layer | owner in code | impersonation found? | +|---|---|---| +| 1 Lifecycle control | `KanbanColumn` DAG (`kanban.rs:98-106`) + `MailboxSoaOwner::try_advance_phase` (`soa_view.rs:311`); Planning = pre-decisional, `Planning→CognitiveWork` = the Rubicon crossing, `CognitiveWork` = actional, `Evaluation` = post-actional, `Commit`/`Plan`/`Prune` = outcomes; `Planning→Prune` = pre-Rubicon veto | none. `Commit`'s calcify step is DECLARED only (`kanban.rs:48-56`) | +| 2 Action semantics | `ActionState` (OGAR `ogar-vocab/lib.rs:676` canonical wire type; contract `action.rs:44` the Rust mirror, unconsumed), `ActionDef`, `KausalSpec`, `ActionInvocation::commit` | `commit` inlines its own RBAC check (`action.rs:283`) — documented design, not drift. `CommitHook` **does not exist** (prose only) | +| 3 Authorization | contract `rbac.rs` + `lance-graph-rbac` (types + un-called kernel); live gate = string-keyed `Policy` | none on lifecycle. The ClassView∧role fold is unbuilt | +| 4 Execution/reasoning | `ogar-loco` (live), `ogar-r2il` (probe), planner thinking (linked, uncalled) | none: zero authorization words in loco/r2il | +| 5 Storage/query | Lance / DataFusion (B1–B9 in the census) | the one policy hook (`patient.rs:146-150`) is on the undeployed path; DataFusion owns no lifecycle state | -- `PolicyHashUdf` (rename; `NotYetWiredHashUdf` is now a false name) in `policy.rs`, same `Signature`/`return_type`, `invoke_with_args` implemented over `ColumnarValue::{Array, Scalar}`: - - NULL → NULL (Arrow null propagation), never the hash of an empty string. - - Hashed byte view per type: `Utf8`/`LargeUtf8`/`Utf8View` (UTF-8 bytes), `Binary`/`LargeBinary`/`BinaryView` (bytes), `Boolean` (one byte), `Int8..Int64`/`UInt8..UInt64` (little-endian bytes of the widened `i64`/`u64` — so `Int32(5)` and `Int64(5)` hash equal; document it), `Float32`/`Float64` (IEEE bits of the `f64` widening; `-0.0 ≠ 0.0` — document it), `Date32/64`, `Timestamp(*)` (the underlying integer's bytes). - - Any other type → `DataFusionError::NotImplemented` naming the type — **loud, and enumerated in the doc comment**, never a silent constant. -- `policy_hash_udf(key) -> Arc` + `register_policy_udfs(ctx, key)` for SQL-text callers, mirroring `register_vsa_udfs` — a convenience, **not** the deliverable (see §0). -- `.claude/patterns.md:89` (`NotYetWiredHashUdf`) updated to the new name. +**The one category error worth naming:** the prior plan treated *authorization* (layer 3) as a *storage/query* concern (layer 5) because the only code that existed lived there. The census shows layers 3 and 5 are currently **disjoint**, not layered — where ClassView×mask genuinely governs columns (MedCare `views/`, atlas/graph reads of the resident bake), DataFusion and Lance are not in the path at all. -### 2.4 Pre-registered gates (each red-then-green; the disable is named) +### 2.5 Stale prose contradicted by the tree (corrected in this PR where the file is ours and non-append-only; dated correction lines elsewhere) -| # | assertion | non-trivial input | disable that must turn it red | -|---|---|---|---| -| G1 | executing a Hash-masked scan over a `MemTable` with ≥3 real rows returns `UInt64`, non-null for non-null inputs | 3 distinct strings | restore `Err(NotImplemented)` | -| G2 | determinism: two separate `SessionContext`s + two rewriters with the SAME key give identical column values | same 3 strings | perturb the key in one rewriter | -| G3 | discrimination: 3 distinct inputs → 3 distinct hashes; and the two equal inputs among 4 → equal hashes | `["a","b","a","c"]` | return a constant | -| G4 | key is load-bearing: two rewriters with DIFFERENT keys give different values for the same input | same string | ignore the key in `invoke` | -| G5 | NULL → NULL; the null count of the output equals the null count of the input | a column with 2 nulls of 5 | hash `""` for nulls | -| G6 | an unsupported type fails LOUD at execute with the type in the message (can-fire); a supported type does NOT (stay-silent) | `List` vs `Utf8` | make the fallback return `0` | -| G7 | the old `:598` test still passes unchanged (plan text) — proves the rewrite site did not move | as-is | n/a (regression) | -| G8 | `cargo clippy -p lance-graph-callcenter --features auth-rls-lite -- -D warnings` clean; `cargo test -p lance-graph-callcenter --features auth-rls-lite` green | — | — | +- `a2ui-rs/CLAUDE.md` § "RBAC is real": "`ClassRbac::field_mask` is being retyped to `WideFieldMask` … `WideFieldMask::ALL`" — `rbac.rs:176` still returns `FieldMask` (u64); `WideFieldMask::ALL` does not exist (`class_view.rs:275` has only `EMPTY`; `full_for` `:360`). *(a2ui-rs repo; not touched here — filed for that repo.)* +- `OGAR/crates/ogar-a2ui-frame/src/lib.rs:32`: states the C1.4 retype as done. *(OGAR repo; not touched here.)* +- `LATEST_STATE.md:2389` lists `commit_via` / `OgarRbac` / `graph-flow-action::dispatch_via` as shipped enforcement — the types exist, the callers do not; `rs-graph-llm` is not on disk. `:2393` "`impl ClassRbac for OgarClassView`" — no such impl (`ogar-class-view/lib.rs:399` impls `ClassView` only). *(Append-only: dated correction line added in this PR.)* +- `.claude/v3/knowledge/mailbox-kanban-model.md:30`, `.claude/v3/COMPONENT-MAP.md:79` ("EXTEND"), `.claude/v3/knowledge/write-on-behalf.md:8` (`ACTOR-OWNED`) and `:68`: present `kanban_actor.rs`/`KanbanActor` as the structural owner / pending W1 work — deleted 2026-08-05 (`kanban_actor.rs:1-27`; `LATEST_STATE.md:1824,1860`). *(Corrected in this PR: dated supersession notes, in place.)* +- This plan's own §0 row 1 and `INTEGRATION_PLANS.md` entry: "the blocker is the UDF body" — true as far as it went and still one generation behind; superseded by this §2. +- `.claude/patterns.md:89` names `NotYetWiredHashUdf` as a live pattern — left as-is until the removal PR lands, then updated in that commit. + +### 2.6 What this plan does NOT do (hard constraints honoured) -**§8 caveat feeding G1:** `DataFrame::collect()` under `query-lite` (datafusion without default features) is **assumed** to compile — the physical planner is core, `sql` is not needed. If it does not, the execution tests move under `#[cfg(feature = "auth-rls")]` (`= query`) and the plan says so; that is a scope note, not a failure. +No hash body, no hash choice, no new actor/controller, no new lifecycle carrier, no new policy VM, no SoA widening, no RBAC moved into loco/r2il, no Rubicon state moved into RBAC, no deletion in this PR, and DataFusion registration was never counted as ownership evidence. ## 3. D-OIF-4 / D-OIF-5 — Σ-propagation: the batched kernel and the hop probe @@ -181,7 +204,7 @@ Whichever provenance the decision picks, the first writer is the ingest/write pa ```text D-OIF-0 probe re-run (jc, seconds) ── unconditional, first -D-OIF-1 policy_hash_v1 body ── independent; needs D-OIF-1-DEC (hash + key) +D-OIF-1 policy_hash_v1 RETIRED (ruling A) ── withdrawn 2026-09-05; no worker, no decision D-OIF-4 ewa_sandwich_x8 (jc) ┐ D-OIF-5 hop re-quant probe ┘ paired ── D-OIF-5 arm 1 needs no artifact D-OIF-2 SigmaCodebook type + builder + home ── needs D-OIF-2-DEC (fitted vs declared) @@ -190,13 +213,13 @@ D-OIF-7 loaded instance + loader (cognitive-shader-driver) ── needs D-OIF-2 D-OIF-6 IDEAS ledger: 4 entries + 3 flips ── THIS PR ``` -Three decisions stand between the plan and the workers: **D-OIF-1-DEC**, **D-OIF-2-DEC**, **D-OIF-5-DEC**. D-OIF-0, D-OIF-4, D-OIF-5 (arm 1) and D-OIF-6 need none. +Two decisions stand between the plan and the workers: **D-OIF-2-DEC**, **D-OIF-5-DEC** (D-OIF-1-DEC withdrawn under ruling A, §2). D-OIF-0, D-OIF-4, D-OIF-5 (arm 1) and D-OIF-6 need none. ## 7. Worker briefs (Sonnet, edit-only; the orchestrator compiles once) Every brief starts with `sonnet-worker-guardrails.md` §1 **verbatim**, then: *Read `.claude/board/AGENT_LOG.md` first; do NOT write it — leave your record in your own tag-file. Do NOT run `cargo` or `git`. Do not claim it compiles or that tests pass — you did not run them. Your file scope is exactly the files named; another worker owns everything else.* -- **W-1 (D-OIF-1)** — files: `.claude/patterns.md:89` (`NotYetWiredHashUdf`), `crates/lance-graph-callcenter/src/policy.rs`. Spec: §2.3 + the decided hash/key from D-OIF-1-DEC. Tests: §2.4 G1-G7 as `#[tokio::test]` under `auth-rls-lite`, each with its disable named in a comment. STOP if `DataFrame::collect` does not resolve under `query-lite` — report, do not change features. +- **W-1 (D-OIF-1)** — **WITHDRAWN 2026-09-05 (ruling A, §2).** No worker. The first removal PR (§2.3 bullet 1) is orchestrator work after grace-period sign-off, not a Sonnet brief. - **W-4 (D-OIF-4)** — files: `crates/jc/src/ewa_sandwich.rs` (append only below the existing kernel), `crates/jc/examples/ewa_sandwich_bench.rs` (new). Spec: §3.2; **no `mul_add`, ever**; same op order per lane as `:185-199`. Tests: §3.5 G1-G2 with the disable named. STOP if any test needs a tolerance — that is a bug, not a tolerance. - **W-5 (D-OIF-5)** — files: `crates/jc/src/sigma_hop_requant_probe.rs` (new), `crates/jc/src/lib.rs` (one `pub mod` line + one pillar-table entry, `lib.rs:150-185` shape). Spec: §3.4. Output: the table `n → (exact growth, requantized growth, bound, PASS/FAIL)` printed by `prove`. - **W-2 (D-OIF-2, after D-OIF-2-DEC)** — files: `crates/lance-graph-contract/src/sigma_propagation.rs` (type + loader + boundary check, zero deps), `crates/jc/src/sigma_codebook_probe.rs` (emitter arm). Spec: §4.4, gates G1-G4. diff --git a/.claude/v3/COMPONENT-MAP.md b/.claude/v3/COMPONENT-MAP.md index c5022e6ca..28956a475 100644 --- a/.claude/v3/COMPONENT-MAP.md +++ b/.claude/v3/COMPONENT-MAP.md @@ -76,7 +76,7 @@ Meta/Plasticity widths differ persisted-vs-hot with no parity test; | `physical/collapse.rs::CollapseOp` + Strategy #10 | REPURPOSE (rename) | per-query resonance-dispersion gate — NOT the retired singleton; rename candidate (`ResonanceDispersionGate`) to end the vocabulary collision | | `cache/` + `serve.rs` | REUSE | autocomplete/thinking cache; serve.rs is LAB surface | | symbiont `SymbiontBoard` (kanban_loop.rs) | EXTEND | POC proves the loop shape + the −550_000 µs Libet anchor **in code**; gap: `phase` is a bare struct field, not tenant-shaped (W2a); Domino work is called, not free-running — the standing-async-plan is NOT yet realized | -| supervisor `KanbanActor` | EXTEND | the most complete arm: S2 atomic MUL-gate-advance, S3 tick, S4 registry delivery, codex #578/#579 fixes tested; gap: unit-proven on TestBoard only, never integration-driven over a real MailboxSoA | +| supervisor `KanbanActor` | EXTEND | the most complete arm: S2 atomic MUL-gate-advance, S3 tick, S4 registry delivery, codex #578/#579 fixes tested; gap: unit-proven on TestBoard only, never integration-driven over a real MailboxSoA ⊘ **STALE (2026-09-05 W0 census):** `KanbanActor`/`KanbanMsg` + the RPC drivers were DELETED 2026-08-05 (`kanban_actor.rs:1-27` tombstone; `LATEST_STATE.md:1824,1860` — "KanbanActor has no assigned architectural responsibility"). The owner is `MailboxSoaOwner::try_advance_phase` (`soa_view.rs:311`) over the `KanbanColumn` DAG; `&mut` is the serialization. Do not extend or await this symbol. | | **ahead-firing batch writer** | NEW | zero code fires a kanban update at write CAST anywhere (grep-confirmed); lands as a new module wrapping BusDto commits, reading `envelope.mailbox_owner()` | | **delegation cache** | NEW | no delegation concept exists anywhere; small keyed cache inside the batch writer | | surreal_container | BLOCKED→flip-on | **coordinates RESOLVED 2026-06-16**; remaining block is the deliberate cold-build gate (`BlockedColdBuild`) — arm #2 is one dependency-uncomment away, at a ~10 min cold-build cost | diff --git a/.claude/v3/knowledge/mailbox-kanban-model.md b/.claude/v3/knowledge/mailbox-kanban-model.md index f08d2fba1..c3e39843e 100644 --- a/.claude/v3/knowledge/mailbox-kanban-model.md +++ b/.claude/v3/knowledge/mailbox-kanban-model.md @@ -27,7 +27,7 @@ proposes; the owner disposes. |---|---|---| | **Arm #1 — planner** | `lance-graph-planner/src/strategy/style_strategy.rs` | The D-MBX-A6 seam: the deferred `Outcome → Candidate/KanbanMove` adapter. Strategy outcomes (converged, cycle_count, gate verdicts) become kanban moves. | | **Arm #2 — symbiont** | `crates/symbiont` (`kanban_loop.rs` = POC) | SurrealDB-on-kv-lance executor: kanban updates as KV transactions on the same Lance substrate. Gated on the AdaWorldAPI surrealdb fork `kv-lance` feature. | -| **Structural owner** | `lance-graph-supervisor/kanban_actor.rs` | ractor actor per mailbox. **ractor is SOLELY the compile-time ownership guarantee** (name the role — the attestation must stay authoritative to the compiler; operator, 2026-07-17) — it spawns and proves single-ownership via move semantics (`KanbanActor` with `type State = O`; the owner MOVES in at `pre_start`); it is NOT a data-plane bus and **not for messaging — it is slow** (operator, 2026-07-02). **It MAY serve as a HELPER where it makes sense** — spawn, supervision, occasional control RPC like the serialized Advance/MulAdvance (the codex #578 atomicity mechanism) — always keeping the speed difference in mind: nothing on the hot path may wait on ractor latency; hot-path dispatch belongs to the D-V3-W2e-probed ExecTarget. | +| **Structural owner** | `lance-graph-supervisor/kanban_actor.rs` | ractor actor per mailbox. **ractor is SOLELY the compile-time ownership guarantee** (name the role — the attestation must stay authoritative to the compiler; operator, 2026-07-17) — it spawns and proves single-ownership via move semantics (`KanbanActor` with `type State = O`; the owner MOVES in at `pre_start`); it is NOT a data-plane bus and **not for messaging — it is slow** (operator, 2026-07-02). **It MAY serve as a HELPER where it makes sense** — spawn, supervision, occasional control RPC like the serialized Advance/MulAdvance (the codex #578 atomicity mechanism) — always keeping the speed difference in mind: nothing on the hot path may wait on ractor latency; hot-path dispatch belongs to the D-V3-W2e-probed ExecTarget. ⊘ **STALE (2026-09-05 W0 census):** `KanbanActor`/`KanbanMsg` + the RPC drivers were DELETED 2026-08-05 (`kanban_actor.rs:1-27` tombstone; `LATEST_STATE.md:1824,1860` — "KanbanActor has no assigned architectural responsibility"). The owner is `MailboxSoaOwner::try_advance_phase` (`soa_view.rs:311`) over the `KanbanColumn` DAG; `&mut` is the serialization. Do not extend or await this symbol. | ## The trigger: kanbanstep. There is no ack — the concept is ELIMINATED (operator, 2026-07-10/17) diff --git a/.claude/v3/knowledge/write-on-behalf.md b/.claude/v3/knowledge/write-on-behalf.md index 939d0231f..5dc285b2c 100644 --- a/.claude/v3/knowledge/write-on-behalf.md +++ b/.claude/v3/knowledge/write-on-behalf.md @@ -5,7 +5,7 @@ > ladybug-rs), and any session adding a write path to SoA rows / Lance > datasets / tenant lanes. -## Status: FINDING (operator-ruled 2026-07-02; batch writer + `owner_adapter` write-on-behalf cast SHIPPED 2026-08-01; `cycle_driver.rs` `cognitive_pass` is the existing production caller of `emit_bootstrap_intent` — HashMap-probe-fleet-driven; the first ACTOR-OWNED `KanbanActor` caller is the open W1 work, plan `kanban-64k-inverted-awareness-v1` D-KIA-A1) +## Status: FINDING (operator-ruled 2026-07-02; batch writer + `owner_adapter` write-on-behalf cast SHIPPED 2026-08-01; `cycle_driver.rs` `cognitive_pass` is the existing production caller of `emit_bootstrap_intent` — HashMap-probe-fleet-driven; the first ACTOR-OWNED `KanbanActor` caller is the open W1 work, plan `kanban-64k-inverted-awareness-v1` D-KIA-A1) ⊘ **STALE (2026-09-05):** `KanbanActor` was deleted 2026-08-05; there is no actor-owned caller to await — see `LATEST_STATE.md:1860`. --- From 23b062354a36e5abfa7f71072b60ce9ad2cef8a1 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 5 Sep 2026 16:33:49 +0000 Subject: [PATCH 4/9] open-ideas-fetch-v1: reconcile with the #1188 D-OIF-1 census MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - §1 frozen decision: masking is projection-side, never a DataFusion rewrite (operator ruling, E-PLANNING-MIGRATES-TO-LOCO-R2IL-DATAFUSION- IS-GRACE-PERIOD-1 on #1188) - §2 cross-ref: the #1188 census scanned lance-graph only; the extra MedCare constructor is why the removal cone is narrower than 'delete policy.rs entire'; one epiphany, not two - grace-period cone widened to the same-shape stubs #1188 named (RowEncryptionPolicy / DifferentialPrivacyPolicy, datafusion-dispatch / datafusion-plan / postgrest dispatcher / with_rls) Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01DCfrD5y19cvFc4AoyydXYv --- .claude/plans/open-ideas-fetch-v1.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.claude/plans/open-ideas-fetch-v1.md b/.claude/plans/open-ideas-fetch-v1.md index 78341672d..f1f49a053 100644 --- a/.claude/plans/open-ideas-fetch-v1.md +++ b/.claude/plans/open-ideas-fetch-v1.md @@ -35,12 +35,15 @@ - **Bit identity between the jc kernel and the contract copy is CI law** — `jc::ewa_sandwich::tests::the_contract_copy_matches_the_certified_kernel_bit_for_bit` (`ewa_sandwich.rs:~425`, 1000 sampled SPD pairs, `to_bits()`, no tolerance; `jc-proof.yml`). Any batched kernel joins that law or does not land. - **Internal head pins are absolutely and permanently prohibited** (MedCare-rs `CLAUDE.md`, operator 2026-08-30). A frozen codebook artifact gets a **tag + content invariants**, never a digest gate. - **Indices, not content** (`I-VSA-IDENTITIES`; `mailbox_soa.rs:128-131`): the codebook stays shared/cold; rows carry the 1-byte reference. +- **Masking is projection-side, never a DataFusion rewrite** (operator ruling 2026-09-05, recorded on #1188 as `E-PLANNING-MIGRATES-TO-LOCO-R2IL-DATAFUSION-IS-GRACE-PERIOD-1`): the field population is `ClassView × WideFieldMask`, consumed by Lance reads and loco programs; DataFusion-hosted surfaces are grace-period — maintained, never extended. No new operator, rule, or UDF routes into DataFusion. - **The falsifiability rule** (`CLAUDE.md`): every guard needs a can-fire AND a can-stay-silent test on non-trivial inputs; a threshold needs an inertness test; a doc claim is not a behaviour. - **Sonnet workers: edit-only, no `cargo`, no `git`, disjoint files; the orchestrator compiles once** (`agent-cargo-hygiene.md`; `sonnet-worker-guardrails.md` §1 pasted verbatim into every brief). ## 2. D-OIF-1 — `policy_hash_v1`: RULING A, SUPERSEDED — a retirement plan, not a crypto task > **Re-derived 2026-09-05 (W0 architecture census, four read-only Opus tracers + orchestrator verification).** +> Independent census on #1188 (banked at `.claude/board/exec-runs/d-oif-1-census-main-thread.md` on that branch) reached the same ruling; it scanned lance-graph only, so it reports the rewriter as test-constructed — the one extra constructor is the private-repo MedCare `routes/patient.rs:150`, which is why the removal cone below is narrower than "delete `policy.rs` entire": that deletion breaks MedCare's `lance-phase2-rbac` compile until MedCare retires the feature first. Its proposed `E-THE-UNFINISHED-UDF-WAS-NOT-THE-DEBT-1` is the same finding as the banked `E-THE-UNFINISHED-FUNCTION-WAS-NOT-THE-DEBT-1` — one entry, not two. +> > The previous §2 asked "which hash?". That question was one abstraction generation behind: it assumed the DataFusion policy-rewriter execution model still owned field-level authorization. The census below shows it never reached a binary, and the operator ruled the same day: **"every planning is in migration to ogar-loco and ogar-r2il; DataFusion is out of the picture; what exists gets a grace period; nothing new will migrate to it."** A hash body for `policy_hash_v1` is *new* work on the DataFusion path and is barred by that ruling regardless of the census. No hash family is chosen; `D-OIF-1-DEC` is **withdrawn**. ### 2.1 Tree verdict (production census; "production" = a real call chain from a binary / server handler, never `pub mod`, a feature flag, a registration helper, a test, or a doc comment) @@ -78,7 +81,7 @@ ### 2.3 Remove / retain / regrade (exact) - **REMOVE now (this arc, own PR, after grace-period sign-off):** nothing is deleted in #1185. The *first* removal PR is scoped to the dead-by-construction pieces only — `RedactionMode::Hash` + `NotYetWiredHashUdf` + the `policy_hash_v1` name (`policy.rs:130-140, 262-339`) and the test `redaction_mode_hash_binds_not_yet_wired_udf` (`:598-620`) — because they cannot execute today and no grace-period consumer can depend on them. Disable-run: removing the variant must break exactly that test and nothing else. -- **GRACE PERIOD (frozen, regraded SUPERSEDED, no new callers):** `policy.rs` remainder (`PolicyRewriter`, `PolicyKind`, `ColumnMaskRegistry`, `ColumnMaskPolicy`, `ColumnMaskRewriter`, `RedactionMode::{Null,Constant,Truncate}`), `rls.rs`, the `lib.rs:114-125` / `:93-99` gates, feature `auth-rls-lite`; MedCare `patient.rs:52-54, 85-211`, `state.rs` `column_mask_registry` / `rls_registry` / `session_context` / `build_session_context`, `medcare-analytics/src/column_mask_bridge.rs`. Removal condition: MedCare retires `lance-phase2-rbac` (its own private-repo PR) — then the callcenter cone falls in one PR. +- **GRACE PERIOD (frozen, regraded SUPERSEDED, no new callers):** `policy.rs` remainder (`PolicyRewriter`, `PolicyKind`, `ColumnMaskRegistry`, `ColumnMaskPolicy`, `ColumnMaskRewriter`, `RedactionMode::{Null,Constant,Truncate}`, and the same-shape stubs `RowEncryptionPolicy` / `DifferentialPrivacyPolicy` `policy.rs:344-420`, zero callers), the DataFusion forward-stubs `datafusion-dispatch` / `datafusion-plan` / `postgrest.rs:940-960` (`Err("not yet implemented")`) / `MembraneRegistry::with_rls`, `rls.rs`, the `lib.rs:114-125` / `:93-99` gates, feature `auth-rls-lite`; MedCare `patient.rs:52-54, 85-211`, `state.rs` `column_mask_registry` / `rls_registry` / `session_context` / `build_session_context`, `medcare-analytics/src/column_mask_bridge.rs`. Removal condition: MedCare retires `lance-phase2-rbac` (its own private-repo PR) — then the callcenter cone falls in one PR. - **RETAIN, untouched:** `lance-graph-python/src/graph.rs` (`SessionContext` `:1208,:1518`), `lance-graph-catalog/src/{connector,table_reader}.rs`, `holograph/src/storage.rs`, `callcenter/src/{graph_table,filter_expr,lance_membrane,unified_bridge}.rs`, `callcenter/src/bin/audit_verify.rs` + `audit.rs` (Lance dataset open), `lance-graph-planner/src/optimize/` (an in-house `OptimizerRule` trait of the same name, unrelated), MedCare `views/project.rs` + `medcare-rbac`, `tesseract-paperless/src/store.rs`. These are storage/query translation over Lance — the grace-period storage layer, not the policy VM. - **REGRADE (board):** `IDEA-POLICY-HASH-UDF` → Superseded; `D-OIF-1` → Superseded (retirement plan); `D-OIF-1-DEC` → Withdrawn; `LATEST_STATE.md:2389,2393` claims (see §2.5) get a dated correction line, not an edit. From b4b84efb8b217909f76e1f6b08e8bc456c8088fe Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 5 Sep 2026 16:35:01 +0000 Subject: [PATCH 5/9] open-ideas-fetch-v1: Rubicon reachability wording + the stub chronology MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - §2.1 item 10: mechanics shipped and SoA-owned; production stimulus into the transition path not yet demonstrated (reconciles #1188's seal-path chain with the no-entry-point finding) - E-THE-UNFINISHED-FUNCTION-WAS-NOT-THE-DEBT-1: chronology (never arrived, not disappeared) and the adjudication note on the narrower cone Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01DCfrD5y19cvFc4AoyydXYv --- .claude/board/EPIPHANIES.md | 2 ++ .claude/plans/open-ideas-fetch-v1.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.claude/board/EPIPHANIES.md b/.claude/board/EPIPHANIES.md index d6186e175..9f3c7d51a 100644 --- a/.claude/board/EPIPHANIES.md +++ b/.claude/board/EPIPHANIES.md @@ -16,6 +16,8 @@ **What holds, so it is not dragged into the retirement:** the Rubicon lifecycle is SoA-owned and checked — `Planning → CognitiveWork` is a one-way edge in `KanbanColumn`'s DAG (`kanban.rs:98-106`), consulted by `try_advance_phase` (`soa_view.rs:314`) with no mutation on refusal (`:329-346`); `KanbanActor` is a tombstone (`kanban_actor.rs:1-27`); no `Baton` type, no `CollapseGateEmission`, no `CommitHook` exists. RBAC holds no Kanban state; lifecycle code makes no authorization decision; `ogar-loco`/`ogar-r2il` contain no authorization vocabulary. Three v3 docs still name the deleted actor as owner — regraded in place this PR. +**Chronology, so the lesson is not misread as "old code went obsolete":** idea → scaffold (`policy.rs`) → feature-gated integration attempt (MedCare `lance-phase2-rbac`) → never deployed, terminally stubbed → architecture moved elsewhere (operator ruling: loco/r2il; projection-side masking) → the stub falsely reads as unfinished debt. The tree shows no once-live DataFusion masking architecture that was later superseded; it shows an attempted one that accumulated scaffolding and never acquired an execution path. **A conspicuous stub attracts implementation work even when the architecture around it never achieved reality.** Adjudication note: the independent #1188 census reached the same ruling but compressed "not live" into "does not exist" at two points (the MedCare constructor; whole-module removal) — the reachability proof above is what makes the narrower cone (remove Hash + UDF, freeze the rest under grace) the safe one. + **Rule extracted:** before giving an unfinished function a body, trace the *plan* that would execute it to a binary. A `cfg(feature)` that no Dockerfile sets, a decoder that returns `None`, and a registration helper with no caller are three independent proofs of the same thing, and any one of them ends the "which algorithm" discussion before it starts. "Superseded" is not a verdict about the code; it is a verdict about whether anything reaches it. --- diff --git a/.claude/plans/open-ideas-fetch-v1.md b/.claude/plans/open-ideas-fetch-v1.md index f1f49a053..88d456197 100644 --- a/.claude/plans/open-ideas-fetch-v1.md +++ b/.claude/plans/open-ideas-fetch-v1.md @@ -57,7 +57,7 @@ 7. The replacement path is **also not enforced**: `lance-graph-rbac::authorize()`/`authorize_scoped()` (`authorize.rs:66,182`), `contract::ClassRbac` (`rbac.rs:143`), `ActionInvocation::commit_via` (`action.rs:327`) and `lance-graph-ogar::OgarRbac` (`rbac_impl.rs:38`) have **zero non-test callers**. `effective_mask` is not an identifier in any `.rs` file. There is no `ogar-rbac` crate; `ogar-auth` is authentication only (password/TOTP). 8. MedCare's live authorization is entity-string keyed: `patient.rs:280 bridge.authorize_read("Patient", …)` → `lance-graph-rbac::policy::Policy` → `AccessDecision`. No mask reaches it. Field projection in production is `views/project.rs:229` (`WideFieldMask::from_positions` from a **view** spec, no role operand) — a view mask, not RBAC. 9. The only genuine `surface ∩ role` fail-closed projection is `a2ui-server/src/project.rs:70-83` (`WideFieldMask::intersect`, `NoRoleGrant` on empty role) — and `a2ui-server` has no `[[bin]]`, no `main`, and no dependent crate. -10. Rubicon/Kanban: no actor/controller survives (`kanban_actor.rs:1-27` tombstone: "All of it is DELETED"); the crossing `Planning → CognitiveWork` is a checked one-way edge (`kanban.rs:98-106`, `can_transition_to` consulted by `try_advance_phase` `soa_view.rs:314`, no mutation on refusal `:329-346`). `try_advance_phase` has one non-test caller (`cycle_driver.rs:560`) that is itself reached only from tests/examples. RBAC code holds no Kanban state; lifecycle code makes no authorization decision; loco/r2il make no authorization decision. +10. Rubicon/Kanban: no actor/controller survives (`kanban_actor.rs:1-27` tombstone: "All of it is DELETED"); the crossing `Planning → CognitiveWork` is a checked one-way edge (`kanban.rs:98-106`, `can_transition_to` consulted by `try_advance_phase` `soa_view.rs:314`, no mutation on refusal `:329-346`). `try_advance_phase` has one non-test caller (`cycle_driver.rs:560`, the seal path: `try_advance_phase → advance_phase → self.phase = to`, `mailbox_soa.rs:953`) that is itself reached only from tests/examples. Canonical wording, reconciled with the #1188 census: **Rubicon transition mechanics are shipped and SoA-owned; production stimulus/reachability into the transition path is not yet demonstrated.** "Code exists" is not inflated into "behaviour is live". RBAC code holds no Kanban state; lifecycle code makes no authorization decision; loco/r2il make no authorization decision. **So:** the invariant «forbidden fields absent from the authorized projection, not materialized and masked by a UDF» is *violated by the only field-level mechanism that was ever written* (item 4) and *satisfied by nothing that is deployed* (items 7–9). The invariant «a Rubicon transition is an SoA-owned mutation, not an actor command» **holds** in code (item 10) and is contradicted only by stale prose (§2.5). From 074710b93be694949aeefa09142284b2f37529eb Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 5 Sep 2026 16:39:49 +0000 Subject: [PATCH 6/9] open-ideas-fetch-v1: census scope stated; blockly-rs is the production ogar-loco consumer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - blockly-rs (thinking palette, axum binary) added to the census on operator input: ogar-loco is production there, not just in MedCare - R2IL vs ogar-r2il: the IR is live in r2sleigh's own r2il crate; the OGAR vocabulary bridge has no code consumer (naming split recorded) - lance-graph-java: projection-currency consumer (ogar-class-view + contract class_view); its G11 fence forbids the kanban module by design - census scope (seven repos) stated explicitly in §2 Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01DCfrD5y19cvFc4AoyydXYv --- .claude/plans/open-ideas-fetch-v1.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.claude/plans/open-ideas-fetch-v1.md b/.claude/plans/open-ideas-fetch-v1.md index 88d456197..adc7c50d3 100644 --- a/.claude/plans/open-ideas-fetch-v1.md +++ b/.claude/plans/open-ideas-fetch-v1.md @@ -46,6 +46,8 @@ > > The previous §2 asked "which hash?". That question was one abstraction generation behind: it assumed the DataFusion policy-rewriter execution model still owned field-level authorization. The census below shows it never reached a binary, and the operator ruled the same day: **"every planning is in migration to ogar-loco and ogar-r2il; DataFusion is out of the picture; what exists gets a grace period; nothing new will migrate to it."** A hash body for `policy_hash_v1` is *new* work on the DataFusion path and is barred by that ruling regardless of the census. No hash family is chosen; `D-OIF-1-DEC` is **withdrawn**. +**Census scope (stated, because a census inherits the blind spot of whoever ran it):** lance-graph, OGAR, MedCare-rs, a2ui-rs, lance-graph-java, r2sleigh, blockly-rs (cloned read-only 2026-09-05 after the operator named it). Repos not on disk are not covered; a deployment that drives `try_advance_phase` outside these seven would change item 10's second sentence and nothing else. + ### 2.1 Tree verdict (production census; "production" = a real call chain from a binary / server handler, never `pub mod`, a feature flag, a registration helper, a test, or a doc comment) 1. `ColumnMaskRewriter` has exactly one non-test constructor in all seven repos: `MedCare-rs/crates/medcare-server/src/routes/patient.rs:150`, inside `get_one_via_lance` (`:85`, `#[cfg(feature = "lance-phase2-rbac")]`), reached only for `?source=lance` (`:52-53`). @@ -57,7 +59,7 @@ 7. The replacement path is **also not enforced**: `lance-graph-rbac::authorize()`/`authorize_scoped()` (`authorize.rs:66,182`), `contract::ClassRbac` (`rbac.rs:143`), `ActionInvocation::commit_via` (`action.rs:327`) and `lance-graph-ogar::OgarRbac` (`rbac_impl.rs:38`) have **zero non-test callers**. `effective_mask` is not an identifier in any `.rs` file. There is no `ogar-rbac` crate; `ogar-auth` is authentication only (password/TOTP). 8. MedCare's live authorization is entity-string keyed: `patient.rs:280 bridge.authorize_read("Patient", …)` → `lance-graph-rbac::policy::Policy` → `AccessDecision`. No mask reaches it. Field projection in production is `views/project.rs:229` (`WideFieldMask::from_positions` from a **view** spec, no role operand) — a view mask, not RBAC. 9. The only genuine `surface ∩ role` fail-closed projection is `a2ui-server/src/project.rs:70-83` (`WideFieldMask::intersect`, `NoRoleGrant` on empty role) — and `a2ui-server` has no `[[bin]]`, no `main`, and no dependent crate. -10. Rubicon/Kanban: no actor/controller survives (`kanban_actor.rs:1-27` tombstone: "All of it is DELETED"); the crossing `Planning → CognitiveWork` is a checked one-way edge (`kanban.rs:98-106`, `can_transition_to` consulted by `try_advance_phase` `soa_view.rs:314`, no mutation on refusal `:329-346`). `try_advance_phase` has one non-test caller (`cycle_driver.rs:560`, the seal path: `try_advance_phase → advance_phase → self.phase = to`, `mailbox_soa.rs:953`) that is itself reached only from tests/examples. Canonical wording, reconciled with the #1188 census: **Rubicon transition mechanics are shipped and SoA-owned; production stimulus/reachability into the transition path is not yet demonstrated.** "Code exists" is not inflated into "behaviour is live". RBAC code holds no Kanban state; lifecycle code makes no authorization decision; loco/r2il make no authorization decision. +10. Rubicon/Kanban: no actor/controller survives (`kanban_actor.rs:1-27` tombstone: "All of it is DELETED"); the crossing `Planning → CognitiveWork` is a checked one-way edge (`kanban.rs:98-106`, `can_transition_to` consulted by `try_advance_phase` `soa_view.rs:314`, no mutation on refusal `:329-346`). `lance-graph-java` deliberately excludes it — its G11 fence (`native/lgj-abi/tests/g11_contract_import_fence.rs:314`) rejects any import of the contract's `kanban` module. `try_advance_phase` has one non-test caller (`cycle_driver.rs:560`, the seal path: `try_advance_phase → advance_phase → self.phase = to`, `mailbox_soa.rs:953`) that is itself reached only from tests/examples. Canonical wording, reconciled with the #1188 census: **Rubicon transition mechanics are shipped and SoA-owned; production stimulus/reachability into the transition path is not yet demonstrated.** "Code exists" is not inflated into "behaviour is live". RBAC code holds no Kanban state; lifecycle code makes no authorization decision; loco/r2il make no authorization decision. **So:** the invariant «forbidden fields absent from the authorized projection, not materialized and masked by a UDF» is *violated by the only field-level mechanism that was ever written* (item 4) and *satisfied by nothing that is deployed* (items 7–9). The invariant «a Rubicon transition is an SoA-owned mutation, not an actor command» **holds** in code (item 10) and is contradicted only by stale prose (§2.5). @@ -76,7 +78,7 @@ | Field-level authorization (the obligation `policy_hash_v1` was one arm of) | **VACANCY** on the canonical path: `ClassRbac × ClassView × WideFieldMask` | items 7–9 | **RECORD as the missing implementation** on the canonical OGAR/ClassView path (OGAR already says so: `DISCOVERY-MAP.md:1581-1584`, `DOCIR-COMPOSITION-GROUNDING.md:75`, `PROBE-OGAR-RBAC-AUTHORIZE`). Not resurrected on DataFusion. Not built in this plan | | `authorize_scoped` mask fold | `lance-graph-rbac/authorize.rs:199-216` | zero callers; folds a **union** over roles and returns `FieldMask::FULL` on non-Allow (`:190-196`) — fails OPEN in the mask | **REGRADE** to "TRANSPORT ONLY, fail-open in the mask value" — a design defect to fix on the canonical path, not evidence for the old one | | Rubicon lifecycle | `MailboxSoaOwner::try_advance_phase` + `KanbanColumn` DAG | item 10 | **RETAIN**, no change. Prose corrections only (§2.5) | -| Thinking/planning | `ogar-loco` (one live consumer: `medcare-cohorts/ddx_loco.rs` ← `views/zugfolge.rs:534`); `ogar-r2il` (probe/test only); planner `thinking/`,`mul/`,`strategy/` linked into medcare-server but uncalled | no DataFusion UDF or rule performs reasoning on any production path (`datafusion_planner/udf.rs:130-663` is vector/hamming distance only) | hypothesis **confirmed for DataFusion** (it never owned reasoning in production); **partially confirmed for loco/r2il** (loco live, r2il probe-only). Nothing to move | +| Thinking/planning | `ogar-loco` — **production**: `blockly-rs` (the thinking palette; axum binary `crates/blockly-web/src/main.rs`, `blockly-abi`/`blockly-shim`/`blockly-run`, `Cargo.toml:40` path dep; the census under-counted this — corrected 2026-09-05 on operator input) plus `medcare-cohorts/ddx_loco.rs` ← `views/zugfolge.rs:534`. **R2IL** is live in **r2sleigh's own `r2il` crate** behind the `r2sleigh` CLI (`crates/r2sleigh-cli`), but r2sleigh has no dependency on OGAR: the OGAR vocabulary bridge `ogar-r2il` still has no code consumer (lance-graph-java references R2IL only in plans/board; `lgj-abi/Cargo.toml` deps are `ndarray`, `lance-graph-contract`, `ogar-class-view`). Planner `thinking/`,`mul/`,`strategy/` linked into medcare-server but uncalled | no DataFusion UDF or rule performs reasoning on any production path (`datafusion_planner/udf.rs:130-663` is vector/hamming distance only) | hypothesis **confirmed for DataFusion** (it never owned reasoning in production) and **for loco** (blockly-rs); for r2il the IR is live in r2sleigh and the `ogar-r2il` vocabulary is the not-yet-consumed bridge — a naming split, not a vacancy in R2IL. Nothing to move | ### 2.3 Remove / retain / regrade (exact) From 972257b2aadeb92c7bddac8198eb45e0c4776ccb Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 5 Sep 2026 16:42:41 +0000 Subject: [PATCH 7/9] open-ideas-fetch-v1: strike three repo-boundary verdicts; the cross-repo reachability law MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Operator correction: a zero-local-callsite result is not a production verdict for a deliberately cross-repo substrate (the error lance-graph-java #76 corrected for WideFieldMask, repeated one layer up). Struck: - 'try_advance_phase has no production entry point' — bardioc substrate-b is a binary over MailboxSoA<32> gating every move on the contract's KanbanColumn::can_transition_to; KanbanShaderSink tags by phase - 'ogar-loco has one live consumer' — blockly-rs is a first-class consumer - 'ogar-r2il is probe-only' — it is the R2IL->loco bridge over r2sleigh's live IR; lance-graph-java lineage consumes R2IL via ruff_r2il RBAC zero-caller verdict rescoped to the nine scanned repos. Ruling A is sharpened: DataFusion policy is grace-period archaeology beside an already-production successor. Law recorded in plan §2 and the epiphany. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01DCfrD5y19cvFc4AoyydXYv --- .claude/board/EPIPHANIES.md | 4 +++- .claude/board/STATUS_BOARD.md | 2 +- .claude/board/SUPERSESSION-INDEX.md | 2 +- .claude/plans/open-ideas-fetch-v1.md | 16 ++++++++-------- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.claude/board/EPIPHANIES.md b/.claude/board/EPIPHANIES.md index 9f3c7d51a..4c0aab37d 100644 --- a/.claude/board/EPIPHANIES.md +++ b/.claude/board/EPIPHANIES.md @@ -14,11 +14,13 @@ **So the sentence that is earned is narrower than the one proposed.** Not "the model that needed the function had disappeared" — it never arrived. **The unfinished function was not the debt. The debt is that field-level authorization has no enforced owner on any production path, and the DataFusion rewriter was a second, wrong-layer answer to that vacancy — a storage/query-layer patch for an authorization-layer hole.** Finishing the function would have made the wrong layer *look* finished. +**Correction, same day (operator): the first pass committed the repo-boundary error.** It read zero call sites *inside lance-graph* as a production verdict for a deliberately cross-repo substrate — the same category error lance-graph-java PR #76 had just corrected for `WideFieldMask` one layer down. Three verdicts struck: "`try_advance_phase` has no production entry point" (bardioc `substrate-b` is a binary over `MailboxSoA<32>` gating every move on the contract's `KanbanColumn::can_transition_to`, `substrate-b/src/kanban.rs:103-120`, with `KanbanShaderSink` tagging emissions by phase); "`ogar-loco` has one live consumer" (blockly-rs, the thinking palette, is a direct first-class consumer — `blockly-web` axum binary, `Cargo.toml:40`); "`ogar-r2il` is probe-only" (it is the R2IL→loco bridge over r2sleigh's live `r2il` crate, and the lance-graph-java lineage consumes R2IL/SSA in-process via `ruff_r2il` — a direct Cargo dep is not the falsifier). The RBAC zero-caller verdict is therefore *rescoped* to the nine repos scanned, never stated globally. **Law: for a cross-repo substrate, production reachability terminates at deployed consumers, not at the repository boundary.** The correction sharpens the ruling: DataFusion planning/policy is grace-period archaeology beside an execution architecture that already has real consumers; `policy_hash_v1` would migrate semantics backwards into it. + **What holds, so it is not dragged into the retirement:** the Rubicon lifecycle is SoA-owned and checked — `Planning → CognitiveWork` is a one-way edge in `KanbanColumn`'s DAG (`kanban.rs:98-106`), consulted by `try_advance_phase` (`soa_view.rs:314`) with no mutation on refusal (`:329-346`); `KanbanActor` is a tombstone (`kanban_actor.rs:1-27`); no `Baton` type, no `CollapseGateEmission`, no `CommitHook` exists. RBAC holds no Kanban state; lifecycle code makes no authorization decision; `ogar-loco`/`ogar-r2il` contain no authorization vocabulary. Three v3 docs still name the deleted actor as owner — regraded in place this PR. **Chronology, so the lesson is not misread as "old code went obsolete":** idea → scaffold (`policy.rs`) → feature-gated integration attempt (MedCare `lance-phase2-rbac`) → never deployed, terminally stubbed → architecture moved elsewhere (operator ruling: loco/r2il; projection-side masking) → the stub falsely reads as unfinished debt. The tree shows no once-live DataFusion masking architecture that was later superseded; it shows an attempted one that accumulated scaffolding and never acquired an execution path. **A conspicuous stub attracts implementation work even when the architecture around it never achieved reality.** Adjudication note: the independent #1188 census reached the same ruling but compressed "not live" into "does not exist" at two points (the MedCare constructor; whole-module removal) — the reachability proof above is what makes the narrower cone (remove Hash + UDF, freeze the rest under grace) the safe one. -**Rule extracted:** before giving an unfinished function a body, trace the *plan* that would execute it to a binary. A `cfg(feature)` that no Dockerfile sets, a decoder that returns `None`, and a registration helper with no caller are three independent proofs of the same thing, and any one of them ends the "which algorithm" discussion before it starts. "Superseded" is not a verdict about the code; it is a verdict about whether anything reaches it. +**Rule extracted:** before giving an unfinished function a body, trace the *plan* that would execute it to a deployed consumer — in whatever repo it lives; the repository boundary is not the falsifier. A `cfg(feature)` that no Dockerfile sets, a decoder that returns `None`, and a registration helper with no caller are three independent proofs of the same thing, and any one of them ends the "which algorithm" discussion before it starts. "Superseded" is not a verdict about the code; it is a verdict about whether anything reaches it. --- diff --git a/.claude/board/STATUS_BOARD.md b/.claude/board/STATUS_BOARD.md index 89161c778..8d9670733 100644 --- a/.claude/board/STATUS_BOARD.md +++ b/.claude/board/STATUS_BOARD.md @@ -37,7 +37,7 @@ records against itself. |---|---|---| | D-OIF-0 | Re-run `cargo run -p jc --example sigma_probe` on the current tree; record R², verdict, and reconcile the `R²=0.9949` (`bindspace.rs:39`) vs `ρ=0.9973` (`arm-discovery/lib.rs:13`) citations to their sources. Orchestrator-run, no worker. Falsifier: the recorded number is the probe's own printed R², not either citation | Queued (plan `open-ideas-fetch-v1` §4.3) | | D-OIF-1 | `policy_hash_v1` — **RULING A, SUPERSEDED (2026-09-05 W0 census, plan §2)**: the DataFusion masking path has no deployed consumer (`ColumnMaskRewriter`'s only constructor is MedCare `patient.rs:150` under default-off `lance-phase2-rbac`, no Dockerfile enables it, decoder stub returns `None`) and redacts above the scan (`policy.rs:210`); operator ruled DataFusion out of planning. Becomes a retirement plan: first removal PR = `RedactionMode::Hash` + `NotYetWiredHashUdf` only; the rest of `policy.rs`/`rls.rs` is grace-period, frozen | Superseded — retirement, no worker | -| D-OIF-1-DEC | ~~hash family + key~~ — **WITHDRAWN 2026-09-05** (ruling A): no hash is chosen because no hash is built; the obligation's canonical owner is `ClassRbac × ClassView × WideFieldMask`, itself unenforced (zero callers of `authorize`/`authorize_scoped`/`commit_via`/`OgarRbac`; `effective_mask` not an identifier) — recorded as the missing implementation on the canonical path, not resurrected on DataFusion | Withdrawn | +| D-OIF-1-DEC | ~~hash family + key~~ — **WITHDRAWN 2026-09-05** (ruling A): no hash is chosen because no hash is built; the obligation's canonical owner is `ClassRbac × ClassView × WideFieldMask`, itself unenforced in the nine scanned repos (zero callers of `authorize`/`authorize_scoped`/`commit_via`/`OgarRbac` there; `effective_mask` not an identifier — a scoped statement, per the cross-repo reachability law in plan §2) — recorded as the missing implementation on the canonical path, not resurrected on DataFusion | Withdrawn | | D-OIF-2 | `SigmaCodebook([Spd2; 256])` TYPE in the zero-dep contract (`from_le_bytes`/`to_le_bytes`, `entry`, `nearest` via the affine-invariant metric, all-SPD boundary check on load per `sigma_propagation.rs:108`); k-means BUILDER/EMITTER in `jc` (float to build); loaded INSTANCE homed in `cognitive-shader-driver` beside the column it serves. Tag + content invariants, **no digest pin**. Gates G1–G4 (§4.4) | Queued (blocked on D-OIF-2-DEC) | | D-OIF-2-DEC | **Operator decision:** σ provenance — *fitted* (k-means over observed Σ, `sigma_codebook_probe.rs`) vs *declared* (typed-value tuple lookup, `sigma_propagation.rs:74-77`). Recommendation: fitted entries, declared as write-time fallback only. See plan §4.2 | Decision — operator | | D-OIF-3 | First writer of a non-zero σ at the ingest path that today calls `BackingStoreWrite::set_sigma` with a constant (`backing.rs:310`). Falsifier: ≥2 distinct Σ shapes in → ≥2 distinct non-zero σ (can-fire); identical shapes in → one value (stay-silent) | Queued (blocked on D-OIF-2) | diff --git a/.claude/board/SUPERSESSION-INDEX.md b/.claude/board/SUPERSESSION-INDEX.md index 1f4f8aaf5..156f5ff85 100644 --- a/.claude/board/SUPERSESSION-INDEX.md +++ b/.claude/board/SUPERSESSION-INDEX.md @@ -61,7 +61,7 @@ coverage instead. | `MergeMode` | REPURPOSE | — | 8 | 13 | 12 | | `ResonanceDto` | REPURPOSE | `PerturbationDto` | 2 | 12 | 7 | | `BindSpace` | RETIRE | — | 68 | 47 | 41 | -| `CollapseGateEmission` | RETIRE | — | 5 | 13 | 12 | +| `CollapseGateEmission` | RETIRE | — | 5 | 14 | 12 | | `ThinkingStyle` | RETIRE-toward-contract | — | 51 | 28 | 24 | ## Table 2 — plans naming a ruled symbol without citing the ruling (73) diff --git a/.claude/plans/open-ideas-fetch-v1.md b/.claude/plans/open-ideas-fetch-v1.md index adc7c50d3..53cfee771 100644 --- a/.claude/plans/open-ideas-fetch-v1.md +++ b/.claude/plans/open-ideas-fetch-v1.md @@ -46,7 +46,7 @@ > > The previous §2 asked "which hash?". That question was one abstraction generation behind: it assumed the DataFusion policy-rewriter execution model still owned field-level authorization. The census below shows it never reached a binary, and the operator ruled the same day: **"every planning is in migration to ogar-loco and ogar-r2il; DataFusion is out of the picture; what exists gets a grace period; nothing new will migrate to it."** A hash body for `policy_hash_v1` is *new* work on the DataFusion path and is barred by that ruling regardless of the census. No hash family is chosen; `D-OIF-1-DEC` is **withdrawn**. -**Census scope (stated, because a census inherits the blind spot of whoever ran it):** lance-graph, OGAR, MedCare-rs, a2ui-rs, lance-graph-java, r2sleigh, blockly-rs (cloned read-only 2026-09-05 after the operator named it). Repos not on disk are not covered; a deployment that drives `try_advance_phase` outside these seven would change item 10's second sentence and nothing else. +**Census scope and the law it violated (operator correction 2026-09-05):** the first pass asked "who calls this inside lance-graph?" and read zero local call sites as a production verdict. That is the wrong boundary for a deliberately cross-repo substrate — the same category error lance-graph-java PR #76 corrected for `WideFieldMask` one layer down. **Law: for a cross-repo substrate, production reachability terminates at deployed consumers, not at the repository boundary.** Scanned after the correction: lance-graph, OGAR, MedCare-rs, a2ui-rs, lance-graph-java, r2sleigh, blockly-rs, bardioc (the last two cloned read-only on operator input). Three verdicts below are STRUCK, not softened; the RBAC zero-caller verdict is rescoped to the nine repos, never global. ### 2.1 Tree verdict (production census; "production" = a real call chain from a binary / server handler, never `pub mod`, a feature flag, a registration helper, a test, or a doc comment) @@ -56,12 +56,12 @@ 4. The rewriter redacts **above the scan**: `rewrite_plan` (`policy.rs:210`) maps expressions and `recompute_schema`s; `TableScan.projection` is never written (`extract_table_name` `:226-241` only reads it). The forbidden column is scanned from Lance, materialized, then overwritten — post-hoc redaction, the exact anti-pattern the invariant forbids. 5. `RedactionMode::Hash` (`policy.rs:130-140`) binds `NotYetWiredHashUdf`; any plan containing it fails at execute with `NotImplemented` (`:339`). `policy_hash_v1` has no implementation and no `register_udf` anywhere. `register_vsa_udfs` (`vsa_udfs.rs:574`) has zero callers in all repos. 6. `PolicyRewriter` (`policy.rs:56`) has one impl and `dyn PolicyRewriter` appears nowhere — a one-impl indirection, not a policy VM. -7. The replacement path is **also not enforced**: `lance-graph-rbac::authorize()`/`authorize_scoped()` (`authorize.rs:66,182`), `contract::ClassRbac` (`rbac.rs:143`), `ActionInvocation::commit_via` (`action.rs:327`) and `lance-graph-ogar::OgarRbac` (`rbac_impl.rs:38`) have **zero non-test callers**. `effective_mask` is not an identifier in any `.rs` file. There is no `ogar-rbac` crate; `ogar-auth` is authentication only (password/TOTP). +7. The replacement path's enforcement is **not found in the nine scanned repos** (a scoped statement, per the law above — not a global one): `lance-graph-rbac::authorize()`/`authorize_scoped()` (`authorize.rs:66,182`), `contract::ClassRbac` (`rbac.rs:143`), `ActionInvocation::commit_via` (`action.rs:327`) and `lance-graph-ogar::OgarRbac` (`rbac_impl.rs:38`) have zero non-test callers there (bardioc and blockly-rs included; `rs-graph-llm`, named as `dispatch_via`'s home, is not on disk and was not scanned). `effective_mask` is not an identifier in any `.rs` file. There is no `ogar-rbac` crate; `ogar-auth` is authentication only (password/TOTP). 8. MedCare's live authorization is entity-string keyed: `patient.rs:280 bridge.authorize_read("Patient", …)` → `lance-graph-rbac::policy::Policy` → `AccessDecision`. No mask reaches it. Field projection in production is `views/project.rs:229` (`WideFieldMask::from_positions` from a **view** spec, no role operand) — a view mask, not RBAC. 9. The only genuine `surface ∩ role` fail-closed projection is `a2ui-server/src/project.rs:70-83` (`WideFieldMask::intersect`, `NoRoleGrant` on empty role) — and `a2ui-server` has no `[[bin]]`, no `main`, and no dependent crate. -10. Rubicon/Kanban: no actor/controller survives (`kanban_actor.rs:1-27` tombstone: "All of it is DELETED"); the crossing `Planning → CognitiveWork` is a checked one-way edge (`kanban.rs:98-106`, `can_transition_to` consulted by `try_advance_phase` `soa_view.rs:314`, no mutation on refusal `:329-346`). `lance-graph-java` deliberately excludes it — its G11 fence (`native/lgj-abi/tests/g11_contract_import_fence.rs:314`) rejects any import of the contract's `kanban` module. `try_advance_phase` has one non-test caller (`cycle_driver.rs:560`, the seal path: `try_advance_phase → advance_phase → self.phase = to`, `mailbox_soa.rs:953`) that is itself reached only from tests/examples. Canonical wording, reconciled with the #1188 census: **Rubicon transition mechanics are shipped and SoA-owned; production stimulus/reachability into the transition path is not yet demonstrated.** "Code exists" is not inflated into "behaviour is live". RBAC code holds no Kanban state; lifecycle code makes no authorization decision; loco/r2il make no authorization decision. +10. Rubicon/Kanban — **first verdict STRUCK.** The first pass said "`try_advance_phase` has no production entry point"; that was the repo-boundary error. The checked Kanban law has a production consumer: **bardioc** `substrate-b` (binary `substrate-b/src/bin/substrate_b.rs` over `MailboxSoA<32>`; `substrate-b/src/kanban.rs:54` re-exports the contract's `KanbanColumn`/`KanbanMove`/`RubiconTransitionError`, `:103-120` gates every move on `KanbanColumn::can_transition_to`; `supervisor.rs` drives it; `substrate-b-telemetry/src/shader_sink.rs` `KanbanShaderSink` tags emissions with the source mailbox's phase). Precision: bardioc enters the law through `can_transition_to` on its own `advance`, so `MailboxSoaOwner::try_advance_phase` (`soa_view.rs:311`, seal path `cycle_driver.rs:560` → `advance_phase` → `self.phase = to`, `mailbox_soa.rs:953`) is one of two entry points into the SAME checked DAG (`kanban.rs:98-106`), not the only one. What held from the first pass and still holds: no actor/controller survives (`kanban_actor.rs:1-27` tombstone; no `Baton`/`CollapseGateEmission`/`CommitHook` type); the crossing `Planning → CognitiveWork` is one-way; refusal does not mutate (`soa_view.rs:329-346`); RBAC holds no Kanban state, lifecycle makes no authorization decision, loco/r2il carry no authorization vocabulary; lance-graph-java excludes the `kanban` module by design (G11 fence, `native/lgj-abi/tests/g11_contract_import_fence.rs:314`). -**So:** the invariant «forbidden fields absent from the authorized projection, not materialized and masked by a UDF» is *violated by the only field-level mechanism that was ever written* (item 4) and *satisfied by nothing that is deployed* (items 7–9). The invariant «a Rubicon transition is an SoA-owned mutation, not an actor command» **holds** in code (item 10) and is contradicted only by stale prose (§2.5). +**So:** the invariant «forbidden fields absent from the authorized projection, not materialized and masked by a UDF» is *violated by the only field-level mechanism that was ever written* (item 4) and *satisfied by nothing found deployed in the scanned repos* (items 7–9). The invariant «a Rubicon transition is an SoA-owned mutation, not an actor command» **holds** in code and **in production** (item 10, bardioc) and is contradicted only by stale prose (§2.5). **This makes the ruling more decisive, not less:** DataFusion planning/policy is grace-period archaeology beside an execution architecture that already has real consumers — `ogar-loco` (blockly-rs), Rubicon/Kanban + SoA (bardioc), R2IL via `ogar-r2il`/`ruff_r2il` (r2sleigh → lance-graph-java lineage). `policy_hash_v1` is rejected because new work would migrate semantics *backwards* into the grace-period architecture after the successor acquired consumers — not because the successor is prospective. ### 2.2 Obligation table @@ -77,8 +77,8 @@ | `unified_bridge.rs` `authorize_{read,write,act}` | `lance-graph-callcenter` | live: `patient.rs:280` | **RETAIN.** Entity-level allow/deny before SQL; never touches a plan | | Field-level authorization (the obligation `policy_hash_v1` was one arm of) | **VACANCY** on the canonical path: `ClassRbac × ClassView × WideFieldMask` | items 7–9 | **RECORD as the missing implementation** on the canonical OGAR/ClassView path (OGAR already says so: `DISCOVERY-MAP.md:1581-1584`, `DOCIR-COMPOSITION-GROUNDING.md:75`, `PROBE-OGAR-RBAC-AUTHORIZE`). Not resurrected on DataFusion. Not built in this plan | | `authorize_scoped` mask fold | `lance-graph-rbac/authorize.rs:199-216` | zero callers; folds a **union** over roles and returns `FieldMask::FULL` on non-Allow (`:190-196`) — fails OPEN in the mask | **REGRADE** to "TRANSPORT ONLY, fail-open in the mask value" — a design defect to fix on the canonical path, not evidence for the old one | -| Rubicon lifecycle | `MailboxSoaOwner::try_advance_phase` + `KanbanColumn` DAG | item 10 | **RETAIN**, no change. Prose corrections only (§2.5) | -| Thinking/planning | `ogar-loco` — **production**: `blockly-rs` (the thinking palette; axum binary `crates/blockly-web/src/main.rs`, `blockly-abi`/`blockly-shim`/`blockly-run`, `Cargo.toml:40` path dep; the census under-counted this — corrected 2026-09-05 on operator input) plus `medcare-cohorts/ddx_loco.rs` ← `views/zugfolge.rs:534`. **R2IL** is live in **r2sleigh's own `r2il` crate** behind the `r2sleigh` CLI (`crates/r2sleigh-cli`), but r2sleigh has no dependency on OGAR: the OGAR vocabulary bridge `ogar-r2il` still has no code consumer (lance-graph-java references R2IL only in plans/board; `lgj-abi/Cargo.toml` deps are `ndarray`, `lance-graph-contract`, `ogar-class-view`). Planner `thinking/`,`mul/`,`strategy/` linked into medcare-server but uncalled | no DataFusion UDF or rule performs reasoning on any production path (`datafusion_planner/udf.rs:130-663` is vector/hamming distance only) | hypothesis **confirmed for DataFusion** (it never owned reasoning in production) and **for loco** (blockly-rs); for r2il the IR is live in r2sleigh and the `ogar-r2il` vocabulary is the not-yet-consumed bridge — a naming split, not a vacancy in R2IL. Nothing to move | +| Rubicon lifecycle | `KanbanColumn` DAG + `MailboxSoaOwner::try_advance_phase` (contract); **production consumer: bardioc `substrate-b`** (item 10) | `substrate-b/src/kanban.rs:103-120`, `bin/substrate_b.rs`, `shader_sink.rs` `KanbanShaderSink` | **RETAIN**, production. Prose corrections only (§2.5) | +| Thinking/planning | **production, cross-repo:** `ogar-loco` ← blockly-rs (the thinking palette; axum binary `crates/blockly-web/src/main.rs`, `blockly-abi`/`blockly-shim`/`blockly-run`, `Cargo.toml:40` path dep) and MedCare `ddx_loco` (`views/zugfolge.rs:534`); `ogar-r2il` = the R2IL→loco bridge (r2sleigh's 82 opcodes as an `ogar_loco::Vocabulary` + masked lane projection) over r2sleigh's live `r2il` crate (`r2sleigh-cli` bin); the lance-graph-java lineage consumes R2IL/SSA in-process via `ruff_r2il` (its board: shipped, not pending — a direct `lgj-abi → ogar-r2il` Cargo dep is NOT required as proof, per the law). Planner `thinking/`,`mul/`,`strategy/` linked into medcare-server but uncalled | no DataFusion UDF or rule performs reasoning on any production path (`datafusion_planner/udf.rs:130-663` is vector/hamming distance only) | first-pass verdicts "one live loco consumer" and "ogar-r2il probe-only" **STRUCK** (repo-boundary error). Hypothesis **confirmed**: DataFusion never owned reasoning in production; the successor stack is already production. Nothing to move | ### 2.3 Remove / retain / regrade (exact) @@ -91,10 +91,10 @@ | layer | owner in code | impersonation found? | |---|---|---| -| 1 Lifecycle control | `KanbanColumn` DAG (`kanban.rs:98-106`) + `MailboxSoaOwner::try_advance_phase` (`soa_view.rs:311`); Planning = pre-decisional, `Planning→CognitiveWork` = the Rubicon crossing, `CognitiveWork` = actional, `Evaluation` = post-actional, `Commit`/`Plan`/`Prune` = outcomes; `Planning→Prune` = pre-Rubicon veto | none. `Commit`'s calcify step is DECLARED only (`kanban.rs:48-56`) | +| 1 Lifecycle control | `KanbanColumn` DAG (`kanban.rs:98-106`) + `MailboxSoaOwner::try_advance_phase` (`soa_view.rs:311`); Planning = pre-decisional, `Planning→CognitiveWork` = the Rubicon crossing, `CognitiveWork` = actional, `Evaluation` = post-actional, `Commit`/`Plan`/`Prune` = outcomes; `Planning→Prune` = pre-Rubicon veto | none. Production consumer: bardioc `substrate-b`. `Commit`'s calcify step is DECLARED only (`kanban.rs:48-56`) | | 2 Action semantics | `ActionState` (OGAR `ogar-vocab/lib.rs:676` canonical wire type; contract `action.rs:44` the Rust mirror, unconsumed), `ActionDef`, `KausalSpec`, `ActionInvocation::commit` | `commit` inlines its own RBAC check (`action.rs:283`) — documented design, not drift. `CommitHook` **does not exist** (prose only) | | 3 Authorization | contract `rbac.rs` + `lance-graph-rbac` (types + un-called kernel); live gate = string-keyed `Policy` | none on lifecycle. The ClassView∧role fold is unbuilt | -| 4 Execution/reasoning | `ogar-loco` (live), `ogar-r2il` (probe), planner thinking (linked, uncalled) | none: zero authorization words in loco/r2il | +| 4 Execution/reasoning | `ogar-loco` (production: blockly-rs, MedCare), `ogar-r2il` (the R2IL→loco bridge over r2sleigh's live IR; lance-graph-java lineage via `ruff_r2il`), planner thinking (linked, uncalled) | none: zero authorization words in loco/r2il | | 5 Storage/query | Lance / DataFusion (B1–B9 in the census) | the one policy hook (`patient.rs:146-150`) is on the undeployed path; DataFusion owns no lifecycle state | **The one category error worth naming:** the prior plan treated *authorization* (layer 3) as a *storage/query* concern (layer 5) because the only code that existed lived there. The census shows layers 3 and 5 are currently **disjoint**, not layered — where ClassView×mask genuinely governs columns (MedCare `views/`, atlas/graph reads of the resident bake), DataFusion and Lance are not in the path at all. From 2e52f4fef2c732381adec227bd6b098a0d2a1183 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 5 Sep 2026 16:43:54 +0000 Subject: [PATCH 8/9] open-ideas-fetch-v1: kanban_actor.rs is live read-only meta-awareness, not a tombstone MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Operator correction. Only the KanbanActor/KanbanMsg actor and its RPC drivers were deleted; the file survives as PhaseCensus / mul_target / parse_kanban_step — re-exported from the supervisor, composed by the production seal driver (cycle_driver.rs:805), cited as the one-read-only- pass precedent (rubicon_witness.rs:32), read by the awareness rungs. Corrected in plan §2.1/§2.2/§2.5, the epiphany, and the three v3 notes. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01DCfrD5y19cvFc4AoyydXYv --- .claude/board/EPIPHANIES.md | 2 +- .claude/plans/open-ideas-fetch-v1.md | 6 +++--- .claude/v3/COMPONENT-MAP.md | 2 +- .claude/v3/knowledge/mailbox-kanban-model.md | 2 +- .claude/v3/knowledge/write-on-behalf.md | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.claude/board/EPIPHANIES.md b/.claude/board/EPIPHANIES.md index 4c0aab37d..1526adc9d 100644 --- a/.claude/board/EPIPHANIES.md +++ b/.claude/board/EPIPHANIES.md @@ -16,7 +16,7 @@ **Correction, same day (operator): the first pass committed the repo-boundary error.** It read zero call sites *inside lance-graph* as a production verdict for a deliberately cross-repo substrate — the same category error lance-graph-java PR #76 had just corrected for `WideFieldMask` one layer down. Three verdicts struck: "`try_advance_phase` has no production entry point" (bardioc `substrate-b` is a binary over `MailboxSoA<32>` gating every move on the contract's `KanbanColumn::can_transition_to`, `substrate-b/src/kanban.rs:103-120`, with `KanbanShaderSink` tagging emissions by phase); "`ogar-loco` has one live consumer" (blockly-rs, the thinking palette, is a direct first-class consumer — `blockly-web` axum binary, `Cargo.toml:40`); "`ogar-r2il` is probe-only" (it is the R2IL→loco bridge over r2sleigh's live `r2il` crate, and the lance-graph-java lineage consumes R2IL/SSA in-process via `ruff_r2il` — a direct Cargo dep is not the falsifier). The RBAC zero-caller verdict is therefore *rescoped* to the nine repos scanned, never stated globally. **Law: for a cross-repo substrate, production reachability terminates at deployed consumers, not at the repository boundary.** The correction sharpens the ruling: DataFusion planning/policy is grace-period archaeology beside an execution architecture that already has real consumers; `policy_hash_v1` would migrate semantics backwards into it. -**What holds, so it is not dragged into the retirement:** the Rubicon lifecycle is SoA-owned and checked — `Planning → CognitiveWork` is a one-way edge in `KanbanColumn`'s DAG (`kanban.rs:98-106`), consulted by `try_advance_phase` (`soa_view.rs:314`) with no mutation on refusal (`:329-346`); `KanbanActor` is a tombstone (`kanban_actor.rs:1-27`); no `Baton` type, no `CollapseGateEmission`, no `CommitHook` exists. RBAC holds no Kanban state; lifecycle code makes no authorization decision; `ogar-loco`/`ogar-r2il` contain no authorization vocabulary. Three v3 docs still name the deleted actor as owner — regraded in place this PR. +**What holds, so it is not dragged into the retirement:** the Rubicon lifecycle is SoA-owned and checked — `Planning → CognitiveWork` is a one-way edge in `KanbanColumn`'s DAG (`kanban.rs:98-106`), consulted by `try_advance_phase` (`soa_view.rs:314`) with no mutation on refusal (`:329-346`); the `KanbanActor` actor is deleted while `kanban_actor.rs` lives on as the read-only meta-awareness census (`PhaseCensus`/`mul_target`, composed by `cycle_driver.rs:805`, read by the awareness rungs — first wording here said "tombstone"; corrected same day on operator input); no `Baton` type, no `CollapseGateEmission`, no `CommitHook` exists. RBAC holds no Kanban state; lifecycle code makes no authorization decision; `ogar-loco`/`ogar-r2il` contain no authorization vocabulary. Three v3 docs still name the deleted actor as owner — regraded in place this PR. **Chronology, so the lesson is not misread as "old code went obsolete":** idea → scaffold (`policy.rs`) → feature-gated integration attempt (MedCare `lance-phase2-rbac`) → never deployed, terminally stubbed → architecture moved elsewhere (operator ruling: loco/r2il; projection-side masking) → the stub falsely reads as unfinished debt. The tree shows no once-live DataFusion masking architecture that was later superseded; it shows an attempted one that accumulated scaffolding and never acquired an execution path. **A conspicuous stub attracts implementation work even when the architecture around it never achieved reality.** Adjudication note: the independent #1188 census reached the same ruling but compressed "not live" into "does not exist" at two points (the MedCare constructor; whole-module removal) — the reachability proof above is what makes the narrower cone (remove Hash + UDF, freeze the rest under grace) the safe one. diff --git a/.claude/plans/open-ideas-fetch-v1.md b/.claude/plans/open-ideas-fetch-v1.md index 53cfee771..2cc5e9409 100644 --- a/.claude/plans/open-ideas-fetch-v1.md +++ b/.claude/plans/open-ideas-fetch-v1.md @@ -59,7 +59,7 @@ 7. The replacement path's enforcement is **not found in the nine scanned repos** (a scoped statement, per the law above — not a global one): `lance-graph-rbac::authorize()`/`authorize_scoped()` (`authorize.rs:66,182`), `contract::ClassRbac` (`rbac.rs:143`), `ActionInvocation::commit_via` (`action.rs:327`) and `lance-graph-ogar::OgarRbac` (`rbac_impl.rs:38`) have zero non-test callers there (bardioc and blockly-rs included; `rs-graph-llm`, named as `dispatch_via`'s home, is not on disk and was not scanned). `effective_mask` is not an identifier in any `.rs` file. There is no `ogar-rbac` crate; `ogar-auth` is authentication only (password/TOTP). 8. MedCare's live authorization is entity-string keyed: `patient.rs:280 bridge.authorize_read("Patient", …)` → `lance-graph-rbac::policy::Policy` → `AccessDecision`. No mask reaches it. Field projection in production is `views/project.rs:229` (`WideFieldMask::from_positions` from a **view** spec, no role operand) — a view mask, not RBAC. 9. The only genuine `surface ∩ role` fail-closed projection is `a2ui-server/src/project.rs:70-83` (`WideFieldMask::intersect`, `NoRoleGrant` on empty role) — and `a2ui-server` has no `[[bin]]`, no `main`, and no dependent crate. -10. Rubicon/Kanban — **first verdict STRUCK.** The first pass said "`try_advance_phase` has no production entry point"; that was the repo-boundary error. The checked Kanban law has a production consumer: **bardioc** `substrate-b` (binary `substrate-b/src/bin/substrate_b.rs` over `MailboxSoA<32>`; `substrate-b/src/kanban.rs:54` re-exports the contract's `KanbanColumn`/`KanbanMove`/`RubiconTransitionError`, `:103-120` gates every move on `KanbanColumn::can_transition_to`; `supervisor.rs` drives it; `substrate-b-telemetry/src/shader_sink.rs` `KanbanShaderSink` tags emissions with the source mailbox's phase). Precision: bardioc enters the law through `can_transition_to` on its own `advance`, so `MailboxSoaOwner::try_advance_phase` (`soa_view.rs:311`, seal path `cycle_driver.rs:560` → `advance_phase` → `self.phase = to`, `mailbox_soa.rs:953`) is one of two entry points into the SAME checked DAG (`kanban.rs:98-106`), not the only one. What held from the first pass and still holds: no actor/controller survives (`kanban_actor.rs:1-27` tombstone; no `Baton`/`CollapseGateEmission`/`CommitHook` type); the crossing `Planning → CognitiveWork` is one-way; refusal does not mutate (`soa_view.rs:329-346`); RBAC holds no Kanban state, lifecycle makes no authorization decision, loco/r2il carry no authorization vocabulary; lance-graph-java excludes the `kanban` module by design (G11 fence, `native/lgj-abi/tests/g11_contract_import_fence.rs:314`). +10. Rubicon/Kanban — **first verdict STRUCK.** The first pass said "`try_advance_phase` has no production entry point"; that was the repo-boundary error. The checked Kanban law has a production consumer: **bardioc** `substrate-b` (binary `substrate-b/src/bin/substrate_b.rs` over `MailboxSoA<32>`; `substrate-b/src/kanban.rs:54` re-exports the contract's `KanbanColumn`/`KanbanMove`/`RubiconTransitionError`, `:103-120` gates every move on `KanbanColumn::can_transition_to`; `supervisor.rs` drives it; `substrate-b-telemetry/src/shader_sink.rs` `KanbanShaderSink` tags emissions with the source mailbox's phase). Precision: bardioc enters the law through `can_transition_to` on its own `advance`, so `MailboxSoaOwner::try_advance_phase` (`soa_view.rs:311`, seal path `cycle_driver.rs:560` → `advance_phase` → `self.phase = to`, `mailbox_soa.rs:953`) is one of two entry points into the SAME checked DAG (`kanban.rs:98-106`), not the only one. What held from the first pass and still holds: no actor/controller survives — the `KanbanActor`/`KanbanMsg` actor and its RPC drivers were deleted 2026-08-05, while `kanban_actor.rs` itself is LIVE as the read-only meta-awareness surface (`PhaseCensus` `:57`, `mul_target` `:149` composed by the production seal driver `cycle_driver.rs:805`, `parse_kanban_step` `:163`; re-exported `supervisor/src/lib.rs:82`; the one-read-only-pass precedent `rubicon_witness.rs:32`; read by the awareness rungs, `rung_horizon.rs:5`) — a census, never a controller; no `Baton`/`CollapseGateEmission`/`CommitHook` type; the crossing `Planning → CognitiveWork` is one-way; refusal does not mutate (`soa_view.rs:329-346`); RBAC holds no Kanban state, lifecycle makes no authorization decision, loco/r2il carry no authorization vocabulary; lance-graph-java excludes the `kanban` module by design (G11 fence, `native/lgj-abi/tests/g11_contract_import_fence.rs:314`). **So:** the invariant «forbidden fields absent from the authorized projection, not materialized and masked by a UDF» is *violated by the only field-level mechanism that was ever written* (item 4) and *satisfied by nothing found deployed in the scanned repos* (items 7–9). The invariant «a Rubicon transition is an SoA-owned mutation, not an actor command» **holds** in code and **in production** (item 10, bardioc) and is contradicted only by stale prose (§2.5). **This makes the ruling more decisive, not less:** DataFusion planning/policy is grace-period archaeology beside an execution architecture that already has real consumers — `ogar-loco` (blockly-rs), Rubicon/Kanban + SoA (bardioc), R2IL via `ogar-r2il`/`ruff_r2il` (r2sleigh → lance-graph-java lineage). `policy_hash_v1` is rejected because new work would migrate semantics *backwards* into the grace-period architecture after the successor acquired consumers — not because the successor is prospective. @@ -77,7 +77,7 @@ | `unified_bridge.rs` `authorize_{read,write,act}` | `lance-graph-callcenter` | live: `patient.rs:280` | **RETAIN.** Entity-level allow/deny before SQL; never touches a plan | | Field-level authorization (the obligation `policy_hash_v1` was one arm of) | **VACANCY** on the canonical path: `ClassRbac × ClassView × WideFieldMask` | items 7–9 | **RECORD as the missing implementation** on the canonical OGAR/ClassView path (OGAR already says so: `DISCOVERY-MAP.md:1581-1584`, `DOCIR-COMPOSITION-GROUNDING.md:75`, `PROBE-OGAR-RBAC-AUTHORIZE`). Not resurrected on DataFusion. Not built in this plan | | `authorize_scoped` mask fold | `lance-graph-rbac/authorize.rs:199-216` | zero callers; folds a **union** over roles and returns `FieldMask::FULL` on non-Allow (`:190-196`) — fails OPEN in the mask | **REGRADE** to "TRANSPORT ONLY, fail-open in the mask value" — a design defect to fix on the canonical path, not evidence for the old one | -| Rubicon lifecycle | `KanbanColumn` DAG + `MailboxSoaOwner::try_advance_phase` (contract); **production consumer: bardioc `substrate-b`** (item 10) | `substrate-b/src/kanban.rs:103-120`, `bin/substrate_b.rs`, `shader_sink.rs` `KanbanShaderSink` | **RETAIN**, production. Prose corrections only (§2.5) | +| Rubicon lifecycle | `KanbanColumn` DAG + `MailboxSoaOwner::try_advance_phase` (contract); read-only meta-awareness `PhaseCensus`/`mul_target` (`kanban_actor.rs`, live); **production consumer: bardioc `substrate-b`** (item 10) | `substrate-b/src/kanban.rs:103-120`, `bin/substrate_b.rs`, `shader_sink.rs` `KanbanShaderSink` | **RETAIN**, production. Prose corrections only (§2.5) | | Thinking/planning | **production, cross-repo:** `ogar-loco` ← blockly-rs (the thinking palette; axum binary `crates/blockly-web/src/main.rs`, `blockly-abi`/`blockly-shim`/`blockly-run`, `Cargo.toml:40` path dep) and MedCare `ddx_loco` (`views/zugfolge.rs:534`); `ogar-r2il` = the R2IL→loco bridge (r2sleigh's 82 opcodes as an `ogar_loco::Vocabulary` + masked lane projection) over r2sleigh's live `r2il` crate (`r2sleigh-cli` bin); the lance-graph-java lineage consumes R2IL/SSA in-process via `ruff_r2il` (its board: shipped, not pending — a direct `lgj-abi → ogar-r2il` Cargo dep is NOT required as proof, per the law). Planner `thinking/`,`mul/`,`strategy/` linked into medcare-server but uncalled | no DataFusion UDF or rule performs reasoning on any production path (`datafusion_planner/udf.rs:130-663` is vector/hamming distance only) | first-pass verdicts "one live loco consumer" and "ogar-r2il probe-only" **STRUCK** (repo-boundary error). Hypothesis **confirmed**: DataFusion never owned reasoning in production; the successor stack is already production. Nothing to move | ### 2.3 Remove / retain / regrade (exact) @@ -104,7 +104,7 @@ - `a2ui-rs/CLAUDE.md` § "RBAC is real": "`ClassRbac::field_mask` is being retyped to `WideFieldMask` … `WideFieldMask::ALL`" — `rbac.rs:176` still returns `FieldMask` (u64); `WideFieldMask::ALL` does not exist (`class_view.rs:275` has only `EMPTY`; `full_for` `:360`). *(a2ui-rs repo; not touched here — filed for that repo.)* - `OGAR/crates/ogar-a2ui-frame/src/lib.rs:32`: states the C1.4 retype as done. *(OGAR repo; not touched here.)* - `LATEST_STATE.md:2389` lists `commit_via` / `OgarRbac` / `graph-flow-action::dispatch_via` as shipped enforcement — the types exist, the callers do not; `rs-graph-llm` is not on disk. `:2393` "`impl ClassRbac for OgarClassView`" — no such impl (`ogar-class-view/lib.rs:399` impls `ClassView` only). *(Append-only: dated correction line added in this PR.)* -- `.claude/v3/knowledge/mailbox-kanban-model.md:30`, `.claude/v3/COMPONENT-MAP.md:79` ("EXTEND"), `.claude/v3/knowledge/write-on-behalf.md:8` (`ACTOR-OWNED`) and `:68`: present `kanban_actor.rs`/`KanbanActor` as the structural owner / pending W1 work — deleted 2026-08-05 (`kanban_actor.rs:1-27`; `LATEST_STATE.md:1824,1860`). *(Corrected in this PR: dated supersession notes, in place.)* +- `.claude/v3/knowledge/mailbox-kanban-model.md:30`, `.claude/v3/COMPONENT-MAP.md:79` ("EXTEND"), `.claude/v3/knowledge/write-on-behalf.md:8` (`ACTOR-OWNED`) and `:68`: present the `KanbanActor` actor as the structural owner / pending W1 work — the actor was deleted 2026-08-05 (`LATEST_STATE.md:1824,1860`); the file survives as the read-only `PhaseCensus` surface (item 10). *(Corrected in this PR: dated notes, in place — first wording called the file a tombstone; corrected same day on operator input.)* - This plan's own §0 row 1 and `INTEGRATION_PLANS.md` entry: "the blocker is the UDF body" — true as far as it went and still one generation behind; superseded by this §2. - `.claude/patterns.md:89` names `NotYetWiredHashUdf` as a live pattern — left as-is until the removal PR lands, then updated in that commit. diff --git a/.claude/v3/COMPONENT-MAP.md b/.claude/v3/COMPONENT-MAP.md index 28956a475..c85a965f6 100644 --- a/.claude/v3/COMPONENT-MAP.md +++ b/.claude/v3/COMPONENT-MAP.md @@ -76,7 +76,7 @@ Meta/Plasticity widths differ persisted-vs-hot with no parity test; | `physical/collapse.rs::CollapseOp` + Strategy #10 | REPURPOSE (rename) | per-query resonance-dispersion gate — NOT the retired singleton; rename candidate (`ResonanceDispersionGate`) to end the vocabulary collision | | `cache/` + `serve.rs` | REUSE | autocomplete/thinking cache; serve.rs is LAB surface | | symbiont `SymbiontBoard` (kanban_loop.rs) | EXTEND | POC proves the loop shape + the −550_000 µs Libet anchor **in code**; gap: `phase` is a bare struct field, not tenant-shaped (W2a); Domino work is called, not free-running — the standing-async-plan is NOT yet realized | -| supervisor `KanbanActor` | EXTEND | the most complete arm: S2 atomic MUL-gate-advance, S3 tick, S4 registry delivery, codex #578/#579 fixes tested; gap: unit-proven on TestBoard only, never integration-driven over a real MailboxSoA ⊘ **STALE (2026-09-05 W0 census):** `KanbanActor`/`KanbanMsg` + the RPC drivers were DELETED 2026-08-05 (`kanban_actor.rs:1-27` tombstone; `LATEST_STATE.md:1824,1860` — "KanbanActor has no assigned architectural responsibility"). The owner is `MailboxSoaOwner::try_advance_phase` (`soa_view.rs:311`) over the `KanbanColumn` DAG; `&mut` is the serialization. Do not extend or await this symbol. | +| supervisor `KanbanActor` | EXTEND | the most complete arm: S2 atomic MUL-gate-advance, S3 tick, S4 registry delivery, codex #578/#579 fixes tested; gap: unit-proven on TestBoard only, never integration-driven over a real MailboxSoA ⊘ **PARTLY STALE (2026-09-05 W0 census, corrected same day on operator input):** the ACTOR half — `KanbanActor`/`KanbanMsg` + the RPC drivers — was DELETED 2026-08-05 (`LATEST_STATE.md:1824,1860`); do not extend or await that symbol. The FILE is live: `kanban_actor.rs` is the read-only meta-awareness surface — `PhaseCensus` (one `&self` pass; the precedent `rubicon_witness.rs:32` cites), `mul_target` (composed by the production seal driver, `cycle_driver.rs:805`), `parse_kanban_step` — re-exported at `lance-graph-supervisor/src/lib.rs:82` and read by the awareness rungs (`rung_horizon.rs:5`). Ownership of the transition itself is `MailboxSoaOwner::try_advance_phase` (`soa_view.rs:311`) / `KanbanColumn::can_transition_to` over the DAG; `&mut` is the serialization. | | **ahead-firing batch writer** | NEW | zero code fires a kanban update at write CAST anywhere (grep-confirmed); lands as a new module wrapping BusDto commits, reading `envelope.mailbox_owner()` | | **delegation cache** | NEW | no delegation concept exists anywhere; small keyed cache inside the batch writer | | surreal_container | BLOCKED→flip-on | **coordinates RESOLVED 2026-06-16**; remaining block is the deliberate cold-build gate (`BlockedColdBuild`) — arm #2 is one dependency-uncomment away, at a ~10 min cold-build cost | diff --git a/.claude/v3/knowledge/mailbox-kanban-model.md b/.claude/v3/knowledge/mailbox-kanban-model.md index c3e39843e..57831cd57 100644 --- a/.claude/v3/knowledge/mailbox-kanban-model.md +++ b/.claude/v3/knowledge/mailbox-kanban-model.md @@ -27,7 +27,7 @@ proposes; the owner disposes. |---|---|---| | **Arm #1 — planner** | `lance-graph-planner/src/strategy/style_strategy.rs` | The D-MBX-A6 seam: the deferred `Outcome → Candidate/KanbanMove` adapter. Strategy outcomes (converged, cycle_count, gate verdicts) become kanban moves. | | **Arm #2 — symbiont** | `crates/symbiont` (`kanban_loop.rs` = POC) | SurrealDB-on-kv-lance executor: kanban updates as KV transactions on the same Lance substrate. Gated on the AdaWorldAPI surrealdb fork `kv-lance` feature. | -| **Structural owner** | `lance-graph-supervisor/kanban_actor.rs` | ractor actor per mailbox. **ractor is SOLELY the compile-time ownership guarantee** (name the role — the attestation must stay authoritative to the compiler; operator, 2026-07-17) — it spawns and proves single-ownership via move semantics (`KanbanActor` with `type State = O`; the owner MOVES in at `pre_start`); it is NOT a data-plane bus and **not for messaging — it is slow** (operator, 2026-07-02). **It MAY serve as a HELPER where it makes sense** — spawn, supervision, occasional control RPC like the serialized Advance/MulAdvance (the codex #578 atomicity mechanism) — always keeping the speed difference in mind: nothing on the hot path may wait on ractor latency; hot-path dispatch belongs to the D-V3-W2e-probed ExecTarget. ⊘ **STALE (2026-09-05 W0 census):** `KanbanActor`/`KanbanMsg` + the RPC drivers were DELETED 2026-08-05 (`kanban_actor.rs:1-27` tombstone; `LATEST_STATE.md:1824,1860` — "KanbanActor has no assigned architectural responsibility"). The owner is `MailboxSoaOwner::try_advance_phase` (`soa_view.rs:311`) over the `KanbanColumn` DAG; `&mut` is the serialization. Do not extend or await this symbol. | +| **Structural owner** | `lance-graph-supervisor/kanban_actor.rs` | ractor actor per mailbox. **ractor is SOLELY the compile-time ownership guarantee** (name the role — the attestation must stay authoritative to the compiler; operator, 2026-07-17) — it spawns and proves single-ownership via move semantics (`KanbanActor` with `type State = O`; the owner MOVES in at `pre_start`); it is NOT a data-plane bus and **not for messaging — it is slow** (operator, 2026-07-02). **It MAY serve as a HELPER where it makes sense** — spawn, supervision, occasional control RPC like the serialized Advance/MulAdvance (the codex #578 atomicity mechanism) — always keeping the speed difference in mind: nothing on the hot path may wait on ractor latency; hot-path dispatch belongs to the D-V3-W2e-probed ExecTarget. ⊘ **PARTLY STALE (2026-09-05 W0 census, corrected same day on operator input):** the ACTOR half — `KanbanActor`/`KanbanMsg` + the RPC drivers — was DELETED 2026-08-05 (`LATEST_STATE.md:1824,1860`); do not extend or await that symbol. The FILE is live: `kanban_actor.rs` is the read-only meta-awareness surface — `PhaseCensus` (one `&self` pass; the precedent `rubicon_witness.rs:32` cites), `mul_target` (composed by the production seal driver, `cycle_driver.rs:805`), `parse_kanban_step` — re-exported at `lance-graph-supervisor/src/lib.rs:82` and read by the awareness rungs (`rung_horizon.rs:5`). Ownership of the transition itself is `MailboxSoaOwner::try_advance_phase` (`soa_view.rs:311`) / `KanbanColumn::can_transition_to` over the DAG; `&mut` is the serialization. | ## The trigger: kanbanstep. There is no ack — the concept is ELIMINATED (operator, 2026-07-10/17) diff --git a/.claude/v3/knowledge/write-on-behalf.md b/.claude/v3/knowledge/write-on-behalf.md index 5dc285b2c..5c6b7c586 100644 --- a/.claude/v3/knowledge/write-on-behalf.md +++ b/.claude/v3/knowledge/write-on-behalf.md @@ -5,7 +5,7 @@ > ladybug-rs), and any session adding a write path to SoA rows / Lance > datasets / tenant lanes. -## Status: FINDING (operator-ruled 2026-07-02; batch writer + `owner_adapter` write-on-behalf cast SHIPPED 2026-08-01; `cycle_driver.rs` `cognitive_pass` is the existing production caller of `emit_bootstrap_intent` — HashMap-probe-fleet-driven; the first ACTOR-OWNED `KanbanActor` caller is the open W1 work, plan `kanban-64k-inverted-awareness-v1` D-KIA-A1) ⊘ **STALE (2026-09-05):** `KanbanActor` was deleted 2026-08-05; there is no actor-owned caller to await — see `LATEST_STATE.md:1860`. +## Status: FINDING (operator-ruled 2026-07-02; batch writer + `owner_adapter` write-on-behalf cast SHIPPED 2026-08-01; `cycle_driver.rs` `cognitive_pass` is the existing production caller of `emit_bootstrap_intent` — HashMap-probe-fleet-driven; the first ACTOR-OWNED `KanbanActor` caller is the open W1 work, plan `kanban-64k-inverted-awareness-v1` D-KIA-A1) ⊘ **STALE (2026-09-05):** the `KanbanActor` actor was deleted 2026-08-05; there is no actor-owned caller to await — see `LATEST_STATE.md:1860`. (`kanban_actor.rs` itself is live as the read-only `PhaseCensus`/`mul_target` surface.) --- From 58b8816d66e2975c96d48f69d347ff95ef4d7861 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 5 Sep 2026 16:49:18 +0000 Subject: [PATCH 9/9] CLAUDE.md: pin ruling caught up to lance 11 / lancedb 0.38 (#1190) Cargo.toml:261-264 said =11.0.0 / =0.38.0 while CLAUDE.md still ruled =9.0.0 / =0.33.0 and named lancedb 0.33 as the crate imposing the exact-equals. Two consecutive bumps left it stale (#1187 lance 10 touched only the arrow-ceiling paragraph; #1190 lance 11 touched neither), so the authoritative lines were wrong across a full major. - pin lines + the 'measured against crates.io' paragraph corrected; the lockstep sentence (duplicated, both copies stale) replaced by one line carrying the 7 -> 9 -> 10 -> 11 state - the E-PIN-LANCE9-... ruling regraded in place on its lance/lancedb coordinates ONLY; its datafusion half (54.1, never 53, delta removed) stands verbatim - arrow/datafusion unchanged: the ceiling is lance-wide, not ours - ISS-PIN-RULING-PROSE-DRIFTS-BEHIND-THE-MANIFEST: the ruling lives in two places and only the manifest is checked; a pins-match-the-manifest gate is proposed, not built (operator decision on cross-repo scope) Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01DCfrD5y19cvFc4AoyydXYv --- .claude/board/ISSUES.md | 32 ++++++++++++++++++++++++++++++++ CLAUDE.md | 34 ++++++++++++++++++++-------------- 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/.claude/board/ISSUES.md b/.claude/board/ISSUES.md index 20c9b79b2..04c7e3c8f 100644 --- a/.claude/board/ISSUES.md +++ b/.claude/board/ISSUES.md @@ -1,3 +1,35 @@ +## ISS-PIN-RULING-PROSE-DRIFTS-BEHIND-THE-MANIFEST (2026-09-05) — OPEN + +**The pin ruling lives in two places and only one of them is checked.** +`Cargo.toml`'s workspace table is what cargo resolves; root `CLAUDE.md` +§ "Key Dependencies" is what a session READS to learn the ruling. Nothing +compares them, so a bump PR that edits the manifest and not the prose leaves +the authoritative-looking text asserting a retired pin. + +**Measured (this session, after #1190 merged):** `Cargo.toml:261-264` said +`lance = "=11.0.0"` / `lancedb = "=0.38.0"` while `CLAUDE.md:1255-1262` still +said `=9.0.0` / `=0.33.0` and named lancedb 0.33 as the crate that *imposes* +the exact-equals. Two consecutive bumps left it that way — #1187 (lance 10) +updated only the arrow-ceiling paragraph, #1190 (lance 11) updated neither — +so the ruling lines had been wrong across a full major. Corrected in the +`open-ideas-fetch-v1` PR (#1185); the stale ⊘ ruling is regraded in place on +its lance/lancedb coordinates only, its datafusion half untouched. + +**Why it matters more than a typo:** every consumer repo's own `CLAUDE.md` +quotes this block as the cross-repo pin whitelist (MedCare-rs carries it +verbatim as an operator ruling). A session reading the stale text would pin a +consumer to lance 9 against a lance-11 spine and get an unsatisfiable graph — +the exact failure the block itself documents at `Cargo.toml:141-144`. + +**Proposed gate (not built — needs a decision):** a `pins-match-the-manifest` +CI check, same shape as `regenerate-and-diff`: parse the four family lines out +of `Cargo.toml` and out of the `CLAUDE.md` toml fence, fail on any mismatch. +Cheap (≈30 LOC), mechanical, and it fires exactly when a bump PR forgets the +prose. Open question for the operator: run it repo-local, or extend it to the +consumer repos that mirror the block. + +--- + ## ISS-STALE-AUTHORITY-LOCKS-RESIDUE (2026-09-04) — RESOLVED Corrects `ISS-STALE-AUTHORITY-LOCKS` (2026-08-25), whose *"Left open, diff --git a/CLAUDE.md b/CLAUDE.md index 400814db6..a3bd28357 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1204,9 +1204,8 @@ cd crates/lance-graph-python && maturin develop # lance / lancedb / arrow / datafusion family is pinned at all, and NO repo # tracks a Cargo.lock (.gitignore; ISS-STALE-AUTHORITY-LOCKS, RESOLVED). # -# Measured against crates.io 2026-09-05 -- lancedb 0.33.0 requires: -# lance* = "=9.0.0" (EXACT -- imposed on us, not our choice; it is also why -# the published lance 9.0.1 is unreachable) +# Measured against crates.io 2026-09-05 -- lancedb 0.38.0 requires: +# lance* = "=11.0.0" (EXACT -- imposed on us, not our choice) # arrow* = "^58.0.0" datafusion* = "^54.0.0" (CARET -- so ours must be too) # An exact `=58.4.0` on our side is strictly NARROWER than anything the family # asks for, and that is what makes a graph unsatisfiable: see Cargo.toml:141-144, @@ -1222,11 +1221,17 @@ cd crates/lance-graph-python && maturin develop # (Rust crate line is 0.33.0 -> 0.37.1 -> 0.38.0; 0.34/0.35/0.36 do not exist as # Rust crates -- those numbers are the independently-versioned PyPI package.) # -# The lance family moves in EXACT lockstep -- currently =9.0.0 (lance 7 was the -# 2026-06-14 state, superseded by the lance-9 sweep, b2b08b07 / PR #896 arc). -# moves in EXACT lockstep — currently =9.0.0 (lance 7 was the 2026-06-14 state, -# superseded by the lance-9 sweep, b2b08b07 / PR #896 arc). -arrow = "58" # 58.3.0 resolved; unmoved by the lance-9 sweep +# The lance family moves in EXACT lockstep -- currently =11.0.0. Line of state: +# lance 7 (2026-06-14) -> 9 (the lance-9 sweep, b2b08b07 / PR #896 arc) -> 10 +# (#1187, D-LNC-1) -> 11 (#1190, D-LNC-3, probe-gated on the D-LNC-2 fragment-id +# probe #1189). arrow/datafusion did NOT move with any of them. +# ⊘ The "=9.0.0 / lancedb =0.33.0" ruling recorded below as +# E-PIN-LANCE9-LANCEDB033-DF541-ARROW58-NO-DF53-1 is SUPERSEDED on its lance +# and lancedb coordinates ONLY (now 11 / 0.38.0); its datafusion half stands +# verbatim -- DF 54.1, never DF 53, and the `delta` feature stays removed. +# (A duplicated copy of this sentence stood here since the lance-9 sweep; both +# copies carried the stale number, so both are replaced by this one.) +arrow = "58" # unmoved by the lance-9, -10 and -11 sweeps alike datafusion = "54" # OUR direct pin, in every crate that DEPENDS on it # (lance-graph, -catalog, -callcenter, -python, holograph), # and the sub-crates move with it: datafusion-common / -expr @@ -1251,12 +1256,13 @@ datafusion = "54" # OUR direct pin, in every crate that DEPENDS on it # 2026-08-18; crates.io releases still DF 53) — as its # own deliberate PR if a consumer needs Delta. # Probe: .claude/plans/lance9-datafusion54-upgrade-probe-v1.md -lance = "=9.0.0" # exact-pinned: lancedb 0.33.0 requires lance =9.0.0 -lance-linalg = "=9.0.0" -lance-index = "=9.0.0" -lancedb = "=0.33.0" # the lance-9 pairing. NOTE: lancedb 0.36 is the PyPI - # package, versioned independently — the Rust crate - # tops out at 0.33.0 (probe §1). +lance = "=11.0.0" # exact-pinned: lancedb 0.38.0 requires lance =11.0.0 +lance-linalg = "=11.0.0" +lance-index = "=11.0.0" +lancedb = "=0.38.0" # the lance-11 pairing (`default-features = false` in + # the workspace table). NOTE: the Rust crate line is + # 0.33.0 -> 0.37.1 -> 0.38.0; 0.34/0.35/0.36 exist only + # as the independently-versioned PyPI package. rust = "1.97.1" # rust-toolchain.toml is authoritative; see its bump log ndarray = { path = "../../../ndarray" } # AdaWorldAPI fork, default, optional fallback nom = "7.1"