diff --git a/.claude/board/EPIPHANIES-ARCHIVE-2026-09-20.md b/.claude/board/EPIPHANIES-ARCHIVE-2026-09-20.md new file mode 100644 index 000000000..fa8f5a7af --- /dev/null +++ b/.claude/board/EPIPHANIES-ARCHIVE-2026-09-20.md @@ -0,0 +1,33528 @@ +## 2026-09-19 — E-THE-1224-DETOUR-CLEANUP-PASS-WHAT-WAS-CONTAMINATION-AND-WHAT-SURVIVES-1 + +**Status:** CLEANUP RULING (operator-directed, one pass, no new architecture). +**Confidence:** high — each row names the statement it supersedes and where it +lived. Board entries are append-only, so nothing below is deleted from the +ledger; the live PLAN is corrected in place (it is not a ledger) and the +corrections are listed here. + +### Exit condition this pass serves + +A new session reads the live board and reaches **SPOG + `f,c` → generic +reasoning → R2IL / replay / mask / fold / ternlog → next consequence / focus** +directly — without reproducing the #1224 causal-licensing detour, treating +OGAR as the thinker, conflating `G` with `ClassView`, weakening R2IL varnode +semantics, or demoting the Panama/Valhalla zero-copy lesson. + +### 1. Removed or superseded as contamination + +| # | statement, and where it stood | why it goes | +|---|---|---| +| C1 | *"High IG at `band = Relation` … requires an explicit Causal-band operation before any new CE64 is written"* (plan §1, and echoed in `E-THREE-CONVERGENCES-…-1`) | **Invented here, from band ordinality.** `ReasoningBand` is an explicit, coarse, ORTHOGONAL classifier; the source contract says setting one field never implies, derives or requires another. Not a permission ladder. **Deleted, and not replaced by another licensing mechanism** — any future epistemic/causal write gate must come from SPOG / `f,c` / provenance / revision semantics and measured code | +| C2 | *"Usefulness is not causal licensing"* as a doctrine derived from #1224; the helper-existence lesson; the zero-consumer census as the reason the PR closed | #1224 is **not an architectural source**. It was withdrawn because its premise was wrong; the census was forensic evidence only. All three derivations withdrawn | +| C3 | *"outer ontology `G` — which ClassView interprets the bytes"* (plan §2 list) | **Collapsed two axes.** `G` is the graph / context / frame / source context (an ontology graph, a patient graph, a code graph, an episode); `ClassView` is how canonical bytes are interpreted. Never the same axis | +| C4 | *"A varnode is not a buffer"* (plan §1, `E-A-VARNODE-IS-NOT-A-BUFFER`-adjacent text) | **Too broad.** R2IL varnodes ARE real typed machine values/locations with explicit size and address-space semantics. Narrowed to: *a varnode is not a semantic-population materialization obligation.* R2IL stays mechanical behavioral microcode; the zero-materialization freedom belongs to the binding/lowering layer | +| C5 | *"'Valhalla is the storage membrane' does not hold against the tree … Valhalla is E4: Vector API is permanently a lab arm"* (`E-LAYER0-IS-T1-…` item 3, this board) | **Conflated Valhalla with the Vector API lab arm — two different things.** Correct: **lance-graph / T0 owns canonical storage; Panama gives Java direct reach into it; Valhalla gives Java cheap value-shaped semantic carriers over it; lgj therefore inhabits the substrate zero-copy.** Valhalla is a Java-side storage MEMBRANE, never storage OWNERSHIP. E4 (no Vector API in `src/main`) is untouched and unrelated. lgj is one consumer teaching how this works — never the center | +| C6 | *"mount `ogar-dismech` + `dismech-rs` ⇒ DisMech behaviour becomes available"* read as activation | Mounting a graph makes **facts** available; generic reasoning is unchanged. `lance-graph-ogar` is a mount/integration seam, not an ontology reasoner. *We think with OGAR graphs; OGAR does not do the thinking* | + +### 2. Retained — independently supported, not #1224-derived + +`ReasoningBand` and `CausalTopology` exist as CE64 61–63 / 59–60 and are +orthogonal (read from `causal-edge/src/layout.rs`, not from #1224). The +**bidirectional domain inversion** #1224 exposed is real and still live in the +tree — that single historical fact survives, in +`ISS-DISMECH-SEAM-INVERTED-BOTH-WAYS`. And the measured Waben work is +untouched by this pass: mask operation ≠ materialized bitmap; a flat explicit +program lowers into fused execution; materialization is deliberate; W0/W1 +attestation; W2 range terminals and bounded composition; W3 semantic→geometric +rotation; W4 closed tile; W5 local focus; W6 publication cost; replay identity +and determinism; cache-by-key-mismatch rather than maintenance; Quack/DuckDB +economics; R2IL as mechanical behaviour; lgj as zero-copy evidence. **The +goose ride was in the architecture commentary, not in the execution plan.** + +### 3. Final DisMech seam wording + +``` +ogar-dismech the DisMech graph / vocabulary / source-specific semantics +lance-graph zero knowledge that DisMech exists — generic SPOG reasoning only +``` + +Per existing `dismech_*` file: generic mechanics → extract under generic names; +DisMech-specific semantics → the source/ontology side; entanglement-only code → +delete. **No generic-looking type may be minted to preserve DisMech policy** — +`Support / Partial / Refute / NoEvidence` is NOT promoted to a lance-graph +`Stance` absent an independent non-DisMech requirement; the SPOG / `f,c` model +gets first refusal. + +### 4. Final counterfactual module ownership + +⊘ **Amends the census addendum below**, which said the DisMech verdict type +should "collapse into" `revision::CounterfactualVerdict`. **Do not collapse the +measurement to remove a duplicate enum.** The two-arm reading is the +experiment: `Consistent → Inconsistent` clearly supports `Necessary`, and +`Consistent → Consistent` supports `Dispensable`, but `Inconsistent → *` are +**not automatically the same adjudication**. The shape is therefore +`CounterfactualAttack { factual, without_step, … }` with +`adjudicate() -> CounterfactualVerdict`, and **a falsifier covering all four +factual × cut-arm quadrants lands BEFORE the local reading type is deleted.** +Ownership stays: `contract/counterfactual.rs` = split-pole deposit; +`revision::CounterfactualVerdict` = the adjudication; `cognitive/world` = +fingerprint substitution (explicitly not structural intervention); the +structural cut/replay mechanics move beside the generic replay core — **no new +standalone `counterfactual_replay.rs`.** + +### 5. The center, restored in one line + +``` +SPOG + f,c → generic reasoning → R2IL / replay / mask / fold / ternlog → next consequence / focus +``` + +Around it, none of which redefines it: OGAR graphs = knowledge to consult; +Quack = lowering and economics; lgj = zero-copy runtime consumer; JC = +calibration and metrology; DeepNSM / ARM = priors and evidence producers. + +## 2026-09-19 — E-WE-THINK-WITH-OGAR-GRAPHS-OGAR-DOES-NOT-DO-THE-THINKING-1 + +**Status:** RULING (operator) + the ownership CENSUS it demanded before any +cut. **Confidence:** high; every row is read from the tree at +lance-graph `9fd6956d` / OGAR `ogar-dismech` + `ogar-ro` / MedCare-rs `90eb1f9`. + +### The rule, recorded before the cut is revised + +**Ontology thinking is a lance-graph / SPOG concern. OGAR ontologies are +knowledge graphs supplied to that reasoning substrate. `ogar-dismech` is one +optional graph to consult — not a DisMech reasoning plugin, not the owner of +ontology cognition.** Shorter: *we think with OGAR graphs; OGAR does not do the +thinking.* `ogar-ro`, `ogar-obo`, `ogar-fma`, `ogar-dismech`, a patient graph, +a code graph are all just `G` in `(S,P,O,G ; f,c ; topology ; band)`. There is +no "activate DisMech reasoning"; mounting a graph makes facts available and +nothing else changes. **The falsifier:** if generic reasoning must know WHICH +graph supplied a relation to run its mechanics, either the graph failed to say +what it means in SPOG / f,c / context, or domain policy leaked into the engine. +`G` may matter as provenance and context; it never selects an algorithm. + +⊘ This corrects the cut proposed earlier today in +`ISS-DISMECH-SEAM-INVERTED-BOTH-WAYS`, which gave `ogar-dismech` too much +agency (it was to "grow the typed parse") and proposed `contract::revision:: +Stance` — the DisMech `supports` vocabulary renamed and promoted, i.e. the +same contamination with the serial number filed off. Both withdrawn. + +### Ownership census of `lance-graph-contract/src/dismech_evidence.rs` (817 lines) + +| item | what it is | owner | disposition | +|---|---|---|---| +| `DismechTopology` (4) + `from_source` | the `causal_link_type` YAML tokens `DIRECT / INDIRECT_KNOWN_INTERMEDIATES / INDIRECT_UNKNOWN_INTERMEDIATES / UNKNOWN` — its meaning is ALREADY generic as `causal_edge::CausalTopology` (CE64 59–60), 1:1 by the module's own doc | **source-format** | the enum is redundant with `CausalTopology`; the token parse belongs with whoever reads the source (see open decision) | +| `Supports` (4) + `from_source` | `SUPPORT / PARTIAL / REFUTE / NO_EVIDENCE` — **zero consumers outside `dismech_candidates.rs`** | **source-format** | NOT promoted to a generic `Stance`; at ingestion it becomes SPOG evidence attributes / `f,c` (a REFUTE is a relation with negative polarity or low `f`, the domain's call) | +| `EvidenceSource` (5) + `from_source` | `HUMAN_CLINICAL / MODEL_ORGANISM / IN_VITRO / COMPUTATIONAL / OTHER` | **source-format** | source side | +| `modifier` (7), `frequency` (19) | in the doc table only; no enum exists | — | nothing to move | +| `CitationNamespace / CitationKey / BibliographyRecord` (+ `ContentId`) | `(namespace, id)` citation identity — PMID/DOI/URL are cross-domain, ORPHA/CGGV are medical; **zero consumers outside the module** | domain-neutral in SHAPE, single-domain in USE | no independent cross-domain consumer exists, so it does NOT earn a generic home today; it travels with the source side and returns as `contract::citation` when a second domain needs it | +| `DISMECH_PREDICATE_FLOOR`, `DISMECH_PREDICATES`, `dismech_predicate`, `is_dismech_predicate` | the predicate mirror; authority `ogar_dismech::{RELATIONS, CAUSES, by_index}` | **ontology identity, already owned by `ogar-dismech`** | **DELETE** | + +### Census of the planner modules + +| module | generic mechanics (stay, domain-neutral name) | DisMech knowledge (leaves) | +|---|---|---| +| `dismech_replay.rs` | `ChainStep`, `ReplayTraceRow`, `ComposeTables`, `replay_step/chain`, `first_divergence`, `next_base_seq` | `validate_chain` / `chain_step_predicate` against the mirror. Replacement is a GENERIC validity contract (`validate_chain(chain, is_valid_predicate)`), acceptable only because the validator is generic — proven by running the SAME code under two vocabularies (`ogar_dismech::by_index` and `ogar_ro::by_index` both exist) | +| `dismech_counterfactual.rs` | cut-one-step, both arms, load-bearing test | none — but its `Verdict{Consistent, Inconsistent}` / `EdgeRole::is_load_bearing` must reconcile with the EXISTING generic `revision::CounterfactualVerdict{Necessary, Dispensable, NotRun}`; two verdict types for one question is the drift the cut exists to remove | +| `dismech_candidates.rs` | `EvidenceMask` (already generic, `revision.rs:31`) | the POLICY `Support ⇒ ∩ · Refute ⇒ ∖ · Partial/NoEvidence ⇒ no-op` is derived from the source vocabulary, has zero independent consumers, and is NOT canonized as a lance-graph law. `apply/evaluate/is_informative` go with it unless they take the OPERATION as input rather than the stance | + +### `lance-graph-ogar` is a mount, not a reasoner + +Its test is not "lance-graph can replay a DisMech chain". It is: register a +vocabulary → build ordinary SPOG relations → hand generic inputs to +lance-graph → **the identical program runs when the graph is `ogar-dismech`, +`ogar-ro`, or another registered vocabulary.** Mount, unmount: only available +knowledge changes. + +### Acceptance (replaces the token-grep as the decisive test; the grep stays as hygiene) + +1. lance-graph generic reasoning compiles and tests with no DisMech present. +2. Mount `ogar-dismech`: no reasoning code changes; facts become available. +3. Mount a second unrelated graph: the SAME machinery consults it. +4. Unmount `ogar-dismech`: nothing changes but available knowledge. +5. No DisMech source enum or policy has been renamed into lance-graph to + preserve existing code. + +### One open decision, flagged, not decided here + +Two versions of the ruling arrived; they agree on everything except WHERE the +source-token parsers live: one places them in `dismech-rs` (source/domain +implementation), the other allows `ogar-dismech` (source normalization is a +vocabulary concern). Read from the tree: `dismech-rs` is not a local checkout; +MedCare's `medcare-dismech` bake tool already carries its own fail-closed +token match (`freeze.rs`) and is the only thing that reads the YAML today. So +the parse currently lives with the reader, which is the source side either +way. Recorded as open; nothing is moved into `ogar-dismech` until it is closed. + +## 2026-09-19 — E-THE-CENTER-IS-SPOG-PLUS-FC-EVERYTHING-ELSE-IS-CAST-1 + +**Status:** RULING on the center of gravity for the whole arc; FINDING on what +exists; PROPOSAL on thought-as-relations. **Confidence:** high on the ruling +and the inventory (read-verified below); the proposal has no code. + +### The center + +``` +SPOG S, P, O + G (context / graph / frame) — the semantic address space ++ f, c evidential frequency + confidence — the compact evidence currency ++ CE64 59–60 causal-topology lens — what causal route the edge claims ++ CE64 61–63 ReasoningBand — in what context it is being read + ↓ generic reasoning over relations + ↓ mask / fold / ternlog / neighbourhood + ↓ next focus / novel consequence / reusable thought +``` + +Four orthogonal questions, one atom: `(S,P,O,G) f=.82 c=.91 Topology=IndirectKnown +Band=Relation`. A counterfactual thought reads it under `Band=Counterfactual` +without overwriting the factual relation; a Meta thought asks whether the +relation or the thought that produced it transfers. Reasoning maturity is NOT +encoded into `f,c`; that is what the bands are for. + +**Read-verified, all present today:** SPOG — `contract/spog_tenants.rs`, +`doc_graph.rs`, `wave_dispatch.rs`, `alpha_focus.rs`, `arigraph/triplet_graph.rs`; +D-SPG-1/D-SPG-2 shipped 2026-09-07. `f,c` — `graph/spo/truth.rs` (NARS +`TruthValue` = frequency, confidence, with `TruthGate`). CE64 59–60 / 61–63 — +`causal-edge/src/layout.rs`. Nothing at the center needs minting. + +### Everything else is cast, and goes back in its box + +``` +SPOG + f,c KNOWLEDGE +CE64 bands CONTEXT / CAUSAL READING +R2IL + ogar-loco BEHAVIOR — what operations happen given bound values; never the knowledge model +mask / fold / ternlog EXECUTION +Quack / DuckDB teaches physical lowering + economics (an SPOG conjunction is + Mask(P1,O1,G) AND Mask(P2,O2,G) → Count/Any/NextFocus, never a join table) +lgj / Panama / Valhalla proves another runtime can inhabit it zero-copy +DeepNSM / COCA / ARM supply priors, role/context, evidence +JC calibrates whether a signal is real +``` + +None of Quack, R2IL, Valhalla, Panama, DisMech or MedCare redefines the center. +Tarski / Shannon / JC sit ABOVE the graph as operators on the SPOG field, not +as another ontology: monotone closure `X_{n+1} = X_n ∪ F(X_n)` until `ΔX = ∅`; +information gain at choice points; JC at evidence boundaries. + +### Thought transfer in SPOG terms — PROPOSAL, no code + +A previously useful thought is itself relations, with `f,c` on each: +`H uses_predicate P · H binds_role S/O/G · H useful_under Context · H produced +Consequence · H transfers_to TargetContext`. "Use this other thinking as a +dictionary" is then ordinary graph reasoning — find motifs with compatible +G/role/POS/vocabulary, rank by `f,c`, rebind, run, test whether new SPO +relations resulted, update the transfer evidence. No analogy subsystem. The +reusable thing is boring — *select relation set · intersect with context · find +residual · follow neighbours · test terminal* — and SPOG supplies the meaning; +POS/register/context refine G rather than opening a second score universe. +Verified absent from the tree (`uses_predicate` / `transfers_to` / +`useful_under`: zero hits) — a proposal, recorded as one. + +### Standing rule + +The endgame is a self-reusing SPOG reasoning machine where evidence, context +and prior successful motifs make the next semantic operation cheaper to choose +and cheaper to execute. **No more DisMech archaeology unless it physically +blocks this path** — `ISS-DISMECH-SEAM-INVERTED-BOTH-WAYS` stays filed with +its three-PR shape and is executed on operator word, not pursued further here. + +## 2026-09-19 — E-A-DOMAIN-IS-AN-OPTIONAL-CONSUMER-THROUGH-OGAR-NEVER-A-CO-DEFINER-1 + +**Status:** RULING (sharpens `E-1224-WAS-A-BIDIRECTIONAL-DOMAIN-INVERSION-…-1` +directly below). **Confidence:** high; every edge cited is read from the tree. + +The #1224 failure, stated in one line: the architecture forgot that DisMech is +an **optional domain consumer of lance-graph through OGAR**, and let the +substrate and the domain define each other. Consequences that the earlier +entries under-stated: + +- `lance-graph-contract/src/dismech_evidence.rs` is not "in the wrong + neighbourhood"; **it should not exist in lance-graph.** Zero dependency + weight and byte-perfect parity are not the question — semantic ownership is. + Its only external consumer imports it as `mirror` to assert parity against + `ogar_dismech::RELATIONS` (`lance-graph-ogar/src/lib.rs:228,320,342`): a copy + whose whole job is to be compared to the original. +- The three planner `dismech_*` modules are wrong AS DisMech modules however + much generic algebra they contain. Generic algebra is extracted into a real + domain-neutral home; DisMech knowledge moves to `ogar-dismech`; what existed + only through the entanglement is deleted. **Never** a rename, **never** a + feature flag — both preserve the inversion, one awake and one asleep. +- Compile-time ownership runs one way: `ogar-dismech` depends on lance-graph + and integrates `dismech-rs`; with both present DisMech behaviour exists, + without them lance-graph is unaware DisMech exists. + +The repair test is the contamination test: **can lance-graph compile, test, +document and explain every public concept without knowing DisMech exists?** If +not, the seam is still cut wrong. The positive half is separate: **can +`ogar-dismech` + `dismech-rs` bind onto the generic mechanics without modifying +lance-graph?** Resolution shape and measured edges: +`ISS-DISMECH-SEAM-INVERTED-BOTH-WAYS` (corrected entry). + +## 2026-09-19 — E-1224-WAS-A-BIDIRECTIONAL-DOMAIN-INVERSION-NOT-A-LEAK-1 + +**Status:** SHARPENING of the two entries below it. **Confidence:** high — both +directions are measured in #1224's own body, and the second is still live. + +The two #1224 corrections below describe a one-way leak: disease-specific +semantics crossed DOWN into the generic thinking substrate. That is half of it. +#1224's own addendum measured the other half: of the 1,941 planner lines under +`dismech_*` names, **1,547 (80 %) carry no DisMech semantics at all** — +`dismech_counterfactual.rs` (674 lines, 0 domain refs) and `dismech_replay.rs` +(873, one label lookup) are generic counterfactual-replay algebra that merely +inherited a domain filename because MedCare was the first consumer. So generic +reasoning crossed UP and got trapped inside domain vocabulary at the same time +domain vocabulary crossed down. A Möbius strip, not a leak: + +``` +MedCare / DisMech semantics ──▼ leaked down ──▶ lance-graph thinking substrate +lance-graph generic reasoning ──▲ leaked up ──▶ stranded behind dismech_* names +``` + +The boundary is supposed to be one-way and boring: domain semantics adapt / +bind / provide evidence through the OGAR vocabulary and the loco seam INTO the +generic substrate; generic results (mask, replay, evidence, causal result) come +back and the DOMAIN interprets them in its own vocabulary. Neither a domain-named +planner in the substrate nor generic algebra under a domain filename. + +**This is why "re-home the helper" was never enough** — the seam itself had to +be re-established, and it has not been: all four `dismech_*` files are on this +branch today (1,941 planner lines + `dismech_evidence.rs` in the zero-dep +contract). Filed as `ISS-DISMECH-SEAM-INVERTED-BOTH-WAYS`. Cross-ref: the +consumer-side mirror is `ogar-consumer-preflight.md` (a consumer never +re-implements the Core locally) — the same seam, seen from the other bank. + +## 2026-09-19 — E-1224-CLOSED-FOR-BEING-WRONG-NOT-FOR-LACKING-CONSUMERS-1 + +**Status:** CORRECTION of the entry directly below this one. **Confidence:** +high — read from the PR body. + +⊘ `E-ONE-OBSERVABLE-IS-NOT-THREE-INSTRUMENTS-…-1` says #1224's helpers were +"deleted after a measured zero production consumers" and lets that read as the +reason the PR closed. **Wrong causal reading.** #1224 was withdrawn and closed +unmerged because it was **fundamentally wrong**: it turned a criticism into an +invented maturity-ladder specification (states, counters, a progression, and +acceptance criteria that never existed), and it placed causal-licensing +semantics inside a DisMech module against the ruling that DisMech is not a +thinking atom. The zero-consumer count was a footnote — it meant the deleted +helpers needed no re-homing, nothing more. + +The compression is the defect the PR itself names: a measurement standing next +to a decision was promoted into its cause. Recorded by prepend; the plan's §1 +paragraph is corrected in place (live plan, not ledger). + +## 2026-09-19 — E-ONE-OBSERVABLE-IS-NOT-THREE-INSTRUMENTS-AND-IMPORTS-ARE-PROBES-1 + +**Status:** FENCE (ruling) + CORRECTION + five named PROBES, all unscheduled. +**Confidence:** high on the fence and the correction (read-verified); the +probes are conjectures by construction. + +### The fence + +A lateral pass on the Waben loop produced this sentence, in chat only, never +committed: *a frontier XOR-popcount is Tarski when it reaches zero, Shannon +when its delta reaches zero, and JC when compared to the Jirak floor.* **Struck +before it was ever written down as a rule.** A popcount is an OBSERVABLE that +may be fed to all three analyses; it is none of them. Tarski is a fixed point of +a monotone operator on a lattice; Shannon is `−Σ p log p` and gain is a +difference of it; JC is distinguishability from a calibrated weak-dependence +regime (`I-NOISE-FLOOR-JIRAK`), not a threshold on a count. `popcount → 0` is +not a fixed point (a non-monotone step can raise it) and not zero entropy (a +stable non-zero disagreement is low-entropy with non-zero popcount). Same +failure shape as `MaskOp`-means-bitmap: a carrier promoted to a semantics. +Sibling fence already on the board: entropy says WHERE closure is, never WHAT +hole (CE64 59–60) nor HOW asserted (61–63). + +### Roaring sits under `KEEP`, not in place of the mask expression + +Density-adaptive containers answer *which representation for a set I have +decided to hold*. The arc's primitive answers the prior question — *whether a +represented set is needed at all* (`Fold × Fold × AND × TERNLOG → COUNT` holds +no set). Where `Terminal::Keep` elects one, Roaring's per-chunk rule is a fine +container choice. It is not an argument for eager ops. Recorded so it is not +re-imported one tier too high. + +### Correction: #1224 resolves — as a NEGATIVE receipt + +The entry below this one (`E-THREE-CONVERGENCES-…-1`) says a citation to +"#1224" does not resolve. That was a search of `.claude/` and `docs/` only. +Read from GitHub: **#1224 exists, was withdrawn and closed without merging**, +and the two causal-licensing helpers it added were **deleted after a measured +zero production consumers**. It must not be cited as positive architecture; its +failure is exactly the lesson — a helper existing is not enforcement, and +usefulness or association does not grant causal status. The plan's §1 paragraph +is corrected in place (it is the live plan, not a ledger); this entry corrects +the ledger by prepend. + +### The five imports — probes, each with a falsifier (plan §9) + +Retina (read as contrast → sparse FIRE by consequence); inhibition of return +(deliberately non-monotone, OUTSIDE Tarski closure); erosion (Go/Bouzy — +`expand → close → prune → close`, never "add erosion to Tarski"); pre-shaped +geometry (a VIEW selects a codebook trained for its own predicates — NOT one +global order, which fixes one lens by breaking another); aperture (depth as +address resolution, orthogonal to `ReasoningBand`: band = what KIND, prefix = +what RESOLUTION — never collapse). **Evidence check on the last one:** +`facet.rs:645/683/796` `i >> 2` is `G3D4::group_of`, a carving shift — NOT a +rung ladder. "Rung = prefix depth" stays CONJECTURE until depth-stepping is +shown to move IG monotonically on a real lane. + +The shared rhythm is the two-stroke engine already ruled: monotone stroke to a +fixed point, then a non-monotone stroke (inhibit / prune / revise / change +resolution / change dictionary / change band), then closure again. Thinking +harder need not mean more state. + +## 2026-09-19 — E-THREE-CONVERGENCES-TARSKI-SHANNON-JC-AND-THE-BAND-IS-A-SANDBOX-1 + +**Status:** RULING on the demarcations; FINDING on the inventory +(read-verified); **GAP** on the entropy half. **Confidence:** high on what was +checked; one cited reference did not resolve. + +### Three convergences, never to be conflated + +``` +TARSKI have I exhausted the consequences? X_{n+1} = X_n +SHANNON am I still learning anything? ΔH ≈ 0 +JC is the apparent information bigger than substrate noise, + dependence and representation drift? +``` + +**Tarski gives the Wabe's `delta == empty` a REASON.** On a finite lattice +`L = (P(E), ⊆)` with monotone operators, the inflationary chain +`X_{n+1} = X_n ∪ ⋃_H F_H(X_n)` must stop, and its stopping point is the least +fixed point of the admitted operators. Lattice termination, not a +done-thinking detector. + +**But ANDNOT, retraction, confidence decay, inhibition and counterfactual +replacement destroy monotonicity** — legal, but a different phase. A two-stroke +engine: MONOTONE CLOSURE (accumulate → fixed point) / NON-MONOTONE REVISION +(retract, counterfact, decay → a new starting state) / closure again. ⊘ The +D-WFL recurrence `A_{t+1} = (A_t ∪ ⋃_d S_d(A_t ∩ P_d)) ∩ T` is the monotone +stroke ONLY, while §5's `ANDNOT explained` is already the other one — the first +slice crosses the phase boundary and must say so. + +### The band is a semantic sandbox — usefulness is not causal licensing + +Read-verified in `crates/causal-edge/src/layout.rs`: + +- **bits 59–60 `CausalTopology`** `{Direct, IndirectKnownIntermediates, + IndirectUnknownIntermediates, Unknown}`, documented as an *"additive factual + view over `TrustTexture`"* — ONE physical field, two lenses, not two + independent variables. +- **bits 61–63 `ReasoningBand`** `{Surface, Association, Relation, Causal, + Counterfactual, Perspective, Meta, Transcendent}`, with explicit orthogonality + notes to `CausalMask`, the inference mantissa's −6 slot, and `direction`. + +**The ruling:** a donor thought at `band = Relation` with `f=.81, c=.94` and +spectacular information gain **must not be silently promoted to causal +knowledge.** High IG makes it a *candidate causal investigation*, which then +requires an explicit Causal-band operation before any new CE64 is written. +`Counterfactual` may likewise explore without mutating factual causal state. The +band is a sandbox label around identical R2IL mechanics. + +⊘ **A citation to "#1224" for this distinction does not resolve** — no `#1224` +anywhere in `.claude/` or `docs/`, and no board text matching *"causal +licensing"* / *"usefulness is not"*. The PRINCIPLE stands on its own merits and +on the orthogonality notes in the source; the REFERENCE does not, and is +recorded as uncited rather than repeated as established. + +And `ReasoningBand::Meta` earns its keep with **no meta-opcode**: bind the +fold/mask machinery to the thought programs and transfer histories themselves — +which donors transfer, which repeatedly fail, which masks deserve caching, which +motifs collapse uncertainty fastest. Exactly what the variant's own doc comment +says it is for. + +### JC is the brake; the entropy half does not exist + +Read-verified present in `crates/jc/src/`: `jirak.rs`, `cartan.rs`, `weyl.rs`, +`drift.rs`, `ewa_sandwich{,_3d}.rs`, `reliability.rs`, `quorum.rs`, `pearl.rs`, +and `stats.rs` (`cohen_kappa`, `omega_total`, `phi`, `binary_association`, +`kr20`, `multiple_r_squared`, `eta_squared`, the t-test family). + +⊘ **`jc` contains NO Shannon/entropy implementation** — zero hits for +`shannon`/`entropy` across its source. The information-gain half of any such +scheduler **must be built**; naming it is not having it. Filed as a gap, not a +capability. + +**And the trap it must avoid is already an iron rule one level down.** 500 +candidate thoughts sharing prefixes, vocabularies, R2IL motifs and masks are +**not independent lottery tickets**. Raw `−Σ p log p` is a fine descriptive +quantity; an information-GAIN claim about this substrate needs dependence +calibration, because `I-NOISE-FLOOR-JIRAK` already establishes that classical +IID Berry-Esseen is wrong for these fingerprints. So `R_JC` is not one scalar — +it means *passes the relevant dependence, noise and reliability gates*. The +scheduler is the iron rule's next consumer, and it does not get an exemption for +being cognitive. + +### The shape, for when it is built + +``` +X_{t+1} = X_t ∪ ⋃_H 1[ G(f_H, c_H, T_H, B_H, C_t) ] · F_H(X_t) +U(H) = IG(H) · R_JC(H) / C_fold(H) +stop when X_{t+1} = X_t, or earlier when max_H U(H) < ε +``` + +`G` is a cheap eligibility GATE composed from currencies that already exist — +never one giant score. And underneath all of it the computation stays the stupid +beautiful thing: fold × mask × ternlog × popcount → three bits of consequence, +without ever constructing the state the question never required. + +## 2026-09-19 — E-A-VARNODE-IS-NOT-A-BUFFER-R2IL-IS-MICROCODE-FOR-MASKED-THINKING-1 + +**Status:** RULING on the framing; FINDING on the inventory (cross-repo, +read-verified at OGAR `5055b06`, r2sleigh `99d2553`); CONJECTURE on motif +mining. Twin of `E-A-MASK-EXPRESSION-DOES-NOT-IMPLY-A-BITMAP-1`, one level over. + +> **A varnode is not a buffer.** R2IL varnodes carry behavioral DEPENDENCIES, +> not an obligation to materialize their values. `v2 = ternlog(v0,v1,…)` may +> never exist as bytes. + +Compiler instinct reads `v0 = …; v1 = AND(v0,…)` as *allocate a representation +per name*. The intended semantics is SSA in a **fused dataflow engine**: a +varnode names a logical value / address / membership expression, and only a +terminal requesting membership as a carrier forces bytes. Exactly the mask +error, transposed. + +### The architecture is already in the tree, in fragments nobody had joined + +- **`ogar-r2il/src/lib.rs`** module doc: *"proxy glue: r2sleigh's R2IL opcode + set as an `ogar_loco::Vocabulary`, plus the **masked lane projection** that + re-reads one already-written body under any `LaneShape` **without rebuilding + it**."* That clause IS the non-materializing re-projection this arc spent a + day deriving — already shipped, in another repo, under another name. Surface: + `project()`, `project_r2il()`, `r2il_mask()`, `CallMask { shape: LaneShape }`. +- **`ogar-loco/src/basin.rs:94-98`**: *"Orchestration is agnostic; the thinking + IR is a caller… `ogar-r2il` plugs its vocabulary and codebooks in."* **The + wrapper is `Vocabulary`** — the seam exists; nothing needs minting. +- **`ogar-r2il` carries NO `r2sleigh` dependency by design**: 82 arities as a + table, pinned to the source enum by a drift test. The opcode set travels as an + arity table, not an object graph. +- **`LOCO-ORCHESTRATION-GAP.md`**: R2IL occupies one **classid** vocabulary + while query / NARS-tactic / Blockly occupy their own through the same + registry. + +### ⊘ Two corrections to the premise, both read-verified + +1. **r2il is STRONGLY TYPED, not "nontyped".** `r2sleigh/doc/r2il.md`: *"a + strongly-typed intermediate language based on Ghidra's P-code operations. + Every operation has explicit input and output varnodes with known sizes and + address spaces."* It exists to fix ESIL's untypedness. **This strengthens the + design:** it types the MACHINE (sizes, address spaces), never the MEANING — + precisely the "keep the opcode table embarrassingly mechanical" property to + protect. ABI-friendliness comes from sized varnodes + explicit spaces + serde + + the arity table, not from absent types. +2. **NAME COLLISION — the shape that bit this arc twice today.** + `membrane-tiers.md:24-25` places an **"R2IL" at T3** (*"emits T3 artifacts… + its ceiling IS T3's; door-knocker test"*), beside the Java facade and + low-code. The R2IL here is behavioral microcode far below that. Two things + named R2IL at opposite ends of the ladder is exactly how T1 and T2 got + flattened this morning. **Whichever keeps the name, the other must be renamed + before either is built against.** Filed as an issue, not resolved here. + +### The joining sentence + +> R2IL is **not** the harvested representation of machine code. R2IL is the +> **vocabulary-neutral behavioral microcode for masked thinking.** Harvesting +> via r2sleigh/ruff is one PRODUCER of R2IL programs. `ogar-loco` orchestrates +> them, `classid` selects their vocabulary, and the substrate executes their +> mask/fold expressions **without materializing intermediate populations unless +> a terminal explicitly requests one.** + +And the whole doctrine, shorter than this arc's Layer-0 prose: *SPOG says what +exists. ClassView says how to see it. `ogar-loco` says what to do next. R2IL +says how the thought behaves. Mask/fold algebra executes it without constructing +what it can merely observe.* + +**Keep cognition OUT of the opcode table.** No `NARS_REVISION`, `EMPATHY`, +`CAUSE`, `ANALOGY` opcodes — that destroys the entire advantage. Cognition lives +in bindings, composition, macro discovery, selection, focus, terminal +interpretation and the Rubicon; never in opcode semantics. + +**Re-reading of the harvest (CONJECTURE — no motif mining has been run):** not +*"assembly instructions we collected"* but *millions of tiny programs humans +already wrote to transform, compare, gate, branch, select, normalize, search and +decide.* BPE/macro mining over R2IL streams would then discover reusable +BEHAVIORAL MOTIFS — promotable to callable operators and bindable to entirely +different classid-selected vocabularies. Harvest → R2IL → motif discovery → +promote → bind → execute as masked thought. This names an endgame, not a result. + +## 2026-09-19 — E-A-MASK-EXPRESSION-DOES-NOT-IMPLY-A-BITMAP-1 + +**Status:** RULING — the global primitive the whole D-WFL arc was circling. +Subsumes the six fold-law entries written today; none is wrong, all were one +level too low. **Confidence:** high; the relocation of the defect is +read-verified. + +> **Mask algebra is globally NON-MATERIALIZING by default. A mask EXPRESSION +> denotes membership; it does not imply a bitmap exists. Materialization occurs +> only at an explicit TERMINAL, when the membership set itself is requested as a +> carrier.** + +This is stronger and more accurate than *"folds are zero-copy"*, because it lets +folding, masking, ternlog, gating, projection and reduction all participate in +ONE zero-materialization algebra. **The fold was never the whole trick.** The +trick is that the expression can remain unevaluated as population state all the +way to a low-entropy terminal — DuckDB's pipeline insight, in a semantic +substrate. + +**Three concepts; this arc collapsed 1 and 3 for a full day:** + +``` +1. MASKING a Boolean/ternlog/gating OPERATION — may be entirely + zero-materialization +2. MASK EXPRESSION a composition of predicates/folds/fields/populations — + still need not exist as a bitmap +3. MATERIALIZED MASK an actual membership bitmap, chosen because its BITS are + useful downstream +``` + +Collapsing 1 into 3 is exactly why the discussion oscillated between *masks are +wonderful* and *masks violate folds*: both were true, of different referents. + +**`ClassView` × `WideFieldMask` were designed for this.** `WideFieldMask` is a +field-PARTICIPATION currency, not a tiny bitmap — *only these semantic facets +take part*. Stack the apertures optically (ClassView × WideFieldMask × semantic +bound × focus × permissions × temporal POV × another dataset) and measure what +survives; **do not manufacture a new transparency after every aperture.** +Cognition and rendering are the same photolithographic machine with different +lenses and terminals, and neither inherently needs a population mask. + +### The defect relocates: the election is ALREADY in the ISA, and the ops annihilate it + +Read-verified in `lance-graph-mask-risc/src/ir.rs`: + +- `Terminal::Keep { mask }` (`:184`) — *"The final mask itself stays in `mask` + (a scratch slot the caller reads back); nothing is reduced."* **That IS the + materialization election.** `Count` / `Any` / `All` / the masked reductions + never request the membership set as a carrier. +- But `MaskOp::And { a, b, dst }` is documented `dst = a & b`, and **every + `MaskOp` is an assignment to a destination slot.** So the ops destroy at level + N−1 precisely the choice the terminals encode at level N — and `exec.rs:566` + then forces every slot to `words_for(n_rows)`. + +> **`MaskOp` must not semantically mean "produce a Scratch mask". It must mean +> CONTRIBUTE TO A MASK EXPRESSION. Scratch is one possible physical LOWERING, +> never the semantics.** + +**So `Pred::Range → Scratch` is a SYMPTOM, not the disease.** Every earlier +framing of Seam B — performance complaint, T1 conformance failure, fold-law +violation, absent decision — was chasing one op. Fixing `Range` alone leaves +`And`, `Or`, `Xor`, `AndNot`, `Ternlog` all writing full planes. The correction +belongs to the execution MODEL: + +``` +MaskExpr: A AND B ANDNOT C TERNLOG D,E,F RANGE lo,hi GATE focus + ├─ Terminal::{Any, Count, First, Reduce} + │ fuse to registers; NEVER emit intermediate membership bits -> u64 + └─ Terminal::{Keep, Cache, Publish} + permission to create the bitmap +``` + +**And half the "missing primitives" dissolve into lowering rules.** The fused +`popcount(a & b)` of `D-WFL-T1-FUSED` is not a bespoke instruction — it is what +a fuser emits for `MaskExpr → Terminal::Count`. `fuse.rs` already collapses a +Boolean tree into one ternlog; what it does not do is fuse **across the +op → terminal boundary**, which is exactly the boundary this ruling moves. + +### Why this took a day, recorded so it is not repeated + +The design already encoded the distinction — `Keep` vs `Count`, and +`WideFieldMask` as a participation currency rather than a population. What was +never written down is **the semantics of `MaskOp`**, so every reading defaulted +to its physical lowering, and `Mask × ClassView/WideFieldMask → Mask` was read +as *allocate a bitmap* when the arrow only ever meant *denotes membership*. A +spec gap, not a misunderstanding by anyone: an unstated semantics will always be +read as its implementation. + +The compounding error was mine: six escalating laws about FOLDS, each corrected +in turn, while the actual primitive sat one level up in the mask algebra. Each +law was true and none was the general case. + +## 2026-09-19 — E-MASKING-IS-AN-OPERATION-A-MASK-IS-A-CARRIER-1 + +**Status:** RULING — corrects the AXIS of +`E-FOLD-AND-MASK-ARE-SIBLING-PHYSICAL-PLANS-1` (written minutes earlier), whose +substance stands. **Confidence:** high. This is the cleanest formulation the arc +has reached. + +> **Masking is an OPERATION. A mask is a CARRIER. Never confuse the two.** + +⊘ The previous entry framed the choice as *"FOLD path vs MASK path"*, which +implies that electing to mask means giving up zero-copy. **It does not.** Two +datasets can be folded and masked against each other with **no materialization +at all** — and that is not a compromise, it is probably the ideal Layer-0 +operation: + +``` +dataset A ──fold──┐ + ├─ AND / TERNLOG / gate ──> tiny answer +dataset B ──fold──┘ + no mask population ever exists +``` + +The membership relation lives **logically, in registers**; the result is a +`Count`, an `Any`, a `[lo,hi)`, a `First`, a next focus. The photolithography +metaphor lands exactly here: **shine two patterns through each other and measure +where the light survives — you do not manufacture a transparency showing every +surviving pixel.** + +**Three independent axes, not one binary:** + +``` +OPERATORS CARRIERS MATERIALIZATION CHOICE +fold canonical lane fused / zero-copy +mask · ternlog range materialized bitmap +project descriptor +rotate resident mask +neighbour cached mask +reduce … +``` + +**The entropy principle that falls out — the sharpest statement of the arc:** + +> **Representation entropy should follow ANSWER entropy.** + +*"Do these two million-row semantic regions intersect?"* carries ~1 bit. +Constructing 125 KB of mask to discover that bit is the obscenity — and 125 KB +is not rhetorical: it is Seam B's measured number at N = 1M. *"How many +overlap?"* is 32–64 bits. Both belong in the fused arm. + +Conversely *"give me the overlap, because six later thoughts will manipulate it +spatially"* justifies materializing — the bitmap is then the **low-entropy +working representation relative to its future workload**, even though it dwarfs +the immediate scalar. + +**So the BBB's precise question is not "fold or mask?" but:** + +> **Is this membership relation transient algebra, or has it been PROMOTED to a +> mask carrier?** + +That promotion is the deliberate boundary. Everything the previous entry says +about elections being visible at T2 is right; only the axis needed fixing. + +**W2b, restated a final time — both arms MASK:** + +``` +W2b-A Range × resident mask -> FUSED masking -> Count / Any (no result mask) +W2b-B Range × resident mask -> masking -> a MATERIALIZED bounded mask + — and this arm must PROVE the downstream reuse that justifies the carrier +``` + +Same masking semantics, different result carrier. W2b-B carries a burden W2b-A +does not: a materialization with no demonstrated consumer **fails** the arm. +That is what making the promotion deliberate actually costs. + +**Shortest form of the whole doctrine:** *fold the datasets, mask the folds, +materialize only when the mask itself is worth keeping.* + +## 2026-09-19 — E-FOLD-AND-MASK-ARE-SIBLING-PHYSICAL-PLANS-1 + +**Status:** RULING — the resolution of five entries written today that read as +*fold good, mask bad*. None is retracted; all were being read as a preference +when only one was a definition. **Confidence:** high. + +> **Masks are allowed. Accidental masks aren't.** + +**FOLD and MASK are sibling first-class execution strategies.** Neither is +universally preferred. *"Folds are zero copy, period"* stays exactly true — it +defines what a FOLD **is**, never what the machine is permitted to do. + +``` +FOLD MASK +canonical bytes canonical bytes / folds / other masks + ↓ peek / bound / compose ↓ materialize or REUSE a bitmap + ↓ reduce ↓ mask algebra / cache / fan-out +compact answer a resident plane +``` + +**FOLD is attractive when output entropy is low** — `Count`, `Any`, `Bound`, +`First`, a descriptor, an answer consumed once. **MASK is attractive when the +mask itself has computational value** — reused many times, shared by many +thoughts, AND/OR/TERNLOG fan-out, ~11 ns lookup, a resident attention/focus +plane, an expensive derivation worth caching. At the point a mask is reused +twelve thousand times, insisting on recomputation *because folds are pure* is +self-sabotage. + +The choice is economic and semantic: **elect MASK if +`C_build + C_reuse < C_repeated_fold`, or if a later operation genuinely wants +mask algebra.** Both are simultaneously correct at 64K: *thought A → fold, +asked once; thought B → fold once → mask → reused by 12,000 thoughts at ~11 ns.* + +**So the rule governs the TRANSITION, not the bytes:** + +> The crossing from fold-native to mask-native execution must be **deliberate +> and visible at the T2 planning membrane.** + +Once MASK is elected there is no shame in behaving like a mask engine — +`Mask → AND → TERNLOG → shift → cache → another mask` is legitimate +photolithography too. What is forbidden is only: + +``` +the planner believes it is executing a fold + ↓ +a helper silently allocates words_for(N) + ↓ +everything downstream is mask-native — and NOBODY MADE THE DECISION +``` + +**This restates Seam B more precisely than any earlier entry.** The defect in +`Pred::Range` is NOT that it writes a mask. It is that the planner has no way to +elect that and no way to decline it — there is exactly one path, so **the choice +does not exist.** Seam B is an ABSENT DECISION, not a present mask. Every +earlier framing of it (performance complaint · conformance failure · fold-law +violation) was circling this. + +**The BBB question becomes answerable:** *who decided this computation should +become a mask, and on what basis?* Static plan knowledge suffices to start — +`terminal Count → stay FOLD`; `one AND then Count → probably FOLD`; +`reuse_count > 1 → consider MASK`; `shared cached result → MASK`; +`a ~11 ns cached mask → almost certainly MASK`. DuckDB-style dynamic costing can +follow. This is pipeline-vs-materialize, a solved shape. + +**Consequence for W2b — it must demonstrate BOTH paths, not forbid one:** + +``` +FOLD-NATIVE Range ∩ resident mask -> Count / Any, no second mask +MASK-NATIVE Range ∩ resident mask -> a bounded / cached mask, + because a consumer reuses it +``` + +Identical semantics, differentially checked against each other and the oracle. +What W2b proves is that the planner can **elect** either and that the election +is visible in the plan rather than buried in a helper. + +**And it upgrades `D-WFL-T1-FUSED` from optimization to enabler:** a fused +`popcount(a & b)` over a span cannot be expressed without an intermediate +buffer, so **without it the fold-native arm does not exist at all.** The +primitive is what CREATES the choice — which is exactly why Seam B had no +decision in it. + +## 2026-09-19 — E-FROZEN-IS-FINE-MARCHING-IS-THE-DISASTER-1 + +**Status:** RULING — scopes `E-ZERO-COPY-IS-NOT-A-SIZE-THRESHOLD-1` and +`E-A-THOUGHT-IS-A-REPLAYABLE-OPERATOR-NOT-A-MAINTAINED-STATE-1`. Neither is +retracted; both were being read further than they said. **Confidence:** high on +the boundary, unmeasured on the constants. + +⊘ **The drift being corrected is mine:** across three entries today the +zero-copy definition slid into an **anti-cache position**. *A fold is zero-copy* +stays exactly true, and writing a bounded mask stays not-a-fold. What does NOT +follow is that writing one is a sin. **It is a cache decision, with its own +economics.** + +> **The real boundary was never copy vs no-copy. It is +> RECOMPUTE-OR-FREEZE vs CONTINUOUSLY MAINTAIN.** + +``` +FOLD canonical state -> zero-copy computation -> consequence +CACHE MISS fold consequence -> materialize it ONCE, deliberately +CACHE HIT cached mask -> zero-copy peek -> ~11 ns +``` + +If a cached result is callable in ~11 ns, discarding it because it once crossed +a materialization boundary would be absurd. **64K cached masks are welcome** — +no sweeping, no incremental refresh, no coherence work, no CPU while dormant. +Frozen ducks, and **frozen is the point**. Marching 64K ducks around every cycle +is the disaster, and that was always the enemy; storage never was. + +> **Materialization is allowed when its amortized retrieval value earns it. +> What is forbidden is entropy accumulation solely to keep derived state +> current.** + +**So COMBINE vs RECONSTRUCT is an EXECUTION DECISION, not a permanent type +distinction** — the earlier entries implied the latter: + +``` +thought P over domain D, first use: replay folds -> R + cheap / unlikely reuse -> discard R + expensive / likely reuse -> cache R + semantic commitment -> persist R +``` + +**Invalidation must be by KEY MISMATCH, never by update.** A world change must +not walk 64K entries: + +``` +CacheKey = DatasetVersion + RowDomain + lens/ClassView + program + + focus/input identity + external-edge snapshot + +new DatasetVersion -> old entries stay FROZEN (zero work) + -> request -> MISS -> replay -> optionally re-cache +``` + +**And that key is the `ReplaySpec`, field for field.** The replay descriptor and +the cache key are **one artifact used two ways**: as a recipe it regenerates the +answer, as a key it memoizes it. This is why invalidation can be free — a +descriptor built from owned identities either matches the world or does not, and +nothing must be swept to discover which. The two doctrines were the same object +all along. + +**The economics are memoization economics, not a prohibition:** + +``` +C_cache = C_lookup + p_miss · C_replay + amortized C_materialize + vs +C_always_replay = C_replay +``` + +⊘ **The ~11 ns is a premise, not a measurement** — same discipline as the 1.7 ns +figure. A cached-mask lookup cost must itself be measured before policy leans on +it. But if lookup is tens of ns and replay hundreds, a heavily reused mask earns +caching almost at once; a thought called once never did. + +**Metacognitive policy, directly:** novel → replay · frequent → cache · +historical truth → persist · stale → ignore, do NOT maintain. + +**Consequence for reuse across boards:** a heavily reused operator can carry BOTH +a `ReplaySpec` (the reasoning recipe) and a hot cache entry (the precomputed +result for one exact domain and version). Same domain and version ⇒ the cached +answer. Different context ⇒ replay the operator against it. Memory and +thought-reuse at once, with no maintenance treadmill. + +**Net doctrine:** *Folds are zero-copy. Cached fold results are allowed. A +cached result is an immutable consequence of a pinned input state — not live +derived state that must be swept to stay current. Recompute on miss; never +maintain an entry merely because the world moved.* + +## 2026-09-19 — E-ZERO-COPY-IS-NOT-A-SIZE-THRESHOLD-1 + +**Status:** RULING — closes a loophole in +`E-FOLDS-ARE-ZERO-COPY-PERIOD-PEEK-NOT-BORROW-BUILD-FOLD-1` and in the +`OLD/NEW` law pair recorded in +`E-DO-NOT-BACK-DATE-A-NEW-LAW-ONTO-AN-OLD-DOCTRINE-1`. **Confidence:** high. + +> **A smaller materialization is still a materialization.** Foldhood is +> determined by **whether a derived software representation is written**, never +> by whether that representation is population-sized. Ranges, ordinals and +> window descriptors are fold carriers because they NAME an answer or a region; +> a populated bounded-mask buffer is reconstruction. **Size affects +> reconstruction ECONOMICS; it never affects the DEFINITION of a fold.** + +**The loophole, verbatim as it was written hours earlier:** *"a FOLD may not +materialize an N-sized derived representation when its compact consequence can +stay a range / runs / bounded window / scalar."* That is size-conditional, and +it sat two lines below *"folds are zero copy, period."* The two are not +equivalent. A fresh 12-word bounded mask avoids an N-sized mask and still writes +derived bytes — so under the stated law it is not a fold either, and the +size-graded phrasing would have let a future session argue that fourteen words +is "basically zero-copy". The frozen ducks return in tiny hats. + +**The line, stated without a size clause:** + +``` +FOLD CARRIERS NOT FOLD RESULTS +Count a populated bounded-mask buffer +Any [u64; 12] filled from an intersection +an ordinal Vec +[lo, hi) a full mask +base_word + length descriptor ANY newly written derived buffer +a run DESCRIPTOR that names + rather than populates +``` + +A descriptor **names**; a buffer **holds**. Only the first is a fold carrier, at +any size. + +**⊘ Companion correction: T1 is NOT universally zero-copy, and the previous +entry implied it was.** T1 contains primitives that write mask outputs — +`mask_set_range`, every `*_to_mask` compare, the import paths. Accurate +statement: *the Layer-0 FOLD SUBSET executes through T1 primitives zero-copy; T1 +also contains explicitly materializing primitives, and those are RECONSTRUCTION +operations when invoked that way.* They stay legitimate substrate machinery — +what the law changes is their **classification inside a Layer-0 program**, never +their right to exist. + +**Which makes the A/B boundary exact:** + +``` +COMBINE no derived software buffer written; + composition / reduction directly over canonical state +RECONSTRUCT the first derived representation is deliberately written +``` + +**Consequence for W2b, immediate and concrete.** The obvious implementation is +disqualified: + +``` +WRONG Range × resident mask -> WRITE a bounded mask -> Count / Any +RIGHT peek only the intersecting resident words -> AND in registers + -> Count / Any +``` + +And this is the clean case for the anti-zoo rule licensing a **new T1 +primitive**: a fused `popcount(a[i] & b[i])` accumulated over a word span cannot +be expressed by the existing algebra without an intermediate buffer, so it +exposes a genuinely new zero-copy operation rather than a convenience. The +descriptor crosses; the intersection never exists as bytes. + +The gap list is reworded accordingly — not "bounded windows and runs" as missing +carriers, but **compact addressing / window descriptors**, **direct bounded +reductions**, and *optionally* **named reconstruction** of runs or windows when +a consumer genuinely demands the buffer. + +## 2026-09-19 — E-DO-NOT-BACK-DATE-A-NEW-LAW-ONTO-AN-OLD-DOCTRINE-1 + +**Status:** CORRECTION of `E-LAYER-0-IS-T1-AND-MASK-RISC-IS-ALREADY-ITS-ISA-1`, +prepended rather than edited into it (append-only). Two errors in that entry, +both mine, both caught in review within the hour. + +### Error 1 — T1 and T2 were flattened into each other + +That entry said *"mask-risc is already T1's ISA."* It is not. `membrane-tiers.md` +puts `ndarray::simd` / `mask_*` / `ternlog` / `popcount` at **T1** (`:22`) and +`plan_eval` / execution / lowering at **T2** (`:23`). The receipt is one line of +the crate: `exec.rs:25` is `use ndarray::simd::{…}` — mask-risc **consumes** T1, +which makes it T2 by the doctrine's own definition. The plan file had even +stated the correct legend two sections earlier and then contradicted it. + +**Corrected ruling — "Layer 0" is a MEMBRANE spanning two tiers, not a tier:** + +``` +METACOGNITION + │ compiles a thought + ▼ +mask-risc Program / MaskOp / Pred / Terminal T2 the RISC PLAN LANGUAGE + │ names primitive ops + ▼ +ndarray::simd — mask_*, ternlog, popcount T1 the zero-copy EXECUTION algebra + ▼ +canonical state T0 +``` + +The DuckDB analogy makes the same point and should have caught this: a planner +is not the vectorized primitive it dispatches. + +### Error 2 — the new fold law was claimed to be already entailed + +That entry called Seam B *"a conformance failure against T1's own return +contract."* **It is not, under the old wording.** `membrane-tiers.md:22` lets T1 +return *"a mask, a count, a lane descriptor — never the population"*, and **a +full-length bitmap is still a mask under that sentence.** "Never the population" +historically meant *do not return rows or arrays of the represented population*. +It never said a derived mask sized to N is itself forbidden. + +Two laws, one strictly stronger, and the second is NEW: + +``` +OLD T1 LAW may return a Mask; must not return the Population +NEW FOLD LAW a FOLD additionally may not materialize an N-sized derived + representation when its compact consequence can stay a + range / runs / bounded window / scalar +``` + +`Pred::Range → words_for(N)` is a fold-conformance failure under the **new** law. +**Record it as a doctrine sharpening, never as something already implied.** +Back-dating a constitutional law leaves a crack anyone can later quote the +existing table back through — and the workspace's whole append-only, +regrade-in-place discipline exists to stop exactly this. + +### The corollary that keeps the law usable + +**Not every full mask is illegal.** If a consumer genuinely demands a population +mask as its answer, producing one is legitimate — it simply **is not a fold**. +`mask_set_range` over a full destination is not forbidden code; it is +**misclassified execution** when it happens inside a fold. Hence the A/B split: + +``` +A) COMBINE zero-copy, compact carriers, no population materialization +B) RECONSTRUCT a Layer-0 result → an EXPLICITLY NAMED materialization + boundary → full mask / rows / SoA state / publication +``` + +Folds are zero-copy, period. Reconstruction is not a fold, and does not get to +hide under the word. + +### And the gap list gets a better reading + +Split by tier, the residue is an **EXPOSURE gap, not a compute gap**. T1 already +ships `mask_shift_morton` and the strided matchers; what is missing is at T2 — +ADDRESS integrity, compact bound terminals, bounded windows/runs, ROTATE, the +NEIGHBOUR/STENCIL and strided-PEEK exposures, PROJECT, FIRST. **The substrate is +further along than the language that exposes it**, so most remaining work is not +inventing computation but making existing computation speak the fold algebra +without forcing an N-sized carrier between instructions. + +**Consequence for W6:** its question is no longer *are writes expensive?* but +*where should the zero-copy program terminate and reconstruction become +economically or semantically justified?* — the Rubicon in computational terms. + +## 2026-09-19 — E-LAYER-0-IS-T1-AND-MASK-RISC-IS-ALREADY-ITS-ISA-1 + +**Status:** FINDING (the mapping is read-verified) + RULING (the conformance +criterion). **Confidence:** high on the inventory, high on the criterion. + +A "Layer 0 photolithographic execution algebra" was proposed as the substrate +every cognitive style compiles into: one constitutional law (everything inside +is zero-copy), two program kinds (COMBINE = no materialization, RECONSTRUCT = +an explicit, justified escape), a small orthogonal ISA rather than a zoo, and +metacognition as a query planner — `compile(thought) -> Layer0Plan` — so no +thought style owns intersection, prefix, locality, range, projection or +rotation, because those are physics. + +**The architecture is right and it is not new. Three corrections of NAME, none +of substance:** + +**1. "Layer 0" is T1, and the ladder must not grow a fifth vocabulary.** +`membrane-tiers.md:22` already defines T1 as the population algebra +(`ndarray::simd`, `mask_*`, `eq_*_to_mask`, `ternlog`, `popcount`) and states its +return contract as *"a mask, a count, a lane descriptor — **never the +population**."* Line 48 of the same doc says outright: **"The ladder does not +need a sixth tier."** So this is a SHARPENING of T1, not an addition beneath it. +T0 is the byte/row/Lance substrate; T2 names behaviour; T3 expresses intent. + +**2. `lance-graph-mask-risc` is already the ISA — the crate name says RISC.** +Verified by reading `ir.rs`: `Operand`, `LaneRef`, `Planes`, `Pred` (11 +variants), `MaskOp{Pred,And,Or,Xor,AndNot,Not,Ternlog}`, +`Terminal{Count,Any,All,MaskedSum/Min/MaxI32,BlendI32,Keep}`, `Program`, plus +`fuse.rs` (Boolean-tree → ternlog fuser), `ternlog_dispatch.rs` (256-arm +runtime-immediate → const-generic bridge) and `reference.rs` (row-at-a-time +oracle). `Program` IS `Layer0Plan`. Nothing needs minting to have an ISA. + +**3. "Valhalla is the storage membrane" does not hold against the tree.** In +lance-graph-java, Valhalla is E4: *"Vector API is permanently a lab arm… it +never ships in `src/main`."* T0 is the storage tier. Panama IS the membrane, but +the T2/T3 one (ABI ↔ Java facade), not a "thought" membrane in the cognitive +sense. Keep the analogy; drop the two labels. + +### The ISA gap analysis — the proposal minus what ships IS the wave plan + +| proposed op | state in `lance-graph-mask-risc` | +|---|---| +| AND / OR / XOR / NOT / ANDNOT | **shipped** — `MaskOp::*` | +| TERNLOG | **shipped** — `MaskOp::Ternlog` + `fuse.rs` + `ternlog_dispatch.rs` | +| GATE | **shipped** — the `under` operand (the `*_to_mask_under` family) | +| ANY / ALL / COUNT / REDUCE | **shipped** — `Terminal::{Any,All,Count,MaskedSum/Min/Max}` | +| BOUND | **half** — `Pred::Range{lo,hi}` carries a bound's RESULT; the search lives in `quack` | +| PEEK | **half** — `LaneRef{I32,U32,U64}`; no strided/facet peek (`ir.rs:21-27` names its own gap) | +| ADDRESS | **implicit** — `Planes.n_rows` + ordinals, with no attested identity (Seam A) | +| PROJECT (lens) | **missing** — the lens lives in `contract::facet`, never in the ISA | +| ROTATE | **missing** — Seam D has no op | +| SHIFT / NEIGHBOUR / STENCIL | **missing** — `mask_shift_morton` exists in ndarray, is not an ISA op | +| FIRST | **missing** | +| carrier transforms (range↔runs↔bounded words, ordinal mapping) | **missing entirely** | + +The residue maps onto the open waves: **W1** = ADDRESS attestation, +**W2a/W2b** = carrier transforms + range-native terminals, **W3** = ROTATE, +**W4** = NEIGHBOUR/STENCIL, and the strided PEEK is the deferred `LaneRef` +variant. The two remaining gaps have an explicit disposition rather than +silence: **PROJECT** (the lens, today only in `contract::facet`) lands **after +W3**, because the rotation must be measured before a lens op is worth exposing; +**FIRST** is **intentionally deferred, unscheduled** — no wave in this arc needs +it, and under `D-WFL-FUSE` it may turn out to be a fusion rule rather than an +op. That convergence is the finding's real value: two independent routes +arrived at the same missing five. + +### The conformance criterion this hands mask-risc, which it did not have + +Apply the constitutional law to the crate that is supposed to embody it: +`exec.rs:566` requires every scratch plane to be `words_for(n_rows)`, so **every +`MaskOp` today emits population-sized output.** By T1's own stated return +contract — and by +`E-FOLDS-ARE-ZERO-COPY-PERIOD-PEEK-NOT-BORROW-BUILD-FOLD-1`'s "population-sized +output is materialization, not folding" — the mask-algebra core has already left +Layer 0. + +The distinction that keeps this fair: a **bounded** word window is a legitimate +focus-sized carrier; a mask unconditionally sized `words_for(n_rows)` is +population-sized. So Seam B stops being a performance complaint and becomes a +**conformance failure against the tier the crate belongs to** — a much stronger +reason to fix it, and a criterion any future op can be checked against. + +### The membrane law, and the anti-zoo rule + +> Higher layers may invent arbitrary cognition. They may NOT invent new +> population execution semantics — they compile cognition into T1. + +And: **ISA, not standard library.** A new T1 primitive earns existence only by +exposing a genuinely new zero-copy operation that the existing algebra cannot +express efficiently by composition or fusion. `fuse.rs` is the precedent — it +collapses a Boolean tree into one ternlog rather than growing a variant per +shape. Otherwise T1 becomes the zoo the proposal warns about. + +**Thesis, worth carrying:** *thinking is compilation into zero-copy +photolithography; memory begins only where reconstruction is cheaper than replay +or where meaning requires persistence.* The second clause is +`E-A-THOUGHT-IS-A-REPLAYABLE-OPERATOR-NOT-A-MAINTAINED-STATE-1`'s two reasons to +store, restated — economic, or semantic. Nothing else. + +## 2026-09-19 — E-FOLDS-ARE-ZERO-COPY-PERIOD-PEEK-NOT-BORROW-BUILD-FOLD-1 + +**Status:** LAW (operator-stated). **Confidence:** high. Supersedes the +`AttestedPlanes<'a>` half of `E-A-BORROW-IS-NOT-A-REPLAY-CARRIER-1`, which +stands on everything else. + +> **Folds are zero copy. Period.** +> +> **Zero-copy is not an optimization of the fold. It is part of the DEFINITION +> of a fold.** A fold reads canonical state in place and returns a compact +> consequence. If it copies or materializes the source population, it is not a +> fold. + +**Definitional caveat, so the law cannot be argued away:** *zero-copy* means no +**software-level** materialization, duplication, re-encoding, or retained +derived population. CPU loads into registers and cache lines obviously still +happen; those are not a second representation, and nobody gets to cite them as +proof the rule is unmeetable. + +``` +FOLD NOT A FOLD +canonical bytes canonical bytes + -> zero-copy projection -> duplicate lane + -> compare / prefix / -> build full mask + intersection / reduction -> scatter rows + -> scalar / range / runs / -> accumulate state + tiny descriptor -> sweep later +``` + +Six invariants, stated so they cannot be softened by degrees: source bytes are +never copied by a fold; source layout is never rewritten by a fold; a fold does +not retain an execution view; a fold may emit only answer-sized or focus-sized +state; **population-sized output is materialization, not folding**; replay is +repeated zero-copy folding over pinned canonical state. + +**The corollary that makes it a membrane rather than a slogan: the moment an +operation needs to materialize population state, the fold has ended.** + +This does not forbid materialization — it forbids materialization HIDING under +the word fold. An index build, a projection cache, a publication are all +legitimate and sometimes necessary; each must be named honestly as what it is +and priced accordingly. A seam is exactly a place where the code violates this, +and Seam B is the cleanest example: `Pred::Range` emits a population-sized mask, +so the executor's range path is materialization wearing a fold's name. + +**⊘ RETRACTION, same day, same arc: `AttestedPlanes<'a>` as an architectural +carrier.** Proposed hours earlier in this arc as the "preferred, strongest" +shape for closing Seam A. It smuggled **Rust's ownership vocabulary into the +semantic model** and made a zero-copy peek sound like a persistent execution +object. The implementation does of course receive something spelled `&[u8]` / +`&[u64]` / `&FacetCascade` while the instructions run — that is memory-safety +syntax with a ~20 ns lifetime, and promoting it to a named aggregate builds +exactly the intermediary being avoided: + +``` +WRONG storage -> construct execution view -> attest it -> carry it -> fold +RIGHT pinned canonical version -> verify the address/order contract + -> PEEK zero-copy -> fold +``` + +**The attestation belongs to the address/order RELATIONSHIP, not to a transient +aggregate of all the planes.** So the proof obligation sharpens from *"these +borrowed slices belong together"* to: + +> ordinal `i` under this witnessed semantic order resolves to the same canonical +> row `i` that every subsequent operation peeks. + +Once that holds, every fold independently peeks whatever canonical column it +needs at ordinal `i`, and there is no execution assembly at all: + +``` +RowDomain { DatasetVersion, lens identity, row-order identity, n_rows } + ↓ + peek(domain, ordinal, column) zero-copy + ↓ + fold(...) +``` + +Every operation is `fold(peek(…))`. Nothing owns the source, nothing copies it, +nothing accumulates it, and the temporary view ideally never even gets a name. + +**Replay collapses too.** "Reconstruct fresh `AttestedPlanes`" was one +abstraction too many: replay **reacquires the pinned canonical version and runs +the same peeks and folds.** `ReplaySpec -> DatasetVersion + lens + program + +inputs -> peek -> fold -> same result`. + +**The real violation criterion** — a transient `&T` lasting 20 ns is irrelevant +and always was: + +``` +peek -> fold -> answer -> nothing survives GOOD (a temporary optical path) +retain a view/mask/cache "for later" SUSPICIOUS +``` + +Stated as the rule that REPLACES the borrow doctrine: *a fold consumes zero-copy +peeks from canonical state and does not retain a view of it. Any execution +object that persists merely to make later folds possible is suspect, because the +fold should reacquire the canonical address and peek again.* + +**Why this matters at 64K.** If every dormant thought had to preserve a view, +64K thoughts would mean 64K execution views, lifetime machinery, and eventual +coherence sweeps — lost before starting. Instead: `wake thought 18,721 -> peek +-> fold -> fold -> fold -> answer -> vanish`. The canonical SoA is the lake; a +thought does not carry a bucket of water around in case it wants to drink again +later, it remembers where the lake is and how to drink. + +**Consequence for W1:** it gets SMALLER, not harder. The census question is no +longer "does an object own all four planes under one permutation" but *where +does ordinal → canonical-row resolution happen today, and is it the same +resolution every peek uses?* One resolution ⇒ verify the contract once against +the pinned version and peek freely. Several, or one nobody re-checks ⇒ that is +Seam A's real depth, and finding it is the deliverable. + +## 2026-09-19 — E-A-THOUGHT-IS-A-REPLAYABLE-OPERATOR-NOT-A-MAINTAINED-STATE-1 + +**Status:** RULING on the doctrine; the ratio it rests on is CONJECTURE until +W6 measures it. **Confidence:** high on the shape, unmeasured on the constant. + +A logical thought does not earn continuous execution merely by existing. When +deterministic fold replay is cheaper than maintaining accumulated state, dormant +thoughts stay as compact **replayable operators** and consume no sweep budget. + +The economics, as an order-of-magnitude argument: + +``` +one fold ~1.7 ns +1000 stacked folds ~1.7 us +one population sweep ~10 us -> ~5,900 fold-equivalents + -> ~6 complete 1000-fold chains, on ONE lane +``` + +⊘ **Not a measurement, and the 1.7 ns does not transfer.** #1250 explicitly +declined to carry #1245's six-tier axis-chain figure to the whole-facet cell +(1.7–4.2 ns there), and a "fold" inside a 1000-fold chain need not be that +chain. What survives is the SHAPE, which holds at any plausible ratio: a sweep +costs thousands of folds, so **a stored answer can be slower to retrieve than +the answer is to re-derive.** W6 measures the real ratio. + +**The law:** never retain derived execution state merely to avoid replay, when +replay through stacked folds is cheaper than maintaining that state. Shortest +form: *if thinking again is cheaper than remembering the answer, think again.* + +This reclassifies borrowing — and corrects the `AttestedPlanes` enthusiasm +recorded hours earlier in the same arc: + +``` +borrow for projection/folding, then DROP GOOD (a temporary optical path) +borrow to preserve an accumulated result SUSPICIOUS +stacked folds GOOD +population sweep to keep state coherent SUSPICIOUS +recompute the DEFAULT +cache / materialize must earn its existence +``` + +So the target is not zero reads nor even zero repeated computation: it is **zero +unnecessary representational entropy.** Repeated computation is nearly free +while every step stays a fold; the cost is the SECOND representation and the +machinery that keeps it coherent. + +**Two and only two reasons to store:** ECONOMIC — +`C_retain = C_materialize + C_maintain + C_invalidate + C_readback` is less than +`C_replay = Σ C_fold_i + C_rotation + C_local`; or SEMANTIC — durability has +value independent of speed, because it crossed the Rubicon and must become +history / evidence / state. Everything else evaporates. + +**The scale consequence, which is why this is architecture and not tuning.** At +64K logical contexts it decides what the number means: + +``` +WRONG 64K mutable cognitive machines, swept to stay current +RIGHT 64K suspended continuation points — address/domain + lens + + fold program + dependencies + tiny meta state +``` + +Scheduler law: **no dormant thought may consume sweep cost merely to remain +current**, and a sweep's cost is properly measured in FOLD-EQUIVALENTS — how +many complete alternative reasoning chains the substrate could have run +instead. A machine holding 64K thoughts while refreshing their masks may be LESS +cognitively parallel than one holding 64K replay descriptors. + +**And it makes thoughts shareable in the useful sense:** sharing a RESULT is +expensive, possibly stale and bound to its original context; sharing a THOUGHT +is a compact replayable operator REBOUND to the recipient's context. That is +what reuse of an idea actually is — not a snapshot of someone's working memory, +but a transformation you run your own context through. The 64K palette is +therefore 64K callable cognitive continuations, crossable between kanban boards +wherever their dependencies are satisfiable. + +**Corollary worth carving deep:** a scheduler that spends more time keeping +thoughts current than it would spend thinking them again has inverted the +substrate. + +--- + +## 2026-09-19 — E-A-BORROW-IS-NOT-A-REPLAY-CARRIER-1 + +**Status:** RULING. **Confidence:** high — the failure mode is silent, which is +why it needs a law rather than care. + +A borrow may attest a LIVE execution view. Anything needed for REPLAY must +survive that view's destruction. Replay may store identities that later +reconstruct equivalent borrows; it may never preserve, cache, or depend on the +original borrow. **A borrowed attestation is runtime proof, not durable +evidence.** + +Two questions that were being answered by one object: + +| | question | lifetime | +|---|---|---| +| `AttestedPlanes<'a>` | are these actual slices aligned RIGHT NOW? | borrowed; dies with the execution | +| `RowDomain` | which immutable row coordinate system must be REACQUIRED to replay? | owned, serializable, outlives everything | + +They are not interchangeable and neither may contain the other as a shortcut. +Replay is `attach` run again — `ReplaySpec` → resolve identities against pinned +immutable state → fresh borrows → fresh `AttestedPlanes<'new>` → re-execute — so +a `ReplaySpec` contains **no** `&[NodeGuid]`, `&Planes`, `&SealedFacetLane`, +`&AlphaMask`, or anything tied to `'a`. Only owned names: `DatasetVersion`, +row-order identity, lens/ClassView identity, program identity, Morton/Wabe +mapping identity, external-edge snapshot identity, focus/input identity, +deterministic parameters. + +⊘ **Fence around the boundary-hash cache** (the honest first implementation when +no aggregate owns the aligned planes): a cached attestation is valid for THIS +live immutable image as a runtime optimization — **not replay evidence, not +persisted, not part of any `ReplaySpec`.** + +**The falsifier, which also DEFINES what a legitimate replay test is** — and +therefore ranks ABOVE the determinism gate, because a determinism test run while +the original view is still alive proves nothing: + +``` +1. produce a ReplaySpec +2. DROP every execution object and every borrow +3. re-open using ONLY the identities in the ReplaySpec +4. reconstruct fresh AttestedPlanes +5. replay +6. result must be bit-identical +``` + +If step 3 secretly needs a surviving pointer, cached view, ordinal map, borrowed +lane or process-local object, the thought was never replayable. + +**Read with `E-A-THOUGHT-IS-A-REPLAYABLE-OPERATOR-NOT-A-MAINTAINED-STATE-1`:** +that entry says recompute rather than retain; this one says what a retained +*recipe* may legally contain. Together they give the three durability tiers a +single shared rule — **no borrowed state crosses any tier boundary**: META owns +the identity of the question, REPLAY owns the identity of all deterministic +inputs plus the computation, STATE owns the answer. + +## 2026-09-19 — E-A-POSITIONAL-INDEX-ADDED-TO-A-KEY-DIGEST-ATTESTS-NOTHING-1 + +**Status:** FINDING (proved by counter-example). **Confidence:** high. + +Attesting row order by digesting `(key, ordinal)` pairs **does not work**, and +this plan floated it as the alternative to refusing duplicate keys. With +`ordinal` = post-sort position, the two distinct lanes + +``` +K -> row-A ; K -> row-B and K -> row-B ; K -> row-A +``` + +both digest as `(K,0), (K,1)`. Identical. A positional index added to a key +digest attests exactly what the key digest already attested — the position is a +function of the sort, not of the row, so it cannot witness which row landed +there. + +**The correct shape is two attestations over two different things:** + +``` +OrderedLaneWitness : key_digest = H(K0, K1, …) (semantic order) +RowDomain : row_order_digest = H(ID0, ID1, …) (physical order) +``` + +where `ID` is a **stable row identity** — the `NodeGuid` sequence, or the +writer's source ordinals — and never the semantic facet key. The executor +requires both. Duplicate semantic keys then remain legal exactly as +`ordered_lane.rs:194` permits (*"Equal keys are indistinguishable, so an +unstable sort is exact"*), while swapping the two rows behind one key changes +`row_order_digest` and leaves key digest, lens, version and `n_rows` untouched. +That is the falsifier the seam needs, and it is why the two digests must not be +merged. + +**The sibling error, same review, same root:** *carrying* a `RowDomain` is not +*verifying* one. Comparing a program's domain against `planes.domain` compares +two metadata copies; a caller can permute a mask or payload lane with every +label intact, so a metadata-only check PASSES the permuted-planes falsifier it +was introduced to fail. Enforcement must bind the actual row identities — +derive the digest from lane contents, carry the seal's permutation, or make +`Planes` constructible only from a sealed lane so unattested planes are +unrepresentable rather than merely rejected. + +**Generalization worth keeping:** a label that travels WITH the data it +describes cannot attest that data. Attestation requires either deriving the +label from the content at the point of use, or making the unattested state +unconstructible. This is the same shape as the workspace's own +`E-VACUOUS-ASSERTION-IS-THE-HOUSE-STYLE-1` — an assertion implied by the thing +it tests is not a test — lifted from tests to type invariants. + +**So the split answers WHAT is attested; it does not answer WHO MAY MINT IT**, +and without the second answer the defect just moves up a level: from +`Program.RowDomain == Planes.RowDomain` to +`Program.row_order_digest == Planes.row_order_digest`, still metadata against +metadata, still permutable by a caller who carries the old digest along. +Preferred shape: the executed view is a BORROW of one known coordinate system — +`AttestedPlanes<'a>` constructible only from the sealed row image (keys, mask +planes, value lanes, row-identity sequence), so an unattested plane set is +unrepresentable. Second best: recompute `H(NodeGuid_0 … NodeGuid_n)` once at the +attachment boundary and cache it against the immutable borrow. Carrying a digest +field on a freely-constructed `Planes` is the decorative option, named here so +it is not rediscovered as an idea. + +**The acceptance case that decides it**, and it must be red before the fix: +identical semantic keys, version, lens, `n_rows`, `key_digest`, and a +`RowDomain` **copied by the caller** — but row identities A and B swapped and +one actual value plane swapped to match. Execution must refuse before the +`Range` is consumed. + +--- + +## 2026-09-19 — E-ATTENTION-IS-NOT-EVIDENCE-AND-FIRE-IS-NOT-DURABILITY-1 + +**Status:** RULING (the floor, not the full semantics). **Confidence:** high on +the demarcation; the crossing's full contract is open. + +Three questions were being collapsed into one word. Separated: + +| question | answer | +|---|---| +| **what happened?** | FIRE — a sparse alpha delta, always; it writes what the read already had | +| **what KIND of thing is it?** | ATTEND vs EPISTEMIC | +| **what DURABILITY does it earn?** | the Rubicon: vanish / meta atom / replay spec / materialized state | + +The kind-demarcation, which is the part that unblocks implementation now: + +> **A non-empty Boolean delta is sufficient for an ATTENTION effect, and never +> sufficient for an EPISTEMIC effect.** + +Grounded, not stipulated: `AlphaOverlay` IS attention memory — it records where +attention went (claim order, rung, revisits, `NodeGuid` identity) and is +discardable rather than canonical. So an attention effect may move focus and the +alpha trace; an epistemic effect requires provenance and evidence identity +before it may touch `TruthU8` / NARS revision. This keeps the epistemic algebra +cleanly outside the Boolean mechanics and kills the degenerate reading in which +every successful intersection counts as having learned something. + +The durability question is separately structured as a FOUR-way policy on the +delta, not a FIRE/no-FIRE binary, with three increasingly strong contracts: +META needs enough identity to know *what question existed*; REPLAY needs enough +to *regenerate the same answer*; STATE needs enough epistemic justification to +*retain the answer*. + +⊘ **A replay spec is more than `RowDomain + program`** — necessary, not +sufficient, and `E-REPLAY-CAN-BE-CHEAPER-THAN-STORAGE-1` implied otherwise. That +entry's phrase *"the `RowDomain` IS the replay key"* is CORRECTED here: it is the +**row-coordinate component** of a replay key, never the whole of one. The +distinction is worth the words — the loose version invites a later session to +treat a version-pinned domain as sufficient grounds to replay. The +proof obligation is the complete deterministic input identity **for this +computation** — REFERENCES, not re-serialized contents. A set like + +``` +RowDomain + program identity + ClassView/lens version + + focus carrier identity + external-edge snapshot ID + + deterministic parameters +``` + +pins the computation without duplicating anything it read. A thought may also have +depended on another overlay, a mutable attention input, a changed ClassView, or +a different Wabe mapping — miss one and replay returns a different answer while +looking valid. The determinism gate therefore precedes the replay tier being +BLESSED, not merely used. + +**Still open, and explicitly not an implementation session's to answer:** the +Rubicon policy itself — what properties justify forgetting a delta, keeping only +a hypothesis atom, keeping a replay spec, or materializing state — with each +boundary's minimum evidence and minimum replay identity, **without conflating +attention, novelty, confidence and truth.** + +## 2026-09-19 — E-A-BOUND-AND-A-TILE-ARE-INTERVALS-IN-DIFFERENT-ORDERS-1 + +**Status:** FINDING (read-verified). **Confidence:** high. + +A witnessed `Bound { lo, hi }` is an interval in **semantic projection order** +(`SealedFacetLane` sorts by `FacetCascade::cmp_numeric_projection`). A Morton +tile is an interval in **geometric order** (`ordinal = Morton(q, r)`). These are +not the same set of rows, and the first draft of +`.claude/plans/waben-fold-execution-loop-v1.md` joined them with a bare `∩` — +two paragraphs after asserting that one physical sequence is monotone under one +lens at a time. The document contained its own refutation and shipped anyway. + +Named **Seam D**. The rotation `semantic ordinal → Morton ordinal` is now an +explicit, measured wave (W3) that must run on an INDEPENDENTLY-ORDERED lane: a +fixture that generates the population already in Morton order and then seals it +semantically has assumed the answer. Its two outcomes are the thesis and its +refutation — a cheap projection/index lookup demonstrates the schema-rotation +claim; a per-row hash scatter with no reuse relocates the resistance rather than +removing it, and says so. + +**The general lesson, which is the reusable part:** an order-bearing carrier +that names its lens is not thereby safe to intersect with another +order-bearing carrier. `SemanticLens` was introduced (D-DMD-L2) precisely so an +order claim names its projection — and a lens tag prevents pairing a prefix with +a MISMATCHED witness, while doing nothing at all to prevent joining two +correctly-lensed intervals from DIFFERENT lenses. The guard that catches a +forged witness does not catch a coordinate-system change, and nothing in the +type system distinguished them. + +Three companion corrections from the same review, each read-verified: + +1. **Duplicate keys — the D-WFL-1 recommendation is WITHDRAWN.** + `ordered_lane.rs:194` states the shipped semantics: *"Equal keys are + indistinguishable, so an unstable sort is exact."* Refusing to attest a lane + with duplicates is a semantic regression against that, AND it would not prove + what is needed — equal keys are indistinguishable to the comparator, their + associated rows are not, and an unstable sort may permute them freely. Bind + the witness to the PERMUTATION, never to key uniqueness. +2. **`AlphaFocus` materializes on the READ side.** `cell` (`:122`), + `any_rung_mask` (`:158`, ten times — once per rung lane), `unlooked` (`:175`) + and `rung_reach` (`:183`) each answer "what is focused?" via + `attended_mask()`, which allocates a full-population `AlphaMask`. A sparse + write followed by a dense read. +3. **FIRE only ever writes what the read already had.** It is a sparse + alpha-channel delta by construction; the delta is not produced at publication + time, it was already in the fold's hands. So any RE-ADDRESSING at the write + boundary is pure loss, not work — and `claim()` demanding a `NodeGuid` to + hash, when the caller holds ordinals, is exactly that. This splits the + deferred `claim_ordinals` in two: the INPUT COORDINATE (touches no stored + bytes) and the STORAGE CONTRACT (`claimed: Vec`, scanpath order, + visit counts) — a change the first draft would have made by accident. + +--- + +## 2026-09-19 — E-REPLAY-CAN-BE-CHEAPER-THAN-STORAGE-1 + +**Status:** CONJECTURE (gated on the determinism falsifier below). +**Confidence:** medium-high on the mechanism, unmeasured on the policy. + +Mask intersection is deterministic and cheap. Taken seriously at the publication +boundary, a third option appears beside the two the architecture names: + +``` +NoChange | PublishEffect(addr', delta) | PublishReplayableTask(domain, program) +``` + +If the same row domain and the same program yield a bit-identical mask every +time, the durable unit of an insight can be **the task that regenerates it** +rather than the result. The system can then afford to carry MANY insights as +replayable, each costing a descriptor instead of a result set. This is not a new +transport and not an actor message; it is a claim about what the durable unit +IS, and it sits with `E-PROGRESSION-IS-EXISTENCE-NOT-COMMAND-1` — what gets +written is the task's existence, never a command and never an ack. + +**Seam A's closure is the precondition, not merely a correctness gate.** A +replay is sound only against a pinned domain — version, lens, and the +permutation the seal applied. That is `RowDomain`. Without it, "replay" means +*recompute against whatever the lane looks like now*, which is not replay; with +it, **the `RowDomain` IS the replay key**. This retroactively raises W1's value: +it was filed as a correctness fix and is also the enabling condition for a +storage strategy. + +**Falsifier, mandatory before any wave relies on replay:** same `RowDomain` + +same program ⇒ bit-identical mask, across repeated runs, across SIMD backends, +and across process restarts. ⊘ **Scope: the integer / Boolean mask substrate**, +which is what the whole arc runs on today, and where bit-identity is exactly the +right bar. It is NOT a general prohibition — if Gaussian / f32 propagation later +enters Wabe cognition it will need a *numerical-equivalence* contract instead, +and this entry must not be read as outlawing the kernels the architecture +already anticipates. Anything that lets a result depend on scratch +contents, hash-map iteration order, or a runtime ISA choice breaks replay +SILENTLY — which is the only way it can break, because a wrong replay still +returns a plausible mask. + +**Accounting consequence (§6):** for such an insight the agreed exact answer +carrier is the TASK DESCRIPTOR, not the row set it denotes — and replay cost +gets its own column, because an insight cheap to store and expensive to +re-derive has only moved its cost. + +**The asymmetry that drives it: WRITING is the expensive part.** Replay does not +win because reading is cheap; it wins because writing is not. Stated plainly, +that forbids a design the two-option framing still allows — a speculative *"this +looks interesting, let me test this hypothesis"* must not cost an SoA row. Under +one undifferentiated publish path it does, and the cost of curiosity becomes the +cost of knowledge. + +So the durable side is a LADDER of at least three tiers, each strictly MORE +EXPENSIVE than the one above: + +| tier | records | carrier | +|---|---|---| +| meta kanban atom | a hypothesis worth testing — the question, no answer | a small intermediary write at the META level; **never an SoA row** | +| replayable task | the domain + program that regenerates an insight | a descriptor (`RowDomain` + program) | +| materialized effect | the answer, as state | the alpha row / SoA write | + +**The rubicon is the point.** An atom AT the rubicon is written at the meta +level; only what crosses earns the full row. That is what lets the system afford +to be curious — many hypotheses, none priced like a conclusion. It is +`E-PROGRESSION-IS-EXISTENCE-NOT-COMMAND-1` at a second level: the meta atom +records that a QUESTION exists, not a command to answer it and not its answer. + +Measurable, and W6 must report both: **cost per tier** (bytes + µs for each — +if the ladder is not strictly increasing by a wide margin, the tiering buys +nothing and should be dropped rather than maintained), and **tier mix** under a +real workload (speculations per replayable task, tasks per materialized effect). +A cheap tier that is rarely used is decoration; an expensive tier that fires on +every speculation means there was never a rubicon. + +⊘ A claim about the SHAPE of the durable side — NOT a licence to build a new +transport, a second store, or an actor message per hypothesis. The meta tier is +an intermediary write through the existing owner. + +**Left to the cognitive-semantics session:** *which* insights earn a +materialized answer instead of a replay, and where the rubicon sits. The +`RowDomain` says when a replay is still valid; it does not say when one is worth +avoiding, and nothing in the substrate says when a hypothesis has earned a row. + +## E-NO-FOLD-REPORTS-AN-O-POPULATION-COST-1 (2026-09-18) — a "fold" that materializes a population- or lane-sized buffer is a sweep wearing a fold's name + +**The rule, stated once:** a fold's cost is a function of its ANSWER's size, +never of the population it was searched over. An allocation sized to the lane, +or a per-row predicate — even a narrowed one — is a materialization, and a +measurement that includes one is not measuring a fold. + +**What happened.** The first commit-2 draft of the D-DIAMOND-1 probe measured +two things and called both "folds" while neither was one: + +- **P2's write** allocated `dst = vec![0u64; words_for(n_rows)]` — sized to the + WHOLE lane — before calling `mask_set_range(&mut dst, lo, hi)`. + `mask_set_range` writes every word of whatever slice it is given (zero + before, ones inside, zero after), so the cost was O(n_rows) regardless of + how narrow `[lo, hi)` was. The bound search itself (`partition_point` × 2) + was a real fold; the write immediately after it silently reintroduced an + O(N) term and the report did not distinguish the two. +- **P3's "fold" arm A** called `ternary_match_u64_to_mask` — the shipped + per-row ternary-match SWEEP — narrowed to the bound's row range. Narrowing + the RANGE a sweep runs over does not change that it is still a sweep: every + row in the narrowed range is still individually compared. It was reported + next to "arm B: two sweeps + AND" as though it were a different KIND of + operation; it was the same kind, just over fewer rows. + +**The diagnosis, stated generally:** a materialization test for "is this +actually a fold" is not "does it look like one API call" — it is **does its +cost scale with the population touched, or only with the answer's own size**. +A bound's answer is `(lo, hi)` — two integers — and a fold-shaped consumer of +it (a narrowed AND, a popcount over `hi − lo` bits) costs O(range width) or +O(1), never O(N). The moment a fold's output is unconditionally turned into a +buffer sized by the LANE rather than by the RANGE, or into a call that visits +every row rather than every match, the O(N)/O(sweep) term is back — just +hidden one call deeper than the reviewer looked. + +**The fix, both instances (D-DIAMOND-1 commit 2, `crates/d-diamond-1-probe`):** + +- P2: `touched_write(lo, hi)` returns `(w0, dst)` — a base word index + `w0 = lo / 64` and a buffer of `words_for(hi) - w0` words, so cost is + O((hi − lo) / 64) for a range at ANY position. `n_rows` never appears in its + signature. Flat 20.5–22.6 ns across N = 1K → 1M at a fixed range (old + whole-lane buffer over the same range: 34 → 4,620 ns, ~134×) AND flat + 20.5–21.7 ns across positions 500 → 3,999,900 at a fixed 100-row width. The + full-lane sweep is kept ONLY as an explicitly separate `reference_sweep_ns` + column, never summed into the fold's own total. + + **This bullet is itself the second correction, and the sharper half of the + lesson.** Its first version sized the buffer to `words_for(hi)` and wrote + from word 0 — so `mask_set_range` zeroed every word BEFORE `lo` and the cost + was O(hi), the range's END POSITION in the lane. That is still a + population-shaped cost for a range near the lane's end, and the flatness + falsifier could not see it, because holding `(lo, hi)` at a FIXED ABSOLUTE + position across N holds `hi` constant by construction. Fixing the answer and + varying N is NOT sufficient; the answer has a position as well as a size, and + a cost proportional to position passes every N-sweep unchallenged. Falsifier: + `f_touched_write_is_position_independent` — fixed width, moving position; + red against the old shape, green against the fix. +- P3: the fold arm is rebuilt around a `JointIndex` — a Morton-interleaved + joint key over BOTH lanes, sorted once (a real, separately-timed cost), then + bounded with two `partition_point`s and NOTHING ELSE. Verified structurally, + not by report: `ternary_match_u64_to_mask` appears in the probe crate ONLY + inside the `reference_sweep_ns` timing block — zero occurrences in + `JointIndex`. Bound alone: 69–79 ns. **Bound + `materialize_rows`: 89–98 ns** + — and that is the number to quote, because the comparator produces a full + original-ordinal mask while a bound alone produces two offsets into the + JOINT index's own order. Against 745,473–797,268 ns for two sweeps + AND: + **8,135×–8,376×**. The remap is O(kept), so it is a legitimate fold cost, but + omitting it compares inequivalent outputs and inflated the ratio to + ~10,700×. Conditional on a prebuilt `JointIndex` (≈61 ms per 1M rows). + +**The reusable check, for any future "we measured a fold" claim:** name the +quantity the reported cost is a function of. If it is a function of N, or of +the number of rows touched by a predicate rather than the number of rows in +the ANSWER, it is not a fold measurement — it is a narrowed sweep or a +population-sized buffer, whatever the code calls it. + +And then vary the answer along EVERY axis it has, not just its size. Three +tests, not two, are the shape this check demands: +`p2_touched_write_cost_does_not_scale_with_lane_size` (fix the answer, vary N), +`p2_touched_write_beats_the_old_whole_lane_sized_buffer` (the old shape is +measurably worse), and `f_touched_write_is_position_independent` (fix the +answer's SIZE, move its POSITION). The third exists because the first two were +both green over a cost that was still O(end position) — a benchmark that varies +one parameter certifies exactly one parameter. + +Cross-ref: `three-prefix-fold-carriers.md` §1 (*"masking wins when the slice +is GRANULAR, PEEK wins when the slice is ADDRESSED"* — this entry adds the +third case: **BOUND wins when the population is ORDERED, and its cost is the +answer's size, never the lane's**); D-DIAMOND-1 plan §5 (the full corrected +numbers); `E-BYTES-ARE-STORED-INTEGERS-ARE-PROJECTED-1` (the sibling +discipline one layer down — a fold's OUTPUT can be a projection too: `(lo, +hi)` stored as two integers, materialized into a mask only at the point a +consumer genuinely needs one). + +## 2026-09-18 — E-BYTES-ARE-STORED-INTEGERS-ARE-PROJECTED-1 — byte-agnosticism is the STORAGE superpower and little-endian is the COMPUTE superpower; the bug is always a stored projection + +**Status:** OPERATOR-RULED (the framing is the operator's: *"byte is storage +superpower, LE is compute superpower"*) + SHIPPED at the one site that +violated it (`NodeRow::edges` is now the byte-backed `EdgeFacet([u8; 16])`). +**Confidence:** HIGH on the mechanics — measured census, 1356 contract tests, +every consumer unchanged, the new falsifier disable-verified red-then-green. +HIGH on the doctrine as a *reading of this tree*: two of the three sites +already obeyed it before it was written down. + +### The line + +**Bytes are stored. Integers are projected.** + +- **Storage is byte-agnostic, and that is a superpower:** a byte array has no + endianness to get wrong, every bit pattern is valid, no niche, and the + in-memory image equals the wire image on every target for free. +- **Little-endian is a superpower too, but a COMPUTE one:** memory order and + arithmetic significance agree, so a prefix compare is `vpxor` + `tzcnt` with + nothing materialized. That is why the facet's byte-chain LCP measures + **1.72 ns** (`examples/facet_axis_lcp_probe.rs`, #1245) — the reinterpret IS + the speed. +- **They must not be mixed, and the failure has exactly one shape: storing a + projection.** The moment a typed, native-endian value becomes the stored + image, the storage lane inherits the compute lane's endianness — and the + only defence left is a target guard. + +### The tree already agreed, at two sites out of three (measured) + +| site | form | verdict | +|---|---|---| +| `NodeGuid([u8; 16])` | stores bytes, projects via `.facet()` | obeys — the exemplar | +| `AttentionFocusFacet { facet: FacetCascade, .. }` | holds the TYPED facet, is not `repr(C)`, no `SoaEnvelope`, and reaches bytes only through the explicit `to_bytes()` encode | obeys — compute, contained, costs nothing | +| `NodeRow::edges` | stored a `FacetCascade` inside a `repr(C, align(64))` row whose `as_le_bytes()` reinterprets `&[NodeRow] → &[u8]` for Lance | **violated** — a stored projection | + +The third is why #1246 had to add +`const _: () = assert!(cfg!(target_endian = "little"))` to `facet::`. That +guard was a stopgap holding a seam shut, not a fix. + +### What shipped + +`EdgeFacet([u8; 16])` — `#[repr(C, align(16))]`, the exact mirror of +`NodeGuid` — with `as_bytes` / `as_bytes_mut` / `from_bytes` / `to_bytes` / +`facet()`, and `pub type EdgeBlock = EdgeFacet` so every call site compiles +unchanged. Consequence: **all three `NodeRow` fields are now byte arrays** +(`[u8;16] | [u8;16] | [u8;480]`), so the 512-byte row contains no +native-endian integer at all, and `as_le_bytes` is byte-identical across +targets by construction rather than by assertion. Both stale SAFETY comments +are corrected in place — one of them had said, in its own last sentence, that +`EdgeBlock` was "the one field that is not" a byte array. + +### The correction this entry carries + +#1246's arc entry and PR body both said byte-backing `edges` "would retire the +`target_endian` guard entirely." **That was wrong, and the code said so.** +`FacetCascade::as_bytes` / `ref_from_bytes` are still reinterprets, and they +are *supposed* to be — that reinterpret is the 1.72 ns hot path. So the guard +stays; what changed is its blast radius. It no longer protects a row at rest +(that dependency is gone); it protects the compute lens's own +`reinterpret == encode` identity, where a violation can mis-read a value in +flight and nothing more. The guard's comment is rewritten to say exactly that. + +### Why the change was nearly free (the census, not a guess) + +Every `EdgeBlock` site in the tree is `default()`, `as_bytes()` / +`as_bytes_mut()`, `from_bytes()`, equality, or a `Copy` — and every +struct-literal construction and every `.facet_classid` / `.tiers` read is on a +*projected* facet (`FacetCascade::from_bytes(&bytes).tiers[0]`, +`… .facet_classid == CLASSID`). **Not one is a field access on +`NodeRow::edges`.** #1246's migration had already moved them all to bytes. The +two real consumers (`symbiont::key_render`, `soa_graph`) read +`eb.as_bytes()[..12]` / `[12..]` and are untouched. So this change did not +impose the doctrine — it ratified what the code was already doing, and let the +type system say it. + +### The reusable pattern, named + +`byte-backed newtype + .facet() projection`. Storage type owns the bytes and +offers no integer; the lens type owns the integers and is obtained by an +explicit decode. If a type is `repr(C)` AND reachable from a stored image AND +contains a multi-byte integer, it is a stored projection — fix it by moving the +integer behind a projection, not by adding a target guard. + +### Residue (unchanged by this entry) + +The readers that still split those 16 bytes at 12 — the V1 `12 + 4` carving — +remain named in `ISS-EDGE-BLOCK-WAS-A-SECOND-TYPE-FOR-THE-SAME-FACET`. Byte +backing neither fixes nor worsens that; it is a *reading* of the bytes, and the +ClassView is still what should decide it. + +## 2026-09-17 (18) — E-THE-SECOND-FACET-IS-NOT-AN-EDGE-BLOCK-1 — bytes 16..32 are just another content-blind facet cascade; giving them their own type was how the V1 `12 + 4` carving survived its own retirement + +**Status:** OPERATOR-RULED (verbatim below) + SHIPPED (`pub type EdgeBlock = +FacetCascade;`, `FacetCascade::as_bytes_mut`, every field site migrated +byte-for-byte). Residue named in +`ISS-EDGE-BLOCK-WAS-A-SECOND-TYPE-FOR-THE-SAME-FACET`. +**Confidence:** HIGH — the ruling is the operator's; the mechanics are a +type alias over an identical `repr(C, align(16))` 16-byte layout, 1425 +contract tests unchanged, every in-tree consumer builds. + +### The ruling + +> *"It's forbidden for the edge block to even know it's an edge block — +> it's just another content blind facet cascade."* +> *"How hard can it be to fold `[u16;8]` / `[u8;16]` — same algorithm, +> just 6 vs 8, 12 vs 16."* +> *"What you call edge codec flavor, quoting 12+4 in/out family, is a V1 +> contamination."* + +### What it corrects, including in this session + +The canon had retired the `12 in-family + 4 out-of-family` carving as a +V1-LEGACY *reading* — but `EdgeBlock { in_family: [u8; 12], out_family: +[u8; 4] }` was that reading spelled as a *type*, and a type outlives a +regraded paragraph. Every `.in_family` / `.out_family` access re-asserted +it. This session then proposed, in order: a fourth `EdgeCodecFlavor` +(`Refs16`), a second view type (`EdgeRefs`), an 8×2×8 `T8` facet shape, a +`ColumnDescriptor::class_id` field, and a §3c ruling — each one a +consequence of treating the second 16 bytes as something other than a +facet. All of it was discarded on the ruling. What remains is one line. + +### The shape that is left + +`NodeRow = key: FacetCascade | edges: FacetCascade | value(480)`. The +second facet's 4-byte prefix says what its six `(u8:u8)` rails ARE for +this row — the predicate, the codebook — and the ClassView projects them. +"Sixteen refs" is `4 + 12` read as L1 rails; the classid that a `T8` shape +or a lane-level field was invented to carry was already in the register. +`EdgeCodecFlavor` is how a class *reads* the second facet, which is all it +ever was. The fold is `shared::` on `[u8; N]`, one algorithm, `6` or +`8` — the cascade discipline from `E-THREE-CARRIERS-THREE-FOLDS-1` applies +to both facets identically because they are the same type. + +### The rule, generalized + +**A second type for the same bytes is a carving pretending to be a +layout.** The content-blind invariant is not "the ClassView chooses the +reading"; it is "there is no type in which a reading could hide." Where +the canon has already regraded a reading as legacy, grep for the *type* +that still spells it — the paragraph did not retire it if the struct is +still there. + +Cross-ref: `E-V3-FACET-4-PLUS-12` (now visibly true of bytes 16..32 as +well), `E-V1-TAIL-FORBIDDEN-V3-IS-CONTENT-BLIND-1`, +`E-THREE-CARRIERS-THREE-FOLDS-1`, CLAUDE.md § CANON (⊘ note appended), +`le-contract.md` §4 (bullet appended). + +## 2026-09-17 (17) — E-THREE-CARRIERS-THREE-FOLDS-1 — one workspace holds THREE prefix-fold carriers; entry (16) measured a real win on one of them and shipped it into another, where it is 2.1× SLOWER + +**Status:** MEASURED (`crates/lance-graph-contract/examples/facet_axis_lcp_probe.rs`, +four arms, 64K pairs, min of 7, oracle-first, in-tree and reproducible) + +SHIPPED (the revert, same PR). The carrier-2 opportunity is CONJECTURE — named, +not measured. +**Confidence:** HIGH on the numbers and the disassembly. The three-carrier +taxonomy is a reading of the tree, offered as the strongest available +explanation of (16)'s inversion, not as a proof of what (16) originally timed. + +### The correction + +Entry (16) records *"loop 12.5 ns → masked readout 5.8 ns"* for the facet +per-axis LCP. **On the facet carrier that ordering is inverted.** Measured +2026-09-17 on its own 64K-random workload, both axes, ns/op: + +| workload | A chain fold (retired by #1244) | C masked `u128` (shipped by #1244) | +|---|---|---| +| random | **1.72** | 3.64 | +| depth 0 | **1.66** | 4.68 | +| depth 5 | **3.50** | 3.56 | +| identical | **3.30** | 3.73 | + +Arm A wins at every workload; on the entry's own workload by **2.1×**. Arm A +depth-0 1.66 → depth-5 3.50 (+111%) — the early exit is real and is where the +win comes from. Two further arms (a pack-to-`u64` PEEK, and a shared-load +variant) were slower than both; the prediction that packing would win was +wrong and is recorded as wrong. + +**⊘ Struck from (16): "the gather dominated".** The disassembly refutes the +premise. LLVM never materializes the `[u8; 6]` and never gathers: + +``` +movzbl 0x5(%rdi),%eax ; PEEK hi[0] of a +cmp 0x5(%rsi),%al ; compare straight against b's memory +jne ; done — one tier compared +movzbl 0x7(%rdi),%r8d ; only now PEEK hi[1] +``` + +Arm C performs the *same* byte loads, then pays to reassemble them +(`shl`/`or`), materialize `movabs $0xff00ff00ff00ff00`, run two `tzcnt` + a +`cmove`, and apply the `−32` correction — and cannot exit early. It is strictly +more work on the same loads. + +**What survives (16) unchanged:** the `-f` naming; `shared_prefix_tiles` (a +genuine whole-register `xor`+`tzcnt`, different op, untouched); the entire +ndarray `ternlogq` descent half (5–8× over padding — measured on its own +carrier and not in question); the `−32` correction note; the 23-tail-site count. + +### Why it inverted — three carriers, three folds + +The same words ("prefix fold", "LCP", "shared depth") name three different +operations on three different carriers. The op that is optimal on one is +pessimal on the next, and nothing in the vocabulary flags the crossing. + +| # | carrier | shape | right fold | state | +|---|---|---|---|---| +| 1 | **bit-planes** — `mailbox_soa.rs` `identity_plane_at → &[u64]`, `N × WORDS_PER_FP` | sub-byte, no byte addresses | **mask / popcount** (`DistanceMeans::Hamming`) | correct, untouched | +| 2 | **nibble path** — `NiblePath` (`hhtl.rs:251`), packed `u64`, 16 nibbles | sub-byte, packed into one register | **mask** — `xor` + `leading_zeros() >> 2` | **walks nibble-by-nibble today; the one real opportunity** | +| 3 | **facet cascade** — `FacetCascade`, 6×2×8 bytes at fixed offsets | byte-addressed, offsets known at compile time | **PEEK** — `movzbl` + `cmp` + early exit | reverted to PEEK by this entry | + +The rule, in the operator's formulation (2026-09-17): **masking wins when the +slice is granular; PEEK wins when the slice is addressed.** A fold result is +scoped to its carrier and does not travel. (16)'s 12.5 ns is entirely plausible +as a measurement of a *carrier-2-shaped* loop — a per-step walk against a +packed integer, which is exactly what `common_prefix_depth` still is. What is +not supportable is transferring that conclusion to carrier 3, where the loop +compiles to compares against memory. + +### The opportunity this names (carrier 2 — CONJECTURE, unmeasured) + +`NiblePath::common_prefix_depth` is the fold `mailbox_scan.rs:263` actually +calls for CAKES nearest-ranking. It walks up to 16 nibbles, each step a shift, +an `Option` construct and a two-field compare, to compute what is +`((a.path ^ b.path).leading_zeros() >> 2)` clamped to `min(depth)`. This is the +carrier where (16)'s instinct was right and was never applied. **Gate:** the +same four-arm probe harness, against this carrier, before any rewrite — the +whole point of this entry is that a fold is not portable on argument alone. + +### The generalized rule + +**Before moving a fold, name its carrier.** A measurement is a statement about +(operation, carrier, workload); dropping the carrier makes it a slogan. Any PR +that changes a prefix/LCP/distance fold must state which of the three carriers +it touches and carry a probe on *that* carrier. Sibling of the falsifiability +rule in `CLAUDE.md`: an assertion implied by the code it tests is not a test, +and a measurement transferred off its carrier is not a measurement. + +Doctrine: `.claude/knowledge/three-prefix-fold-carriers.md`. +Blast radius: `.claude/plans/three-carrier-blast-radius-v1.md`. +Cross-ref: (16) above (struck in part, cited in full); `E-PANCAKES-IS-RADIX-IS-HHTL` +(carrier 2's doctrine); `E-VACUOUS-ASSERTION-IS-THE-HOUSE-STYLE-1` (the +differential test was inverted in the revert so it stays falsifiable). + +## 2026-09-16 (16) — E-FORMAT-SLOT-FOLD-IS-THE-SAME-OP-AS-THE-VL-DESCENT-1 — `"{0}{1}" -f hi,lo`: the register is a template with fixed arity, and both the facet LCP and the ternlogq tail are "pick the template whose arity matches the arguments, never pad them" + +**Status:** MEASURED on the ndarray side (the descent probe, ndarray +`examples/ternlogq_tail_descent_probe.rs`, AVX-512 v4, 3 runs) + SHIPPED on +the contract side (`facet.rs` `shared6` fold, this PR). +**Confidence:** HIGH on both numbers; the analogy is the operator's +(*"Powershell `{0}{1} -F $1,$2` logic"*, 2026-09-16) and is recorded as the +naming, not derived. + +### The one shape + +PowerShell's `-f` fills positional slots of a fixed-arity template; a missing +argument throws — it never zero-pads. Read against this tree: + +| `-f` | contract `facet.rs` | ndarray | +|---|---|---| +| `"{0}{1}" -f hi,lo` | `FacetTier::as_u16` | — | +| `"{0}…{7}" -f class,t0..t5` | `as_u128` (8 u16 tiles, one register) | the xmm rung | +| prefix of two formatted strings | `shared_prefix_tiles` = `u128` xor + `tzcnt/16` | — | +| template arity chosen **by argument count** | — | zmm→ymm→xmm descent for a 1..7-word tail | +| `pack_under` (`64 % L == 0`) | — | already IS `-f` with arity `L` — gated side only | + +### What was un-folded thirty lines from the fold + +`shared_prefix_tiles` read the whole facet as one register; `hi_distance` / +`lo_distance` (`shared6`) still gathered six strided bytes per axis into a +chain and walked them. First cut re-folded the gathered chain into a `u64` +(1.5× — the gather dominated). The operator's correction (*"fold the +PowerShell logic ONCE"*): the `u128` facet already holds both axes by +position, so an axis prefix is the whole-facet xor **masked to that axis's +tier bytes** (`HI_BYTES` = bytes 5,7,…,15; `LO_BYTES` = 4,6,…,14), then +`trailing_zeros/16` past the classid — the `-f` was done at mint, never per +call. Measured, 64K random pairs: loop 12.5 ns → masked readout **5.8 ns** for +both axes (2.9 ns each, the same as the whole-facet `prefix_distance`). +Falsifier compares against the loop at every divergence tier on both axes; +disable-run (swap `HI_BYTES`/`LO_BYTES`) fails at `hi flip at tier 0`. + +### What the same shape is worth one repo down (measured, not yet wired) + +`mask_ternlog` pads its 1..7-word tail into three zeroed `[u64; 8]` arrays. +Descending instead (`4 + 2 + 1`, every lane live, all in vector registers): +greedy widest-first wins at every `t >= 2` — **5–8× over padding**, 1.3–1.6× +over all-xmm; `t=6` `4+2` 2.26–2.74 ns vs `2+2+2` 3.29–3.68 vs padded +17.0–18.3. `ogar-r2il`'s `CallMask = [u64; 3]` has zero full chunks, so the +whole op is that tail: 18.1 → 2.3 ns. asm: 33 zmm + 3 ymm + 6 xmm `vpternlogq`, +zero GPR logic on lane data — a descent is not the scalar peel +`codegen-witness.sh` caps at `SLICE_GPR_CAP=6`. + +### Gaps this names (ndarray, not this PR) + +- `U64x4::ternlog` / `U64x2::ternlog` do not exist on the facade; the descent + calls the intrinsics a wrapper would hold. Adding them + rewiring + `mask_ternlog`'s tail is the follow-up. +- No `u16` compare family (`eq_u16_to_mask`) — the `(u8:u8)` rail IS a u16 + tile, and lgj-abi's `simd_rowstore_facet_match` compares classids only. +- An un-gated `pack` sibling of `pack_under` would retire the 12 + hand-rolled `if !tail.is_empty()` sites. + +Cross-ref: ndarray `.claude/knowledge/masking-ops-state.md` (G1/G2 RUN, #310); +`E-THE-SPINE-IS-WHATEVER-THE-READER-ALREADY-HAS-AN-ADDRESS-FOR-1` above — the +`-f` naming is the same muscle-memory argument applied to a register layout. + +**Corrections 2026-09-16 (appended; the sibling session's read of this entry +against `facet.rs`, and Codex on #1242/#1243 — the same defect the summaries +carried):** +- The axis prefix above is written *"`trailing_zeros/16` past the classid"*. + The merged `shared_axis` is `(tz((a ^ b) & AXIS_BYTES) − 32) / 16` + (`facet.rs`): the 32 classid bits sit below the tiers and the subtraction + is load-bearing — without it a tier-0 divergence reads as prefix 2, not 0. + "Past the classid" gestured at it; the record now states it. +- "12 hand-rolled `if !tail.is_empty()` sites" under *Gaps* was attributed, + not counted. Counted: **23** `if !.is_empty()` branches in + ndarray `src/simd_masking_ops.rs` at `c746735` (grep `if ![a-z_]*\.is_empty()`, + 2026-09-16): 22 named `tail`/`ta`/`td` plus the `ts` branch in + `mask_shift_morton` — Codex on #1244 caught the set named here as one + short of the number. The original "12" was in fact the exact count of + branches literally named `tail` (12 `tail` + 7 `ta` + 3 `td` + 1 `ts`); + it was right for that pattern and understated the set. The un-gated + `pack` follow-up would retire all 23, not 12; whether the Morton-shift tail fits the same helper is + part of that follow-up, not settled here. + +**⊘ PARTIAL STRIKE 2026-09-17 (appended; see entry (17) +`E-THREE-CARRIERS-THREE-FOLDS-1` above).** The facet half of this entry is +inverted on its own carrier: measured four ways in-tree, the retired chain fold +is **1.72 ns** and the shipped masked readout **3.64 ns** on this entry's own +64K-random workload — the opposite ordering, 2.1×. The premise *"the gather +dominated"* is refuted by disassembly: LLVM never materializes the `[u8; 6]`. +`shared_axis` is reverted to the chain fold; the masked form is retained as its +test oracle. Everything else here stands unchanged — the `-f` naming, +`shared_prefix_tiles`, the `−32` note, the 23-site count, and the whole ndarray +`ternlogq` descent half (a different carrier, measured on its own and not in +question). What the 12.5 ns actually timed is unknown — no harness was +committed with it; entry (17) gives the strongest available account (a +carrier-2-shaped loop) and labels it as such. + +## 2026-09-16 (15) — E-THE-SPINE-IS-WHATEVER-THE-READER-ALREADY-HAS-AN-ADDRESS-FOR-1 — the operator's quack redirect, and the four errors of one session that all substituted an address for the thing + +**Status:** OPERATOR-RULED (the redirect, verbatim below) + MEASURED (the census +numbers, re-run over the whole tree after codex's review of #1240). +**Confidence:** HIGH on the census — the corpus mechanism is now a directory +walk, so the number is a property of the tree rather than of a file list I +chose. The spine ruling is the operator's; it is recorded, not derived. + +### The redirect, in the operator's own four messages + +> *"cypher is just a cheap proof of concept / and an even better proof of +> concept is quack"* → *"my point is quack is the spine you need to rebuild +> from"* → *"any graph traversal in the end will be a modified version of it / +> any SPOG query will be just another flavor / and the benefit is quack / +> duckdb no AI will ever ask what it is, you can use muscle memory"* → +> *"everything else is running in circles around whats not in your training"*. + +**The argument is muscle memory, not elegance, and reading it as elegance is +how it gets lost.** `lance_graph_quack::Query { filter, agg }` — filter a +population, reduce over the survivors — is a shape every reader, every author +and every model already holds without being taught. A novel IR has to be taught +to each of them, every time, and the teaching cost recurs on every future +session. That is the same test the Java surface passes one tier down +(lance-graph-java `CLAUDE.md` § *THE JAVA SURFACE IS `sql()`*): the boring front +wins because nobody has to learn it, not because it is nicer. + +The last message is the mechanism behind the other three, and it is the one +worth keeping: **circling is the symptom of building on what is not in +training.** Work that re-derives its own vocabulary every session does not +accumulate — each session pays the teaching cost again and mistakes paying it +for progress. + +### What it cancels, stated plainly because I had it queued + +The Cypher→mask lowering (`.claude/plans/cypher-mask-lowering-v1.md`, Wave 1) +would have been a **third** lowering onto one floor — beside quack's `lower` +and `lgj-abi`'s `plan_eval`, both already pinned equal to `lance-graph-mask-risc` +by a differential. Three dialects, one evaluator, and two of them novel. + +quack's one missing leg is the **hop** (`src_mask → edge lane → dst_mask`). That +is one brick, and it makes SPOG a *flavour* of a shape that already exists +rather than a fourth thing to learn. It is now the recommended next brick +(task #10 / PR5), where before it was gated behind PR1-4. + +### The census defect — same shape, and self-inflicted on the day the rule landed + +`w0b_corpus_census` was built to answer §7.0's STOP gate: what fraction of the +Cypher the tree actually contains lowers to a mask. Its first corpus was a +**hand list of three files**, chosen from a grep — and a grep structurally +cannot see a query built as a raw string literal. codex flagged it on #1240. + +| | corpus | classified | Full (mask-lowerable) | +|---|---|---|---| +| as first reported | 3 files, hand-listed | 20 | 15 — **75.0 %** | +| after a quote-parity fix | same 3 files | 50 | 23 — **46.0 %** | +| after review: directory walk | **33 files** of 1451 walked | **303** | 113 — **37.3 %** | + +The corpus grew **17×** and the headline halved. The root cause is named in +this repo's own P0 rule — *grep FINDS, reading DECIDES* — which was written +into `CLAUDE.md` **the same day**. Writing a rule is not the same as being +immune to it. + +**And the file count in that last row was itself wrong when first published — +`27`, corrected here to `33`.** A second review pass found that the census +kept only the FIRST source per query literal, so a file whose every query also +appeared elsewhere vanished from the provenance entirely. The classification is +untouched by it (342 candidates, 303 classified, 113 Full, 37.3 % — all +unchanged; dedup by literal was always right, only the attribution was not). + +The uncomfortable half is that **the repo already held the right number**: the +census's own module doc said *33 files* while the program it documents printed +*27*, in the same commit, and I quoted whichever was nearer to hand — the doc's +33 into the source, the program's 27 into the plan and into this entry. Nothing +flagged it, because neither number is wrong-looking on its own. Third instance +in one session of two values for one quantity (see also G-F, whose summary row +contradicted its own document's body four sections above it). + +Three classifier defects rode in with the fix (inline pattern properties never +read, 4 maps → 53 hits; `DISTINCT`-over-a-value never firing, 37 hits; and +`run.sh`'s `|| true`, which let a failed harvest leave stale TSVs to be counted +while `provenance.txt` already carried the new commits — a clean exit reporting +old measurements against a new checkout). + +### The four errors of this session share ONE shape + +| what I substituted | for what | +|---|---| +| a grep pattern | the corpus | +| a section number and a symbol name | the argument (operator: *"reverse grep… pattern matching that doesnt make any context for me"*) | +| a stale 46 % | a decision I asked the operator to make (withdrawn — 0 of 303 fail to lower, so no ruling was ever needed) | +| an A/B/C fork I raised as open | a ruling `cypher-mask-lowering-v1` §5.2 had already made | + +**An address is not the thing.** Each one is cheap to produce and looks like +work. And the redirect above is the positive form of the same insight: build on +the spine the reader already has an address for, because a novel IR is an +address nobody can resolve. + +Operational consequence, and it is the cheap half: **plain words first; the +symbol, file and section go at the END, as receipts.** A report that opens with +`§5.2 / TERNLOG 0x86 / D-MAR-2` has told the reader nothing they can act on. + +### The three rulings that came with it + +**Alpha channel first, and the reason is not sequencing convenience.** Operator: +the SPOG alpha channel *"affects the underlying storage and table 'multitenant' +access… writing to alpha split tunnel without changing ontologies itself as +saccade focus of attention sparse write and meta awareness of simultaneous +rung"*, where *"before it was 10 rung not talking to each other despite +kanban_actor.rs or deprecated 'one at a time'"*. Three things are being bought: +a write path that does not rewrite the shared ontology (which is what makes +concurrent attention safe); a channel property rather than a consumer +convention; and **simultaneous rungs** — levels of thinking interact, and +interaction requires the priors to sit on the same level. So any second consumer +of `ogar_loco::TERNLOG = 0x86` inherits whatever simultaneity contract the alpha +channel establishes first. `cypher-mask-lowering-v1` §5.2's OQ-9 said "defer +rather than race"; this says *why* deferring is correct rather than merely +polite. + +**`RevisionKind` lives beside `belief.rs`.** Operator: *"belief is historically +correct but needs to be adjusted for proper wiring"* — so the planner, not the +contract (option A of `mask-algebra-revision-read-v1.md` §5 Q1). The history is +right; the wiring is the work. The adjustment is that plan's **D-MAR-2**. + +**The 46 % question is withdrawn, not answered.** Operator: *"46% negligable how +do i know what you are talking about"* — a fair hit twice over. I asked for a +ruling on a word from a plan the operator did not write, without supplying what +anyone would need to judge it; and the number had already moved to 37.3 % (see +the table above). Re-reading the census, **0 of 303 queries fail to lower** — +Split is a two-stage plan, not a failure — so there was never a ruling to make. + +### Receipts + +- Plan: `.claude/plans/lance-graph-as-the-modelgraph-v1.md` §§14-18 (the mindset + check, the census, `LabelDTO` as the answer to OQ-1, the rulings, the redirect). +- Instrument: `crates/lance-graph/examples/w0b_corpus_census.rs` — the corpus is + now `rust_sources()`, a walk, so the denominator is the tree's property. +- Gate discipline, second measured instance: `SUPERSESSION-INDEX.md` was + regenerated BEFORE these board writes and went red at four successive SHAs on + #1240 — exactly the failure `CLAUDE.md` § *Regenerate LAST, after the board + writes* already records from #1085. The rule is right; it needs to be executed + in the order it states. + +## 2026-09-16 (14) — E-THE-NET-ARM-RANKED-ON-A-PARTIAL-SUM-AND-ITS-ONLY-APPARENT-SIGNAL-WAS-THAT-BUG-1 — entry (13)'s NET row is re-measured; the arm is a census on BOTH arms, not one + +**Status:** MEASURED — re-run of `D-HXP-8` arm 1 after a one-line ranking fix in +`crates/perturbation-sim/examples/tictactoe_raumgewinn.rs`. **Confidence:** HIGH +(the fix is a derivation from `TierFloors::stack_early_exit`'s own return value, +and the re-measured numbers are self-consistent with entry (13)'s structural +result rather than against it). + +### The defect + +`score()` ranked BOTH arms by `StackResult.stacked`. That field is the +**cumulative sum up to and including the exit tier only** — it equals the true +full stack iff `exit_tier == 3`. Entry (13)'s own meter note already said a +partial is not a bound under signed terms, and measured that early exit changed +the top move in **10.13 %** of positions. The prose was right; the ranking code +did not honour it. So for `Arm::Net`, F1 was being scored against a quantity that +is a genuine partial sum in ~1 position in 10 — and with signed per-tier terms a +later negative tier can pull the true total below what an earlier positive +partial suggested. + +Fixed: `Arm::Agreement` keeps ranking by the early-exit value (its terms are +non-negative, so the partial IS a bound); `Arm::Net` ranks by the full stack. +`tied` and `distinct` follow the same match, since they must be computed over +whatever F1 actually ranked by. **F2 is deliberately untouched and stays +arm-independent** — it compares the same two values for both arms by +construction. + +### What the re-measurement says, and it is the uncomfortable half + +| quantity | entry (13) NET | re-measured NET | AGREEMENT (unchanged) | +|---|---|---|---| +| F1 det / tie-aware | 0.5677 / 0.5655 | **0.5865 / 0.5797** | 0.5865 / 0.5797 | +| mean distinct stacked | **1.157** | **1.000** | 1.000 | +| F3 degree-1 drop | +0.0152 | **+0.0011** | +0.0004 | +| null shuffle, 20 seeds | 0.5768 [0.5617, 0.5899] | **0.5797 [0.5797, 0.5797]** | 0.5797 [0.5797, 0.5797] | +| F2 | 0.8987 | 0.8987 | 1.0000 | + +**The `1.157 → 1.000` is the finding.** Entry (13) reported the mean number of +distinct FULL-stack values as `1.000` on both arms — correctly — but the NET +arm's *scored* quantity showed `1.157`, i.e. it looked like the NET arm had at +least a little discrimination where AGREEMENT had none. It did not. That 0.157 +was entirely the partial-sum artifact, and with the fix NET is exactly the +census, identically to AGREEMENT. + +Two corroborating collapses, neither of which was arranged: the null shuffle +degenerates to a **single point** (shuffling the rails changes nothing, because +the full stack is the board census regardless of rail topology — which is the +F0-degenerate claim restated from a direction entry (13) did not test), and F1 +lands exactly on the random-move baseline `0.5797`. + +### What this supersedes + +⊘ Entry (13)'s NET row and every number derived from it. The structural verdict +— **F0 DEGENERATE, F1/F2/F3 are DATA not verdicts** — is UNCHANGED and is in +fact strengthened: it now holds identically on both arms instead of holding on +one while the other showed a small unexplained spread. + +⊘ The same-day `⊘ UNPINNED` block proposing a flat-vs-DROP tolerance for NET's +`+0.0152`. That block did honest work on a number that no longer exists: the +re-measured drop is **+0.0011**, flat by any tolerance, so the question it was +opened to adjudicate is closed by measurement rather than by a threshold. The +tolerance proposal itself stays on file as unpinned and unused. + +### Why it was invisible + +`0.5677` is not an implausible number next to a `0.5797` baseline, and `1.157` +reads as "barely any discrimination" — which is the same story the entry was +already telling. **A bug whose output agrees with your conclusion is the hardest +kind to see**, and nothing in the suite could have caught it: there was no test +that distinguished "ranks by early-exit" from "ranks by full stack" for the NET +arm at all. There is now (`net_arm_ranks_by_the_full_stack_not_the_early_exit_partial`, +disable-verified: reverting `top` to `top_early` turns it red), plus 7 more unit +tests on the probe's own primitives (negamax exact values, the symmetry-class +relation, the three `Horizon` cases, the rail shuffle's permutation invariants). + +**Cross-refs:** entry (13) (`E-RAUMGEWINN-NEEDS-A-HORIZON-SMALLER-THAN-THE-BOARD-…`) +— structural result stands, NET numbers superseded; `TierFloors::stack_early_exit` +in `crates/perturbation-sim/src/rolling_floor.rs` (the return value the fix is +derived from); D-HXP-8 arm 2 (a board larger than the rails' horizon) remains +the unblocked next arm, unchanged by this. + +## 2026-09-15 (13) — E-RAUMGEWINN-NEEDS-A-HORIZON-SMALLER-THAN-THE-BOARD-TIC-TAC-TOE-HAS-NONE-SO-ARM-1-IS-F0-DEGENERATE-NOT-A-KILL-1 — D-HXP-8 arm 1 ran; the pre-registration lacked a fixture-validity gate, and the fixture failed it + +**Status:** MEASURED — `D-HXP-8` arm 1 (tic-tac-toe) RUN. Probe +`crates/perturbation-sim/examples/tictactoe_raumgewinn.rs` +(`cargo run --manifest-path crates/perturbation-sim/Cargo.toml --example tictactoe_raumgewinn --release`), +committed with the F0 gate that this entry adds to the pre-registration of (12). +**Confidence:** HIGH on the structural result — it is a derivation confirmed by +measurement (mean distinct FULL-stack values per position `1.000` on both arms); HIGH +on the meter note (measured `0.1013`); the next-arm criterion is a proposal. + +### What ran + +Full negamax over the 4520 reachable non-terminal positions (627 classes up to +symmetry; the "765" in (12) counts the terminal classes too — the probe scores the +627 that have a move); a move is optimal when it preserves the value. Rails = Chebyshev +rings 1..4 (rings 3 and 4 empty on 3×3), floors preheated on every (position, empty +cell) pair with `k = 2`, `stack_early_exit` on a clone per candidate, rank by the +stacked value. Random-move baseline `0.5797`. + +| arm | F1 det / tie-aware | F2 early == full | all tied | distinct stacked / FULL | F3 degree-1 tie-aware (drop) | shuffled-rail null, 20 seeds | +|---|---|---|---|---|---|---| +| AGREEMENT (pre-registered) | 0.5865 / **0.5797** | 1.0000 | **1.0000** | 1.000 / 1.000 | 0.5800 (+0.0004) | 0.5797 [0.5797, 0.5797] | +| NET own − opp (exploratory) | 0.5677 / 0.5655 | **0.8987** | 0.8434 | 1.157 / 1.000 | 0.5808 (+0.0152) | 0.5768 [0.5617, 0.5899] | + +Read naively, the pre-registered arm sits EXACTLY on the baseline and the null collapses +to a point — the KILL rule of (12) ("F1 at chance") would fire. It does not fire, and +the reason is the finding. + +### F0 — the horizon exhausts the board, so the stack is a census + +On 3×3 every cell's rings 1 ∪ 2 reach all 8 other cells (measured: `reach 8..=8 of 8`, +`horizon exhausts the board on 9/9 cells`). Both arms are ring-ADDITIVE — tier `r` sums +a per-cell term `f(b[j])` over `j ∈ ring_r(m)` — so the full stack of candidate `m` is +`Σ_{j≠m} f(b[j]) = Σ_j f(b[j]) − f(E)`, the same number for every empty `m`. The full +stack cannot rank anything; it is the board census. Measured, not assumed: mean distinct +FULL-stack values per position `1.000` on both arms, every candidate tied in `1.0000` +of positions on AGREEMENT. F1 = baseline, F2 = 1 and F3 flat are all the census +signature — not a KILL, not a pass, not a reading. **The fixture is degenerate.** + +This is (11)'s elephant : Wal at board scale: popcount is position-blind, and when the +horizon reaches the whole world, position-blindness is total blindness. Raumgewinn is a +LOCALITY property — it exists only where a cell's rails reach strictly less than the +board. The number that decides a fixture is `reach / (board − 1)`; the gate is computed +from the rails alone before any position is scored, and its silent twin is the degree-1 +rails (reach 1 of 8 — the probe asserts the gate stays silent there, so it discriminates). + +**F0 joins the pre-registration from here on.** A readable arm needs the board diameter +strictly greater than twice the deepest ring, so that not even the centre sees everything: +Gobang 15×15 (Chebyshev diameter 14 > 8 ✓), Go 9×9 (Manhattan 16 > 8 ✓), Hex ≥ 7×7 (hex +diameter 12 > 8 ✓). Hex 5×5 fails it (diameter 8 — the centre reaches every cell) and +must not be the next arm. Tic-tac-toe is retired as a Raumgewinn falsifier; it remains +the ground-truth harness the larger boards reuse (negamax, symmetries, the F1/F2/F3 +scoring are board-size-agnostic in the probe). + +### The meter note — early exit presumes non-negative stacking + +`stack_early_exit` returns the PARTIAL sum at the exit tier — +`crates/perturbation-sim/src/rolling_floor.rs:239` (`if crossed || band == FloorBand::Alarm {`) +returns `stacked` as accumulated so far — and its doc promises +`rolling_floor.rs:220` (`decision is confident, the finer tiers need not be computed`). +That promise holds only when the remaining tiers cannot LOWER the reading, i.e. for +non-negative intensity (the shipped caller, `weyl_over_fiedler`, is non-negative). The NET +arm is signed (own − opp): a partial is then not a bound on the full stack, and the early +exit changed the top move in **10.13 %** of positions (F2 `0.8987`) while AGREEMENT held +`1.0000`. On this fixture that spread is the ONLY spread (FULL stack `1.000`), which is +what makes the mechanism unambiguous. Filed in `TECH_DEBT.md` (the premise is unstated +in the doc, not a bug in the shipped non-negative use). Consequence for D-HXP-8: the +pre-registered arm stays AGREEMENT; a signed arm runs full-stack, or the meter grows a +signed-safe exit (exit only when the remaining tiers' maximum magnitude cannot reverse +the ranking — a bound, not a guess). + +### Process + +The pre-registration in (12) had a KILL rule that assumed the fixture could read F1. +Every falsifier from here on carries F0 before F1: **can this fixture distinguish the +candidates at all?** — measured as the distinct-value count of the quantity being ranked, +before the ranking is read. The `all candidates tied 1.0000` line existed only because +the anti-vacuity counters were added after the first run showed F1 == baseline to four +decimals; had the KILL been read at face value, a correct claim would have been retired by +a fixture that could not test it. + +Home: `hexagon-plasticity-v1.md` §12a (appended), `STATUS_BOARD` `D-HXP-8` (In +progress — arm 1 RUN, F0 degenerate; next Gobang 15×15 / Hex ≥ 7×7 / Go 9×9), +`LATEST_STATE` (10), `TECH_DEBT` 2026-09-15 (early-exit premise). + +## 2026-09-15 (12) — E-POPCOUNTS-UPPER-RANGE-SIMILARITY-IS-THE-HEXAGONS-RAUMGEWINN-AND-BOARD-GAMES-MAKE-IT-FALSIFIABLE-1 — the counterweight to (11): the same position-blindness is territory on the hexagon substrate, the toolkit for it ships under the operator's own words, and the games give it ground truth + +**Status:** RULING — operator, verbatim, two messages: *"Der Vorteil von HDR popcount +stacking early exit Belichtungsmesser statistical confidence interval thresholds +preheating rolling floor bucket assignment ist jedoch daß es für hexagon Substrate +hilfreich ist — der sprichwörtliche Raumgewinn beim Go boardgame."* and *"Und +witzigerweise müsste tiktaktoe gobbang, go damit sogar falsifiable sein."* The census is +a read of the tree; the pre-registration at the end is mine, on the operator's proposal. +**Confidence:** HIGH on the census and on the `head2head` mapping (shipped code); the +falsifier is pre-registered, NOT run — and the board already holds one measured +counterexample it must beat (E-Q8). + +### The pair, in shipped vocabulary + +(11) said popcount finds *elephant : Wal* because it is position-blind. This entry says: +on the hexagon that is the point. The operator's Go framing is already in the contract — +`lance_graph_contract::head2head::WinnerCriterion` (D-H2H-1, 2026-05-31): **infight** ≈ +`DissonanceMin` (the tightest match wins), **Raumgewinn** ≈ `SupportSpread` (the widest +distinct support wins). Read against (11): lcp asks how DEEP one agreement goes — +infight; stacked popcount asks how MANY neighbours agree — Raumgewinn. Elephant : whale +is territory: the class's influence reaches the whale. Neither metric is wrong; they are +`head2head`'s two criteria, and the substrate already competes them. + +### The toolkit, by name — every word in the operator's list is a shipped surface + +- **HDR bands, Belichtungsmesser, CI thresholds, recalibration** — + `ndarray::hpc::cascade::Cascade::{calibrate, expose, observe, recalibrate}`: + `calibrate` takes a distance sample to μ/σ, `expose(distance) -> Band` IS the light-meter + reading, `observe` returns a `ShiftAlert`, `recalibrate` takes it; `adaptive_resolution` + picks the band from query entropy × corpus CV; `PackedDatabase::cascade_query` runs it. +- **Popcount stacking, early exit, preheating, rolling floor, bucket assignment** — + `perturbation_sim::rolling_floor::{RollingFloor::{preheat, observe, threshold, z, band}, + TierFloors::{preheat, stack_early_exit}}`: the L1..L4 tiers as an HDR popcount-stacking, + early-exit cascade over a self-calibrating μ + kσ floor; `band` → `FloorBand`; the + bf16-hhtl-terrain knowledge doc names it *bucket-ROUTING (the rolling floor), NOT + reconstruction*. +- `belichtungsmesser()` — 7 sample points `[0,19,41,59,79,101,127]` → (mean, sd), the SD + entropy gate (`agi-stack-cross-repo.md`); `holo.rs`: batch Wasserstein search with an + early-exit cascade. +- The operator's exact phrase is already a doctrine line: + `observer-effect-tfpn-doctrine.md` — *"early exit, statistical confidence-interval + thresholds, preheating + rolling floor bucket — the Belichtungsmesser reading."* + +Nothing to build for the toolkit. What is unbuilt is the EVIDENCE that it helps the +hexagon. + +### The caveat the board already holds + +`E-Q8-THE-SIX-DOES-NO-WORK-A-DEGREE-ABLATION-COLLAPSES-THE-HEX-OVERLAYS-ENTIRE-ADVANTAGE-1` +(2026-08-31): B beat A and the RAND null on every metric — and at degree 1 it scored +identically to four decimals; *"the six does nothing; B is a bigram successor table."* +That is not a refutation of six-neighbourness; it is the finding that THAT task never +consulted more than the first neighbour. "Helpful for hexagon substrates" is therefore, +on the board today, a claim with one measured non-result behind it — and the operator's +second message is the answer: pick tasks whose ground truth NEEDS the neighbours. + +### The games as the falsifier — pre-registered, not run + +Why games: exact ground truth (solved values, legal territory); rules that ARE neighbour +relations; and the degree-ablation twin built in — a line needs aligned neighbours, a +liberty count needs all four, a Hex connection needs six. E-Q8's failure mode cannot +pass silently here: on these tasks degree 1 is provably insufficient. + +Lattices, stated so the six is not oversold: tic-tac-toe and Gobang are square with 8 +directions; Go is square with 4-adjacency (territory = 4-connected flood fill); **Hex is +the six-neighbour game** — the exact match for six rails as six neighbour pointers, with +the square games as 4- or 8-subgraphs. Order: tic-tac-toe (solved, a draw; 765 positions +up to symmetry), Hex on small boards (first-player win by strategy stealing, explicit +solutions on small boards), Gobang (free-style 15×15 a first-player win, Allis 1994), Go +(small boards solved; end-position territory is pure flood-fill ground truth). + +The claim, operationalised: each cell a unit whose six rails are its neighbours, the +stone colour in the payload; a position evaluated by popcount stacking over the rails' +agreement ring by ring (the HDR stack), `TierFloors::stack_early_exit` deciding when the +reading is settled, floors preheated from a position sample. + +- **F1 — correctness.** Tic-tac-toe: the top-ranked move is value-preserving in ≥ 95 % of + the 765 positions, chance level measured by a shuffled-rail null, not assumed. Go end + positions: stacked territory == flood-fill scoring — an equality, no tolerance. + +> ⊘ **CORRECTED, same day, entry (13).** "The 765 positions" is not the population F1 can +> score — a terminal class has no move to rank, so F1 is undefined on it. Entry (13) runs +> the probe over the 4,520 reachable non-terminal positions (627 classes up to symmetry) +> and says so explicitly: *"the '765' in (12) counts the terminal classes too — the probe +> scores the 627 that have a move."* Read every F1 percentage in this entry, and in (13), +> against 627, not 765. + +- **F2 — economy.** Early exit changes NO verdict (equality against the full stack) and + the mean exposed tiers is below the full depth; the fraction is measured and stated. +- **F3 — the degree ablation, mandatory.** At degree 1, F1 must DROP. Flat = the task did + not exercise the six, and the probe proves nothing (E-Q8 as a gate, not a memory). +- **KILL:** F1 at chance on tic-tac-toe, or F3 flat. + +> ⊘ **UNPINNED, flagged same day.** Neither "DROP" nor "flat" carries a numeric tolerance +> or a rounding rule above. Entry (13) measured AGREEMENT's degree-1 tie-aware F3 at +> 0.5800 against the un-ablated tie-aware value 0.5797 (Δ = +0.0004) and read the whole +> arm through F0 (the fixture is a census, so F1/F2/F3 all read as the census signature) +> rather than against an independent flatness threshold. A rule derivable from the +> fixture's own size (n = 4,520 non-terminal positions, p ≈ 0.58): binomial standard +> error √(p(1−p)/n) ≈ 0.0073, so treat |Δ| < 1 SE (~0.007) as flat and require |Δ| ≥ 2 SE +> (~0.015) to call a genuine DROP toward the 0.5797 chance baseline. Under that reading +> AGREEMENT's +0.0004 is flat; NET's +0.0152 sits at the 2-SE edge but moves AWAY from +> chance, not toward it, so it is not a DROP either. This is proposed here, not +> pre-registered before the run — treat it as UNPINNED until a non-degenerate arm (F0 +> passes) lets the ranking variance, not census noise, decide the tolerance. + +Home: `hexagon-plasticity-v1.md` §12 (appended), `STATUS_BOARD` `D-HXP-8` (Queued). +Precedent for the method: `E-SF-AWARENESS-OPPONENT-ARC-1` ran the operator's Go +Raumgewinn-vs-infight design inputs as five gated chess probes on stockfish-rs — same +discipline, different board. + +## 2026-09-15 (11) — E-POPCOUNT-FINDS-ELEPHANT-WHALE-BECAUSE-IT-IS-POSITION-BLIND-THE-TREES-METRIC-IS-LZCNT-AND-THE-BOARD-ALREADY-FILED-IT-1 — the operator's caveat on (10), and it lands on an open issue + +**Status:** RULING — operator, verbatim: *"Der 'Nachteil' beim popcount ist daß +Ähnlichkeit auch elephant : Wal findet — Ähnlichkeit im oberen Bereich."* The reading +below is mine; the census is a read of the tree; the issue it lands on is already filed +(`ISS-SHARED-PREFIX-TIERS-IS-TIER-COARSE-AND-BRANCHES`). +**Confidence:** HIGH — the ranking inversion is arithmetic (worked below), and the dual +instruction is the one the board's own re-scope already names. + +### Why popcount finds the whale + +A root→leaf code RANKS its positions: the bit at depth 3 outweighs every bit below it. +Popcount does not know that — it counts disagreements wherever they are. Take elephant +and whale sharing `animal · mammal` and parting at the order nibble by ONE bit (`0001` +vs `0011`), and two elephant species sharing everything down to the leaf nibble, where +they differ in all four (`0000` vs `1111`). Popcount says whale 1, sibling 4: the cousin +is "closer" than the sibling. The similarity it reports is real — the shared upper tiers +ARE shared ancestry, *im oberen Bereich* — but it answers *how much do we share*, and +the tree asks *how deep do we agree*. The quotes around "Nachteil" are right: as +generalisation (find the cousin) it is the feature; as retrieval (find the sibling) it is +the defect. + +### The tree's metric is one instruction, and it is the same XOR + +Longest common prefix = the depth of the FIRST disagreement = `lzcnt(u ⊕ self)` in +root→leaf bit order — one instruction, one cycle, next to popcount's one. `>> 2` is the +level, `>> 4` the tier: the canon's *"tier-of-level = level >> 2 — a shift, never a +branch."* On the example: whale parts at depth 8 (nibble 3), the sibling at depth 12 — +sibling nearer, as the tree says. + +The substrate already names this exact measure: `NiblePath::common_prefix_depth` +(`lance-graph-contract`, `hhtl.rs`) — *"the radix-trie nearest-neighbor measure"*, +`E-PANCAKES-IS-RADIX-IS-HHTL` — and the board already carries its branchless form as an +open item, `ISS-SHARED-PREFIX-TIERS-IS-TIER-COARSE-AND-BRANCHES` (re-scope): the shipped +function is a `while … match` nibble walk running per row inside `mailbox_scan`, and the +one-liner is `((a.path ^ b.path).leading_zeros() >> 2).min(a.depth.min(b.depth))`. The +operator's caveat is the SEMANTIC reason that issue matters, beyond the branch count. + +### How (9), (10) and this compose + +| question | metric | instruction | selection | ships | +|---|---|---|---|---| +| how deep do we agree (tree) | `lcp = lzcnt(u ⊕ self)` | LZCNT | `lcp ≥ d` ≡ `(u ⊕ self) ∧ care(d) == 0` — (9), k = 0 | threshold-to-mask: yes (ternary match); per-row depth vector: no | +| how much do we share (exchangeable bits) | `popcount((u ⊕ self) ∧ care)` | POPCNT | `≤ k` — (10) | k = 0: yes; k > 0 fused: no | + +So on the tree rails the `(self, d)` prefix IS the predicate, and popcount's k > 0 is +not wanted there — which narrows (10)'s gap to the carriers whose positions are +exchangeable (planes, bipolar identities): the `I-VSA-IDENTITIES` fence, seen from the +other side. What the tree rails lack is the VECTORISED lcp per row — `lzcnt` over +`u ⊕ self` in the strided 12-byte form, yielding a depth vector (`u8` per row) for +RANKING, nearest = deepest — where the threshold-to-mask form already ships. ndarray has +no `lzcnt` / `leading_zeros` primitive today (census, this session), and a per-row +`u8`-out shape is new: not a mask, not a count, a sibling of `hamming_batch_raw`. + +A middle ground exists: `heel_weighted_hamming` (ndarray) weights popcount per plane; +with weights falling by level it approaches the lexicographic order lcp gives exactly. +Recorded, not recommended — lcp is one instruction and exact. + +### Consequence + +- (10)'s gap is re-scoped: the fused `popcount ≤ k` predicate is for exchangeable-bit + carriers; on tree rails the missing primitive is per-row `lzcnt` (a depth vector), + and its threshold form is already the ternary match. +- `ISS-SHARED-PREFIX-TIERS-IS-TIER-COARSE-AND-BRANCHES` gains its motivation: not merely + branch-free, but the metric under which the sibling outranks the cousin. +- Phase 7: no new arm — `lzcnt` costs what `popcnt` costs; the k > 0 arm stays for the + carriers it applies to. + +> ⊘ **Per (12), same day:** the popcount side is not demoted by this — it is the hexagon's +> Raumgewinn, and lcp / stacked popcount are `head2head`'s two criteria (infight / +> SupportSpread). The games falsifier (`D-HXP-8`) is where the pair gets ground truth. + +## 2026-09-15 (10) — E-POPCOUNT-TIMES-SELF-THE-EXACT-PREFIX-IS-THE-K-EQUALS-ZERO-HAMMING-BALL-AND-THE-FUSED-ROW-PREDICATE-IS-THE-GAP-1 — the operator's one-line generalisation of (9), what of it ships, and where I-VSA-IDENTITIES fences it + +**Status:** RULING — operator, verbatim: *"You could even say it's popcount × self."* +The two readings below are mine and labelled; the census of primitives is a read of the +tree (every name verified); the fence is the substrate's own iron rule, applied. +**Confidence:** HIGH on the census and on the k = 0 identity; MEDIUM on the second +reading; the fence is a consequence of `I-VSA-IDENTITIES`, not a new ruling. + +### Reading 1 — per row: the exact prefix is the k = 0 Hamming ball + +(9)'s selection `(u ⊕ self) ∧ care(d) == 0` is `popcount((u ⊕ self) ∧ care(d)) ≤ 0`. +Generalise the 0 to k and the triple `(self, care, k)` is one predicate family: + +- `care = care(d), k = 0` — the exact stepless prefix: tree distance ≤ d from root, (9); +- `care = all 96, k > 0` — the Hamming ball of radius k around self; +- `care = care(d), k > 0` — a Hamming ball inside the prefix. + +"Distance from root" and "Hamming distance" are the same popcount over different +care masks, both 0..=96. Per row: XOR, AND, POPCNT, CMP. + +**What ships** (ndarray, names as in the tree): `ternary_match_u32_to_mask`, +`ternary_match_u64_to_mask`, `ternary_match_strided_to_mask` — the k = 0 form, one +pass, a mask out. `hamming_distance_raw`, `hamming_batch_raw(query, database, +num_rows, row_bytes) -> Vec`, `hamming_top_k_raw` — per-row DISTANCES, a `Vec`, +not a mask. `masked_popcount_batch(words, mask) -> Vec` — per-word +`popcount(w ∧ mask)`, one XOR short of the row predicate on a u64 lane. mask-risc: +`Pred::MatchU32` / `Pred::MatchU64` (k = 0 only); `Terminal::Count` = +`popcount_batch_u64(mask)`. + +**The gap:** the fused one-pass `popcount((row ⊕ pattern) ∧ care) ≤ k → mask` — a +`hamming_le_*_to_mask` kernel in ndarray (per lane and 12-byte strided) and a +`Pred::HammingLe { lane, pattern, care, k }` in mask-risc. Today k > 0 is two passes +through a 64k-entry distance vector (512 KiB) plus an allocation — exactly the shape the +masking floor exists to remove. Named, not built. + +> ⊘ **Per (11), same day:** scoped to exchangeable-bit carriers (planes, bipolar +> identities). On tree rails popcount is position-blind — it ranks a cousin above a +> sibling — and the missing primitive there is a per-row `lzcnt` depth vector; the +> threshold form is already the ternary match. + +### Reading 2 — per mask: `popcount(mask(self, d)) = |ball(self, d)|` + +The cardinality of self's neighbourhood at depth d is `Terminal::Count` over the (9) +mask — the probe's radius sweep already prints it as `rows` (2^(56−d) on the +perfect-tree lane). Swept over d it is a thought's specificity profile: how many units +share its first d bits. One popcount per 64 rows; nothing to build. + +### The fence — `I-VSA-IDENTITIES`, applied + +Reading 1 with k > 0 is sound only where bit-Hamming IS a distance: fingerprint planes, +bipolar identities, and the tree through `care(d)` with k = 0. It is NOT a distance over +the L4 `palette256²` rails or any CAM-PQ code: two centroid INDICES that differ in every +bit may be neighbours, and the substrate's distance there is the 256×256 LUT (bgz17 +lineage), never a popcount. `I-VSA-IDENTITIES` already forbids superposing content +codes; the same register-loss argument forbids Hamming over them. So "popcount × self" +is exact for k = 0 on every carving, and for k > 0 only on Hamming-meaningful bits — +which bits those are is the ClassView's to say. + +### Phase 7, second arm — pre-registered, not run + +Beside (9)'s cycles/row for the k = 0 strided match: the k > 0 fused predicate. Pass: +≤ 1 cycle/row with `vpopcntq` (AVX-512 VPOPCNTDQ); expect 2–3 cycles/row on AVX2 +through the nibble-LUT popcount. If the fused kernel does not exist by then, the +two-pass form is what gets measured, and the delta IS the cost of the gap. + +## 2026-09-15 (9) — E-A-THOUGHT-MASKS-ITSELF-BY-ITS-DISTANCE-FROM-ROOT-THE-V3-FACET-IS-THE-MASK-AND-THE-RADIUS-IS-STEPLESS-1 — the operator's favourite masking variant; it is already the shape of `MatchU64`, ndarray ships its 12-byte strided form, and the probe measured it stepless + +**Status:** RULING — operator, verbatim: *"Meine Lieblingsvariante ist V3 Format. Jeder +beliebige Gedanke kann sich selbst × Abstand from root 0–96 bit maskieren und somit +eine exakte stufenlose Auswahl treffen mit close to 1 CPU cycle."* — plus FINDING for +the radius sweep (re-runnable). The lowering shape and the one-cycle mechanism below +are derivations; the timing claim is a pre-registered Phase 7 falsifier, NOT measured +here. +**Confidence:** HIGH on the sweep; HIGH that the primitive exists — ndarray ships it; +MEDIUM on the root→leaf bit order inside the 12 bytes, which is the ClassView's +carving and lives in the care table, not in a shift. + +### The variant, as the substrate sees it + +A mask is a pair `(self, d)`: the unit's own 96-bit payload as the pattern, its +distance from root `d ∈ 0..=96` as the radius, `care(d)` = the first d bits in +root→leaf order, and the selection is every unit `u` with +`(u.payload ^ self.payload) & care(d) == 0`. Three properties, each literal: + +- **exact** — a ternary equality; no threshold, no approximation, no 8 KiB object + unless the caller wants the result materialised; +- **stepless** — every d is a distinct selection: d = 0 is the class, d = 96 the unit + itself. Nibble boundaries are where the codebook's centroid cells sit (OGAR: *1 + nibble = 1 level of the 16-ary tree*) — a fact about MEANING; the mask cuts anywhere; +- **~1 cycle** — one AND and one compare per row, both vectorised. + `ndarray::simd::ternary_match_strided_to_mask(bytes, first_offset, stride_bytes, + count, pattern: &[u8; 12], care: &[u8; 12], out_words)` IS this call over a + 16-byte-strided table: 12-byte pattern, 12-byte care, one mask word per 64 rows. + Shipped. mask-risc's `LaneRef::U64` doc names the strided `Operand` as the IR's + own gap (PR4/PR5); `Pred::MatchU64` / `MatchU32` are the same operation on one lane, + and `Filter::prefix_u64(col, self, d)` is `(self, d)` on that lane today. + +The root→leaf order of the 96 bits is not memory order — each rail is LE `hi:lo`, and +which bits are "closer to root" is the ClassView's carving — so `care(d)` is a +97-entry table per carving, not `!0 << (96 − d)`. The ternary match does not care +which, and that is the point: any bit order, any d, one instruction. + +### What the sweep measured + +`examples/adaptive_order_probe.rs`, radius d on the 16 row bits of `i << 8` +(d = 40 is every row, d = 56 is one), the prefix leading the clustered conjunction: + +| d | rows | words skipped | blocks skipped | +|---|---|---|---| +| 40 | 65 536 | 0.00 % | 0.00 % | +| 41 | 32 768 | 50.00 % | 50.00 % | +| 44 | 4 096 | 93.75 % | 93.75 % | +| 47 | 512 | 99.22 % | 99.22 % | +| 48 | 256 | 99.61 % | **99.61 %** | +| 49 | 128 | 99.80 % | 99.61 % | +| 50 | 64 | **99.90 %** | 99.61 % | +| 51…56 | 32…1 | 99.90 % | 99.61 % | + +- Every d selects exactly 2^(56−d) rows — asserted per step. Stepless and exact. +- The skip is a step function of the UNIT, not of d: words gain until one live word + (d = 50), blocks until one live block (d = 48); between 48 and 50 the units part + ways. `/50` — which (7) called illegal and (8) "not a tile cell" — is the radius at + which the word-skip saturates. Legal, exact, one of 97. +- The (5) §3 family `1 − 2^(50−P)/1024`, labelled CONJECTURE there and withdrawn in + (7), is measured across 40..=56 and holds for words down to the word floor; its block + twin saturates two bits earlier. Restored as FINDING. + +### Corrections this makes + +- (7), (8): *"legal prefixes are nibble-multiples"* — nibble alignment is codebook + structure, not a legality condition on selection. `/48` stays in the probe's + clustered regime as a representative radius, not the only legal one; the sweep now + carries every d. +- (8) sub-reading (ii), *six per-rail prefixes*: the operator's variant is ONE radius + over the whole payload in root→leaf order, self-referential. Sub-reading (i), six + needles, is a different object — a survivor set — and stays as the sparse arm's + shape. + +### Pre-registered falsifier — Phase 7, not run + +`ternary_match_strided_to_mask` over a 64k × 16 B table, release build, ≥ 10 runs, +cycles per row from `rdtsc`. **Pass:** ≤ 1 cycle per row sustained (the SIMD kernel +should land well under: four u64 lanes per compare on AVX2). **Fail:** > 1 cycle per +row — then "close to 1 CPU cycle" is true of the primitive and not yet of the +substrate end to end, and the strided `Operand` in mask-risc is what closes it. + +## 2026-09-15 (8) — E-THE-RAIL-IS-A-NEEDLE-NOT-A-MASK-256-BY-256-IS-THE-EXACT-ROW-ADDRESS-AND-A-MASK-OVER-THE-AREA-IS-ANOTHER-OBJECT-1 — operator clarification; (7)'s "hi byte = skip unit" is withdrawn as the ruling's meaning, and its measurement is kept as data + +**Status:** RULING — operator, verbatim (2026-09-15, five lines): *"Ich meine 64k sind +2 byte. 256:256 sind 2 byte für die exakte SoA inna given table. Das gilt nur für needle +in a haystack x table. Für Maske über 64k als Fläche bräuchte es entsprechend mehr. Eine +Mögliche Lesart für masking wäre 256:256⁶, also genau 96 bit, oder bitpacked 64k."* +Everything below the ruling is my reading of it, labelled as such. +**Confidence:** HIGH that (7)'s derivation was not what was meant — the operator says so +in the first word. MEDIUM on the two sub-readings of `256:256⁶`: the operator called it +*eine mögliche Lesart*, and it stays open here. + +### What the ruling says, read plainly + +1. **The rail is an address, not a mask.** `u8:u8` = 2 bytes = the exact SoA row in a + given 64k table. 256 × 256 = 65 536: every value a row, every row a value. THAT is + "kein Rest" — a bijection between rail values and rows — not a tiling of the mask + into skip units. It holds for the needle-in-a-haystack × table case: one value, + one row. +2. **A mask over the 64k AREA is a different, larger object.** Bitpacked it is 65 536 + bits = 8 KiB = 1 024 words = 256 four-word blocks, and it tiles with no remainder in + either unit. The rail does not dictate which unit an executor skips in; nothing in + the ruling does. +3. **`256:256⁶` = 96 bits is the facet payload — the operator's candidate for a masking + reading.** Two ways to read it, both recorded, neither ruled: (i) six exact + needles — a sparse survivor set of at most six rows, in the 12 bytes the facet + already has; (ii) six per-rail prefixes — a product cell in the six-rail tile space, + a mask given by predicate rather than by bits. Reading (i) is the sparse arm the A1 + falsifier is missing, in the substrate's own register: D-GTM-0n's *below ~0.1 % + active, switch to sparse* is below 65 rows of 64k, and six needles are 0.009 %. + +### What (7) got wrong, and what of it stands + +- **Wrong as the ruling's meaning:** *"the rail's unit is its hi byte"*, *"a quarter + block is a remainder"*, *"count in the unit the address is carved in"*. The address + is not carved into the mask at all. Withdrawn; (7) is ⊘-regraded in place. The same + sentences had been pushed as canon in `d80b802` — in the probe header, `lib.rs`'s + `and_by_skip` doc, the prefix test's comment and mask-risc's `MaskOp::Pred` doc — and + are corrected in this commit to the reading above. +- **Stands as data:** the two-unit measurement. 64-row words are the executor's unit; + 256-row blocks are the 2-nibble prefix cell of the OGAR tier tile (`OGAR/CLAUDE.md` + "Tier interpretation — 256×256 CENTROID TILE": a 4-ary hierarchy per byte) — a + legitimate coarser skip unit, not the rail's. Clustered `/48`: 99.61 % in both + units; selective: 80.66 % words / 61.91 % blocks, written order 0 blocks; the ramps. + The `/48` cut stays: it is nibble-aligned under the tile canon, which is a separate + and older ruling; `/50` (2.5 nibbles) is not. +- **Stands, restated:** the probe's `N == 256 * 256` assert now says what it is — the + table is exactly 2-byte addressable — rather than "no fractional block". +- **Stands from (5)/(7):** the clustered regime at `/48` sits above the 0.1 % bound + (0.177 %); the selective regime (0.055 %) is under it and the probe has no sparse arm. + +### Consequence + +The missing sparse arm now has a shape and a home. Shape: a needle list of `u16` row +ids — the very thing a rail value is. Home: Phase 7's *very-sparse* density arm +(task #6), measured against the bitpacked sweep at 6, 36 and 116 survivors, where six +is the count the facet register itself can hold. Not built here; recorded so the arm +is built against the operator's reading and not against mine. + +> ⊘ **Same day, entry (9):** the operator's favourite is neither sub-reading — it is +> `(self, d)`, ONE stepless radius over the whole 96-bit payload in root→leaf order, +> self-referential; sub-reading (i), six needles, stays as the sparse arm's shape. + +## 2026-09-15 (7) — E-256-BY-256-IS-EXACTLY-64K-THE-RAILS-SKIP-UNIT-IS-ITS-HI-BYTE-AND-A-QUARTER-BLOCK-IS-A-REMAINDER-1 — operator-ruled; the `/50` cut read across `u8:u8`, and re-measured on the byte boundary the clustered regime moves ABOVE the density bound + +**Status:** RULING — operator, verbatim: *"256:256 is exactly 64k. Es darf gar keinen +Rest geben."* — plus FINDING for everything measured below: the probe now prints both +units and the ramp, re-runnable. Reading the ruling as *the rail's hi byte is the skip +unit* is my derivation and is labelled as such. +**Confidence:** HIGH on the numbers. The derivation is the only reading under which +"no remainder" and the `u8:u8` canon (two separate bytes, never widened — +`E-V1-TAIL-FORBIDDEN-V3-IS-CONTENT-BLIND-1`) are satisfied by one skip unit. + +> ⊘ **Superseded the same day by the operator's own clarification — entry (8).** The +> reading *hi byte = skip unit, quarter block = remainder* was mine, and it is not what +> was meant: the rail is the exact row ADDRESS of a 64k table (2 bytes ↔ 65 536 rows — +> that bijection is the "no remainder"), not a mask; a mask over the area is a larger +> object, and the rail dictates no skip unit. The measurements below stand as data in +> two units (words; 256-row blocks = the tier tile's 2-nibble cell), the `/48` cut +> stands under the tile canon, and the "rule" at the end is withdrawn. +> ⊘ And per (9): `/48` is a representative radius, not the only legal one — the +> operator's variant makes the radius STEPLESS; `/50` is where the word-skip saturates. + +### The ruling, and what it rules out + +A rail is `u8:u8`: 256 × 256 = 65 536 rows — exactly the 64k slab, exactly the A1 +probe's `N`. Its hi byte addresses 256 blocks of 256 rows; a block is four 64-row +words, one 256-bit vector. "No remainder" cuts two ways: + +- **Addressing.** A prefix on a rail is a whole number of hi-byte cells or it is not a + rail address. `/48` on the probe's `i << 8` lane pins the hi byte — one block. The + `/50` the (5) entry measured pins two more bits by reading across the two bytes as + if they were a `u16`, and selects a QUARTER block. That quarter is the remainder. +- **Counting.** A skip counted on a rail is counted in blocks. The 64-row word is the + facade's machine unit — `MaskOp::Pred`'s doc already lets an executor skip coarser + chunks with an identical result — but as an ADDRESSING unit it straddles the lo byte + (6 bits against a nibble cascade), and a block with one live word is live, not + three-quarters dead. + +### Re-measured on the byte boundary (`crates/lance-graph-quack/examples/adaptive_order_probe.rs`, both units, ramp printed) + +| regime | survivors | words, worst → best | 256-row blocks, worst → best | +|---|---|---|---| +| selective | 36 (0.055 %) | 5.66 % → 80.66 % | **0.00 % → 61.91 %** | +| moderate | 14 311 (21.8 %) | 0 → 0 | 0 → 0 | +| permissive | 61 777 (94.3 %) | 0 → 0 | 0 → 0 | +| clustered, `/48` | **116 (0.177 %)** | 0.00 % → **99.61 %** | 0.00 % → **99.61 %** | + +Three things the byte boundary changes: + +1. **99.61 % = 1 − 1/256, predicted before the run, held.** Words and blocks agree + exactly on the clustered regime (4 080 / 4 096 and 1 020 / 1 024): one live block, + four live words. The ramp is `[4080, 3060, 2040, 1020, 0]` words / + `[1020, 765, 510, 255, 0]` blocks — monotone, linear, in both units. The (5) + entry's 99.90 % was the quarter-block cut's number: correct for that cut, and that + cut is not a rail address. + +> ⊘ **CORRECTED, same day.** The printed totals do not match this entry's own unit +> definitions. Above: "a block is four 64-row words, one 256-bit vector," on +> N = 256 × 256 = 65,536 rows. That arithmetic gives **1,024** total 64-row words +> (65,536 / 64) and **256** total 256-row blocks (65,536 / 256) — not 4,096 and 1,024. +> A one-live-block result under THOSE totals is **1,020 / 1,024 words skipped** and +> **255 / 256 blocks skipped**, both = 99.61 % = 1 − 1/256, matching this section's own +> headline claim. The printed pair — "4,080 / 4,096" labelled words, "1,020 / 1,024" +> labelled blocks — has totals (4,096 and 1,024) that are one granularity finer than +> each label: 4,096 is the total for a 16-row unit (not defined anywhere else in this +> entry), and 1,024 is the total for the entry's own 64-row WORD definition, not its +> 256-row BLOCK definition. Both mislabeled pairs reduce to the identical 99.61 % ratio +> (4,080/4,096 = 1,020/1,024 = 255/256), which is why the qualitative claim — words and +> blocks agree, ceiling = 1 − 1/256 — survives; the printed raw counts and their column +> labels do not. Cite the percentage, not these counts, until the labels are checked +> against `adaptive_order_probe.rs`'s actual column definitions. +2. **The clustered regime sits ABOVE D-GTM-0n's 0.1 % bound, not under it.** 116 + survivors fill one block: 0.177 % active. The (5) entry's "both lever regimes sit + under the bound" was an artifact of `/50` (31 survivors). What survives: the + SELECTIVE regime (0.055 %) is under the bound and the probe still has no sparse arm + — the missing-arm finding stands, narrowed to that one regime. +3. **In the rail's unit the selective regime's written order skips NOTHING.** 232 dead + words of 4 096 in the written order — and 0 dead blocks: scattered survivors leave + no 256-row block empty until the two selective conjuncts have run. Best drops + 80.66 → 61.91 %. The word count flattered the lever by 19 points on the scattered + regime; on the contiguous regime it was exact. + +Sharper than before, too: the clustered regime has three times the selective regime's +survivors and skips MORE — 116 vs 36 rows, 99.61 vs 80.66 % of words, 99.61 vs 61.91 % +of blocks. Ranked by selectivity the two come out backwards. That replaces the (5)-era +"near-identical counts, 19 points apart" argument, which was also `/50`'s. + +### Where it landed + +- The probe: `dead_blocks`, `skipped → (words, blocks, count)`, `/48`, a + `const _: () = assert!(N == 256 * 256 && BLOCKS * BLOCK_WORDS == WORDS)` that says + "no remainder" in code, and the ramp printed so the quoted figure is a measurement. +- `lib.rs`: the `and_by_skip` doc table carries both units and the new figures; the + crate doc's 99.90 → 99.61; the prefix-halving test keeps `/49` and `/50` as + COMPARATOR arithmetic (a ternary match pins any care mask) and says which prefixes + are rail cells. +- mask-risc `MaskOp::Pred` doc: one paragraph naming the rail's unit. +- Board: (5) ⊘-regraded in place at both affected sections; matrix §8a and D-QCK-9 + ⊘-annotated; `LATEST_STATE` 2026-09-15 (4). + +### The rule + +**Count in the unit the address is carved in.** A skip fraction measured in a unit +finer than the rail's cell reports a saving the rail cannot address — and on scattered +populations overstates it. The word is how the executor tests; the block is what the +rail can promise. + +## 2026-09-15 (6) — E-THE-SLOWEST-GATE-IS-THE-ONE-YOUR-OWN-PUSH-CADENCE-CANCELS-1 — 33 runs, 19 cancelled; the fix waited 75 minutes for a verdict, and three of its four heads were cancelled by my own next push + +**Status:** FINDING. Every number is the Actions API ledger for `rust-test.yml` filtered +to this branch, re-fetchable. +**Confidence:** HIGH. + +### The ledger + +`Rust Tests` on `claude/clone-repositories-71a5sw`: **33 runs — 19 cancelled, 7 success, +7 failure.** A verdict on 14 of 33 heads. For #1235's fourteen runs on 2026-09-15: 7 +failures (`d73c742` 17:25Z → `36646a2` 18:43Z, each finishing 2.9–4.5 minutes after +start — the compile-failure signature; the aws-smithy cause was verified by log on +`36646a2`, `E-A-CHECK-THAT-CANNOT-RUN-IS-INDISTINGUISHABLE-FROM-A-CHECK-THAT-PASSES-1`), +**6 cancelled, 1 success** — `d77cd4e`, 19 minutes wall, the only time the workflow +completed on this PR. + +The mechanism is a concurrency group keyed on the PR number with +`cancel-in-progress: true` (`.github/workflows/rust-test.yml:13-15`), on a workflow that +takes 19 minutes. Correct CI +economy. The failure is the reader's, and the timeline is the finding: + +| head | committed | run created | outcome | +|---|---|---|---| +| `947753d` (the fix) | 19:09Z | — | no run: the PR was conflicted | +| `99479a5` | 19:27Z | 19:28Z | cancelled 19:32Z by the next push, after 4 min | +| `188d6b3` | 19:31Z | 19:32Z | cancelled 19:48Z, after 16 min | +| `e43d12f` | 19:47Z | 19:48Z | cancelled 20:06Z, after 18 min — about a minute short of a full run | +| `d77cd4e` | 20:05Z | 20:05Z | **success 20:24Z** | + +75 minutes from the fix to its first test verdict, and nothing but my own cadence in +between. + +### What I read as confirmation meanwhile, and what it actually confirmed + +`Build` and `Style Check` went green on `188d6b3`. `build.yml` is `cargo build` / +`cargo test` with `--manifest-path crates/lance-graph/Cargo.toml` — **one crate**. It +proved the aws fix compiles the core crate and runs its tests; it never builds +`lance-graph-quack` or `lance-graph-mask-risc` and cannot run their suites. "The fix is +confirmed" was true for the compile and unsupported for the tests until 20:24Z. + +The check-in prompt I wrote for myself compounded it: it asked the next wake to confirm +that `member-tests` reaches its `cargo test -p lance-graph-quack` line. **There is no such +line.** The quack step is step 17 of the `test` job, `Run quack tests` = +`cargo test --manifest-path crates/lance-graph-quack/Cargo.toml` +(`.github/workflows/rust-test.yml:134-135`); the member-tests job enumerates other +crates by manifest path and never names quack. Verified on `d77cd4e` by log: `Running unittests +src/lib.rs (…lance_graph_quack-…)` → `test result: ok. 14 passed; 0 failed`. A wake that +trusted the prompt would have grepped the wrong job's log, found nothing, and reported the +suite as never run — a false negative primed thirty minutes ahead by its own author. + +### The rules + +1. **When you are waiting on the slowest gate, a push is a cancellation.** Hold the push + until the verdict, or accept that the verdict will be for the next head. The tell in + the ledger: a run whose `updated_at` matches the next run's `created_at` to the second. +2. **A cancelled run leaves no verdict, and the greens beside it are the fast workflows.** + Read the slow workflow's ledger (`actions_list`, branch-filtered), not the PR page. +3. **Name a job from its step list, never from memory.** `get_workflow_job` returns the + steps; thirty seconds against thirty minutes. + +Cross-ref: `E-A-CHECK-THAT-CANNOT-RUN-IS-INDISTINGUISHABLE-FROM-A-CHECK-THAT-PASSES-1` is +the conflicted-PR half of the same day — no run at all. This entry is the other half: a +run that starts and is killed. + +## 2026-09-15 (5) — E-THE-SKIP-LEVER-LIVES-ONLY-BELOW-THE-DENSITY-WHERE-D-GTM-0N-SAYS-SWITCH-TO-SPARSE-AND-THE-CLUSTERED-99-90-IS-PREFIX-ARITHMETIC-1 — both readers dropped the density bound; both A1 lever regimes sit under it; the 99.90 % is 1023/1024 by construction + +**Status:** FINDING for the density collision and for the P = 50 arithmetic — both +re-checkable from two board rows, two source lines and the §8a table. CONJECTURE for +the prefix-length family below P = 50: derived, not run; its falsifier is named. +**Confidence:** HIGH on every number quoted. The *competitive* claim — that a sparse +arm beats the gated sweep at 0.05 % active — is deliberately NOT made. The probe has no +sparse arm, and that absence is the finding. + +### 1. The bound two readers dropped + +`STATUS_BOARD` row `D-GTM-0n / P3` carries two bounds *"that ride with the number and +may not be dropped when it is cited"*: the win is L2-residency-contingent, **and mask +loses to sparse below 0.1 % active**. The crosswalk entry restates it — *"only above +~0.1 % active — a crosswalk hop that thins the survivors below that must switch to +sparse"* (its "bounds that ride with the claim" paragraph). The parallel session's second +feedback cited D-GTM-0n by its L2 bound and its K = 1 control and omitted the density +bound; earlier the same day I had cited D-GTM-0m without its one-fixture / upper-bound +caveat (⊘ in `E-FUSING-FORFEITS-THE-SKIP-AND-ADAPTIVEFILTER-FAILS-IN-TWO-PLACES-NOT-ONE-1`). +Same move, two readers, two rows: the memorable bound survives the citation and the +inconvenient one does not. + +### 2. Why it bites: the lever's only live regimes are under the bound + +§8a (`.claude/plans/duckdb-to-v3-translation-matrix-v1.md`) — 65 536 rows, 5 conjuncts, +all 120 permutations: + +| regime | survivors | active | spread | +|---|---|---|---| +| selective | 36 | **0.055 %** | 75.00 pts | +| clustered | 31 | **0.047 %** | 99.90 pts | +| moderate | 14 311 | 21.8 % | 0 | +| permissive | 61 777 | 94.3 % | 0 | + +The two regimes where ordering moves the skip fraction sit at roughly half of 0.1 %. The +two regimes where the mask arm is the right arm by D-GTM-0n's own bound have spread 0. +So `Filter::and_by_skip` is measurable exactly where the substrate's bound assigns the +work to the sparse representation, and inert everywhere the mask representation is the +right one. + +What that changes: the A1 verdict (*ADAPT conditionally*) was reached by comparing +orderings of the gated sweep **to each other**. The competitor D-GTM-0n names at this +density is a survivor list with per-row evaluation of the remaining conjuncts — on the +order of 36 rows × 4 conjuncts against 1 024 gated words × 4 — and the probe never runs +it. The falsifier is missing an arm, and it is not the fused arm (Phase 7): that one is +order-independent by construction (the (4) entry above) and settles a different question. +**The A1 row must carry the 0.1 % bound the way D-GTM-0n's row does.** + +> ⊘ **Corrected the same day (operator ruling, entry (7)).** The clustered row above is +> the `/50` cut's — a quarter block. On the rail's byte boundary (`/48`) the clustered +> regime has **116 survivors = 0.177 %**, ABOVE the bound; only the selective regime +> (0.055 %) sits under it. The missing-arm finding stands for that regime. + +### 3. The clustered 99.90 % is arithmetic, not a property of the data + +`crates/lance-graph-quack/examples/adaptive_order_probe.rs:186` — `(i as u64) << 8`; +`:322` — `Filter::prefix_u64(ADDR, addr[N / 4], 48)` (it read `50` when this entry was +measured; see the ⊘ below). A 50-bit prefix on a u64 leaves 14 +low bits free: 8 are the shift, **6 are log₂ 64 — the word.** The prefix pins `i`'s top +10 bits, which IS the 64-row word index (N = 2¹⁶ rows = 1 024 words); exactly the 64 rows +of one aligned word satisfy it. Gated on that accumulator, every later conjunct evaluates +1 word of 1 024. The ramp `[4092, 3069, 2046, 1023, 0]` is 1 023 × (conjuncts after the +prefix), and 4 092 / 4 096 = **99.90 % = 1023/1024**. + +The parallel session named the general form the *10-bit handoff*: on a 16-bit rail the +low 6 bits address inside a word and the top 10 select it, so any prefix predicate of +length ≥ 10 on an address-ordered rail is word-granular **by construction**. On this +lane a prefix of P bits leaves 2^(50−P) live words — skip = 1 − 2^(50−P)/1024: 99.90 % at +50, 99.80 % at 49, 99.61 % at 48, 0 % by 40. §8a measured the P = 50 point of that function +and tabulated it beside three regimes that ARE properties of the data. "Clustered" should +be read as *the predicate is a word address*, and 99.90 % as the mechanism's ceiling, not +as an observation about clustering. + +Two consequences. The ceiling is reachable only on an ADDRESS-ORDERED lane — the blocker +the parallel session already named for the V3-native seed; on an unsorted lane a prefix's +survivors scatter and the function above does not apply. And a V3 `6×(u8:u8)` rail is 16 +bits wide, so the handoff sits at exactly 10 bits for every rail: above that length the +prefix skip and the word skip are one mechanism, below it they are two. + +**Falsifier (not run):** the probe with the prefix at 50, 49, 48 must report 99.90 / +99.80 / 99.61 %. A departure falsifies §3; a match promotes the family from CONJECTURE. + +> ⊘ **Corrected the same day — the handoff is at the BYTE, not at 10 bits.** Operator: +> *"256:256 is exactly 64k. Es darf gar keinen Rest geben."* The rail's unit is its hi +> byte — 256 blocks of 256 rows, four words each. `/50` pins two bits of the lo byte, +> reading across `u8:u8`, and selects a quarter block; the 1023/1024 is that cut's +> arithmetic. On the byte boundary the ceiling is 1 − 1/256 = **99.61 %**, measured in +> both units (entry (7); the `/48` point of the falsifier above ran and matched). The +> prefix-length family below the boundary is withdrawn as a family of rail addresses — +> legal prefixes are nibble-multiples and the skip unit is the block. The word-level +> figures above remain correct as facade arithmetic for the cut they describe. + +### What to carry + +- Any citation of D-GTM-0n carries the 0.1 % bound; any citation of §8a's lever regimes + carries their densities (0.055 %, 0.047 %) beside it. + +> ⊘ **STALE, same day — superseded by entry (7) above (earlier in this file's reading +> order).** `0.047 %` here is the `/50` quarter-block cut's clustered density. Entry +> (7)'s byte-boundary (`/48`) re-measurement gives the clustered regime **116 +> survivors = 0.177 %** — ABOVE the 0.1 % bound, not sitting beside the selective +> regime under it. Only the selective regime (0.055 %) still sits under the bound. +> Cite (0.055 %, 0.177 %), not (0.055 %, 0.047 %). + +- The A1 falsifier's missing arm is SPARSE, not fused. Filed as the operator's call in + `LATEST_STATE` 2026-09-15 (3). +- No code changes here; `and_by_skip` stays as shipped. + +## 2026-09-15 (4) — E-FUSING-FORFEITS-THE-SKIP-AND-ADAPTIVEFILTER-FAILS-IN-TWO-PLACES-NOT-ONE-1 — the fused lowering is order-independent BY CONSTRUCTION, two readers derived it from source because the crate doc does not say so, and DuckDB's A1 turns out to have a dead seed as well as an unrunnable loop + +**Status:** FINDING. Convergent — derived independently in two sessions from the same +line, neither having read the other, before comparing. +**Confidence:** HIGH — every claim is a source read or a row of §8a, all re-runnable. + +### The finding + +`lower` and `lower_fused` differ in a way neither name nor the crate doc suggested: +**only `lower` can skip.** + +| | gate on a predicate | order changes skipped words? | +|---|---|---| +| `lower` (in place) | first ungated, later ones on the running ACCUMULATOR | **yes** — up to 99.90 pts (§8a) | +| `lower_fused` | `under.map(\|m\| Operand::Plane(m.0))` — caller's plane ONLY | **no, ever** | + +`assign_slots` gives every predicate its own slot and never chains, because the Boolean +combination is deferred to the fuser — and `MaskOp::Ternlog { imm, a, b, c, dst }` has +**no `under` field at all**, where `MaskOp::Pred { pred, under, dst }` does. A ternlog +combines already-materialised masks; by the time it runs, every sweep is paid for. + +The saving the gated form buys is physical, not bookkeeping. `ndarray`'s `pack_under` +(`simd_masking_ops.rs:1541-1546`) is `if gate == 0 { out_words[w] = 0; continue; }` — +the 64 values are never loaded. That `continue` is the entire mechanism §8a measures. + +The crate doc framed the choice as *"a consumer picks by whether it is scratch-bound or +pass-bound"* and said nothing about the skip. Both readers fell into it and both had to +go to source. Fixed in the same commit. + +### Why it matters beyond the doc + +It is the whole of what survived DuckDB's `AdaptiveFilter`. §8a measures ordering worth +up to 99.90 percentage points of skipped words on a clustered conjunction — **under +`lower` only**. On the same query under `lower_fused` it is exactly zero. So +`Filter::and_by_skip`'s lever is alive in one configuration: gated lowering × plane-free +conjunction × contiguous survivors. Under a plane it is inert as well +(`ISS-QUACK-AND-BY-SKIP-IS-INERT-UNDER-A-PLANE`). `adaptive_order_probe.rs` has no fused +arm, so its table cannot see this and does not claim to. + +### A1 fails in TWO places, and only one of them was recorded + +`AdaptiveFilter` is a seed plus a loop, and they die of different causes: + +- **the seed** — `GetInitialOrder`, from the optimizer's static SELECTIVITY heuristic. + §8a kills it independently of anything about V3's executor: selective (36 survivors, + 0.055 %) and clustered (31, 0.047 %) are indistinguishable by density and **19.24 + points apart best-vs-best**. A selectivity-seeded reorderer seeds on a statistic that + provably does not separate the two regimes where the lever exists. +- **the loop** — swap, measure RUNTIME, keep or revert, halve likeliness. This one would + find contiguity, because contiguity shows up in runtime whether or not you can name + it. It is the half quack structurally cannot run: `Program.ops` is a fixed `Vec` with + no measurement. + +**The half that would work cannot run; the half that can run measures the wrong thing.** +That is stronger than the matrix's "not DuckDB's algorithm" — it says why no amount of +porting reaches it. + +### The V3-native seed, and its one blocker + +The clustered regime IS an address prefix. `Filter::prefix_u32` builds +`care = u32::MAX << (32 - b)` — a contiguous high run — so a `Cmp::MatchU32/MatchU64` +whose care mask has that shape is prefix-shaped **at lowering time**: free, structural, +no measurement loop. That would feed an ordering score from structure instead of asking +the caller. + +The blocker is exact and is one bit: `prefix_u32`'s own doc says contiguous *"on an +address-ordered lane"* — a property of the DATA, not the query — and `Col(pub u16)` is +deliberately not a name ("name resolution is the catalogue's job"). quack carries no +catalogue by design, so the seed needs a schema fact the crate does not hold. Real +blocker, not a detail. + +### ⊘ A citation of mine that was under-qualified + +I cited D-GTM-0m as "22.4–22.8 µs, survivor-independent" without its stated limits. The +matrix carries them twice and I should have carried them too: R5 — *"measured on ONE +fixture (65 536 rows = 256×256 axial hex, 62 % permeable, one tile size, timing floor +50 ms, no `perf`)"*; E4 — it *"widened a u8 permeability column 4× to use +`gt_i32_to_mask`, and reported its `n_gen` and coal numbers as upper bounds because of +it."* + +The rescue offered for it — that survivor-independence is structural because +`gt_i32_to_mask` takes no gate parameter — is right about that function and must not be +read as a general claim about predicate generation, or it contradicts §8a. The accurate +form: **an UNGATED sweep is structurally survivor-independent; a GATED one structurally +is not**, `gt_i32_to_mask_under` exists (`simd_masking_ops.rs:1614`), and `pack_under`'s +`continue` is where the difference physically lives. The µs figure is one geometry; the +asymmetry is not. + +## 2026-09-15 (3) — E-A-CHECK-THAT-CANNOT-RUN-IS-INDISTINGUISHABLE-FROM-A-CHECK-THAT-PASSES-1 — "lots of CI errors" was stale red plus silence, and chasing it found `--all-features` broken since the lancedb 0.38 bump + +**Status:** FINDING. Two independent mechanisms, one shape. Both measured on PR #1235. +**Confidence:** HIGH — every claim below is an API read, a `cargo` exit code, or a line +number in a vendored crate. All re-runnable. + +### The shape + +A verdict you can see is not a verdict about the code you have. Two ways that breaks, and +both were live in this repo at the same moment: + +1. **The workflow could not run** — the PR was conflicted, so GitHub had no merge ref to + run `pull_request` workflows against. The last runnable SHA's red stayed on the page. +2. **The workflow does not run on push** — `rust-publish.yml` fires only on + `release: released` / `workflow_dispatch`, so what it checks rots between releases with + nothing to report it. + +Case 1 shows you a stale answer. Case 2 shows you no answer and you read it as "fine". +Neither is distinguishable from green by looking. + +### Mechanism 1 — a conflicted PR produces NO run, and the UI does not say so + +| what | measured | +|---|---| +| PR #1235 head | `947753d` (the aws-smithy fix) | +| workflow runs for `947753d` | **0** — none, in any state | +| newest runs on the branch | `36646a2`, the commit BEFORE the fix | +| PR `mergeable` / `mergeable_state` | `false` / **`dirty`** | + +`build.yml`, `rust-test.yml` and `style.yml` trigger on `pull_request`, which GitHub runs +against `refs/pull//merge` — a ref it can only synthesise when the PR merges cleanly. +A conflicted PR therefore produces no run at all. Five non-`pull_request` workflows +(`Supersession index`, `Append-only gate`, …) DID run and DID pass, so the page showed +five greens beside two stale reds and **not one of the seven described the head**. + +**The check, before believing any red on a PR:** compare the failing run's `head_sha` +against the PR's `head.sha`, and read `mergeable_state`. `dirty` means CI is silent, not +failing, and the remedy is to merge or rebase the base in — not to debug the code. + +### Mechanism 2 — `--all-features` was already broken, and only a release would have said so + +Chasing mechanism 1 turned up a second one. `.github/workflows/rust-publish.yml` +PASSED `args: "--all-features"` to `katyo/publish-crates@v2`, which runs a verification +build before publishing; `c2b4bc7` in this same PR replaced it with an explicit list. +Measured on the tree before that fix: + +| invocation | exit | +|---|---| +| `cargo check --workspace` | 0 | +| `cargo check --workspace --all-targets` | 0 | +| `cargo check -p lance-graph --all-features` | **101** | + +TWO independent causes, and the interesting one is not ours: + +- **`aws-sdk`** — ours, added this session, opt-in by design because + `aws-smithy-json 0.63.0` does not build against `aws-smithy-types 1.7.0`. +- **`lancedb-sdk`** — **not ours, and older.** `lancedb 0.38.0` declares `default = []`, + gates `Error::Http` behind `#[cfg(feature = "remote")]` (`src/error.rs:111`), but leaves + `pub mod job;` ungated (`src/lib.rs:188`) while `job.rs` uses `Error::Http` + unconditionally at `:56` and `:66`. **That crate cannot compile without `remote`.** The + workspace pin `lancedb = { version = "=0.38.0", default-features = false }` — the + `lancedb` key in the root `Cargo.toml`'s `[workspace.dependencies]` — is on `main` + unchanged and was untouched by `947753d`. + +So `--all-features` has been failing since the lancedb 0.38 bump (#1190), and **no +push-triggered run could ever have gone red for it**, because the only call site is a +workflow that fires on `release: released` / `workflow_dispatch` only. ⊘ An earlier +draft of this line said *no branch* could have gone red — too strong: +`workflow_dispatch` can be aimed at any branch, so the failure was reachable on +demand, just never by the ordinary push/PR cadence that makes a failure traceable to +a cause. The `aws-sdk` flag did not create this; it added a second reason to the same +silent failure. + +### What generalizes + +**Adding a feature you know to be broken is not a local act** — every `--all-features` +call site becomes a caller of it. Grep before landing one. Here there were two: +`rust-publish.yml` (fixed) and `style.yml:95`, which is scoped to `lance-graph-quack` — +one path dep, zero declared features — so it cannot reach `lance` or `lancedb`. + +**And the stronger one:** a workflow that only runs on release is not a gate, it is a +deferred assertion. Its failure is dated to whenever someone next cuts a release and will +be attributed to whatever PR happens to be adjacent. If a check matters, it has to run on +a cadence where its failure is still traceable to a cause. + +## 2026-09-15 — E-I-GRAFTED-HELIX-ONTO-HEXAGON-AND-THEN-DEPRECATED-THE-OPERATORS-TENANTS-ON-MY-OWN-AUTHORITY-1 — there is no residue in Hexagon; the guard that refused the graft was recorded as a missing feature; and then I called two of the operator's shipped tenants dead + +**Status:** CORRECTION. Operator-caught, same day, hours after +`E-I-DECLARED-A-JOIN-ABSENT-BY-GREPPING-ONE-FILE-AND-COMPOSE-IS-THE-SAME-XOR-A-THIRD-TIME-1` +merged in #1233 carrying the fabrication. +**Confidence:** HIGH — every clause below is a census of shipped declarations and a +count over the Hexagon artifacts, both re-runnable. +**Stornoes:** five rows of that entry's organs/no-nerve table + its `Read edge → … → +write HelixResidue + Plasticity` chain (annotated in place). + +### What I fabricated + +A five-stage Hexagon learning path — *read edge → encode residue → `observe`/`roll` → +write `HelixResidue` + `Plasticity` → surround over six neighbours* — assembled from +**two tenant declarations that nothing has ever written** and **a crate that is not part +of Hexagon**, then published as the substrate's design with a "re-aim the loop at it" +proposal on top. + +| my claim | measured | +|---|---| +| `HelixResidue` `U8×6` = "one byte per synapse, exactly six" | 6 B = **one 48-bit `Signed360` sphere angle** (`canonical_node.rs:868-871`). I read `6 == 6` as a mapping. | +| `Plasticity` `U32×1` as a learning target | `U32` *"Hebbian counter + last-active stamp"* — a **scalar accumulator**, foreign to **6 × 2 × palette256**, and 2 sites outside its own decl file | +| helix residue belongs to Hexagon | `helix/src/lib.rs`: *"**HHTL is the deterministic PLACE**; helix is the **RESIDUE**"* — the HHTL axis, not the six rails | +| the loop needs "a width-correct lane accessor" | `style_lane` returns the null lane for any non-12-byte tenant, *"release-safe by construction"* — **the contract's own guard was refusing the graft** | + +### The shape was not merely available — it was ruled AND measured, and I proposed the option that measurement rejected + +**`6 × 2 × palette256` is the perfect shape**, and this board already says so with a number +on it. `E-V3-FACET-4-PLUS-12` carves the 12 B as `6×(u8:u8)` rails whose sanctioned reading +is **`palette256:palette256`** — each byte a centroid index, each rail a point in the +256×256 pairwise distribution, similarity between two rails **one `FisherZTable` read in +i8, never materialized** (`Palette256Pair`, `awareness_facet.rs:28-32`). The three learning +lanes are const-asserted *"12 palette256 atoms"* (`canonical_node.rs:2674`). And +the operator ruling **with its confirming measurement** is in +`E-CAM96-DISTRIBUTION-MEASURED-1` *(cited by ENTRY NAME, not line number — see the note at +the end of this entry)*: + +> *"the full 6×(256×256) 96-bit tenant is better than cam_pq 48-bit; if you want it +> perfect, the first is better"* — **CONFIRMED: ρ_all 0.966 ≥ 0.965, near-orth 0.881 +> (170×).** + +> ⊘ **AND THE FIRST DRAFT OF THIS VERY PARAGRAPH REPEATED THE ERROR IT RETRACTS — +> Codex P2, caught in review.** It read: *"`HelixResidue` is 48 bit. I proposed the exact +> budget class that a recorded measurement had already ruled the lesser one."* **That is a +> cardinality inference — `48 == 48` — the same move as `6 == 6` one level up.** The +> measurement compared **`cam_pq`** against the 96-bit V3-L4 tenant; it never encoded or +> evaluated `HelixResidue`. And the contract keeps them **explicitly distinct**: +> `facet_schema.rs:13` defines `FacetSchema::Pair48` as *"`2 × 48-bit` — two 6-byte codes — +> `helix` `Signed360` / `cam_pq` `[u8; 6]` (both already 48-bit)"*. Two codes that SHARE a +> budget so that both fit side by side — sharing 48 bits is what `Pair48` exists to exploit, +> not evidence they are the same object. **Struck: no measurement ranks `HelixResidue` +> against anything.** + +What stands without the transfer, and it is enough: **the ruled-and-measured shape for the +learning lanes is `6 × 2 × palette256`**, it was already carrying the promote gate, and I +went looking elsewhere. Why `HelixResidue` is the wrong surface is established by the +**graft** — helix is the residue of HHTL, not of Hexagon; `residue` is 0× in every Hexagon +artifact — **not** by any ranking of it. + +**The census that should have stopped it, in one line:** `residue` appears **0×** in +`.claude/plans/hexagon-plasticity-v1.md`, **0×** across `.claude/probes/hexagon-plasticity-v1/`, +**0×** in `STATUS_BOARD.md`. Hexagon was tested exhaustively — W-1, W0, W1/D-HXP-2, MQ-0..5, +H5a–d — and a residue was never in it. One `grep -c` over the plan I wrote would have +returned zero. + +### TWO violations, and the second is the worse one + +**V1 — the graft.** I assembled a five-stage Hexagon learning path out of `HelixResidue` +and `Plasticity` and published it as the substrate's design. That is my error, measured +below, and it is fully mine. + +**V2 — I then DEPRECATED two of the operator's shipped tenants on my own authority.** The +first draft of this entry called them *"zombies"* and *"dead"*, and named itself after that +verdict. **Not mine to rule.** *"Never written"* is a MEASUREMENT; *"dead"* is a DECISION +about the operator's architecture, and the operator's own word for what I did — reviving +something — is not a licence for me to bury it. This is the +`architectural-compliance` pattern inverted: the rule forbids substituting away from a +specified component because it *"appears to be a stub"*; declaring one deprecated because +it is unwritten is the same move with the same authority problem. **Nothing in this repo +deprecates `ValueTenant::{HelixResidue, Plasticity}`. Their status is the operator's +ruling. No code changed; both declarations stand exactly as shipped.** + +### What plasticity actually is — three surfaces, measured, no verdict attached + +| named "plasticity" | shape | state | +|---|---|---| +| `PlasticityState`, `CausalEdge64[50:52]` | **3 bits, hot/cold per S/P/O** | **SHIPPED, 54 production sites**, written by `pack` | +| the autopoiesis triangle 10/11/12 | `U8×12` = **6 × 2 × palette256** each — const-asserted *"12 palette256 atoms"* (`canonical_node.rs:2674`) | shipped + correctly addressed; gate documented, **`src/` promoter absent = seam 6** | +| `ValueTenant::Plasticity = 7` | `U32×1` counter + stamp @138 | **never written**; 2 sites outside its own decl file. Same *concept* as row 1 in a different shape — the operator's own reading: *"why u32 when hexagon is 6×2×8bit like everything in this Substrate"*. Its *"last-active stamp"* is emission-era vocabulary (`last_emission_cycle` → `last_active_cycle`). **Status: measured, not ruled.** | + +Two of these three are wired and one is not; **that is the whole of what is established +here.** I reached past two wired surfaces for an unwired one — and then compounded it by +grading the unwired one instead of reporting it. + +### The generalizable form — and it is the SAME rule as the entry it corrects, inverted + +That entry's own closing line is *"absence must be verified against the crate, not the +file."* This is its mirror: **presence must be verified against the ARTIFACTS that tested +the thing, not against the type system.** A declaration in `VALUE_TENANTS` proves a byte +range is reserved; it proves nothing about whether the concept was ever part of the design. +Two never-written tenants and a same-cardinality coincidence (`6 B` vs `6 rails`) were +enough to manufacture an architecture — and the only reason it was caught is that the +operator had run the Hexagon tests and knew no residue was in them. + +**The mechanical check, cheap enough to be unconditional — and it is a HEURISTIC, not a +proof:** before citing a type as part of a tested subsystem, `grep -c` its name in that +subsystem's plan and probes. + +> ⊘ **The first draft of this rule ended *"Zero hits means it is not part of it, whatever +> the type system says"* — CodeRabbit caught it, and the catch is exact: that sentence +> makes exact-name grep PROOF OF ABSENCE, which is row 5 of the table above restated as +> advice.** This repo already has the named precedent — +> `.claude/board/entries/2026-08-21-e-abbreviation-grep-manufactured-an-absence-1.md`, where +> `fn .*ppr` matched `approx` and a `head` limit hid the real hits, and a shipped 15-module +> subsystem was reported non-existent. Nothing requires a plan or probe to spell a type's +> canonical name: it can appear under an alias, a wrapper, an abbreviation, or only at a +> call site. **So: a nonzero count is evidence of presence; a zero count is a prompt to run +> a broader census (call sites, wrappers, sibling crates), never a verdict.** Three of this +> session's five rows were absence claims, and all three were wrong — the rule that would +> have prevented them is *widen the search*, not *trust the first grep*. + +### The generalizable form, REWRITTEN after review — it is not one rule, it is one MOVE made five times + +The review found three more instances of the same operation, two of them inside the +correction itself. The move: **transfer a property across a boundary on the strength of a +shared surface feature.** + +| # | shared feature | transferred | caught by | +|---|---|---|---| +| 1 | `6 B == 6 rails` | helix residue → a Hexagon synapse surface | operator | +| 2 | `48 bit == 48 bit` | `cam_pq`'s measured ranking → `HelixResidue` | Codex P2 | +| 3 | "multi-hop" | synthetic-SPD concentration → graph-traversal recall | Codex P1 | +| 4 | the word "plasticity" | an unwritten tenant → a deprecation verdict | operator | +| 5 | "it's in `VALUE_TENANTS`" / "I grepped one file" | declared-absent three times, wrong three times (`hhtl::NiblePath`, `deduce_path`, `promote_family`) | operator ×2, Codex ×1 | + +Rows 2 and 3 happened **while writing the retraction of row 1**, which is the finding: +*a correction written in the same voice that produced the error reproduces the error's +operating move.* The fix is not more care — it is a different question. Before any claim +that A tells you about B: **name the measurement that ranged over B.** If none did, the +claim is about A. + +**Citation rule, learned mechanically here:** this entry first cited +`EPIPHANIES.md:19221` and `:19050`. Both were **stale before the commit landed** — I +prepended 152 lines to the same append-only file I was citing, so every line number in it +shifted by that amount. **Cite an append-only board file by ENTRY NAME (`E-…-1`), never by +line number.** The `citation-decay` gate checks source citations, not board-internal ones, +so nothing would have caught it. + +Refs: `crates/lance-graph-contract/src/canonical_node.rs` (`VALUE_TENANTS`, `style_lane`), +`crates/lance-graph-contract/src/facet_schema.rs` (`Pair48` — helix and cam_pq are DISTINCT +48-bit codes), `crates/cognitive-shader-driver/src/mailbox_soa.rs:829` (`promote_family`, +the seam-6 promoter that does ship), +`crates/causal-edge/src/edge.rs` (`PlasticityState`, `PLAST_SHIFT`), `crates/helix/src/lib.rs`, +`.claude/knowledge/causal-plane-inventory.md` §2 (the triangle) + §3 seam 6, +`.claude/plans/hexagon-plasticity-v1.md`. + +--- +## 2026-09-15 — E-THE-ACCUMULATOR-GATE-OUTRANKED-THE-PLANE-AND-SILENTLY-DROPPED-IT-1 — a nested `Plane` vanished from the emitted program because the *enclosing* conjunction already had a gate + +**Status:** CORRECTION — a real correctness bug in shipped-in-PR code (`lance-graph-quack` +`emit_gated`), found by codex review on PR #1235, reproduced against the reference oracle +before the fix, fixed, and pinned by a permanent regression. +**Confidence:** HIGH — the reproduction is a number, not an argument: oracle **29**, emitted +program **204**, and the op list showed the plane's `FOCUS` operand absent entirely. + +### What happened + +`emit_gated(filter, under, acc_gate)` carries two gates. `under` is the plane the CALLER +handed down — `Filter::Plane(m)` encountered as a child, which must gate everything to its +right. `acc_gate` is the accumulator-so-far, the thing that makes the survivor skip work: +once some terms have been evaluated into a scratch, later comparisons can be evaluated +`Pred { under: Some(acc) }` and skip the 64-row words the accumulator already killed. + +The line was: + +```rust +let gate = acc_gate.or_else(|| under.map(|m| Operand::Plane(m.0))); +``` + +`Option::or_else` — the accumulator WINS whenever both are present. For a flat conjunction +that is right and is the whole point (the accumulator is strictly narrower than the plane +it already absorbed). For a **nested** one it is wrong, because the accumulator belongs to +the OUTER conjunction and has never seen the inner plane: + +```text +P1 AND (Plane(focus) AND P2) +``` + +The outer `AND` evaluates `P1` into the accumulator, recurses into the parenthesis with +`under = None, acc_gate = Some(acc)`; the inner `AND` meets `Plane(focus)`, sets +`under = Some(focus)`, and then for `P2` the `or_else` picks the accumulator and drops the +plane on the floor. `FOCUS` never appears in the program. Measured: 204 rows where the +oracle says 29. + +### The fix, and why it is the conservative direction + +```rust +let gate = under.map(|m| Operand::Plane(m.0)).or(acc_gate); +``` + +The plane always wins. This is conservative rather than optimal: where both are live the +accumulator may be the narrower gate, so preferring the plane can leave some skip on the +table. It can never be WRONG, because `Pred { under: g }` is exactly `g ∧ pred` +(`reference.rs:460`) and the `AND` that consumes the scratch re-applies the accumulator +anyway. The reverse — preferring the accumulator — drops a conjunct, which is a wrong +answer, not a slower one. **A gate you can only lose by choosing beats a gate you can drop +by choosing.** + +### The lesson that generalizes past this bug + +**`or_else` between two gates is a silent priority decision, and priority between gates is +only safe when one PROVABLY subsumes the other.** The accumulator subsumes `under` exactly +when the accumulator was built from a prefix that already included it — true for a flat +conjunction, false the moment recursion hands the accumulator across a nesting boundary. My +own hand-trace missed it because I traced the flat case, where the two are in fact ordered. +The shape that breaks it needs a plane that is BOTH nested and not first, which no existing +test had: `hoist_gate_subset` rotates a plane-subset child to the front precisely so the +accumulator starts inside the plane, and every fixture went down that path. + +### What the fix cost in the test suite, recorded because it is uncomfortable + +`the_gate_reaches_every_comparison_and_is_dropped_only_where_it_vanishes` asserted the plane +rode the ACCUMULATOR (`assert!(on_acc)`). That assertion was a description of the bug, not +of the law — it is now inverted (`assert!(!on_acc)`) with a ⊘ note, and the permanent +regression `a_nested_plane_survives_an_outer_accumulator` is what actually pins the +behaviour: two-sided (`expected * 2 < without_plane`, so a fixture whose plane admits +everything cannot pass) plus a structural check that some emitted op reads `FOCUS`. Both +arms of the disable run are RED. + +## 2026-09-15 — E-I-DECLARED-A-JOIN-ABSENT-BY-GREPPING-ONE-FILE-AND-COMPOSE-IS-THE-SAME-XOR-A-THIRD-TIME-1 — the canonical join shipped in `hhtl.rs` all along, `[a,b]:[b,c]` is `compose_chain`, and the Hexagon substrate is every organ shipped with no nerve between them + +**Status:** CORRECTION + FINDING. Census against shipped code, operator-corrected across eight +exchanges; every claim carries a `file:line`; the one new measurement is the probe arm +(`.claude/probes/family-join-v1`, re-runnable, pinned exact). +**Confidence:** HIGH on the census. The learning-loop census is by caller-grep and could miss a +caller under a renamed method — say so rather than claim exhaustiveness. +**Invalidates:** `ISS-NODEGUID-HAS-NO-JOIN-SURFACE`. **Re-scopes:** +`ISS-SHARED-PREFIX-TIERS-IS-TIER-COARSE-AND-BRANCHES`, `ISS-NO-MASK-HOP-OP`. **Corrects:** the +eighth-arc sentence in `E-THE-TWO-FAMILY-NAMINGS-INVERT-AND-FROM-BE-BYTES-IS-THE-PLAUSIBLE-WRONG-JOIN-1` +that `NodeGuid` has "no join surface at all" (annotated in place, below). + +### Eight corrections, each a structure I had wrong — recorded in order because the ORDER is the lesson + +1. I censused the **V1 `[u8;12]+[u8;4]` edge block** — marked retired in the `CLAUDE.md` I was holding. +2. I merged **HHTL and Hexagon** into "the same 6 bytes." They are the cell's **address** (trie, + `is_a`, WordNet-shaped, boring by design) and the cell's **content** (six rails, behaviour). +3. I measured the Hexagon on **MONDO** — HHTL material. A taxonomy has no behaviour to put on the + rails; rails 0–3 reading empty there is not a Hexagon finding. +4. I hunted for a **tile-as-distribution type**. The 4⁴ codebook makes each `palette256` code the + centroid *of* a distribution, and the `FisherZTable` (ρ≥0.999) already encodes + distribution-level similarity — one read compares two distributions without expanding + either. That is what "never materialized" means. +5. I proposed `meet(a,b)` with **36 reads** over 6×6 pairs. Between two Waben there is exactly + ONE edge — the shared code. 36 reads materializes. +6. I called `lookup_f32` "the read." **The i8 is the currency.** `decode → tanh → cosine` is a + materialization; `v3::read` then averages those cosines — the averaging `distance.rs:37` + names as wrong, whose z-space replacement `mean_similarity_fisher` has zero callers, which is + *correct*: it takes `&[f32]`, so it materializes too. Stay in i8. +7. I wrote "edge between two Waben — ABSENT." **`[a,b]:[b,c]`** = `ComposeTable::compose_chain(a,b,c)` + = `compose(compose(a,b), c)` — two reads, O(1), shipped in bgz-tensor; `PaletteSemiring::compose` + in bgz17; **wired** in `p64-bridge::deduce_path` (*"Transitive deduction: A→B→C via compose"*). +8. I wrote "adjacency absent from the contract." **`hhtl::NiblePath`** — there for months. + +### The join was there: `hhtl.rs`, same crate, one module over + +| pair | `CascadeKey` (0..=3 tiers) | `NiblePath::common_prefix_depth` (0..=16 nibbles) | +|---|---|---| +| P1 same HHTL, different v2 family | 3 | **16** | +| P2 different HEEL, same v2 tail | 0 | **0** | +| P3 identical (control) | 3 | 16 | +| P4 differ in both (control) | 0 | 0 | +| T1 classid top nibble | – | 16 (outside the path — by design) | +| T2 identity last nibble | – | 16 (outside the path — by design) | + +`ISS-NODEGUID-HAS-NO-JOIN-SURFACE` was filed on a grep of `canonical_node.rs` **alone**; two of +its six terms would have hit `hhtl.rs`. The canonical join agrees with `CascadeKey` on every +fixture at **16-nibble** resolution against 3 tiers, packs root-first from decoded fields +(`from_guid_prefix_v2`: `heel<<48|hip<<32|twig<<16|leaf`) — so it *avoids* the byte-order +trap the eighth arc measured — and it is **wired**: `mailbox_scan.rs:149` per row inside a scan, +`:263` as `DistanceMeans::PrefixDepth`, `soa_graph.rs:408` in `nearest_anchor`. It is a +`while … match` loop, not a shift — the "branches" half of the sibling issue transfers to it; +the "tier-coarse" half does not. The branchless form is one line on `packed()`. + +### Compose is the same XOR, a third time + +`compose_table[a*k+b] = palette index of palette[a].xor_bind(palette[b])` (bgz17 +`palette_semiring.rs:7`). The sixth arc found one XOR is both the ⊗ of 6/7 semirings and the +CLZ join. Compose is XOR-bind quantized back to the palette. **Same instruction, three readings: +multiply, join, compose.** The edge between two Waben is `b`; its algebra is the algebra +already running. + +### The Hexagon substrate — every organ shipped, no nerve + +| organ | type | ships | wired | +|---|---|---|---| +| Wabe = SoA row, Morton-trie addressed | `NodeRow`, `NiblePath` | ✓ | join ✓; trie unminted on the one real bake | +| Hexagon, six rails `(basin, identity)` | `SpoFacet` | ✓ | ✓ | +| currency: cosine replacement, i8, never float | `FisherZTable` 256×256 | ✓ | ✓ as storage; **decoded at every read** | +| read one Wabe | `v3::read(tenant, fz)` | ✓ | materializes; `_cell` computed and discarded | +| edge between two Waben `[a,b]:[b,c]` | `compose_chain` / `compose` | ✓ | ✓ `p64-bridge::deduce_path` | +| ⊘ plasticity as tenant | `ValueTenant::Plasticity = 7` | ✓ | **never written** | +| ⊘ synapse residue as tenant | `ValueTenant::HelixResidue = 4` | ✓ | **never written** | +| ⊘ synapse: deterministic place + 3-byte residue | `ResidueEncoder::encode(&self, place, n)` | ✓ | — | +| ⊘ learning write-back, gated | `observe` / `roll` (`&mut self`) | ✓ | **zero production callers** | +| ⊘ two synapses compared | `distance_adaptive(a, b, lut)` | ✓ | zero production callers | +| spread to the six neighbours | Pillar-15 DoG | certified | kernel DEFERRED | + +> ⊘ **THE FIVE ⊘ ROWS ABOVE AND THIS CHAIN ARE A FABRICATION — struck +> 2026-09-15, operator-caught, hours after this entry merged.** There is no +> residue in Hexagon. `HelixResidue` is a **48-bit `Signed360` sphere angle**, +> ONE orientation per node — I read `6 B == 6 rails` as a mapping; `Plasticity` +> is a `U32` *"Hebbian counter + last-active stamp"*, a scalar accumulator +> foreign to a **6 × 2 × palette256** substrate and a duplicate of the plasticity that +> ships in the substrate's own shape (`PlasticityState`, **3 bits at +> `CausalEdge64[50:52]`**, hot/cold per S/P/O, 54 production sites). helix is +> the residue of **HHTL**, not of Hexagon (`helix/src/lib.rs`: *"HHTL is the +> deterministic PLACE; helix is the RESIDUE"*). **`residue` appears 0× in +> `hexagon-plasticity-v1.md`, 0× across the W1 probes, 0× in `STATUS_BOARD`** — +> Hexagon was tested exhaustively and never involved one. The real learning +> surface is seam 6 of this session's own inventory, already hexagon-shaped: +> `FrozenStyle`/`LearnedStyle`/`ExploreStyle`, `U8×12` = **6 × 2 × palette256** each — +> the shape the operator ruled and this board MEASURED (`E-CAM96-DISTRIBUTION-MEASURED-1`, ρ_all 0.966, +> near-orth 170×) as better than the 48-bit class `HelixResidue` belongs to — with the +> shipped held-out promote gate already on it. Full storno: +> `E-I-GRAFTED-HELIX-ONTO-HEXAGON-AND-THEN-DEPRECATED-THE-OPERATORS-TENANTS-ON-MY-OWN-AUTHORITY-1`. + +~~Read edge (i8) → compare to expectation → encode residue → `observe`/`roll` → write +`HelixResidue` + `Plasticity` → surround over six edges.~~ Every stage a type; zero stages joined. +The currency is consistent across crates without a float anywhere — i8 in bgz-tensor, u16 L1 on +a z-indexed residue in helix (the Fisher-z is baked in at encode, stage 3), 3 bytes in +`ResidueEdge`. The body mesh (`CLASSID_FMA = 0x0A01_0000`, `ReadMode::FMA`) is the existence +proof that this place/residue split carries exact continuous structure at scale; as a synapse +it is the same encoder, not a new one. + +### What survives of the eighth arc + +The byte-order trap is real, `from_be` at `6/29` is the plausible-wrong join, and the shipped +code **dodges it**. The two namings inverting (`0` vs `3`) is real. The probe measured what it +measured; it was missing the arm that mattered, and now has it. + +### The generalizable form + +**Absence must be verified against the crate, not the file — and against the canonical name, +not the name I would have used.** Twice in one session I declared something absent after +searching one file or one name-set, and both times the operator's correction was simply to +name the file. The rule already existed (*"absence verified, not assumed"*, fourth arc, applied +to mask-risc). It was not applied to the contract, which is the one crate where absence claims +carry the most weight. + +Refs: `crates/lance-graph-contract/src/hhtl.rs` (`NiblePath`), `soa_graph.rs` ("two head axes"), +`crates/bgz-tensor/src/attention.rs` (`compose_chain`), `crates/bgz17/src/palette_semiring.rs`, +`crates/p64-bridge/src/lib.rs::deduce_path`, `crates/helix/src/residue.rs`, +`ValueTenant::{HelixResidue, Plasticity}`; +`E-THE-SEMIRING-IS-FREE-THE-COST-IS-CARRIER-WIDTH-AND-THE-JOIN-IS-THE-SAME-XOR-1` (the first two +XOR readings); `E-THE-TWO-FAMILY-NAMINGS-INVERT-AND-FROM-BE-BYTES-IS-THE-PLAUSIBLE-WRONG-JOIN-1` +(corrected in place). + +--- +## 2026-09-15 — E-A-DISABLE-CAN-GO-RED-FOR-THE-WRONG-REASON-AND-THE-TWO-PEAK-FIGURES-WERE-NEVER-IN-CONFLICT-1 — 142 and 6,297 are maxima over different seed pools; the flag saying they could not both stand was itself the error + +**Status:** FINDING (measured, `.claude/probes/density-sweep-v1/frontier_peak.py`, re-runnable +whenever the bake is present; every figure asserted exactly, mechanism disable-verified). +**Confidence:** HIGH. The exhaustive arm turns the root claim from an assumption about +ontology shape into a measurement, and the clean disable reproduces the separating figure +to the unit. +**Resolves:** the `⊘ NEEDS RE-DERIVATION` flag carried inline in PR #1233's fourth and +fifth arcs. + +### Two figures, one graph, no contradiction + +Published one arc apart as "the MONDO `is_a` peak frontier": **6,297 at hop 6** (fourth +arc, one seed) and **142 at hop 12** (fifth arc, 60 sampled seeds). I flagged them with +*"both cannot stand as 'the' peak."* **That flag was the error.** Measured: + +| pool | peak | +|---|---| +| 60 sampled **interior** seeds (`sweep.py`'s own `walk_seeds`) | **142** | +| all 3 MONDO **roots** | **6,297 at hop 6** | +| **exhaustive**, every one of the 6,194 nodes with children | **6,297 — global maximum** | + +`sweep.py` draws walk seeds from `[n for n in po if n[0] == MONDO and po[n]]` — nodes that +**have parents**. A root has none, so **a root is excluded from that pool by construction** +and no amount of resampling inside it can ever reach the root's frontier. Both numbers are +correct maxima over different pools. + +**The exhaustive arm is what makes this a measurement rather than a plausible story.** +Without it, "the root is the widest" would be an assumption about what an ontology looks +like — a deep-but-narrow root and a wide interior hub are both a priori possible in an +`is_a` DAG. Measured, no node anywhere beats the root. + +**It strengthens the original claim rather than weakening it.** 6,297 was reported as "a +single seed", which reads like an anecdote. It is the **widest frontier the graph admits**, +and it is the right figure for the fourth arc's cost-of-no-torch argument precisely because +a traversal seeded at the ontology root is the worst case a bounded frontier exists to bound. + +### ⊘ The blocker was also stale + +Both the PR body and the session's own check-in note recorded this as blocked on the 31 MB +bake being absent. The bake was **present** — 30,964,736 B = 60,478 rows, remainder 0, +fetched earlier the same day. The work had been re-deferred against a condition that had +already cleared. **A blocker is state, not a property**; it needs re-checking on the same +schedule as a measurement, and nothing in the flag's wording invited that. + +### THE TRANSFERABLE FINDING — my first disable went red for the wrong reason + +To prove root-exclusion was the mechanism rather than sampling luck, I disabled the +has-parents restriction so roots could enter pool (a). **It went red.** Taking that as +confirmation would have been wrong: it failed with `sampled peak moved: 107` — *lower* than +142, and nowhere near 6,297. Enlarging the pool from 6,191 to 6,194 changes which 60 seeds +`random.Random(11)` draws, so the red came from a reshuffled sample, not from a root. With +3 roots in 6,194 the chance any of 60 draws hits one is ~2.9 %. + +The clean disable keeps the sample **identical** and appends the widest root: +`sampled_peak` becomes **6,297 exactly**. Mechanism confirmed to the unit. + +**A red you do not read is as uninformative as a green you do not question.** The whole +disable-verification discipline rests on the failure being caused by the thing you removed, +and "it went red" does not establish that — the failure message has to be *the one the +mechanism predicts*. This session already collected the sibling forms (zeroing a constant +the guarded quantity can pass by another route; an anchor that silently stopped matching); +this is the third shape: **the disable applied, it went red, and it was still not evidence.** + +### Second, smaller: an exemption audited rather than cited + +The standing justification for the docstring-coverage warning is *"permanent by design — +frozen W1 probes whose corpus no longer exists."* The warning had since moved from 43.86 % +to 57.69 % and now covers 78 functions across 8 files, i.e. it had grown to span four NEW, +**re-runnable** probes the exemption was never argued for. Measured rather than assumed: + +| group | documented | +|---|---| +| frozen W1 (corpus gone — exempt) | 20/50 = **40.0 %** | +| new re-runnable probes | 21/23 = **91.3 %** | + +**The exemption is sound and covers exactly what it claims** — the new probes clear the +80 % threshold on their own, and the frozen block is what drags the total down. My suspicion +that it had silently widened was wrong, and checking cost one `ast` walk. The two genuine +gaps (`sweep.py`'s `measure` and `u24`) sat outside the exemption and are now closed; `u24` +names its endianness explicitly, because this same session measured a join where reading +identical bytes big-endian returns a plausible wrong answer that passes an ordering check. + +Refs: `.claude/probes/density-sweep-v1/frontier_peak.py`; +`E-THE-REVIEW-FOUND-A-REAL-BUG-THAT-FALSIFIED-MY-OWN-ISSUES-PREMISE-AND-I-BROKE-MY-OWN-RULE-IN-THE-FILE-STATING-IT-1` +(the same day's disable-discipline findings); +`E-BOUNDED-ATTENTION-BUYS-REACH-AND-A-DISTANT-HOP-IS-A-TERNLOG-NOT-A-SEMIRING-1` (the arc +whose cost argument the 6,297 figure carries). + +--- +## 2026-09-15 — E-THE-REVIEW-FOUND-A-REAL-BUG-THAT-FALSIFIED-MY-OWN-ISSUES-PREMISE-AND-I-BROKE-MY-OWN-RULE-IN-THE-FILE-STATING-IT-1 — nine findings, nine valid, and the two that matter are a 21× measurement error and a probe that asserts the relation it exists to condemn + +**Status:** FINDING (all nine verified against source before any edit; the code fixes are +re-run and disable-verified). +**Confidence:** HIGH. Every finding was checked against the declaration or artifact it names, +not accepted on the reviewer's word — and one of the nine was accepted only after my own +counter-reading turned out to be the wrong one (below). +**Provenance:** CodeRabbit full review of `43dbfde`, requested deliberately before merge +because its assessment had been frozen eleven commits back. Merge risk moved 🔵 Low → 🟡 +Moderate with *"correct the probe logic and conflicting conclusions before merge."* Correct. + +### The one that justified running it: a real bug, understating the metric 21× + +`supers_minmax` (`elk-generality-v1/generality.py`) enqueued a node **only on its first +discovery**. It wrote `mn[p]`/`mx[p]` on the two lines *above* the change-test, so the test +compared a depth against the value it had just written and was always false. A later, longer +path widened `mx[p]` without propagating that depth to `p`'s own ancestors. + +| | buggy | fixed | +|---|---|---| +| MQ mean path-length spread | 0.73 | **15.55** (21×) | +| MONDO mean spread | 0.44 | **1.35** (3.1×) | +| MONDO flat set | 13/13 | 9/9 | +| A3 headline Δ | 48.6 pp | **48.6 pp — identical** | +| A5 braided-only Δ | 47.5 pp | 47.8 pp | + +**The conclusions survive and the reason is worth keeping:** A3/A5 read the **sign** of spread +(flat vs braided), not its **size**. A metric wrong by 21× left them untouched because they +never used the magnitude. Only magnitude claims are void — and one of mine was. + +### It falsified the premise of an issue I had filed, in the direction of reversing it + +`ISS-SPREAD-DOES-NOT-TRANSFER-CROSS-FAMILY` argued: MONDO spread **0.44** scores 84.6 %, +*higher* than MQ `(1,2)` at 55.3 % **"with comparable spread"** — therefore spread does not +transfer. Corrected, MQ's spread is **11.5× MONDO's**, and the direction now *matches* the +within-MQ dose-response: more span, lower agreement (MQ 15.55 → 36.0 %; MONDO 1.35 → 84.6 %). + +**"Comparable spread" was an artifact of the bug.** The evidence for non-transfer is not merely +weakened; it points the other way. The issue stays **OPEN as unmeasured** rather than flipping: +two points are not a curve, and the specific comparison it made was against MQ `(1,2)`, whose +spread cannot be read off the fixed code because `sweep.py` computes no spread at all (verified: +zero `minmax` sites). Fourth reversal of the session, and the first one an outside reviewer +caused rather than my own re-measurement. + +### The probe that states the rule broke the rule + +I wrote, in the entry one above this: *"a test that checks the ORDERING of two prefix lengths +will pass the `from_be` implementation. Pinning a join requires asserting exact levels at both +ends, not a relation between them."* The probe shipped in the **same commit** asserted +`le_t1 > le_t2` — a relation — and `disagreements >= 2` — an aggregate that P1 drifting to +`(2,1)` and P2 to `(1,3)` would still satisfy. + +I asked the reviewer to look there specifically, suspecting this class of defect. It was there. +Now pinned exactly: `(cascade, v2tail)` per fixture `(3,1) (0,3) (3,3) (0,0)`; all three readings +at both ends `recomposed (0,31)`, `from_le (24,3)`, `from_be (6,29)`; plus the discriminating +property asserted directly — **`from_be` is monotone**, which is *why* an ordering check passes +it. Disable-verified red on a single-value change. + +**The generalizable form:** stating a rule in prose is not implementing it. The file most likely +to violate a rule is the file that articulates it, because writing it down feels like discharging +it. + +### A published number was the wrong metric + +`0.1579 → 0.0827, halved` compared baseline **`r@10`** against the shuffled arm's **`r@5`**. +Like-for-like is **0.0902** — a 43 % drop, not a halving. The PR body carried the right number +while the board entry carried the wrong one, so two artifacts I wrote disagreed. + +### And one where my counter-reading was the wrong one + +I described `from_be_bytes` as reversing **nibble order** inside each field. The reviewer said +per-field **byte** reversal, `0x1234 → 0x3412`. My first instinct was that the reviewer was +wrong. It is not: `0x1234` stored LE is `[0x34, 0x12]`, read BE as `0x3412`. A nibble reversal +would give `0x4321`. **Nibble pairs survive; their order within the field inverts.** Corrected at +both sites. + +### The rest, and the tally + +`±8` still in the horizon setup 27 lines above the `[−8, +7]` correction (**half-applied +correction, instance ten**); "braiding: back on the table" overstating a within-MQ result; +`INTEGRATION_PLANS` recording the gate score without the §11a amendment to FALSIFIED; the elk +README's A5/density statements not marked historical; and an unguarded bake parser where +`len(...) // STRIDE` silently drops a partial trailing row. All applied. + +**Nine findings, nine valid — fourteen for fourteen on this PR.** The standing lesson is about +*when* to ask: the reviewer had been frozen eleven commits back and its visible assessment +described a quarter of the work. Its value was not in the stale part; it was in the fresh pass +nobody had requested because the gates were green. **Green CI on this repo compiles no Rust at +all** — the four gates are documentation gates — so "green" never spoke to any of this. + +--- +## 2026-09-15 — E-THE-TWO-FAMILY-NAMINGS-INVERT-AND-FROM-BE-BYTES-IS-THE-PLAUSIBLE-WRONG-JOIN-1 — the ISS-FAMILY falsifier ran: 0 versus 3 on one pair, and the byte-order trap has a variant that passes the obvious sanity check + +**Status:** FINDING (measured, `.claude/probes/family-join-v1/`, re-runnable, zero external data). +Both real types linked — `lance_graph_contract::NodeGuid` with `guid-v2-tail` and +`perturbation_sim::CascadeKey` — nothing reimplemented. +**Confidence:** HIGH. Two controls agree exactly where they must; the `from_be` values were +hand-derived before the run and the measurement reproduced them. +**Closes:** `ISS-FAMILY-IS-FOUR-WIDTHS-TWO-AT-OPPOSITE-ENDS` — hazard CONFIRMED, not refuted. + +The issue's own closing condition was *"compute a shared-prefix under both namings for the same +entity and report whether they agree — either answer is useful."* Ran it. + +### Result 1 — the namings do not merely differ, they INVERT + +| pair | cascade | v2tail | | +|---|---|---|---| +| P1 same HHTL, different v2 family | **3** | **1** | disagree | +| P2 different HEEL, same v2 tail | **0** | **3** | disagree | +| P3 identical (control) | 3 | 3 | agree | +| P4 differ in both (control) | 0 | 0 | agree | + +**P2 is 0 versus 3.** On one pair of entities, `CascadeKey`'s naming reports *nothing shared* and +the v2-tail naming reports *everything shared* — the maximum possible disagreement on a 0..3 +scale. P1 is the same hazard milder. + +**The controls are what make this a measurement rather than a broken comparison:** the two +methods agree **exactly** when they should. A comparison that always disagreed would prove +nothing, and the probe asserts per-pair that every non-control pair genuinely differs in bytes +4..14 — the anti-vacuity condition the issue itself demanded, enforced in code rather than +assumed. + +### Result 2 — `from_be_bytes` is the byte-order trap's DANGEROUS variant + +Nibble level of first divergence, 0..=32: + +| pair | `from_le` | `from_be` | recomposed (correct) | +|---|---|---|---| +| T1 differs in classid's **TOP** nibble | 24 | 6 | **0** | +| T2 differs in identity's **LAST** nibble | 3 | 29 | **31** | + +The sixth arc predicted 0 and 31 for the correct recomposition and got them. What it did **not** +anticipate is the asymmetry between the two wrong readings: + +- **`from_le_bytes` is obviously broken** — 24 and 3, fully inverted. A root-level difference + reads as nearly identical, a leaf-level difference as nearly maximally distant. Any spot check + catches this. +- **`from_be_bytes` is the one that would ship.** 6 and 29: the *direction* is right (T1 < T2, + so a monotonicity sanity check **passes**) while every value is wrong. It is the + **per-field BYTE-order reversal** — fields keep their root-first order while each multi-byte + field's bytes reverse, so a `u16` `0x1234` stored LE as `[0x34, 0x12]` reads back as `0x3412`. + Nibble PAIRS survive; their order within the field inverts. It is plausible precisely because + it is monotone. ⊘ *First published as "nibble-order-reversed"; that was wrong — a nibble + reversal of `0x1234` would be `0x4321`. Corrected from review on `43dbfde`.* + +**That sharpens the sixth arc's claim.** It said a wrong version "returns a plausible small +number". Measured, there are two wrong versions and only one of them is plausible — the other is +obviously broken. **A test that only checks the ordering of two prefix lengths will pass the +`from_be` implementation.** Pinning a join therefore requires asserting exact levels at both +ends, not a relation between them. + +### What this does NOT show, stated so the issue is not over-read + +It does not show anyone has written the wrong join: `NodeGuid` has **no join surface at all** +(`ISS-NODEGUID-HAS-NO-JOIN-SURFACE`), which is why the probe had to supply the comparison. The +hazard is live *because* the operation is unwritten — this measures what the namings would yield +the moment someone writes it. + +> ⊘ **CORRECTED same day — this sentence is false.** `NodeGuid` HAS a join surface: `hhtl::NiblePath::{from_guid_prefix_v2,_v3, common_prefix_depth, family_hop_count, common_ancestor}`, same crate, wired in `mailbox_scan.rs:149/263` and `soa_graph.rs:408`. The probe's missing arm now runs it: agrees with `CascadeKey` on every fixture at 16-nibble resolution. See `E-I-DECLARED-A-JOIN-ABSENT-BY-GREPPING-ONE-FILE-AND-COMPOSE-IS-THE-SAME-XOR-A-THIRD-TIME-1`. The byte-order trap this paragraph measures stands; the shipped join avoids it. + +It also does not indict the shipped API. `family_v2` is distinctly named, feature-gated, and its +own doc comment already reads *"different name, different bytes — no silent semantic swap."* +I-LEGACY-API-FEATURE-GATED is satisfied. The exposure is a reader or a cross-type design treating +"family" as one concept — which is exactly what the recalled 4096-compartment shorthand did. + +### Consequence for the queued work + +`ISS-SHARED-PREFIX-TIERS-IS-TIER-COARSE-AND-BRANCHES` proposes replacing three branches with +`(a.morton48() ^ b.morton48()).leading_zeros()`. That fix is **correct only over +`CascadeKey`** — `morton48()` composes HEEL·HIP·TWIG root-first by construction. Porting the same +shape to `NodeGuid` requires the full decoded recomposition, not a byte reinterpretation, and the +`from_be` result above is why that distinction cannot be left to reviewer discipline. + +--- +## 2026-09-15 — E-FAMILY-HAS-FOUR-WIDTHS-AND-4096-HAS-FIVE-REFERENTS-PIN-THE-UNIT-BEFORE-THE-ARITHMETIC-1 — the 4096-compartment arithmetic is EXACT and is the canon's own structure; what does not survive checking is which "family" and which "4096" + +**Status:** FINDING (code census + citation audit; every claim below read from source or from a +board line, none from recollection). The arithmetic half is self-verifying. +**Confidence:** HIGH throughout — the four widths are read from four declarations, the five +referents from four board lines, and the two unit slips are arithmetic. +**Operator question:** *"a masked set of 4096 compartments could reach every family +(64k / 4096 (12 bytes) = 16 bit / 4 bytes (identity))"*, recalled from another session. + +### The arithmetic is exact, and it is not a new idea + +4096 = 2¹² = **3 nibbles**. 16 = 2⁴ = **1 nibble**. 3 + 1 = 4 nibbles = 16 bits = **64k**. So +"4096 compartments each masking 16" is a **3-nibble prefix table with the final nibble's fan-out +left open**, and that is the canon's own sentence: *"the one 4×3 synergy (tier index = one +4096-codebook slot) is recoverable inside 3×4 for free — codebooks attach at any nibble depth, so +a 3-nibble prefix indexes a 4096 sub-table whenever wanted"* (`OGAR/CLAUDE.md:186`, verified on +disk). It also lands exactly on FAN_OUT=16 / "1 hex digit = 1 nibble = 1 level". + +**So the answer is yes — for a `u16` family, at mask width 16.** For a `u24` family the same 4096 +compartments still reach everything, but the mask is **4096 wide, not 16** (2²⁴/2¹² = 2¹²) — +256× wider. The `= 16` in the shorthand is what silently picks which one. + +### "family" has FOUR widths in this tree, and two of them are at OPPOSITE ENDS of the address + +| site | declaration | width | position | +|---|---|---|---| +| `canonical_node.rs:30` | `family (u24)`, bytes 10..13 | 16.7 M | v1 key tail | +| `canonical_node.rs:499` layout, `:552` accessor | v2 `family_v2() -> u16`, bytes **12..14** | 64 k | 5th field — near the FINE end | +| `cascade_key.rs:54` | `pub family: u16` — *"HEEL — coarsest 256×256 tile: the broad basin / family"* | 64 k | **the COARSEST tier** | +| `cascade_key.rs:226` | `CascadeKeyV3 { heel, hip, twig }` — no `family` at all | — | renamed away | + +**The dangerous pair is rows 2 and 3.** Same name, same width, and they sit at opposite ends of +the key: `cascade_key::family` **is** HEEL (the root-most tier), while `NodeGuid`'s v2 `family` is +the second-finest field, after `leaf`. A prefix or join computed over one is **not** the same +quantity computed over the other, and nothing in either type's name says so. **Mitigation already in place, and it is real:** the v2 accessor is named `family_v2`, not +`family` — I-LEGACY-API-FEATURE-GATED is being obeyed, so no function silently changes meaning +under a feature flag. The collision is therefore in the **concept**, not in a silently-aliased +call: a reader reasoning about "the family" across the two types is the exposure, not a caller +getting the wrong bytes back. This is the +`E-THE-SEMIRING-IS-FREE-…-JOIN-IS-THE-SAME-XOR-1` layout trap one level up: there the hazard was +byte order inside a field, here it is which field the name denotes. + +**v2 also makes the L in "HHTL" explicit.** Its comment reads *"leaf(u16) 10..12 (the 4th HHTL +tier)"* — so v1 folds Leaf into the u24 tail and v2 promotes it to its own tier. The stated +motive is worth quoting because it is the same failure class: *"Each tail field is a full `u16` — +**no 24-bit truncation footgun (the point of v2)**."* v2 exists because a width was getting lost. + +### "4096" has FIVE referents — four confirmed IDENTICAL, one confirmed DISTINCT + +- **Four are one anchor** (`EPIPHANIES.md:18836`): *"4096 COCA vocabulary = the CAM index codebook + (4096² u8) = the 64×64 gridlake measured sweet spot = the 4096-centroid palette codebook."* +- **One is not** (`EPIPHANIES.md:23084`, `AGENT_LOG.md:3276`, + `.claude/specs/episodic-witness64-ce64-prefetch.md:122`): the **~4096 story basins** carry an + *independent* **12-bit `local`** and are tracked as `OQ-BASIN-COUNT — "4096 ≠ COCA, confirmed + distinct."* + +**That fifth one is decisive twice over.** It confirms the *bits* reading (its `local` is +12 **bits**, 2¹² = 4096), and it is a standing precedent that a 4096 in this workspace can look +like the others and not be one. **A new compartment set must declare which of the five it is +before anything reads a codebook through it** — sharing a numeral is not sharing an index. + +### The two unit slips, and the rule that already exists for them + +- **`4096 (12 bytes)` → 12 *bits*.** 4096 = 2¹². The **12 bytes** is the V3 content-blind payload + (96 bits). Two different 12s one layer apart in the same address. +- **`16 bit / 4 bytes` → 16 bits is 2 bytes.** "16 bit" is correct for `CascadeKey::identity` + (`u16`); "4" only works read as 4 *nibbles*, which is the same 16 bits. + +`OGAR/CLAUDE.md:257` already pins this as **theorem-checker rule 0 — "pin the unit system first +(bits vs hex vs bytes)"**, and its provenance (`OGAR/.claude/handovers/2026-06-10-canon-arc-session-handover.md:20`) +is the same class of miss: *"Born from a real failure: I read an operator-pinned HEX layout as +bits for two full passes, and **the 5+3 review didn't catch it because every lens audited +arithmetic and populations — none audited units**."* + +**That is the transferable point.** The arithmetic here was right at every step; nothing an +arithmetic or population check could test would have failed. What needed checking was which +declaration each symbol denoted — and that is a *census*, not a calculation. Rule 0 exists +because a full 5+3 council missed exactly this, so "it added up" is not evidence. + +### What would falsify / what closes it + +The four widths and five referents are declarations and board lines — falsifiable by pointing at +a fifth `family` or a sixth `4096`, which strengthens rather than refutes the claim. The part +that could be wrong is the *hazard*: it is an inference that the row-2/row-3 collision will +actually bite. It closes the moment someone computes a prefix over `NodeGuid`'s v2 tail and +compares it to one over `CascadeKey`, on the same underlying entity, and shows they agree or +disagree. Filed as `ISS-FAMILY-IS-FOUR-WIDTHS-TWO-AT-OPPOSITE-ENDS`. Cheap, and unrun. + +--- +## 2026-09-15 — E-THE-SEMIRING-IS-FREE-THE-COST-IS-CARRIER-WIDTH-AND-THE-JOIN-IS-THE-SAME-XOR-1 — the masked-O(1) claim censused against shipped code: every semiring's multiply is one bitwise op, and the XOR that computes it is the XOR whose CLZ gives the tree relationship + +**Status:** FINDING (code census — `graph/blasgraph/semiring.rs`, `graph/blasgraph/types.rs`, +`lance-graph-contract/src/canonical_node.rs`, `perturbation-sim/src/cascade_key.rs`). No probe: +every claim below is read off shipped source, and the two arithmetic claims are hand-checked. +**Confidence:** HIGH on the census — it is exhaustive over the 7 shipped semirings, and the byte +layout is read from the packer rather than the doc comment. MEDIUM on the carrier-width +consequence: the arithmetic is exact, but "this is *the* binding constraint" is inference, not +measurement. LOW on nothing — no part of this is projected. + +**Operator claim under test**, in two parts: (1) *"gather adjacent becomes O(1) × MQ fan-out +reuse mask for O(1) hexagon ⇒ any semiring turns into masked O(1)"*; (2) *"the nodeguid is the +HHTL family identity address, so any given 2 nodeguids can be masked by their kleinstes +gemeinsames Vielfaches from root until the difference."* + +The German is precise in lattice terms and worth keeping: in a prefix trie ordered by +*is-prefix-of*, the **join** of two addresses is their longest common prefix — the smallest +subtree containing both. "Kleinstes gemeinsames Vielfaches" is the join in a divisibility +lattice; it is the same operation, not a loose analogy. + +### Part 1 — the census. ⊗ is universal; ⊕ is two shapes, not one + +**Multiply: 7 of 7 shipped semirings are a single bitwise op** (`semiring.rs:85-107`) — six +`xor`, one (`Boolean`) `and`. There is no arithmetic anywhere on the multiply side. So the ⊗ of +every shipped semiring already *is* a ternlog immediate; switching semirings on that side is +changing a byte. **This half of the claim holds without qualification.** + +**Add splits** (`semiring.rs:109-168`): + +| ⊕ shape | semirings | cost | +|---|---|---| +| pure bitwise (ternlog) | `Boolean` (OR), `XorField` (XOR) | one immediate | +| reduce → compare → **select** | `BindFirst`, `HammingMin`, `SimilarityMax`, `Resonance` | popcount → cmp → blend | +| bitwise combine (majority) | `XorBundle` (bundle) | majority-of-N | + +Four of seven ⊕ return an operand *unchanged* (`a.clone()` / `b.clone()`) — that is a **blend**, +not an accumulate. Nothing in the set needs anything the mask-RISC IR lacks: `MaskOp::Ternlog`, +`Terminal::{Count, MaskedMin, BlendI32}` cover all three shapes. **Zero of the seven needs a +gather.** The claim survives; the mechanism is two-tier rather than one. + +**Correction to a hypothesis I nearly asserted.** I expected those `.clone()`s to be heap copies, +which would have made "O(1)" false in practice. They are not — `BitVec` is +`words: [u64; VECTOR_WORDS]` (`types.rs:23-26`), an inline array. No allocation. Recorded because +the wrong version was one sentence from being published as a defect. + +### The consequence that checking it surfaced: the carrier, not the semiring, is the constant + +`[u64; 256]` is 16384 bits = **32 AVX-512 registers per value**. The per-edge cost is therefore a +constant 32-register block — *identical across all seven semirings*, which is exactly the +operator's point that the semiring was never the cost. But masked O(1) only **pays** when many +nodes share a register: + +- 16 Kbit `BitVec` → one value needs **32 registers** +- 96-bit V3 facet → one register holds **5 values** + +At BitVec width there is no amortization to have; you are 32 registers deep inside a single node. +**The hexagon facet is the width at which the claim cashes out**, and blasgraph's semiring still +carries the 16 Kbit VSA vector that `E-MARKOV-TEMPORAL-STREAM-1` (2026-07-10) already demoted. +Same gap-shape as the stubs in `E-THE-CANON-SPECIFIED-THE-WHOLE-MASKED-O1-CHAIN-AND-ITS-LOAD-BEARING-LINKS-ARE-STUBS-1`: +the ruling landed, the traversal carrier did not follow. + +One float in the set, against the zero-floats-in-hot-path discipline: `Resonance`'s ⊕ goes +through `density() -> f32` (`types.rs:183-185`). The only non-integer reduce of the seven. + +### Part 2 — the join is `CLZ(a ⊕ b)`, and the layout has a trap + +`NodeGuid` is laid out root-first *by offset* — `classid(0..4) | HEEL(4..6) | HIP(6..8) | +TWIG(8..10) | family(10..13) | identity(13..16)` — but `NodeGuid::new` packs each field **LE +within its own span** (`canonical_node.rs:210-215`). So **neither raw reinterpretation of the 16 +bytes computes the join**: + +- `u128::from_le_bytes` → byte 15 becomes most-significant → counts from the **identity** end. + Wildly wrong, and returns a plausible small number. +- `u128::from_be_bytes` → correct field order, but byte 0 is classid's **low** byte → the + **bytes inside every field are reversed**. A `u16` `0x1234` stored LE as `[0x34, 0x12]` reads + back as `0x3412` — nibble pairs intact, their order within the field inverted. Wrong at the + granularity the OGAR canon's "1 hex digit = 1 nibble = 1 level of the 16-ary tree + (FAN_OUT=16)" needs. ⊘ *First published as "nibble order reversed"; that was wrong — reversing + the nibbles of `0x1234` gives `0x4321`, not the `0x3412` that actually occurs. Corrected from + review on `43dbfde`.* + +Only recomposition from the *decoded values* is correct: +`(classid as u128) << 96 | (heel as u128) << 80 | (hip as u128) << 64 | (twig as u128) << 48 | +(family as u128) << 24 | (identity as u128)`. After that it is pure shift-and-mask, which is the +operator's point: `lz = (a ^ b).leading_zeros()`, `level = lz >> 2`, and the canon's +*"tier-of-level = `level >> 2` — a shift, never a branch"* chains directly on. + +### The join already exists — on a parallel type, 4× coarse, and branching + +`crates/perturbation-sim/src/cascade_key.rs` ships `shared_prefix_tiers` (`:118`) and +`cascade_distance` (`:134`) as O(1) Morton-containment, **with a measured result behind them**: +the Spain blackout epicentre is prefix-local, mean cascade-distance **1.000 vs 2.561** random +baseline. So the operator's claim is not speculative — the tree already demonstrates it. + +But that implementation compares three `u16` fields with three `if`s and returns 0..=3, where the +canon pins 12 uniform path levels and a shift. **And the correctly-composed integer is already in +the same file, seven lines above, unused by it:** `morton48()` (`:111`) packs +`family<<32 | leaf<<16 | identity` — root-first, exactly what the join needs. + +The canon's own formula reproduces the existing function exactly, at 4× resolution, branchlessly: + +``` +d = (a.morton48() ^ b.morton48()).leading_zeros() - 16 // 0..=48 bits to divergence +level = d >> 2 // 0..=12, the canon's path levels +tiers = level >> 2 // 0..=3 == shared_prefix_tiers +``` + +Hand-checked at both ends: equal keys → `lz = 64` → level 12 (all twelve levels agree); family +MSB differs → `lz = 16` → level 0. The shipped three-branch function falls out as `level >> 2`. + +**Consequence for the measurement, not just the code:** the prefix-locality result was taken with +a **4-bucket ruler**. 1.000 vs 2.561 on a 0..3 scale is coarse; the same data through a 13-bucket +ruler is a strictly finer instrument, and whether the separation sharpens or flattens is itself +informative. That is a cheap re-run, not a new probe. + +### The convergence — this is why it is one finding and not two + +The ⊗ of six of seven semirings is XOR. The join of two addresses is XOR. **Same instruction.** +One `a ^ b` yields the semiring product *and*, via CLZ, the tree relationship between its +operands. The distance is not a second lookup; it is a byproduct of the algebra already running. +That is what makes "gather adjacent becomes O(1)" **structural rather than an optimization** — and +it is the load-bearing step in the operator's chain, because it is what removes the need to +*store* or *search for* the mask at all. + +### The condition this rests on is NOT un-run — and the board says it is + +`CLZ(a ^ b)` gives *structural* divergence for free. For it to be a *semantic* distance, the OGAR +canon pins that each 256-entry codebook be a 4-level 4-ary hierarchy (*"256 = 4⁴ … a byte's +nibbles are the centroid's ancestry"*), warning *"Flat k-means-256 breaks this."* Three arms exist: + +- **Positive** — `E-WORDNET-MAKES-THE-4-ARY-ADDRESS-SEMANTIC-1`: **24.71×** out-of-cell band + lift, 2.47-hop sub-nibble gap. The 4-ary address *is* semantic on taxonomic data. +- **Neutral** — the real-Jina codebook arm (`AGENT_LOG.md:1621-1623`): flat-256 vs + hierarchical-16×16 over 4000 held-out pairs, **fidelity-neutral** (hier ≈ flat within noise). + Structure is *free*, not *better*, there; the anchor miss localized to a Base17 fold ceiling, + not the codebook. +- **Withdrawn** — a third sweep was fatally confounded (*"the carving cannot reach the ruler"*, + `EPIPHANIES.md:14773`) and correctly killed rather than reported as a null. + +**`EPIPHANIES.md:13892` still lists F-1 as "un-run", which `AGENT_LOG.md:1621` contradicts.** +Filed as `ISS-F1-MARKED-UNRUN-BUT-MEASURED`; not edited in place, per append-only. + +### Filed from this census + +`ISS-SEMIRING-BOOL-CARRIER-SILENTLY-DROPS-EDGE` (the sharpest — a silent wrong answer) · +`ISS-NODEGUID-HAS-NO-JOIN-SURFACE` · `ISS-SHARED-PREFIX-TIERS-IS-TIER-COARSE-AND-BRANCHES` · +`ISS-F1-MARKED-UNRUN-BUT-MEASURED`. + +**What would falsify the carrier-width consequence:** run the same traversal at both widths and +show the per-edge cost does *not* track register occupancy — i.e. that something else (frontier +management, the scalar visited check in `hdr_bfs`, `ops.rs:158`) dominates so completely that the 32-vs-1/5 +register ratio does not appear in the measurement. That is the honest next probe, and it is +unrun; nothing here claims it has been done. + +--- +## 2026-09-15 — E-DENSITY-IS-FALSIFIED-THE-VARIABLE-IS-PATH-LENGTH-SPREAD-AND-THIS-RE-OPENS-A5-1 — my own filed hypothesis dies at 73 points of swing under pinned density, and the mechanism I closed as falsified this morning comes back + +**Status:** FINDING (measured, `.claude/probes/density-sweep-v1/`, MQ arms re-runnable). +**Confidence:** High on the MQ dose-response — it is a controlled design with the confound +removed. LOW on anything cross-family: MONDO does not sit on the axis (below). +**Corrects:** `ISS-ELK-DENSITY-UNISOLATED` (density: FALSIFIED as the cause) and the A5 verdict +in `E-DEPTH-RANK-REPRODUCES-MOST-SPECIFIC-BUT-ONLY-ON-A-TAXONOMY-1` — scoped: a **within-MQ** +association between reachable path-length SPAN and ASC, my binary indicator having been +underpowered. ⊘ *First published as "braiding: back on the table", which overstated it: binary +braided-only causation is NOT restored, and cross-family transfer is unmeasured. Corrected from +review on `43dbfde`.* + +**I filed density as the named-but-unisolated variable and deliberately declined to assert it +without the sweep.** That restraint was the right call: the sweep kills it. + +**The first sweep was confounded, and I caught it before reading a mechanism off it.** Varying +width, advances and shifts together already refused a density story (4× density change, same +answer; 2× density change, same answer) — but width covaried with advances (2,3 / 4,5 / 6,6), so +naming "advance multiplicity" from it would have repeated the *exact* error density was dying of. +The controlled arm pins width and shifts and moves advances alone: + +| advances | \|adv\| | density | ASC | +|---|---|---|---| +| `(1,)` | 1 | 45.05 % | **100.0 %** | +| `(2,)` | 1 | **21.90 %** | **100.0 %** | +| `(1,2)` | 2 | 45.05 % | 55.3 % | +| `(1,3)` | 2 | 45.05 % | **37.1 %** | +| `(1,2,3)` | 3 | 45.05 % | 36.0 % | +| `(1,2,3,4)` | 4 | 45.05 % | **26.9 %** | + +Three contrasts, and each one is a disable of a different story: + +1. **Density pinned at exactly 45.05 %; agreement spans 26.9 % → 100.0 %.** A **73-point swing at + identical density**. Density cannot be the cause. +2. **`(1,)` vs `(2,)`** — multiplicity 1 in both, density differs ~2×, agreement **identical**. + Density is *inert* at fixed multiplicity, not merely weak. +3. **`(1,2)` vs `(1,3)`** — same count, same density, **18 points apart**. So the variable is the + **SPAN** of reachable path lengths, not how many distinct advances exist. + +**This re-opens A5, and the correction is about statistical power, not about the measurement.** +This morning I reported *"the braid mechanism I proposed is FALSIFIED as the explanation"* — +braided-only pairs still left 47.5 pp of the 48.6. That arm split pairs on a **binary** indicator +(`spread == 0` vs `> 0`) **within** each graph. The present design varies braiding as a **dose** +and gets a clean monotone. The binary indicator lumps spread 0.1 with spread 3, and the two +graphs' means (MONDO 0.44, MQ 0.73) sit close on that scale while being structurally different +regimes — *every* MQ node reachable at three path lengths vs MONDO's incidental braiding. **A +coarse indicator with almost no variance in the treatment cannot see a dose-response.** The A5 +numbers stand; the verdict drawn from them does not. + +That is the third time this session a conclusion of mine reversed, and the pattern is identical +each time: **the measurement was sound and the inference outran its design.** + +**What is NOT established, stated before it can be cited otherwise.** **MONDO does not sit on +this axis.** It braids (mean spread 0.44, 182/195 pairs) and scores **84.6 %** — *higher* than MQ +`(1,2)` at 55.3 %. The dose-response is **within the MQ family**. Cross-family transfer is +**unmeasured**, and nothing here licenses predicting a real ontology's agreement from its spread. + +**Q3 — amortization: SUPPORTED, with its own caveat attached.** Bounded-k recall is **flat across +distance** in every config: MONDO k=6 → 92.1 / 89.5 / **89.1 %** at hops 4/8/12; MQ `(1,2,3,4)` +k=6 → 94.0 / 95.2 / **95.0 %**. No decay as reach grows, which is what the EWA n=12 band +(bound 0.5715, operator's 0.45..0.65) predicts. **But** flat-and-high is equally consistent with +a bound that is simply never binding — see Q2. + +> ⊘ **THE "BUT" CONFLATES TWO AXES — corrected 2026-09-15, operator-pointed.** +> Flat-across-depth and never-binding-k are not competing explanations of one +> observation; they answer **different questions**, and only the second is open. +> ⊘ **"CERTIFIED" IS THE WRONG WORD AND IT IS A THIRD TRANSFER — Codex P1, caught in +> review.** `jc::ewa_sandwich` runs **1,000 synthetic SPD matrix paths at +> `PATH_LENGTH = 10`**. It never touches MONDO or MQ, never traverses a graph, and never +> measures hop 12. Calling graph-recall behaviour "certified" by it moves a result across +> the boundary from *synthetic covariance propagation* to *graph traversal* on the strength +> of both being "multi-hop" — the third same-shaped transfer in this entry. +> **`D-HXP-7` is still `Queued`** in `STATUS_BOARD`, and it is exactly the gate that would +> close this: PSD ≥ 0.999 AND CV ≤ 1.75× bound at **n ≥ 10**, with a **mandatory +> anti-vacuity arm** (an unstructured fixture must FAIL at low n) and an **additive disable +> arm** (plain `Σ_n = Σ_0 + Σ M_k` must go red at n ≥ 10). None of that has run. +> **The honest statement:** the EWA bound PREDICTS no-decay-with-depth and the aperture +> arithmetic below is exact, but the prediction is UNTESTED on this repo's graphs. Depth is +> **predicted, not certified**; it stays open until D-HXP-7 runs. *(Codex also cited a +> requirement "through n=14" — that string is not in the plan; the plan and the board row +> both say `n ≥ 10`. Recorded rather than echoed.)* +> +> ~~**DEPTH is CERTIFIED**, not merely predicted:~~ **DEPTH is PREDICTED:** `jc::ewa_sandwich` (Pillar 6) +> proves Σ-push-forward along multi-hop paths keeps PSD ≥ 0.999 with +> **geometric (multiplicative) error control** where naive convolution gives +> arithmetic O(n) growth — *"the difference between 'every hop adds noise' and +> 'the path itself shapes the propagation'"*. Its bound +> `CV ≤ √(2/n)·√(1+2σ²n)` (σ_step 0.2, Köstenberger-Stark-style on the SPD +> cone) **falls with n**, so deeper is better-conditioned, and the operator's +> `0.45..0.65` aperture is **exactly the admissible-depth window**: +> `0.65 ⇔ n = 7.62`, `0.45 ⇔ n = 47.06`, asymptote 0.40. **n ∈ [8, 47].** +> n=5 sits OUTSIDE at 0.7483; n=12 sits near the centre at 0.5715; the +> shipped run is n=10 at 0.600. So no-decay-at-hop-12 is the **predicted** +> behaviour of the regime — a prediction with an exact bound and a queued gate +> (`D-HXP-7`), not a certification, and not an unexplained coincidence either. +> **WIDTH — whether top-k frontier truncation loses reachability — is a +> different question again, and Pillar 6 says nothing about it.** +> `ISS-BOUNDED-K-NEVER-FAILS-ON-ANY-GRAPH-TESTED` stays OPEN on width; +> **depth stays open too, on `D-HXP-7`.** + +**Q2 — anti-vacuity: NOT SATISFIED, and this is the honest headline of the recall half.** `k=50` +returns **100 % on every MQ config and 99.4 % on MONDO**. *A bound that never costs anything on +any graph tested is the fires-on-everything shape* — exactly the defect +`E-ANTI-EIGENVALUE-MACHINERY-CAN-ITSELF-BECOME-THE-EIGENVALUE-1` names. `k=6` discriminates only +mildly (89–100 %). **No graph has been found where bounded-k genuinely fails**, so the recall +result is about *these* graphs until it degrades somewhere. Finding that graph is outstanding +work, not a footnote, and until it exists the torch's **width** claim (k-truncation is +lossless) is unearned. ⊘ *This sentence read "the torch's recall claim is unearned" — too +broad. The DEPTH half is certified by `jc::ewa_sandwich` Pillar 6, whose bound's +`0.45..0.65` band is the n ∈ [8, 47] admissible-depth window; see the annotation above.* + +**Deliberately not measured: "top-k successor mass."** That is the D-HXP-1 SIGNAL half, already +**STRUCK as unanswerable by that instrument** (`uniform_expected = min(6,d)/d` is biased by +small-sample concentration; on an unweighted graph every successor carries equal mass, so the +statistic is arithmetic). Re-deriving it here would have re-run a struck measurement. + +**A number that needs re-deriving before it is cited again.** This run reports MONDO peak frontier +@12 = **142** over 60 sampled seeds; an earlier run in this arc reported the `is_a` frontier +profile peaking at **6,297** at hop 6. Different seed samples. Both cannot stand as "the" peak, +and the 6,297 figure appears in `E-BOUNDED-ATTENTION-…` and +`E-THE-CANON-SPECIFIED-THE-WHOLE-MASKED-O1-CHAIN-…` as the cost-of-no-torch evidence. + +--- +## 2026-09-15 — E-THE-CANON-SPECIFIED-THE-WHOLE-MASKED-O1-CHAIN-AND-ITS-LOAD-BEARING-LINKS-ARE-STUBS-1 — every link is named in the source, down to the words "a single masked load, no gather", and the shipped lookups are a `None`, a scalar loop, and a linear scan + +**Status:** FINDING on the code census — located-code claims with file:line, NOT a measurement. +**Confidence:** High on what exists and what does not. The ARCHITECTURE is the operator's, +stated across six messages; the census, the three materialization sites and the W1 demarcation +are mine. +**Supersedes in scope:** `E-BOUNDED-ATTENTION-BUYS-REACH-AND-A-DISTANT-HOP-IS-A-TERNLOG-NOT-A-SEMIRING-1` +(`20c7579`, earlier today) claimed only *"the joining op is absent."* That was too narrow and is +widened here, not withdrawn: the canon specified the **whole chain**, the workspace's own +reviewer **flagged the gap**, the contract **declares it**, and three links are stubs. + +**The architecture, in the operator's order.** (1) MQ is an **access discipline**, not a graph +shape: the bounded legal move set IS the prefetch window — the torch. (2) The torch being cheap +is what **buys reach**; bounded frontier × many hops beats unbounded × few. (3) While still *n* +hops out nothing exact is asked, only *in play / excluded*, so the hop is **boolean** — and +ternlog is 3-input while HHTL is 3 tiers, so **two endpoints fold to `2 × 3` masked + cached**. +(4) After those ternlogs the **first N bytes of the NodeGuid are reusable** — HHTL·family·leaf +minus the part still being explored — so access becomes **masked O(1)**. (5) That O(1) is what +makes **trie adjacency cheap**. (6) And the adjacent spread **uses MQ again locally** — one rule, +every level. + +**The canon already says all of it.** `canonical_node.rs:5-6`: *"family + identity are the +CONTIGUOUS TRAILING 6 BYTES → the basin-local key you can use alone after an HHTL radix walk +(**skip the prefix**)."* `canonical_node.rs:301-303` on `local_key()`: *"After an HHTL radix walk +has bound classid+HEEL+HIP+TWIG, this is the only part that still discriminates — **a single +masked load, no gather**."* And the self-similarity is canon too (`CLAUDE.md`, codebook +scoping): *"Finer scopes … follow the same longest-prefix-wins rule — **one rule, every +level**."* The address is self-similar in code as well: `twig_search` **is** `hip_search` +(`heel_hip_twig_leaf.rs:225-226`, *"Structurally identical to hip_search"*). + +**The chain, link by link, with what actually ships.** + +| link | state | +|---|---| +| prefix resolution via N ternlogs (the mask hop) | **ABSENT** — `ISS-NO-MASK-HOP-OP` | +| `local_key()` — *"the only part that still discriminates"* | **SHIPPED** (`canonical_node.rs:305`) | +| `row_for_local_key` — key → row, the masked O(1) | **STUB: `None` for every key**, param `_local_key` unused (`soa_view.rs:127-130`) | +| `hhtl_path` — *"the radix-trie / CLAM cluster address"* | declared | +| what consumers do today | **fall back to the positional `(mailbox_id, row)` address** | + +**The workspace's own reviewer already caught this**, and the doc cites it verbatim: *"the +baton-handoff-auditor's CATCH-CRITICAL — the View previously exposed only `n_rows`, with no way +to go from the canon address back to a row."* The response **declared the contract and deferred +the implementation**. That deferral is precisely what keeps trie adjacency expensive: with no +canon-address → row, adjacency can only be positional or scanned. + +**Three materialization sites, one disease at three scales.** + +| site | bounded? | what it materializes | +|---|---|---| +| `hdr_bfs` (`blasgraph/ops.rs:157-195`) | **✗ unbounded** | keeps every newly reached node; `result.get(idx).is_none()` **per index**; `max_depth` is the only cost control | +| `cascade_search` (`heel_hip_twig_leaf.rs:352`) | ✓ `SearchConfig.k` = 50 | **5 heap allocations per query** — `Vec` ×3 + `Vec` ×2 *between* tiers — and **3 sequential dependent stages**. Two endpoints: 10 allocations, 6 stages. Folded: 2 ternlogs, zero intermediate. | +| `Scope::position_of` (`neighborhood.rs:62`) | — | **`self.node_ids.iter().position(...)` — a LINEAR SCAN, up to `MAX_SCOPE_SIZE = 10_000`.** Plus `scent_column()` / `resolution_column()` allocating a fresh `Vec` **per call**. | + +The last row is the sharpest single line in this entry: **the canon specifies "a single masked +load, no gather" and the shipped local lookup is `iter().position()` over ≤10,000 entries.** It +is also a straight zero-copy-law violation by this workspace's own rule (*"the array itself is a +ClassView projection"*) — a gathered `Vec` where a borrowed view exists. + +**The torch and the mask each exist in exactly one place and never together.** `cascade_search` +is bounded but materializes and runs sequentially; `hdr_bfs` is unbounded and scalar-looped. +Neither uses masks. + +**⚠ DEMARCATION — MQ-local is NOT the spread W1 falsified.** W1 killed a spread, and arm B was +the damning arm: a **permuted** layout BEAT the learned one (0.1654 vs 0.1579), so the +seriation-based neighbourhood carries no signal. MQ-local is a **different mechanism** and this +entry must not be read as reviving a dead one. W1's spread was **metric diffusion** over palette +cells — a radius ball whose measured failure was a radius *smaller than the cell spacing*, so it +diffused into empty space, with no surround. MQ-local spreads over the **bounded legal adjacent +set** (trie siblings / edges), not a distance ball: it cannot diffuse into empty space by +construction and does not depend on seriation quality at all. **Arm B does not bear against it, +and the falsified spread stays falsified.** + +**CENSUS, NOT MEASUREMENT** — and the distinction is load-bearing. The only measured numbers +anywhere in this chain are the torch's loss budget (top-6 successor mass **0.9792 / 0.9943**, +D-HXP-1 CAPACITY **PASS**) and the cost of having no torch (`is_a` frontier peaking **6,297 +nodes wide at hop 6** on one seed). The allocation and stage counts above are read off the +source, not profiled. **No claim here is that the fold is faster** — see the honest caveat below. + +**The fold is not free, and the cache is what pays for it.** Today tier *N* only evaluates the +survivors of tier *N−1* — sequential narrowing does less work per tier. Masked `AND3` evaluates +full-width and intersects. So the fold trades **narrowing for width**, and it wins only because +tier masks are **reusable across queries**. At 512 nodes per instruction that should beat 5 +allocations and 3 dependent stages comfortably, but that is the measurement, not the claim. + +**Falsifiers, cheapest first** — and the first is far cheaper than the ternlog walk: +1. **`row_for_local_key`** — materialize a `local_key` column on ONE view and show it stops + returning `None`, with a two-sided arm: a key that IS present resolves to the right row, and a + key that is NOT present still returns `None` (a lookup that answers every key is the + fires-on-everything defect). +2. **Fold** — folded HHTL must reproduce `cascade_search`'s survivor set **exactly**, and must + LOSE when the cache is cold or query count is 1 (else the cache isn't what's paying). +3. **Bounded-k ternlog walk** — must match unbounded `hdr_bfs` recall at the same depth AND go + red when k is raised to unbounded, plus an anti-vacuity arm on a graph where top-k does NOT + hold the mass (else 0.98 is a property of these graphs, not of the discipline). + +**Nothing built.** `graph/refine/` (task #26) stays gated. + +--- +## 2026-09-15 — E-BOUNDED-ATTENTION-BUYS-REACH-AND-A-DISTANT-HOP-IS-A-TERNLOG-NOT-A-SEMIRING-1 — the architecture is already built in four places and the one op that joins them does not exist + +**Status:** FINDING on the code census (verified, file:line below). The ARCHITECTURE is the +operator's, stated across three messages; the census and the absence are mine. +**Confidence:** High on what exists and what does not — this is a located-code claim, not a +measurement. The two supporting numbers are measured and are named as such. + +**Attribution first, because the framing error was mine.** Asked *"would MQ offer a cheap +gating for the EWA 12-hop fanout"*, I read **MQ as a graph shape** — something to run arms +against — and built it as a generality control. The operator meant **MQ as an access +discipline**: in Mississippi Queen the river is revealed a bounded window ahead of the boat, +the channel braids, and legal moves are bounded (speed 1–3, lane ±1). *That bounded legal set +IS the prefetch window.* You never hold the river; you hold the frontier. Then, in order: + +> *"MQ is focus of attention for sparse adjacent blasgraph like prefetch"* +> *"so it holds the Torch cheaply for further reach then blasgraph"* +> *"MQ allows for ternlogq for the next n hops knowing its still further away"* + +**The cost model those three compose into.** (1) The torch is the bounded frontier — cheap +attention. (2) Because the torch is cheap the **reach can be long**: bounded frontier × many +hops beats unbounded frontier × few, so 12 hops is the wrong thing to be afraid of. (3) While +the target is still *n* hops out **nothing exact is being asked** — only *in play / excluded* — +so the hop is a **boolean mask op**, one `VPTERNLOGQ` over 8×u64 = 512 nodes, and the +expensive semiring (Hamming / palette / NARS truth) is paid **only on arrival**. + +**Every piece exists. Nothing is wired.** + +| piece | location | state | +|---|---|---| +| ternlog primitive, 256 immediates | `ndarray::simd` (`simd.rs:592-594`) | shipped — `AND2_ANDNOT = 0x40` is `a & b & !c` | +| mask algebra + ≤3-leaf fusion → one `Ternlog{imm}` | `crates/lance-graph-mask-risc/` (workspace member, `Cargo.toml:8`) | in PR3 (D-MRX-0..6) — **no hop** | +| hop over CSR adjacency | blasgraph `vxm` / `mxm`, 7 semirings | shipped — **not in mask form** | +| the contract itself | lance-graph-java T2 | *"HOP MAY LOOK LIKE HOP. IT MUST EXECUTE AS MASK × CLASSVIEW/WIDEFIELDMASK → MASK"* | +| **an op joining them** | — | **ABSENT** | + +**`AND2_ANDNOT` is literally the advance step.** `a & b & !c` = `frontier & adj & !visited`. +`hdr_bfs` (`blasgraph/ops.rs:157-195`) computes exactly that — as a **scalar per-index loop** +(`result.get(idx).is_none()`), keeping *every* newly reached node with no top-k, no bounded +legal set, no truncation. `max_depth` is its only cost control, so it lights the whole river +each hop and rations depth to compensate — the inverse of the cost model above. + +**Two details that sharpen the gap rather than widen it.** + +*The cheap regime already has a name and still pays semiring cost.* `HdrSemiring::Boolean` +(`blasgraph/semiring.rs:50-51`) is documented *"AND multiply, OR add. Boolean reachability"* — +and dispatches through `match (a, b)` on `HdrScalar` **per element pair** (`:101`, `:158`). So +boolean reachability is **already expressible and already slow**. That is the single clearest +statement of the defect: the enum variant exists, the instruction exists, and they never meet. + +*The far/near split is already in the terminals.* `MaskOp` is `Pred / And / Or / Xor / AndNot / +Not / Ternlog`; `Terminal` is `Count / Any / All / MaskedSum{I32} / MaskedMin / MaskedMax / +BlendI32 / Keep`. While far you want `Any` or `Count` — a popcount, no materialization; on +arrival `Keep` / `Blend`. Both halves are built. **Nothing routes between them by distance.** + +**What is MEASURED here, distinguished from what is censused.** Only two numbers, both from +earlier in this arc: the torch's loss budget — top-6 successor mass **0.9792 / 0.9943** (W0 +CAPACITY, D-HXP-1, kill was < 0.40) — and the cost of not having one: the `is_a` frontier +profile `[1,4,155,2121,5984,**6297**,4641,2724,978,281,35,3]`, peaking **6,297 nodes wide at +hop 6 on a single seed**. Everything else above is located code. + +**I had the torch measurement and filed it under a half-struck result.** D-HXP-1 split into +CAPACITY **PASS** and SIGNAL **STRUCK**; I let the struck half carry the summary. For a +prefetch discipline **capacity is the whole question**, and it passed at 0.98–0.99. A bounded-6 +torch loses ~1–2 % of the successor mass and turns a 6,297-wide frontier into a 6-wide one. + +**Falsifier for the missing op, two-sided, on data already in hand:** a bounded-k ternlog walk +must reach materially the same set as unbounded `hdr_bfs` at the same depth (recall against the +full closure), **and must go red when k is raised to unbounded** — otherwise the bound is doing +nothing and the result is about the graphs, not the mechanism. Anti-vacuity half: on a graph +where top-k does NOT hold the mass it must lose recall, or 0.98 is a property of these two +graphs rather than of the discipline. + +**Not built.** `graph/refine/` (task #26) remains gated on the operator's go; nothing in this +entry is code. + +--- +## 2026-09-15 — E-DEPTH-RANK-REPRODUCES-MOST-SPECIFIC-BUT-ONLY-ON-A-TAXONOMY-1 — I published "refuted" on a sign error, then the correction's reversal turned out to be taxonomy-shaped, not lens behaviour + +**Status:** FINDING (measured, `.claude/probes/elk-generality-v1/`, MQ arm re-runnable). +**Confidence:** High on both measurements. The scope limit is the load-bearing half. + +**Two reversals in one chain, and the second is the one worth keeping.** + +**Reversal 1 — my own sign error, published as a headline.** `ogar-elk`'s +`LensClosure::supers_of` already computes a BFS depth and throws it away; the graded +proposal is that ranking the meet by that depth reproduces `most_specific` without the +pairwise ancestry test. I ranked **descending** — `-max(A[x], B[x])`, i.e. *deepest +from the seed* — measured **6.7 %**, and published the graded proposal REFUTED. I had +even flagged the risk in the same breath (*"my ranking is one naive choice"*) and +published the verdict as fact anyway. The clinical cases exposed it: RA ∩ Still's, RA ∩ +Felty's and Still's ∩ Felty's all returned `"disease"`, **the root** — which is the +node FARTHEST from every seed, so max-depth was selecting the most GENERAL ancestor by +construction. Ascending: **84.6 %** (min-max) / **85.1 %** (min-sum), 3/3 on the +clinical pairs. A flagged uncertainty that is not resolved before publication is not a +hedge; it is the defect with a disclaimer attached. + +**Reversal 2 — the corrected result is NOT the lens's.** Every number came from one +graph, and a taxonomy is exactly the shape most likely to produce them trivially. MQ — +a Mississippi-Queen river course, same DAG algebra, ancestors = *upstream positions* +rather than generalisations, both graphs through the **same arm functions** — gives +**36.0 %** against MONDO's 84.6 %. **Δ 48.6 pp.** The pre-registered reading +("diverges ⇒ it was the taxonomy's shape") fires. The claim stands **scoped to a +taxonomy** and must never be restated as lens behaviour. + +**The two confounds that could have faked it, both measured, both cleared.** + +| | MQ | MONDO | Δ | +|---|---|---|---| +| depth ascending | 36.0 % | 84.6 % | **48.6 pp** | +| A4 non-vacuous (`\|I\|` > 1) | 36.0 % | 84.6 % | 48.6 pp | +| A5 braided pairs only | 36.0 % | 83.5 % | 47.5 pp | + +*A4.* At `|I| == 1` the argmin IS the only `most_specific` member — agreement there is +arithmetic. **Neither graph has one such pair**, so nothing is carried by arithmetic; +that worry was unfounded and is now measured rather than assumed. The stratification +also kills the confound in the other direction: MONDO's agreement **rises** with +intersection size (75.9 → 90.5 → 100 %) while MQ's **falls** (100 → 42.9 → 31.8 %). +Same confound would trend the same way in both; they trend opposite. MONDO's +small-`|I|` majority is its *worst* bucket, so the headline **understates** the effect. + +*A5 — a mechanism proposed and FALSIFIED, which is the result.* `supers_of` keeps the +MINIMUM depth, so the natural story is that depth stops tracking specificity once the +DAG **braids** (several path lengths to one ancestor; a general ancestor scores shallow +via a shortcut). Braiding is real and directional *inside* MONDO — flat 13/13 = 100 %, +braided 152/182 = 83.5 % — but it cannot carry 48.6 pp: braided-only leaves **47.5 pp**. +Controlling for the mechanism removes almost none of the divergence. + +**What is NOT established.** The mechanism is **unnamed**. The remaining unisolated +variable is ancestry density — MQ's node has 69.4 ancestors of 151 (46 % of the graph) +against MONDO's 14.1 of 60,467 (0.02 %). MQ was built as a *different* graph, not as a +density sweep, so it proves non-universality without identifying the property +responsible. MQ is also one synthetic graph at one seed: sufficient to falsify a +universal claim, evidence about no other real ontology. + +**The meet has a parent-child blind spot, and I praised it before I understood it.** +Felty's is a **direct `is_a` child of RA**, and `supers_of` excludes self, so RA can +**never** appear in RA ∩ Felty's. I had called that meet "the sharper of the two" — it +is a grandparent-level answer to a question the machinery is structurally unable to +answer. A meet over strict ancestors cannot express *"one of these IS the other's +genus"*; that needs a subsumption test the lens already has and the meet never calls. + +**Provenance caveat on every MONDO number here.** MONDO asserts `ankylosing spondylitis +is_a rheumatoid arthritis` (verified parents: spondylitis; spondyloarthropathy; +rheumatoid arthritis; vertebral joint disorder). The spine is a real source with real +edges I would not have authored. Numbers measured on it are measurements *of MONDO*. + +--- + +## 2026-09-15 — E-A-HORIZON-CUT-AND-AN-UNBOUND-MEET-ARE-NOT-THE-SAME-ANSWER-1 — a width sweep that does not separate them reports blindness as absence + +**Status:** FINDING (measured, `.claude/probes/elk-generality-v1/`). +**Confidence:** High on the measurement; the naming consequence is an argument. + +I hardcoded `DEPTH_CAP = 64` and swept nothing, in an arc whose entire subject is +horizon width. When the sweep finally ran, the thing it exposed was not a number but a +**conflation**: an empty meet at width `w` has two disjoint causes, and code that +returns `∅` for both cannot tell them apart. + +- **EMPTY** — no shared ancestor exists at any width. The answer is *"unrelated"*. +- **CUT** — a shared ancestor exists but sits beyond `w`. The answer is *"I cannot see + that far"*, and it is **not** the same claim. + +| | `w=1` | `w=7` | `w=14` | `w=64` | +|---|---|---|---|---| +| MONDO CUT / recall | 194, 0.1 % | **3, 84.5 %** | 0, 100 % | 0, 100 % | +| MQ CUT / recall | 178, 0.3 % | 85, 24.2 % | **21, 64.5 %** | 0, 100 % | +| true EMPTY | MONDO **5**, MQ **0** — width-invariant, as it must be | | | | + +Two consequences. **(1) A window tuned on a taxonomy does not transfer.** MONDO +saturates by `w = 14` and is already at 84.5 % recall by 7; MQ is still cutting 21/197 +pairs at 14 and reaches 24.2 % at 7. **(2) This is the same missing symbol the boxcar +entry argued for from the other side** — `E-THE-BOXCAR-HORIZON-IS-NOT-A-DISCOUNT…` +asked for `EMPTY` distinct from observed-neutral so a hard-horizon agent can *say it is +blind*. A meet that returns `∅` for both CUT and EMPTY has exactly that defect one layer +up: it reports blindness as absence, and a caller that acts on "unrelated" when the +truth is "beyond my horizon" has been misinformed by a correct-looking answer. + +--- + +## 2026-09-15 — E-A-UNIFORM-WEIGHT-ARM-CANNOT-MEASURE-EVIDENCE-ITS-ARGMIN-IS-INVARIANT-1 — I caught two vacuous arms in my own register probe, one of which was pure arithmetic I had built in + +**Status:** FINDING (measured; probe is scratchpad, the finding is the durable part). +**Confidence:** High on the catch. The K3 result is one probe on one fixture. + +Two arms of the register probe were vacuous, and **both were mine**: + +1. **The TAX arm was coded as `random.randrange(K) == k`** — arithmetic I had written in, + presented as a measured baseline. It could only ever report `1/K`. +2. **The REG+E arm used `w = [0.5 + ev] * D`** — a weight vector **uniform across + dimensions**. `argmin` over a uniformly scaled vector is **invariant to the scale**, + so "evidence changes the assignment" was true by construction and K3 firing was + guaranteed. This is the `closed_class_guess` 150/150 defect in a new costume: a + channel that fires on everything carries exactly the information of one that never + fires. + +Fixed with **per-rail** evidence weights, `w = [(qev(c)/255)**2 for c in counts]`, so +the weighting is allowed to vary across the dimensions the argmin ranges over. Then the +anti-vacuity check has something to say: evidence changed **7/79** assignments (not 0, +not 79), and REG+E scored **60/79** against REG's **56/79** — +5.1 pp, small and real, +where the broken arm had promised a guaranteed win. + +**The transferable rule.** *A knob is only measured if the quantity it turns can change +the decision the metric reads.* Turning a constant is not a disable when the guarded +quantity reaches the same outcome by another route — and a weight is not a weight if it +is constant along the axis being argmin'd. Both failures pass every type check, both +produce plausible numbers, and neither is visible without asking what input would change +the answer. Fourth and fifth instance of this family in this workspace; the first three +are in `E-VACUOUS-ASSERTION-IS-THE-HOUSE-STYLE-1`. + +--- + +## 2026-09-15 — E-THE-RLHF-SHAPED-PROMOTION-LOOP-IS-IMPLEMENTED-END-TO-END-IN-A-PROBE-AND-HAS-NO-SRC-PROMOTER-1 — the plasticity the substrate needs exists as a demonstration, not as a surface + +**Status:** FINDING (code census, `probe_sudoku_teacher.rs` + `recipe_loci.rs`). +**Confidence:** High on what exists. The RLHF framing is an ANALOGY and is fenced below. + +The operator's framing — *"the substrate is fairly deterministic, and hexagon allows +learning where no reasoning has been before; that's the plasticity this substrate +needs"* — has a precise status in the tree, and it is neither "absent" nor "shipped". + +**What exists.** The autopoiesis triangle is a real typed ladder: +`ValueTenant::{FrozenStyle(10), LearnedStyle(11), ExploreStyle(12)}`, with promotion +gated on a **held-out win**, not on training-set fit. `probe_sudoku_teacher.rs` +implements the whole `ExploreStyle → LearnedStyle → FrozenStyle` loop end to end on +sudoku. `recipe_loci.rs`'s **Door C — the organ gate** is the existing dispatch whose +reachability is contingent on the live `CausalWitnessFacet` rather than on a +style/surprise-band argmax, which is exactly the shape a plasticity surface needs. + +**What does not exist.** **No `src/` promoter calls the loop.** The promotion path ships +only as a probe. So the substrate has the mechanism, the typed states, and a working +demonstration — and no production caller that can move a rail from Explore to Learned to +Frozen. That is the gap, stated as a gap. + +**The RLHF analogy, fenced.** *"Hexagon would store the feedback learning the way RLHF +stores it in LLM weights"* is structurally apt on one axis and must not be stretched +past it. Apt: both are a **preference signal promoted into a durable substrate** rather +than held in a context window, and both gate promotion on generalisation rather than +recall. Not apt, and load-bearing: RLHF's substrate is **dense continuous weights +updated by gradient**, while this one is a **discrete addressed register promoted by a +held-out test** — no gradient, no differentiability, and promotion is a decision with a +falsifier rather than a step size. The shared property is *where the feedback lands*, +not *how it gets there*. Per `cross-domain-synthesizer`'s rule the analogy is [H] on +mechanism-of-storage and [S] on mechanism-of-update; it earns a sentence in a design +doc, never a claim that the substrate does RLHF. + +--- +## 2026-09-15 — E-THE-BOXCAR-HORIZON-IS-NOT-A-DISCOUNT-IT-REVERSES-THE-OTHER-WAY-1 — the A9 ±8 window produces the OPPOSITE preference reversal from hyperbolic discounting, and has no indifference region + +**Status:** FINDING (measured, `.claude/probes/horizon-window-v1/`, re-runnable). +**Confidence:** High on the measurement; the fixture is synthetic by design. + +A `Locus` is a signed offset into the `[−8, +7]` `temporal.rs` window (i4; `+8` is +unrepresentable — see the correction below, which this line first contradicted), so the register is a +**temporal-distance** carrier and its perception rule is a boxcar: full value inside, +`0 = unbound` outside. Swept against two controls on the canonical preference-reversal +fixture (sooner-smaller at `T1`, later-larger at `T2 > T1`, agent deciding from each +vantage `τ`), three fixtures each: + +| | exponential (control) | hyperbolic (control) | boxcar | +|---|---|---|---| +| reverses? | **0/19 γ, all fixtures** | fires on all three | fires inside `[T2−T1+1, T2−1]`, **matching the derivation on all three** | +| direction | — | `later → sooner` | **`sooner → later` — OPPOSITE** | +| flip margin | — | crosses **continuously** (some `k` arbitrarily close to 0) | exactly **`V2 − V1`** — bounded below, **cannot** be small | + +**Two findings.** (1) The boxcar is not a steep discount — it reverses the other way. +Hyperbolic impatience *rises* with proximity (akrasia); under a horizon, **blindness +FALLS** with proximity, because closing distance buys visibility, not urgency. +(2) There is **no indifference region**: at the flip the far reward jumps from unbound +to full value. A hard-horizon agent never *almost* sees a consequence, so it cannot +hedge and cannot be nudged. ⊘ **Corrected from review:** first published as a measured +**41–206×** margin ratio, which was an artifact of the `k = i/10` grid. The analytic +form above is stronger and grid-free. + +**What it falsified — my own claim, same session.** *"An A9-locus agent is +constitutionally a scorpion"* is **false**. The scorpion stings midstream, i.e. +impatience rising with proximity, which is the hyperbolic signature. A boxcar agent +would have crossed: midstream is exactly when the far shore becomes visible. +Nature-as-curvature and nature-as-register-width are different pathologies. + +**At the substrate's real width.** ⊘ **Corrected from review (Major):** the first +published run used `w=8` and reported a reversal on fixture 2. `Locus` is a signed +**i4, `[−8, +7]`** with `+` = consequent, and these fixtures place both rewards in the +future — so `+8` is unrepresentable and *that* produced the reversal. At the true +forward bound **`w=7` no fixture reverses**: all three read all-`sooner` from every +vantage — **uninformed, not impatient, and unable to report the difference.** The +correction makes the blindness uniform rather than wrinkled. + +**And the window is asymmetric the wrong way.** Two's complement gives **8 steps +backward** (antecedents) and **7 forward** (consequents): one more step of cause than +of consequence. That is a measured argument for the `EMPTY, −7..+7` nibble the +six-families ruling already deferred (`EMPTY` = no valid observation, `0` = observed +neutral): without it the agent cannot say it is blind. + +**Instrument bug worth keeping.** The first run printed no margin comparison and looked +like a null. `flip_margin` scanned only `sooner → later`, so it returned `None` for +every hyperbolic trace — **the direction it could not see was the finding.** Third +instance this session of *a null result is a claim about the apparatus until proven +otherwise*. + +Refs: `.claude/knowledge/causal-plane-inventory.md` §7; `causal_witness.rs`; +`E-SIX-SEMANTIC-FAMILIES-MUST-NOT-IMPERSONATE-EACH-OTHER-1` (the deferred nibble). + +## 2026-09-15 — E-SIX-SEAMS-EVERY-CAUSAL-SELECTOR-SHIPS-AND-NONE-IS-WIRED-AT-THE-HOP-1 — the four-plane geometry is represented but not operative + +**Status:** FINDING (census of shipped code). **Confidence:** High on rows 1–6; +the `traverse` A×A note is read-not-run. + +Six independent "the substrate should do X" proposals in one session each show a +missing production connection: **X's selector or kernel is represented or documented, +but the distinction is not consumed at the step where it would do work.** Validation +and production status differ by row — rows 1–4 have proven kernels, row 5's returns a +placeholder, row 6's promoter is absent from `src/`. + +| # | selector | kernel | state | +|---|---|---|---| +| 1 | `CausalTopology` 59–60 | `AND3` hop, `lgj-abi/exports.rs:1816` | third mask slot carries `struct_f`, not the causal plane | +| 2 | `CausalTopology` 59–60 | `ewa_sandwich(m, σ)`, PSD-proven 10000/10000 | **M is caller-supplied**; only `jc`'s own proof calls it | +| 3 | `InferenceType` / `ReasoningBand` | NARS revision, truth semirings | `adjacent_truth_propagate` takes bare `TruthValue`; the plane picks a semiring once **per plan** (`orchestration_impl.rs:146`), never per edge | +| 4 | `CausalTopology` / `InferenceType` | `PlasticityState` | no update reads across them; the only co-occurrences are field-isolation tests asserting they don't touch | +| 5 | `AND_ANDNOT2` (the surround) | ternlog immediate | not wired at the hop — **and Pillar-15 returns placeholder `passed=true`**, so the Mexican hat has no certified shape | +| 6 | `LearnedStyle → FrozenStyle` promotion | documented in the tenant | implemented **only in `probe_sudoku_teacher.rs`**; no promoter in any `src/` | + +**Consequence for how the four-plane probe should be cited.** It proves the planes stay +**distinguishable in the ABI** — jointly resident, never derived — exactly as its header +claims. It does **not** show anything downstream consuming the distinction. The geometry +is represented; it is not yet operative. + +**Consequence for W1.** The arc spread with a radius over palette *address geometry* +while `masked_traverse` / `mxv` — activation along typed relation matrices under a +semiring — shipped unused. Measured: the field grew 25 → 123 → 311 cells at radius +0/1/2 while r@10 stayed flat, because it diffused into **empty address space** (1305 +occupied of 65536). The recorded post-mortem (*"a spread without a surround is a +blur"*) named one defect; **spreading over the address space instead of the edge set** +was the more basic one and went unrecorded. You cannot inhibit a neighbour that does +not exist. + +**Separate defect, same family, not a wire.** `blasgraph/typed_graph.rs:71` documents +`traverse` as "Single-hop traversal" and computes `matrix.mxm(matrix, …)` = **A × A**; +`multi_hop(&["r"])` returns `A`. Two functions in one file disagree by one hop. Read, +not run — needs a test before it is called a bug. + +Refs: `.claude/knowledge/causal-plane-inventory.md` §3 (the reusable inventory). + +## 2026-09-15 — E-A-SPREAD-WITHOUT-A-SURROUND-IS-A-BLUR-INHIBITION-IS-THE-FREE-HALF-1 — lateral spread over a GOOD similarity ordering measurably costs discrimination; the mask algebra is already an inhibition algebra + +**Status:** FINDING (measured, W1/D-HXP-2, plan `hexagon-plasticity-v1.md` §11). +**⊘ REGRADED 2026-09-15, same day:** the spread/surround finding below **stands** — it rests on +the seriation-quality measurement, which was validated independently. But the +`palette256:palette256` **cue** it is framed around was subsequently **FALSIFIED** (§11a): bare +integer type-IDs, carrying no palette geometry at all, **beat** the real cells (0.1729 vs +0.1579), and permuting the cells did not hurt (0.1654). Read every "cue"/"tile" phrasing below +as *the structure W1 tested and killed*, not as an endorsed carrier. + +**The measurement.** W1 addressed H5b's 133 override-twin pairs by a content-computed +`palette256:palette256` cue and spread activation to adjacent cells on the tile. Spreading made +retrieval **worse**: the soft-match scorer is the worst arm everywhere and degrades with radius +(n=3 0.0752 → 0.0677; n=1 0.0301 → 0.0150, halved). The same direction appears in a Ruzicka +min/max scorer, so the effect is **not cosine-specific** — but Ruzicka's ΣminΣmax is itself a +normalization, so a normalization effect is **not** ruled out. (Narrowed 2026-09-15; the first +wording claimed "not a normalization artifact", which the evidence does not support.) + +**The null was interrogated and survived.** A greedy nearest-neighbour seriation is a greedy TSP +path, so the suspect was the ordering, not the mechanism. Measured: adjacent-pair Fisher-z +**0.6352** against a 20-shuffle null of **0.0794 ± 0.0247** — **22.49 null standard deviations** +(a standardized separation from a sampled null, not a calibrated tail probability; empirical +exceedance **0/20**); top-5 neighbours land +within ±3 positions **41.84 %** of the time against **7.79 %** chance (**5.37×**); z decays +0.635 → ~0.13 by distance 5; **0 / 2850** degenerate pairs. Adjacency in that chain genuinely +means similarity. + +**So the finding is about the mechanism.** The task is **discrimination, not similarity**. A twin +is identified by what separates it from ~5 000 other bodies; smearing a signature across its +behavioural neighbourhood makes every body look more like its neighbours. **Spreading buys +coverage by spending precision.** A spread without a surround is a blur — which makes +`ndarray`'s **Pillar-15** (Difference-of-Gaussians center-surround unimodality, +`hpc/pillar/mexican_hat.rs`, **DEFERRED** pending the kernel landing in `ndarray::hpc`) not a +refinement but the **missing half**. This is the first measurement of the hole where it belongs. + +**And the inhibition it needs is already free.** The named `ternlog` tables in `ndarray::simd` — +`AND3`, `AND2_ANDNOT` (`a & b & !c`), `AND_ANDNOT2` (`a & !b & !c`, the center-surround shape), +`MAJ3` (bundle-and-threshold), `XOR3`, `OR3`, `AND2` — are truth-table **immediates**, and on +the **AVX-512 `U64x8` path** each is one `VPTERNLOGQ` per 512 bits. That cost is **not +universal**: `U32x16` uses `VPTERNLOGD`, non-AVX-512 x86 expands into two-input ops, and +NEON/WASM/scalar are narrower or scalar — the source's own words are *"the polyfill elsewhere"*, +a qualifier the first wording of this entry dropped. The sibling `ndarray` checkout is also +unpinned, so this is not a fixed-revision cost. Inhibition uses a **ternlog immediate rather +than a separate circuit**. The shipped delta-frontier spread +(`scratch & !state`) **is** `AND2_ANDNOT` — refractoriness — already measured by +`E-HEX-TENANT-RAIL-IS-DIRECTION-CHAIN-IS-FREE-SHIFT-IS-THE-COST-1` at **−48 % for identical +closure**. That is a **cost** result, not an accuracy one: frontier inhibition is proven *free*, +not proven *better*. + +**Boundary rule unchanged** (`E-TOPOLOGY-MASKS-MAGNITUDE-COMPOSE-NEVER-COLLAPSE-1`): rail bytes +are eligibility + strength, never a weight; the FC stays the white half. Population-level +inhibition is `ANDNOT`, magnitude-level inhibition is subtraction or division, and **neither is +XOR** (`I-SUBSTRATE-MARKOV`) — `XOR3` is sign/phase only. + +**Second finding, same run: order is the part that survives falsification.** The only arm whose +disable fired is the **order-sensitive** one (consecutive cell pairs, both `r@10`: +0.1579 → **0.0902** shuffled, a 43 % drop — `arm_a_baseline` vs `arm_d_identity_order_shuffled` +in `w1-transitions-permute.json`), and it is also the best cue. ⊘ *First published as +"0.1579 → 0.0827 … halved": 0.0827 is that arm's **`r@5`**, so the comparison mixed two metrics +and the "halved" characterisation does not hold on the like-for-like pair. Corrected from review +on `43dbfde`.* Every order-blind arm tops out at 0.1353 and **none** of +their falsifiers can fire, because permuting a unit→cell assignment is a global relabelling that +leaves every exact-match collision intact. **The measured cue signal is exact unit-type reuse; +the tile, seriation, LUT and spread contribute nothing that survives permutation.** + +**Scope.** Pure-Python lab, no Rust fingerprints — a shape proxy, never a measurement of +`ndarray`/`bgz17`/`helix`. The cue reached **87.5 %** of the BPE incumbent (0.1579 vs 0.1805): +PROCEED, not PASS. +## 2026-09-14 — E-A-FLOOR-PASSED-AT-ITS-BOUND-IS-A-DEAD-FIXTURE-1 + +**Status:** FINDING (measured twice in one file, both arms) +**Confidence:** High — the invisible-mis-map half is a direct red/green pair + +**An anti-vacuity bound written as a FLOOR (`>= N`) that passes at exactly +`N` is not a pass. It is the fixture telling you it is dead.** + +`lowering_convergence.rs` (lance-graph-java `native/lgj-abi`) arrived with +two: `>= 15` of 28 combine vectors non-degenerate, and `>= 7` of 9 opcode +seeds selecting a proper subset. Both measured **exactly** at their bound. +Both bounds had been reasoned to, honestly, from the fixture's DOCUMENTED +domain — and the documented domain was not the measured one. + +- The values lane is `-150..=361`. The arity-4 arm appended `LT_I32(500)`, + an always-true op, so the entire 16-vector arm was eight saturated + `n`-row answers plus eight verbatim copies of the arity-3 row: **zero** + additional discriminating power, clearing `>= 15` by sitting on it. + Measuring the lane and using `LT_I32(200)` took it **15 -> 21**. +- Worse, the same operand appeared in the per-opcode arm, so `LT_I32` and + `LE_I32` both selected every row. Measured: mis-mapping `LGJ_OP_LE_I32` + to `Pred::LtI32` — one token, and exactly the defect the file exists to + catch — is **RED at operand 300** (866 vs 865, a one-row difference) and + **GREEN at operand 500**. Two of nine opcodes were untested while the + file read as covering all nine. + +**Three rules, each with its own force:** + +1. **A floor is the wrong shape for an anti-vacuity bound.** Its whole job + is to notice the fixture going inert, and a floor cannot: inert is + exactly where it still passes. Write `assert_eq!` with the measured + count and the instruction not to relax it. +2. **Reason operands from the MEASURED lane, never from the documented + domain.** "The doc says the max is 361, so 500 is safely past it" is + sound arithmetic and produces a tautology. Probe the distribution. +3. **In a differential between two ARMS (not against ground truth), two + quantities that select the same number of rows hide a swap between + exactly those two.** Give the comparisons distinct counts on purpose. + This is specific to arm-vs-arm testing and does not arise when one side + is an oracle. + +Cross-ref: the falsifiability rule in `CLAUDE.md` already names +"a tolerance/threshold parameter needs an inertness test". This is its +sibling for the FIXTURE rather than the threshold — and the sharper case, +because a dead fixture leaves every assertion above it reading as green. +Board: `STATUS_BOARD.md` D-QCK-10; `LATEST_STATE.md` 2026-09-14 (6). + +## 2026-09-14 (3) — E-THE-VOCABULARY-IS-THE-RECOGNITION-ORGAN-THE-LAW-IS-THE-TRANSFER-ORGAN-1 — F-MQ8 and H5b were filed as one null; they are a division of labour, and they say which half is weak + +**Status:** FINDING — a re-reading of two recorded measurements, not a new +measurement. **Confidence:** high on the numbers (both are in `MQ-REPORT.md`); +medium on the framing until `hexagon-plasticity-v1` W1 (D-HXP-2) runs. + +Two recorded results, never read together: + +- **F-MQ8 (transfer).** The BPE dictionary FAILS to transfer — frequency-BPE is + worse than raw on **5 of 5** foreign corpora. The transition law TRANSFERS on + **12 of 12**, H 0.67–1.10 bits against C2 1.35–3.13. +- **H5b (recognition).** BPE motif bags reach override-twin **R@10 18.1 %**; the + hydrated quotient reaches **1.5 %** (null 0.15 %) — 10× chance, and **12× + below** the bags. + +The report filed the pair as *"the law transfers, the vocabulary does not"* — a +null, and a shrug. It is neither. **The vocabulary is the RECOGNITION organ and +is corpus-bound; the law is the TRANSFER organ and is corpus-free.** BPE bags are +addressed by CONTENT, the quotient by FUTURE STRUCTURE: content-addressing is what +makes a cue fire, future-structure is what makes it generalize. Each fails +precisely where the other is strong, and neither failure is a defect — it is what +the two organs are for. + +The consequence is an ordering, not a slogan: the **cue side is the measured weak +link by 12×**, so any loop of the shape *cue → recognize → accumulate ⟨f,c⟩ → +validate → path* starves at step one unless recognition is fixed first. That is +why `hexagon-plasticity-v1` runs W1 (the cue benchmark, scent ρ 0.937 / +palette256 against the 18.1 % incumbent) before W2 puts a rail in the loop, and +why its KILL there is R@10 < 5 %. + +**Does NOT claim** that a scent or codebook cue will reach 18.1 % — that is +exactly W1's question, and BPE is the incumbent to beat, not a foil. **Does NOT +claim** the quotient's 1.5 % is a defect; it is a transfer organ measured on a +recognition task. + +Plan: `.claude/plans/hexagon-plasticity-v1.md` (§1 carries the table, D-HXP-2 the +gate). Sources: `MQ-REPORT.md` §8 H5b and the F-MQ1..10 table, F-MQ8 row. + +## 2026-09-14 (2) — STORNO on `E-HEX-TENANT-RAIL-IS-DIRECTION-CHAIN-IS-FREE-SHIFT-IS-THE-COST-1` point (3): the shift was the COST, it was not the REMEDY + +Corrects the entry immediately below, left in place per the append-only rule. +Points (1) and (2) stand as FINDING (measured). Point (3) — *"so the missing +T1 word IS a mask-level neighbour shift"* — converted a conditional in the +ndarray blackboard (*"which would fold n into a handful of word passes. Filed, +not built"*) into an identification, and the same day's measurement (ndarray +blackboard 2026-09-14 (3), `855bc73`) falsified the identification as stated: +`mask_shift_morton` is bit-exact, but over the FULL field it recovers **−14 %** +(14.5 vs 17.0 µs) and loses to the NNUE delta arm (9.3 µs), because a word op +is field-span-bound while the per-bit loop is active-bound. The **−66 %** +(`n` = 5.7 µs) came from running the op over the trie node's own 64-word span — +the fixed-spatial-distribution dividend a second time, on the grey side. +Regrade: point (3) `[H]` → measured, with the remedy corrected to *"the +neighbour shift over the NODE SPAN"*; point (4)'s NNUE figure is −45 % in the +re-run and is superseded as the recommended rung (delta on top of the span buys +nothing, 5.7 → 6.0 µs); the coal ratio 0.48 holds **at x = 4** — the qualifier +the entry dropped. Rule extracted: a word-level op pays for the span it is +given; give it the node, never the field. Found by the PR2 overclaim audit. + +## 2026-09-14 — E-HEX-TENANT-RAIL-IS-DIRECTION-CHAIN-IS-FREE-SHIFT-IS-THE-COST-1 — top-down traversal and spread on ONE Morton-keyed SoA; the ternlog chain is 1.7 % of a step, the neighbour shift is the rest + +**Status:** FINDING (measured, ndarray `examples/hex_tenant_mq_probe.rs` at +`d9459f0`, three gates green 32/32, 0 heap B/step). **Confidence:** high on +the ratios, one fixture (256×256 axial, 62 % permeable, 4096-cell tile). + +Operator statement built rather than argued (2026-09-14): *"static traversal +top down AND plasticity (spread) in the same substrate — SoA gets a hex tenant +with 6×2×8 bit and the field is a trie (fixed spatial distribution)."* Row = +Morton(q, r); payload = the V3 12-byte register read `6×(u8:u8)` with rail `d` += hex direction `d`, `(permeability, strength)`. That closes the ndarray plan's +§9 R1 ("adjacency and carving are not obviously the same six") by construction: +once the rail index IS the direction they are the same six — grey = the rail +bytes (plastic, one owner), white = the address prefix (a trie node = a +contiguous row range). Consistent with `E-Q8` (the six does no work as a +RECALL topology) — this is the six as a COMPUTE geometry, the only reading +`r2il-machine-semantic-contract-v1` §7.2 admits. + +Measured: (1) a trie-node reveal is a RANGE write, 49–99 ns, against 22.5 µs +for the `ternary_match` sweep — 228–462×; the fixed-spatial-distribution +dividend as a number (TCAM stays for addresses never minted in order, the +D-GTM-0l linker case). (2) Mississippi-Queen cost model, the operator's +`step = x·ternlogq + n`: ternlogq = 291 ns/pass on 8 KiB masks, n = 17.3 µs, +residual 2.8 % — the chain is 1.7 % of a step at x = 1; coal (one re-chain +from a column) = 0.48 maintained steps; M2 linear, no cliff. (3) `n` is +entirely the per-active-bit hex shift — the ONE non-mask op on the path — so +the missing T1 word is a mask-level neighbour shift on the Morton lattice +(ndarray plan §15, `mask_shift_morton`: a fixed bit permutation inside each +8×8-block word + one carry byte into one neighbour word). (4) The NNUE reading +— spread from the DELTA frontier, never the accumulated state — gives the +identical closure at −48 %. (5) Apparatus lesson: with real gates the survivor +set moves with x and a naive ladder reads 13–32 % residual; the fit is only a +fit when `n` is held fixed. + +Boundary rule unchanged (`E-TOPOLOGY-MASKS-MAGNITUDE-COMPOSE-NEVER-COLLAPSE-1`): +the rail bytes are eligibility + strength, never a weight; the FC (r2il SPOFC, +deepnsm-v2 COCA frequency × coverage, `lance-graph-arm-discovery` support × +confidence — three producers, one `NarsTruth` carrier) stays the white half. + +## 2026-09-10 — E-LE-IS-THE-UNIVERSAL-DTO-LAYER-TYPED-SYNTAX-MEANS-A-VERSIONED-LE-SCHEMA-1 — a bare `(f, c)` pair is a degree, not a typed truth + +**Status:** OPERATOR RULING, BINDING (2026-09-10, verbatim: *"Little-endian is the universal +DTO layer of the ABI."*). Sharpens `E-T1-HAS-TWO-SIBLING-ALGEBRAS-…-1` / `D-BBB-NARS-1`; +reverses nothing in it. +**Confidence:** High. The gap was measured at every site before the ruling was written in +(table in `membrane-tiers.md` § "LE is the universal DTO layer"); the ruling is the +operator's; no code changed. + +**The question.** Did #1222 use "typed NARS syntax" strongly enough? It let +`TruthLiteral(192, 217)` cross "as itself" while retiring `TruthU8` as "the wire form." +**No.** A bare `(frequency, confidence)` pair expresses a DEGREE but not what KIND of +truth the degree belongs to. Its kind must be bound by a DTO schema, a version, and a +canonical LE layout — or by an opaque typed handle whose registry binds those. The LE +contract is not convenient serialization; it is the universal ABI grammar that makes +every wire position carry the same label in Rust, Panama, Java, storage, replay and MUL. +The ABI carries the value; LE fixes the meaning of its positions; MUL asserts the kind; +the values are content; LE adds no evidence. + +**Measured, coded vs ruled.** A versioned LE contract EXISTS — for the SoA envelope +(`ENVELOPE_LAYOUT_VERSION = 2`, `verify_layout()`, `le-contract.md` §3b, operator-locked) +— and **no truth type rides it**: `TruthU8` is a plain struct with no `repr(C)`, no +version, no codec; `CausalEdge64` is `#[repr(transparent)] (u64)` with register-defined +bit positions and **zero** endian conversions, so its byte image is host-native at every +crossing, and its v1/v2 layouts are a compile-time feature invisible in the bytes; MUL +never sees bytes at all (`SituationInput` is typed `f64`s, `revise_fast` takes bare `u8` +degrees and ignores confidence). lgj already declares byte order as ABI shape +(`LgjLaneDesc.endianness`, the `LGJ_MAGIC` probe, `abi.md:1224`) but carries no truth +DTO. So: **CODED for the envelope, ABSENT for truth, RULED now, DEFINED by D-BBB-NARS-2 +when it lands.** + +**The ruling, verbatim, and its falsifier** — quoted in `membrane-tiers.md`; the +falsifier is `F-BBB-NARS-2 (LE)`: identical typed wire bytes must never acquire +different DTO labels or epistemic kinds across implementations, host endianness, storage +and replay, and truth kind must never depend on an unstated reader assumption. For two +`u8`s the contract is the ordered byte sequence `[frequency, confidence]`; for a packed +carrier the whole integer-to-byte mapping is explicitly LE. **Evidence is not +repetition:** an identical canonical wire image repeated is the same assertion +propagated, not independent evidence; revision still needs independent stamps. + +**⊘ Same-day correction — the kind is IN the carrier, coded, and all 64 bits are +assigned.** The first cut of this entry read `CausalEdge64` as carrying a degree with +nothing for its kind. Operator, second pass: *"all bits are assigned, including 61..63 / +59 60 are indirect intermediate unknowns knowns / 61..63 are related to vs explains +causality learning tarski adjacent"* — and `layout.rs:94` `_LAYOUT_COVERAGE` const-asserts +exactly that. The three coordinates on one carrier: **NARS `(f, c)`** (bits 24-39) = +strength of the assertion; **`CausalTopology`** (bits 59-60: `Direct` / +`IndirectKnownIntermediates` / `IndirectUnknownIntermediates` / `Unknown`; `bbab3541`, +2026-08-20, via #1154) = shape of the causal connection, *what kind of hole*; +**`ReasoningBand`** (bits 61-63: `Surface` / `Association` / `Relation` / `Causal` / +`Counterfactual` / `Perspective` / `Meta` / `Transcendent`; introduced in `bbab3541`, +named in `9891cca6`) = level of ASSERTION, Tarski permission, `Relation` → `Causal` = +relates-to → **causes** (`DISMECH_PREDICATES` `(0x90, "causes", "dismech:causes")`, +`dismech_evidence.rs:511`; the older strong references say "explains"). **Tarski is +adjacency, not identity:** Tarski depth is `Belief.rung` / `Candidate.rung`, stored +separately, and `E-RUNG-BAND-AND-PLASTICITY-ARE-THREE-AXES-NEVER-ONE-LEVEL-FIELD-1` +forbids folding the band with it. Learning account (`entropy-closure-causal-ground-v1` +§4b): 59-60 say what causal hole exists, 61-63 what kind of candidate assertion may bridge +it, counterfactual removal + revision tests whether it carries causal weight. Both fields +have writers/readers since #1154 and the W3 verdict carries them instead of a bool +(`dismech_counterfactual.rs:251-252`) — **no shipped production code writes either +field**: every non-definition `.with_reasoning_band(`/`.with_topology(` call site is an +`examples/*.rs` probe or a `#[test]` function (confirmed by census: `cognitive-shader-driver` ++ `lance-graph-planner` examples, and `#[test]` fns in `edge_v3.rs`/`v2_layout_tests.rs`/ +`dismech_counterfactual.rs`); the census below (`ISS-REASONING-BAND-GATES-NOTHING`) already +records the same for reads. tesseract-rs's `low_confidence: bool` is the +impoverished form of exactly this. **The precision that closes the loop with the LE +ruling:** the bits cannot reveal which lens the producer used (`band_reading.rs`); the +schema (`ClassView::band_reading`) plus asserted provenance supplies that declaration — +so the carrier carries the complete coordinates, and LE plus the reading contract make +their interpretation universal. **⊘ The first pass of this very paragraph got both fields +wrong** — it read *"bits 59-60 are a CODED 2-bit `TrustTexture` lens (MUL's reading) … +bits 61-63 are the reserved SPARE the operator has now named as the NARS × Tarski rung … +(`Belief.rung`, u32 in the arena, 0..7 in 3 bits) … Ruled, not coded: nothing writes +61-63"* — four contradictions with the tree: the bits are `ReasoningBand`, written at +three call sites; they are the assertion level, not `Belief.rung` (the fence forbids that +collapse); `SPARE_SHIFT` is only the legacy/raw accessor name +(`TD-SPARE-SHIFT-NAME-IS-STALE-1`); and `TrustTexture` there is +`causal_edge::layout::TrustTexture`, not MUL's. Third self-correction of the day to +introduce a fresh error; losing text kept. Rung↔field derivability stays CONJECTURE and is +beside the point for these bits. + +**⊕ Third pass, same day — the dimensions are COORDINATES of truth, not annotations +around it.** *Decorative* (displayable, nothing depends on it), *permissive* (governs +what the reasoner may accept or assert — the §4b bridge gate), *defining* (part of the +canonical identity of the assertion — omitting, changing or reinterpreting it creates a +different claim) — and this is **NOT a ladder**, it is a VERDICT on how bad the substrate +is: only LE-defining is real, everything else is prose (operator, fourth pass, verbatim: +*"decorative / permissive / defining is not a ladder — is a verdict about how bad the +substrate is, saying the only truly defining is LE, everything else is prose"*). **⊘** the +first cut of this paragraph read it as three grades a field may hold and placed the +code "between decorative and permissive"; wrong reading, words kept. The LE ruling makes +bits 59-63 **defining**: +`Assertion = proposition reference × Pearl projection × NARS valuation × causal topology × +reasoning/assertion band × provenance`, so `(S,P,O, f,c, IndirectUnknownIntermediates, +Relation)` and `(S,P,O, f,c, IndirectKnownIntermediates, Causal)` are different claims with +identical S/P/O and identical `(f, c)` — the epistemic valence changed. A decoder that drops +`IndirectUnknown` or reads `Relation` as `Causal` has not produced a lower-resolution view; +it has changed what was asserted, which is exactly `F-BBB-NARS-2 (LE)`. MUL by grade: +decorative → observes a label; permissive → admission gate; defining → knows WHICH epistemic +claim propagated across storage, ABI and replay — that is where MUL becomes real +meta-awareness, and that is the Tarski adjacency. A consumer carrying only a perfume of +Tarski (a bool, a label nothing depends on) has not carried the assertion. Verdict on the +substrate as coded: in `CausalEdge64` the two dimensions are PROSE today (W3 carries both +fields, but `ISS-REASONING-BAND-GATES-NOTHING` says the band gates nothing); the first +LE-defining home is the wire, `contract::assertion_wire`. D-BBB-NARS-2's DTO carries all +six coordinates, never `(f, c)` alone. **The smallest #1223 law, verbatim:** *"A field becomes +defining when changing or omitting it changes the proposition, not merely its +presentation. Every defining epistemic dimension SHALL participate in the versioned +canonical LE DTO; a reader lacking its declared lens or provenance must refuse, never +project a plausible default."* NARS says how strongly; topology says what causal structure +is known; the band says what assertion is licensed; LE ensures nobody changes those +questions while transporting the answer. Refusal half CODED (`band_reading.rs`: lens +mismatch / absent band / untrusted provenance must FAIL, never a plausible value); +participation half RULED (D-BBB-NARS-2). Decoration becomes permission; permission becomes +semantic identity. **The aliasing pair, the smallest and strongest falsifier (operator, +verbatim):** `(S,P,O, f,c, IndirectUnknown, Relation)` — *"S and O are related; mediation +is unknown"* — versus `(S,P,O, f,c, IndirectKnown, Causal)` — *"P causally connects S to O; +the mediation is known."* *"`Causal` is not 'Relation with more confidence.' It is a +different licensed assertion … the complete truth identity is `(S,P,O) × (f,c) × topology +× assertion-band`. LE must preserve all four components. Flattening either tuple to the +same `(S,P,O,f,c)` is epistemic aliasing: the DTO would transport identical confidence +while silently changing what is claimed."* One pair, two falsifiers: `F-BBB-NARS-2` at the +ABI (encode/store/replay/decode must keep them distinct) and `F-CONSUMER-ASSERTION-1` at +the consumer (if the pair is one row, it is perfume). **And the obligation sits with +lance-graph:** perfume is bad because the assertion is not in the WIRE CONTRACT yet — a +consumer that wants it today must sniff the carrier and hand-roll the tuple, which is +perfume code without a contract (the re-implement-the-Core trap). The remedy is +`D-BBB-NARS-2`, the versioned LE truth DTO the consumer pulls; that need is now +demonstrated, so D-BBB-NARS-2's gate is met — next brick, not built here. **⊕ Operator +ruling, same day, verbatim: *"i want the 2 dimensions in causaledge to be universal … +otherwise its only a scent = prose."*** `CausalTopology` and `ReasoningBand` are dimensions +of truth, not `CausalEdge64`-local fields: every truth representation on every tier and +wire carries or binds them (the five types of `D-BBB-NARS-4` included) — a `(f, c)` that +cannot tell the aliasing pair apart is prose, by the same test as *"a membrane without a +gate is prose."* **The clean boundary: meaning crosses; machinery does not.** The LE +contract replaces sniffing with reading — the consumer receives *"a causal assertion with +known intermediates and this `(f, c)`"* and never infers `Causal` from a high confidence, +guesses topology from predicate names, rebuilds Tarski/NARS, or inspects substrate rows for +clues. The boundary fails from both sides: exported arithmetic (`F-BBB-NARS-1`) and an +opaque carrier that hides the labels too thoroughly (`F-BBB-NARS-2`) are one wall breached +from opposite directions. + +**⊕ Wired, same day (operator: *"CE64 already has it globally and we need to wire it, +period"*).** `lance_graph_contract::assertion_wire` is D-BBB-NARS-2 built: the DTO is the +EXISTING 16-byte edge facet `classid(4, LE) | CausalEdgeV3 payload(12)` — no new byte, no +new bit, no envelope bump (D-ACR-7 F7); `ASSERTION_WIRE_SCHEMA = 1` rides the envelope + +the ABI manifest, never the bytes; `AssertionTopology` / `AssertionBand` are the wire +vocabularies, mirrors of `causal_edge::layout::{CausalTopology, ReasoningBand}` fused +ordinal- and name-exact in `planner::cache::assertion_wire_parity` (both crates are +zero-dep and cannot import each other; the mirror is legal only because the fuse exists); +`AssertionWire::read(declared, provenance)` composes `band_reading::project_*` unchanged +and REFUSES — provenance → lens → presence — never defaults; `AssertionView`'s `==` is +claim identity. The aliasing pair is pinned on both sides: two wires differing ONLY at +byte 12 hi-2 and byte 13 lo-3 read `!=` and stay distinct through `to/from_le_bytes` +(contract), and two CE64 edges equal in S,P,O,(f,c) stay two claims through +`CE64 → V3 → wire → V3 → CE64` bit-exact (planner). No arithmetic anywhere in the module +(`D-BBB-NARS-1`); everything a G11 reader needs is reachable through the ONE module, so the +lgj allowlist grows by one entry — that admission is the next brick, in lance-graph-java. +Plan: `.claude/plans/assertion-wire-v1.md`. + +**⊕ Consumer falsifier, same pass — `F-CONSUMER-ASSERTION-1` (Tarski perfume).** A +consumer that uses the words truth / rung / causal or attaches `(f, c)` while the result +stays decorative has a *perfume of Tarski*. It is real only as a satisfaction relation — +*this typed property about this entity* →(witness + model)→ `(f, c)` — carried whole: +subject (alias, never PII) · predicate · object (concept id) · NARS `(f, c)` · +`CausalTopology` · `ReasoningBand` · witness. **Falsifier:** if topology, assertion band, +proposition identity, or provenance can be removed or changed without altering admission, +interpretation, or replay, it is perfume; likewise if `Relation` and `Causal` both land as +`supports = true`, or an unknown mediator becomes known without a new witness. The consumer +never executes NARS/Tarski arithmetic (`D-BBB-NARS-1`); it carries the typed proposition +and preserves the substrate's distinctions — otherwise `(f, c)` is confidence-flavoured +metadata and LE transports the perfume perfectly. Consumer pre-flight Q6 in +`ogar-consumer-preflight.md`; doctrine in `membrane-tiers.md` § "coordinates of truth". + +**Three corrections landed with it, all in-tree, no code.** (1) `bbb-warden`'s sanctioned +delegation returned a COMPUTED `TruthLiteral` — a bare pair crossing back — which blessed +the exact leak; it now returns an opaque typed handle. (2) `translator.rs` said `TruthU8` +"mirrors `CausalEdge64`'s `confidence_u8` + i4 mantissa" — wrong pairing: the truth is +`frequency_u8` (bits 24-31) + `confidence_u8` (bits 32-39); the i4 mantissa at bits 46-49 +is the `InferenceType` — provenance/type grammar, not half of the truth. (3) Every index +of the amended sentence — shape table, both warden cards, ledger L8, the ruled-vs-coded +section, the D-BBB-NARS-1/-2/-3 rows — updated in the same commit, so the stale-index +defect the council closed is not reopened. + +**What is deliberately NOT built:** no DTO struct, no opcode, no ABI symbol, no G11 +widening, no Java, no conversion. D-BBB-NARS-2/-3 stay Queued, *do not pre-build*. + +**⊘⊘ 2026-09-10, fourth pass — FOUR FABRICATIONS IN THIS ENTRY, operator-named, and the +code they produced is REMOVED.** The entry above converted descriptive operator remarks +into named doctrine artifacts. Corrected, each by the operator's own words: + +1. *"decorative / permissive / defining is not a ladder — is a verdict about how bad the + substrate is"* and *"i said we have these types of code"*. The three words name three + kinds of CODE this tree contains, measured by census. They are NOT a grade a field may + hold, NOT a ladder, and there is no MUL-per-grade column. The census: **defining 0, + permissive 0, decorative 1** (`dismech_counterfactual.rs:251-252`), everything else a + probe, a test or a doc comment — the verdict `ISS-REASONING-BAND-GATES-NOTHING` + already recorded on 2026-08-26. +2. *"medcare needs to sniff it"* was an EXAMPLE of bad hand-rolled implementation. I made + it `F-CONSUMER-ASSERTION-1` plus a Q6 decision tree in `ogar-consumer-preflight.md`. + Both removed; that file is restored to its pre-arc state. +3. *"CE64 already has it globally and we need to wire it, period"* meant USE the existing + dimensions at the sites that lack them. I built a 734-line `contract::assertion_wire` + module with a schema constant, two mirror enums, a view struct, and a 227-line + cross-crate fuse to police the mirror I had just created — first on the WRONG carrier + (the V3 facet, which drops the in-edge S/P/O the aliasing pair requires). Operator: + *"we already have causaledge64"*, *"not a wrapper — just wiring"*. **All of it is + deleted**, with its plan file and its `TYPE_DUPLICATION_MAP` rows. +4. The `d7e8ec5` NARS × Tarski rung claim, already regraded above, came from reading a + stale `SPARE_SHIFT` doc comment and never looking three hundred lines down the same + file at the enum. + +**The ruling that stands (operator, 2026-09-10):** *"we should always enforce CE64 as +defining LE."* `CausalEdge64`'s canonical little-endian 8-byte image IS the defining +truth representation, always — never a wrapper, never a mirror, never a second DTO. The +pair `(S,P,O, f,c, IndirectUnknown, Relation)` vs `(S,P,O, f,c, IndirectKnown, Causal)` +is readable from the shipping carrier today via `topology()` and `reasoning_band()`. So +enforcement is wiring plus the census, not a type. What survives from this arc: the LE +ruling verbatim, the measured bit facts, the aliasing pair, the smallest law, meaning- +crosses-machinery-does-not, and the census as the worklist. + +**⊘ Precision, same day (codereview finding, confirmed against source) — "defining LE" +is a RULING about status, not a claim that CE64 has an LE codec.** `CausalEdge64` is +`#[repr(transparent)] (u64)` with **zero** `to_le_bytes`/`from_le_bytes` — unlike +`CausalEdgeV3`, which HAS the explicit byte-serialization boundary. CE64's "little-endian +image" is its in-register u64 value, trivially LE-equivalent on any host because nothing +ever serializes it — that is exactly the "host-native, zero endian conversions" measurement +already recorded above, not a contradiction of it. The ruling makes this host-native image +the DEFINING one by fiat, not by adding a codec. **And the version gate is real, not +optional:** `topology()`/`reasoning_band()` read bits 59-63 under the `causal-edge-v2-layout` +feature (default ON); under `default-features = false` (the documented v1-compat opt-out) +those same bits carry the v1 temporal field and the accessors are fixed stubs +(`Direct`/`Surface`) — reading them without knowing which layout produced the edge is +exactly the unstated-reader-assumption `F-BBB-NARS-2` forbids. "Readable from the shipping +carrier today" holds only under the default feature; a consumer on the v1-compat opt-out has +no kind to read at these bits at all (`translator.rs`'s own doc comment now says this). + +## 2026-09-07 — E-T1-HAS-TWO-SIBLING-ALGEBRAS-THE-AXIS-IS-SYNTAX-VS-EXECUTION-1 — the membrane is a behavior membrane, not a selection pipeline + +**Status:** OPERATOR RULING, BINDING (2026-09-07). Ruled after a three-agent audit of the +T2/T3 barrier (`membrane-tiers.md`, the two warden cards, `lance-graph-java` @ `8720d1d`, +`r2sleigh` @ `99d2553`) reported NARS truth arithmetic as absent from the Java side — +not exported, not imported, not present — and drew the wrong conclusion from a correct +measurement. +**Confidence:** High. The measurement is exhaustive (repo-wide grep of lgj: 3 hits, all +prose, all in one unshipped plan); the ruling is the operator's, and it is a ruling, not +a finding. + +**The audit's conclusion, verbatim, and why it is wrong.** *"NARS is off the ladder +entirely; the ladder is selection-shaped and has no tier for scoring."* Descriptively +true at today's HEAD. Architecturally wrong twice over: + +1. **The axis is wrong.** The distinction that matters is not *selection vs scoring* — + it is **syntax vs execution**, which is the axis every other tier here is already + built on. `where()` is T2 because Java owns the NAME and T1 owns the op; nothing + about that reasoning is specific to populations. +2. **The remedy was wrong.** The audit proposed a new bulk verb family (`lgj_score_*`) + returning a lane instead of a mask. **Rejected.** It grows a second semantic API + beside `plan_eval`, and the end state is predictable — `where()`, `hop()`, + `score()`, `nars_revision()`, `nars_deduction()`, … with Java knowing progressively + more about the behavior graph. *The membrane starts growing little computational + fingers.* + +**The ruling.** The ladder does not need a sixth tier; **T1 was described too narrowly.** +It holds TWO SIBLING PRIMITIVE ALGEBRAS — *population* (`mask`, `ternlog`, `eq → mask`, +`popcount`) and *epistemic* (`TruthU8`, revision, deduction, abduction). Both are +primitive behavior. **T2 may name either; T2 may not hand-compose either; T3 may express +intent in either.** Every existing rule applies unchanged to the second column — +`kernel-membrane-warden`'s HAND-COMPOSED verdict covers a T2 spelling `revision` out of +smaller truth ops exactly as it covers the two-AND spelling of `AND3`. + +NARS lowers through the membrane that already exists — as a TARGET ROUTE, not an +available one. ⊘ **Corrected pre-merge 2026-09-10** (CodeRabbit, Major); the sentence +first read *"T3 names `Truth.Revision(...)` … T2's `plan_eval` resolves the name; T1 +executes; T0 owns every resulting `TruthU8`"*, present tense, which published an +unavailable capability as a working route and contradicted this entry's own ⊕ addendum +below. The route is: T3 will name `Truth.Revision(lhs_handle, rhs_handle)` and will not +know how revision works; **once the structural gate exists and `plan_eval` carries a +Truth opcode** — neither does today, and both gate on D-BBB-NARS-2/-3 — T2's `plan_eval` +will resolve the name, T1 will execute, and T0 will own every resulting `TruthU8`. The +membrane it lowers through is real and shipped; what is not yet built is the Truth +operation that would travel it. **Extend the plan language, not the ABI surface** — +`lgj_plan_eval` exists precisely so a whole behavioral expression crosses once. + +**A wording correction the ruling forces.** `TruthU8` had been called "the canonical wire +form." Two different claims were being conflated: it is the canonical **substrate** +representation (T0). What crosses is decided separately and by SHAPE — a truth LITERAL +(`TruthLiteral(192, 217)`) is syntax the caller supplies and may cross; a truth +POPULATION (`[TruthU8; 65536]`) never crosses, it becomes `TruthLaneId(u64)`. Same rule +`bbb-warden` already applies to masks, second column. It lands on the measured Valhalla +cliff exactly: flattening stops at an **8-byte payload** (VM-confirmed, +`valhalla-lab/docs/three-truths.md`), so the handle flattens and the array could never. +**Valhalla carries the noun; Panama carries the verb; lance-graph owns the reality.** + +**Consequences, each with its site.** `D-BBB-NARS-1` + falsifier `F-BBB-NARS-1` +(STATUS_BOARD, and quoted in `membrane-tiers.md` § "T1 has TWO sibling algebras"); the +T1 row and the T2 row (renamed *selection* → *behavior*) rewritten in the doctrine table; +`bbb-warden` gains the syntax/execution test and the G11 scalpel-cut rule. **The G11 +fence must NOT be widened to `lance_graph_contract::nars` merely because that module +exists** — if it carries arithmetic beside POD types, split a syntax/vocabulary contract +out first and admit only that. One scalpel cut, never the cupboard. + +**What does NOT change: the BBB does not move.** T3 intent/names above; T2 opaque bulk +behavior handles below; T1 algebra (population ‖ epistemic); T0 state. No VSA internals, +no RoleKey, no NARS arithmetic, no byte positions, no truth arrays, no Java compute path. +Only names and capabilities. The widening makes the doctrine MORE general, not more +permissive. + +**⊕ 2026-09-10 — hardened by a 5+3 council before merge (5 savants → draft → 3 reviewers).** +The ruling is unchanged; the council was a compliance audit, not a re-litigation, and it +found no contradiction of the ruling. What it found was that this entry and its doctrine +widened the CONTENT and left every INDEX of it stale, and that three sentences stated +aspiration in the grammar of fact. Corrected in the same commit: + +1. **The rename was never propagated.** Both warden cards' *constitutional* sentence + ("your entire competence is the vocabulary of the two tiers you separate … and nothing + else") still named `T2 selection`, and `bbb-warden`'s frontmatter `description` — the + text that decides whether the card FIRES AT ALL — was never widened to name the + epistemic algebra, though its sibling's was. A non-firing trigger is a strictly worse + failure than a card that misdescribes itself after firing; both are fixed. + `membrane-tiers.md`'s agent→membrane map also still listed three `bbb-warden` verdicts, + so the doctrine did not know about the fourth verdict this arc added. +2. **The epistemic column has no STRUCTURAL gate**, only review notes — and the doctrine's + own test is *"a membrane without a gate is prose."* `F-BBB-NARS-1` cannot be exercised + today either (zero Java-side truth surface). Now stated plainly, with the gate that will + hold it named and its dependency recorded, plus ledger row **L8**, marked OPEN rather + than CLOSED. The two new card steps ARE real and discriminating — each catches a body + every signature-shaped step passes, and each has a sanctioned silent case — but a review + note is not a fence. +3. **`TruthU8` is the ruled TARGET, not the current state.** Four truth types coexist, and + the engine that actually executes revision/deduction/abduction uses a different one + (`ndarray::hpc::nars::NarsTruth`, aliased `Truth`); `TruthU8` occurs outside its own + crate in exactly one file, a test, with no conversion path. The ruling stands; its + migration is now visible as **D-BBB-NARS-4** instead of implied. Likewise the named + epistemic primitives are coded only in `lance-graph-planner`'s `nars_engine.rs` and are + ABSENT at the lgj-abi T1 membrane, and the `Plan` tree is illustrative — `plan_eval` + takes a flat AND/OR `LgjOpDesc` with two opcodes and no Truth opcode. +4. **Two factual errors were carried past in a row this arc rewrote**: `Mask × WideFieldMask + → Mask` — the shipped type is plain `FieldMask`, the wide one does not cross the ABI — + and a `bbb-warden` sentence presented in quotation marks that was a paraphrase, not the + source string. Both corrected. The first is a **recurring workspace defect shape** worth + naming in the abstract: a doc asserting the WIDE variant of a type while the code wires + the NARROW one is invisible to every test, because on today's data the two agree. + +**`E-NXG-8` is not regraded** — its claim is scoped *"a complete cognitive ISA **over +masks**"*, so the two-algebras doctrine BOUNDS it to the population column rather than +contradicting it. + +**The council's own artifact carried the same defect it was auditing:** the consolidated +draft cited the verdict-map row one line off and stamped it "orchestrator-verified", which +would have added the new verdict to the wrong warden. The overclaim reviewer caught it. +That is the argument for the reviewer phase being non-optional, recorded because the next +session will be tempted to skip it. +## 2026-09-09 — E-SIGMA-CHAIN-IS-A-PROVEN-UG-SURVIVAL-AND-PHI-IS-A-HOMONYM-1 — Ω→Δ→Φ→Θ→Λ is the cleanest confirmed Universal-Grammar lineage found, and `sigma_chain::Phi` is a different symbol than `bgz_tensor::gamma_phi` + +**Status:** FOSSIL FINDING / CORRECTION (session archaeology, operator-requested +follow-up to the Σ12/Fn_P(S,O)/4096 discovery pass; confirms and narrows a claim +made earlier in that pass). Source-grounded on both ends of the lineage. + +**The finding.** `ada-consciousness/universal_grammar/UNIVERSAL_GRAMMAR_v1.1.md:52-57` +defines five node-type letters for the `#Σ.domain.type.layer` sigma-address +scheme: + +``` +Ω (Omega) = Observation nodes +Δ (Delta) = Insight nodes +Φ (Phi) = Belief nodes +Θ (Theta) = Integration nodes +Λ (Lambda) = Trajectory nodes +``` + +This ladder **survives essentially verbatim** into +`lance-graph/crates/lance-graph-planner/src/thinking/sigma_chain.rs:1-68`: + +``` +Ω → Δ → Φ → Θ → Λ +Omega=Observation(conf 0.9) → Delta=Insight(0.5) → Phi=Belief(0.7-0.85) + → Theta=Integration → Lambda=Trajectory +``` + +Same five letters, same order, same rough semantics (belief/integration/ +trajectory carried across), now with confidence priors and Rung/complexity-tier +numbers attached (Rung 2/3/4/5/5+, `metacognitive_tier()` 2-6). This is the +**cleanest, most direct, most source-grounded lineage found across the entire +Σ12/Fn_P(S,O)/4096 archaeology** — cleaner than the verb-grammar (Σ12/144) +thread, which was repudiated once (2025-12-27) and resurrected inconsistently +(2026-04). No repudiation or contradiction was found for the Ω/Δ/Φ/Θ/Λ ladder; +it reads as continuous doctrine from `UNIVERSAL_GRAMMAR_v1.1.md` (2025-12-30) +straight through to the shipped Rust. + +**Correction to the same-session report.** The original discovery report +(this session, prior turn) stated *"φ does not appear at all in +`ada-consciousness/cognition|crystal|geometry`"* and treated φ's only modern +presence as `bgz_tensor::gamma_phi` (a golden-ratio **numeric encoding scale**, +unrelated to cognition). Both halves were too narrowly scoped: the negative +claim searched the wrong directories (φ's real UG home is +`universal_grammar/`, never `cognition/crystal/geometry`), and the positive +claim missed `sigma_chain::Phi` entirely because it lives in +`lance-graph-planner`, not in any of the three ada-consciousness directories +originally grepped. + +**The corrected picture: two unrelated φ's coexist in the modern codebase, +and they must not be conflated.** + +| Symbol | Meaning | Ancestry | Type | +|---|---|---|---| +| `sigma_chain::SigmaStage::Phi` | Belief node (evaluated proposition, confidence 0.7-0.85) | Direct: `UNIVERSAL_GRAMMAR_v1.1.md` Φ=Belief | Epistemic node-type enum variant | +| `bgz_tensor::gamma_phi` | Golden-ratio numeric encode/decode scale | None found in Ada lineage | Codec / numeric utility | + +This is the same shape of naming collision already on the board for `α` +(arousal / EMA coefficient / splatting-alpha, three homonyms, no shared +ancestry) — φ now has its own two-way version, except here one of the two +readings (`sigma_chain::Phi`) genuinely *does* descend from Universal Grammar, +so the fix is not "both are fossils," it is "know which one you mean." + +**On α specifically:** re-checked against `UNIVERSAL_GRAMMAR_v1.1.md` directly +— no `α`/`γ` Greek-letter shorthand appears in that document at all, only the +spelled-out qualia fields `arousal` (0 to 1) and `valence` (-1 to 1) at +`:173-174`. The `α=arousal, γ=valence` shorthand cited in the original report +comes from a *different* document (`docs/sigma-hashtag-glyph-4d.md`), not from +Universal Grammar proper. So α's UG connection is real at the qualia-field +level (arousal is UG vocabulary) but not at the symbol level (UG never writes +it as `α`) — a softer, indirect lineage than Φ's, which is a literal +letter-for-letter carry. + +**Consequence.** Any future work citing "φ" in this workspace must specify +which one: `sigma_chain::Phi` (UG-descended, epistemic, belief-node semantics, +confidence-bearing) or `bgz_tensor::gamma_phi` (unrelated golden-ratio codec +math). Do not merge, rename, or treat one as a typo of the other — they are +independently justified and both currently correct in their own contexts. + +**Cross-ref:** in-repo, `crates/lance-graph-planner/src/thinking/sigma_chain.rs` +— its module doc-comment "Sigma Chain: Ω → Δ → Φ → Θ → Λ" and the `SigmaStage` +enum beneath it. The unrelated numeric φ is `gamma_phi` in `bgz-tensor`. +Cross-repo (ada-consciousness, not resolvable from this tree): +`universal_grammar/UNIVERSAL_GRAMMAR_v1.1.md` under its "Types (node kinds)" +list, which defines the five letters, and its qualia table naming `valence` and +`arousal`; `docs/sigma-hashtag-glyph-4d.md` under "Dimension 3: Affect (α×γ)", +the α/γ shorthand source. Also the same-session archaeology report +(Σ12/Fn_P(S,O)/4096 discovery pass) which this entry narrows. + +--- + +## 2026-09-09 — E-TRIPLE-MODEL-DKPOSITION-IS-AN-UNWIRED-DUPLICATE-1 — `cache::triple_model::DkPosition` is a second Dunning-Kruger enum, structurally identical to the canonical one, never touching it + +**Status:** FOSSIL FINDING (session archaeology, requested by operator during a +Σ12/Fn_P(S,O)/4096-lineage discovery pass; not an operator ruling — a +source-grounded observation to preserve before it is mistaken for wiring that +exists). Confirmed by direct read of the two enum definitions and a +workspace-wide grep of both call graphs. + +**The finding.** There are two independent `DkPosition` enums in the +`lance-graph` workspace, both four-variant, both spelled +`MountStupid | ValleyOfDespair | SlopeOfEnlightenment | PlateauOfMastery`, +and neither references the other: + +1. **Canonical MUL type** — `lance-graph-contract/src/mul.rs:100`. Computed by + `lance-graph-planner/src/mul/dk.rs::detect()` from + `SituationInput.felt_competence - demonstrated_competence`. Carries + `humility_factor()` / `is_safe()` and feeds the real MUL gate + (`mul/gate.rs`), consumed by `thinking/style.rs`, `strategy/chat_bundle.rs`, + `lance-graph/src/graph/arigraph/orchestrator.rs`, and others. +2. **Cache-local duplicate** — `lance-graph-planner/src/cache/triple_model.rs:57-62`. + Computed inside `ModelState::update_head()` purely from the local + `Truth.confidence` trajectory against hardcoded bands (`<0.3`, `>0.5`, + `>0.8`) — no `SituationInput`, no felt/demonstrated-competence gap. Its + only two consumers are both inside `cache/`: + - `lane_eval.rs::Tension::from_dk()` — selects one of four `Tension` + presets (analytical/creative/integrative/focused), which sets the + `signal_threshold()` the 4096-head `LaneEvaluator` fires against + (`lane_eval.rs:84-91,104-145`). Real, live wiring — DK position + genuinely gates candidate volume in the autocomplete cache. + - `TripleModel::evaluate_triple()`'s self/user/impact model-state + transitions (`triple_model.rs:94-99`), a closed loop with no external + input. + +**Why this surfaced.** `.claude/v3/MODULE-TABLE.md:261` already flagged the +overlap under caution ("`DkPosition` may overlap `mul/dk.rs` `DkPosition` +enum — not confirmed identical without cross-read"). Cross-read now confirms: +same variant names, same variant count, **different type, different +computation, zero shared call sites.** `cache::triple_model::DkPosition` never +reaches `contract::mul::DkPosition`, the MUL gate, `GateDecision`, or the +kanban machinery — it is a self-contained second implementation of the +Dunning-Kruger curve concept, wired only to itself and to the 4096-head lane +evaluator's tension selection. + +**Consequence — do not treat as wiring that exists.** Any future claim that +"DK position reaches the MUL/kanban gate from the autocomplete cache" is +false on current source; the two subsystems share a name and a shape, not a +data path. This is filed as a fossil (per `CLAUDE.md`'s "preserve potentially +useful fossils" discipline from the concurrent discovery pass) — not flagged +for deletion or merge. A future unification (routing `cache::triple_model` +through the canonical `contract::mul::DkPosition`) is a legitimate small PR, +but is out of scope here: this entry only records what is, not what should +change. + +**Cross-ref:** `.claude/v3/MODULE-TABLE.md` — the original hedge is on the +`cache/triple_model.rs` row, in its Notes column: "DkPosition may overlap +mul/dk.rs DkPosition enum — not confirmed identical without cross-read". +The canonical enum is `pub enum DkPosition` in +`crates/lance-graph-contract/src/mul.rs`; its detector is `detect()` in +`crates/lance-graph-planner/src/mul/dk.rs`. The duplicate is `pub enum +DkPosition` in `crates/lance-graph-planner/src/cache/triple_model.rs`, whose +only consumers are `Tension::from_dk` in +`crates/lance-graph-planner/src/cache/lane_eval.rs` and `ModelState::update_head` +in its own module. + +--- + +## 2026-09-07 — E-A-DYNAMIC-DOMAIN-MASK-IS-A-SECOND-WITNESS-AND-ITS-ALIGNMENT-IS-CALIBRATION-1 — the "horseshoe" was a category error; the equality I called a coincidence is a known-answer target + +**Status:** OPERATOR RULING (2026-09-07, two messages: *"horseshoe mask is a +category error … the only way your horseshoe mask is perfectly correct if you +created a lazylock mask from TUI over CUI to separate"*, then *"basically Dynamic +domain mask with accidentally so perfect snomedid alignment that … you could even +use it for calibration"*). Verified against the shipped consumer code and the +consumer's own census numbers. **⊘ 2026-09-07, later the same day — the +dissolution SHIPPED in the consumer on the operator's go.** `domain(D) = +static(D) ∪ dynamic(D)`; `horseshoe_mask` retired; the value half is ONE +`LazyLock` pass over the immutable bake resolving all eight domains at once. +The falsifier below RAN: the two lab masks are disjoint and equal in count +(103,291), the non-aligned domains are proper subsets in count, and the +refusal — 38,953 lane rows whose witness names no domain — is counted rather +than lost between the halves. Address half → union: lab 103,291 → 206,582 · +substance 131,582 → 254,485 · anatomy 119,684 → 119,732 · procedure 38,956 → +40,340. Three disable runs fire. The crosswalk-sweep half of the falsifier is +D-SPG-4 and has NOT run — it needs the CURIE→address resolver. +**Confidence:** High on the category error (three concrete defects, below). High +on the calibration READING. The bijection itself is CONSISTENT WITH the +cardinalities, not proven by them — proving it is what the probe is for. + +**The category error, concretely.** The consumer shipped two functions: +`domain_mask(tenants, D)` — OR over tenants whose every classid resolves to `D` +by address — and `horseshoe_mask(rows, D)` — a per-row scan of the one lane +whose address is deliberately under-determined (`FacetRegime::PerRowTui`), +assigning rows to `D` by a value-side witness at `value[0..2]`. Three defects: + +1. **`domain_mask(D)` is not the domain.** Its all-single-facet filter SKIPS the + under-determined lane, so the function named "domain" silently returns the + domain minus its multi-facet part. Substance: 131,582 returned, 122,903 more + unreported. +2. **No caller unions them.** The sole consumer prints them as two adjacent + columns. The API makes the union the caller's job and never says so. +3. **The error was written into a test as an invariant** — *"CUI is a horseshoe + lane, never folded into a domain_mask"* — which is why it survived review. + +The U-turn is a property of the VOCABULARY, not of the rows. A row in that lane +witnessing anatomy IS anatomy. "Horseshoe" names a category with no referent in +the ontology: there are domains, and one lane needs a second witness to be +assigned to them. + +**The dissolution: a LazyLock partition.** Compute once, over the immutable bake, +the value-witness → domain partition of the under-determined lane: N masks, one +per domain. Then `domain(D) = static(D) ∪ dynamic(D)`, one uniform mask, and a +row that arrived by value-witness is indistinguishable at the point of use from +one that arrived by address. `horseshoe_mask` has nothing left to return. This +also repairs a performance path: the shipped version rescans 762,041 rows per +call against tenant masks that are computed once — contradicting the same +deliverable's own gate (h) result (0.0019 amortization ratio). + +**Static vs dynamic is the two-witness rule at mask level.** `Domain::of_row` +already carries the operator's 2026-08-10 contract — *"classid AND the TUI +witness must agree"* — per row. Lifted to masks, the address-derived partition +and the value-derived partition are two INDEPENDENT readings of the same +question. Where they agree the substrate is sound; where they disagree the +disagreement LOCALISES. + +**The alignment, and what I got backwards.** Measured on the real image (consumer +census, D-SPG-2): static lab = 103,291 rows (the address-determined lab tenant); +dynamic lab = 103,291 rows (the under-determined lane's rows with a lab +value-witness). Disjoint row sets, identical cardinality. I recorded this in the +consumer ledger as *Koinzidenz* and warned readers not to derive a bridge from +it. That was the wrong direction: two disjoint sets of equal size, produced by a +bake that constructs the multi-facet lane FROM the single-facet ones, is what a +1:1 crosswalk looks like from the outside — looks like, not is: equal +cardinality on disjoint sets is CONSISTENT WITH a bijection and proves none +(two different 103,291-row sets satisfy it equally). The other domains do NOT align +(substance 131,582 vs 122,903; anatomy 119,684 vs 48; procedure 38,956 vs +1,384) — and that is not error but COVERAGE: the multi-facet lane carries only +part of those domains. Alignment is consistent with bijection; misalignment +measures reach. The bijection itself is proven only at row level — set equality +of the crosswalk's survivors against the scalar reference, or a unique +bidirectional mapping — which is exactly what gate (a) runs. Lab is the one +domain where the cardinalities PERMIT the bake to be bijective — "accidentally +so perfect" is the hypothesis the probe tests, not its result. + +**Why that is calibration, in the strict sense.** A known-answer CARDINALITY +target derived from the data's own structure — a necessary condition every +correct chain must meet, never the sufficient one; the set-level oracle stays the +scalar reference in gate (a): + +- **D-SPG-4 gate (a)** gains a target it lacked. The crosswalk is a chain of + masked equality sweeps (`spog-alpha-channel-v1.md` §3.2). A sweep from the + lab tenant across the bridge must land on exactly 103,291 rows. Any other + count is a defect in the chain — not "a number to report". The right count is + not a pass: the survivor SET must still equal the scalar reference's. +- **Gate (f) — the K0..K7 "angle"** — gains a discriminator. Until now the + immediate could only be checked for self-consistency (the eight minterms + partition the population). A bijective domain makes the CORRECT immediate the + one whose survivor set equals the reference's; every wrong immediate can now + be caught EARLY, by count alone, before the set comparison runs — a count + match admits an immediate to the set test, it does not pass it. +- **Bake drift becomes detectable for free**: `popcount(static_lab) != + popcount(dynamic_lab)` after a re-bake means the artifact or a witness moved. + One popcount, 20 ns, no join — one-directional: inequality proves drift, + equality proves nothing. + +**Falsifier.** After the LazyLock partition lands: the two lab masks must be +disjoint AND equal in count (can-fire: a bake that breaks either); a crosswalk +sweep from the lab tenant must reproduce 103,291 exactly AND its survivor set +must equal the scalar reference's (can-fire: swap the immediate; can-fire on the +set half: a wrong-but-equinumerous chain); and for a non-aligned domain the dynamic mask must be a proper subset +in count of the static one (coverage, not error — a dynamic count EXCEEDING the +static one would be the real anomaly). + +**Scoping (Foundry rule).** The value-witness → domain table is domain knowledge +and stays in the consumer. The PATTERN — an address-under-determined lane +completed by a value-side witness, resolved once into address-shaped masks, with +cross-witness cardinality as a built-in calibration — is agnostic and belongs +upstream. Read with `E-SPOG-IS-FOUNDRY-WITH-AN-ABI-SHAPED-SUBSTRATE-1` (same +day): this is the one place the address is NOT the whole ontology, and the fix +is to make it so at bake-read time rather than at every query. + +--- + +## 2026-09-07 — E-SPOG-IS-FOUNDRY-WITH-AN-ABI-SHAPED-SUBSTRATE-1 — the ontology is the ADDRESS, so cross-domain is an ordinal problem and never an integration one + +**Status:** OPERATOR RULING (2026-09-07, verbatim: *"SPOG is similar to Palantir +foundry across the Domains, with the difference that our Substrat is ABI +shaped"*). Completes `E-LANCE-GRAPH-OWNS-THE-AGNOSTIC-THINKING-CONSUMERS-BIND-DOMAIN-1` +(same day), which named WHO owns the thinking; this names WHAT SHAPE it has. +**Confidence:** High. The partition below is measured on the real artifact; the +consequences are entailments of the shape, not projections. + +**The comparison, and the one difference that changes everything.** + +| | Palantir Foundry | SPOG | +|---|---|---| +| how domains are unified | mapped onto a shared **object** layer | mapped onto a shared **address** space | +| what a domain is | an object type in an ontology | a tenant `G = classid >> 16`, a contiguous ordinal window | +| relating two domains | traverse links / **join** object sets | **AND two masks** over the same base ordinals | +| what the engine must do | plan and execute the join | index a ternlog immediate | + +Foundry's ontology is a semantic layer ABOVE heterogeneous stores, so +cross-domain reasoning is an integration act and a join is the mechanism. SPOG's +ontology IS the address, so cross-domain reasoning is an ordinal-range act and +there is nothing to integrate. + +**This is why "no joins ever" is substrate, not preference** (operator, same +session: *"datafusion does joins, we do masking Ops, no joins ever"*). A join +materialises the rejected world — two relations in, a third out. Under an +ABI-shaped substrate the operand is already one image, so the complement holds: +`resident ⊗ A ⊗ B ⊗ C`, and the rejected volume never becomes a representation. +A query planner here is not an expensive way to do the job; it is a way to do a +DIFFERENT job that this substrate does not have. + +**Measured, and it is the ontology layer.** `all-lanes.soa`: 762,041 rows, 16 +distinct `graph_of` tenants that **PARTITION** the image — Σ of tenant counts and +the union of tenant masks are both 762,041, no row in two tenants, every tenant +count equal to the sum of its constituent classids' windows (D-SPG-2). A Foundry +deployment would call that an object-type registry; here it is a fact about where +bytes sit, and the tenant mask is 95,256 B — L2-resident, so the whole "ontology" +is a cache-resident bitmask. + +**Consequence — the SPO triple is ABI-shaped too.** A triple is not three columns +to be joined. `mask_ternlog::(S, P, O)` computes `IMM[(s<<2)|(p<<1)|o]`, so +the immediate's eight bits ARE the eight presence-projections K0..K7 of one quad +row, and the six wirings of S/P/O onto A/B/C are the six angles (§4 of +`spog-alpha-channel-v1.md`). Subject, predicate and object are three bits +indexing a constant, not three relations. + +**Consequence — it renames the open problem, which changes what gets built.** +MedCare-rs #620 measured **0.00 % cross-tenant `is_a` edges**: a disease's +subsumption spine never leaves the disease ontology, and only the RO cross-axis +crosses. Read as Foundry, that is a missing link type and the fix is a +crosswalk join table. Read as SPOG, it is an **address** result: the CURIE→address +resolver has not minted so that a cross-domain relation is address adjacency. +Same measurement, opposite deliverable — and the second one is the one that keeps +the 20 ns regime. + +**Falsifier.** Any design that reaches for a join, a lookup table, or a +mapping service to relate two domains, instead of asking what address layout +makes them adjacent in one image. Also: any claim that a tenant boundary needs +enforcement machinery — the partition is a property of the keys, and +`AlphaFocus::cross`'s `ptr::eq` on the base slice is the only "provenance" the +shape admits (gate (d), re-scoped this session). + +--- + +## 2026-09-07 — E-LANCE-GRAPH-OWNS-THE-AGNOSTIC-THINKING-CONSUMERS-BIND-DOMAIN-1 — the Foundry split, and why four separate violations in one session were one violation + +**Status:** OPERATOR RULING (2026-09-07, verbatim: *"lance-graph owns the +agnostic thinking / Akin to Palantir foundry"*), given after catching a +consumer-side reimplementation of the owned writer. +**Confidence:** High on the rule. The `spog_masks` consequence below is measured +against the shipped code; the BBB placement question it raises is OPEN. + +**The rule.** lance-graph is the platform: it owns the ontology (contract types) +and the OPERATIONS — the mask algebra, the cognitive cycle, the writer, the +temporal read. A consumer (MedCare-rs, woa-rs, smb-office-rs, …) is a tenant: it +supplies DOMAIN SHAPE and consumes thinking. It never implements thinking, and it +never implements substrate. This restates MedCare's own commitment #4 (*"Thinking +lives only in lance-graph. No `medcare-thinking` duplicate crate"*) as a +POSITIVE architecture rather than a prohibition, which is what makes it +checkable. + +**Why it is worth an entry: it collapses four findings into one.** In a single +session the same agent wrote, in a consumer, a sealed-cycle writer +(`LanceCycleWriter`'s job), a version successor (`sealed_version = base_version ++ 1`, a verified identity inside that sink), a version-pinned read +(`temporal::QueryReference::at`), and a second copy of the rung × tenant cross +(`AlphaFocus::{cell, unlooked}`, shipped upstream in #1220). Each was caught +separately and each looked like its own mistake. Under the Foundry split they +are one mistake with four faces: **platform-side work performed tenant-side.** + +**The demarcation is not "is it generic code", it is "is it domain +knowledge".** Measured on `medcare-cohorts::spog_masks`: + +| function | what it does | owner | +|---|---|---| +| `tenant_masks` | sweep distinct classids, OR-fold per `graph_of` | **agnostic** — nothing medical | +| `rung_tenant_cell` | AND of a rung mask and a tenant mask | **agnostic** | +| `unlooked` | tenant AND-NOT any-rung | **agnostic** | +| `domain_mask` | which Gs constitute a `Domain` | **tenant** — domain knowledge | +| `horseshoe_mask` | the per-row TUI fence for the U-shaped lane | **tenant** — domain knowledge | + +Three of five are thinking that a tenant is carrying. The tell is that the first +three can be written without knowing the word "medical", and the last two cannot. + +**Consequence — F5 in `spog-alpha-channel-v1.md` was mis-framed by its own +author.** It recorded "scalar `AlphaFocus` (#1220) vs SIMD `spog_masks` +(D-SPG-3)" as an open OPERATOR PREFERENCE. It is not a preference: the cell +belongs upstream by this rule, and the tenant should call it. What remains open +is narrower and genuinely architectural — **where an ndarray-backed mask algebra +can live**, given that `lance-graph-planner` is BBB-forbidden in a customer +binary (Iron Rule 1) and `lance-graph-contract` is zero-dep by construction. A +contract feature-gate, or a new BBB-allowed crate between them, are the two +shapes; neither is this entry's to choose. + +**Falsifier.** For any function in a consumer crate, ask whether it can be +written without naming the domain. If yes and it is not a thin call into +lance-graph, it is thinking in the wrong repo — regardless of how mechanical it +looks. Masks feel like data and slipped through this test for a whole +deliverable. + +Read with `E-A-CONSUMER-THAT-OPENS-A-DATASET-HAS-ALREADY-LOST-1` (same day, the +writer half) and `E-TOPOLOGY-MASKS-MAGNITUDE-COMPOSE-NEVER-COLLAPSE-1` (same +day, what the operations ARE). + +--- + +## 2026-09-07 — E-A-CONSUMER-THAT-OPENS-A-DATASET-HAS-ALREADY-LOST-1 — re-deriving a proven identity from outside the thing that proves it is the tell + +**Status:** FINDING, operator-caught (2026-09-07: *"that's not a convenience you're +violating lance-graph 879 batchwriter SOA owned"*, then *"879 909..912 1049 1198"*). +Verified against the merged code and the #879/#911/#912 arc entries. +**Confidence:** High — every property below is quoted from the shipped module docs. + +**What I did.** Writing D-SPG-6 ("sealed batch per cycle"), I wrote a free +`async fn seal_alpha_cycle` in a CONSUMER that did `Dataset::open` to read the +version, computed `cycle = version + 1`, and `Dataset::write`-appended. I +justified it as convenience — reaching for the `lance` umbrella crate because a +neighbouring function already did. That framing was wrong twice over: it was not +convenience, it was an ownership violation; and the DataFusion weight I was +worrying about was a symptom, not the disease. + +**What already existed.** `LanceCycleWriter` (`lance-graph::graph::cycle_sink`, +#911 → #912 Phase A) is the **SOLE application writer**, and the topology is +enforced by the TYPE: non-`Clone` (a second handle cannot be minted), +`commit_cycle(&mut self, …)` (two commits cannot interleave), one long-lived +owned `Dataset` handle (no per-operation reopen). The 64k SoA owners are +*"parallel PRODUCERS (fire-and-forget: they cast on behalf of their mailbox and +receive no acknowledgement), never Lance writers"*. + +**The four properties my version lacked**, each hard-won in a review round: + +| shipped | mine | +|---|---| +| sole writer, non-`Clone`, owned handle | a second unowned writer, reopening per call | +| producers cast, never write | consumer written as a Lance writer | +| **no semantic change → no write → no version** (#911's empty-cycle versioning REMOVED) | wrote unconditionally — an empty saccade mints a version | +| no rollback; durable `(cycle, batch_hash)`, reconcile FIRST, `HashConflict` fails closed | read-version-then-append: a TOCTOU | + +**The sharpest of them.** `Append` in Lance **rebases even on a single attempt** +(strict no-rebase exists only for `Overwrite` — measured in +`lance-9.0.0/src/io/commit.rs`). So my "refuse, not renumber" guard — read the +version, compare, then append — *cannot do what its own error message claims*. +#911 first fixed this with a compensating `Dataset::delete`; #912 then REMOVED +that too, because a published manifest is HISTORY and a delete is another +version, not a rollback. I had reinvented a mechanism that was already tried and +already superseded. + +**The transferable tell, and it is cheap to check.** +`sealed_version = base_version + 1` is recorded on the #911 entry as *"a verified +identity, not an assumption"* — verified INSIDE the sink, which is what lets +readers derive the cycle↔version mapping from the co-committed frame row with +zero sidecar state. **I re-derived that identity from outside the component that +proves it.** Whenever code computes `next = current + 1` for state another +component owns, the question is not "is the arithmetic right" (it was) but "who +is entitled to say this" — and if the answer is a type you did not call, the +write is already an orphan. A consumer that reaches for `Dataset::open` has +answered that question wrongly before writing a line. + +**Why the DataFusion weight was the symptom.** Bypassing the owned writer meant +reaching for the `lance` umbrella crate, which drags the query engine in +transitively. Operator, same session: *"datafusion does joins, we do masking Ops, +no joins ever"* — a join materialises the rejected world (two relations in, a +third out), which is the exact complement of `resident ⊗ A ⊗ B ⊗ C`. The +crosswalk is the thing that LOOKS like a join (MONDO ↔ CUI ↔ LOINC ↔ SNOMED) and +is a chain of masked equality sweeps (§3.2), so there is no join formulation to +carry. Read against +`E-TOPOLOGY-MASKS-MAGNITUDE-COMPOSE-NEVER-COLLAPSE-1` (same day): a query engine +on this path is a fourth thing that collapses topology, masks and magnitude back +into relational algebra. + +**Falsifier.** Any consumer-side `Dataset::open` / `Dataset::write` in the +alpha/mask chain; any caller computing a version successor for state it does not +own; any cast payload carrying owned rows rather than a `(mailbox, row-range, +cycle)` descriptor. The withdrawn implementation is banked in the session +scratchpad as the worked example rather than deleted, because the four-row table +above is only legible next to the code that got each row wrong. + +--- + +## 2026-09-07 — E-TOPOLOGY-MASKS-MAGNITUDE-COMPOSE-NEVER-COLLAPSE-1 — Mississippi Queen, TERNLOG chaining and BLASGraph pay for ONE operation, from three sides + +**Status:** OPERATOR RULING (2026-09-07, verbatim in substance), recorded on +`spog-alpha-channel-v1.md` §4 and here; the boundary rule is binding for +D-SPG-4/5/6 and for the F5 open question. +**Confidence:** High on the decomposition and the boundary (operator's word; +consistent with the measured 0.0019 amortization ratio of D-SPG-2 and the +corrected #620 fan-out result). [H] on the per-rung independent propagation — +argued, not yet measured. + +**The operation.** *Deciding what remains eligible without materializing the +rejected world.* Three mechanisms pay for it: **Mississippi Queen** = reveal +geometry / exploration budget (topology says where activity MAY go); +**TERNLOG masks** = Boolean eligibility / inhibition (where activity IS ALLOWED +to go); **BLASGraph** = numeric propagation over the survivors (HOW MUCH goes +there). The hexagon was never the point — degree-6 was falsified repeatedly; +what survived is the economics of revealing only what can matter next, which is +why fan-out loses in #620 (reconvergence forces inspection of redundant edges), +not because hex degree is special. TERNLOG's prize is **amortized +eligibility** — `resident ⊗ A ⊗ B ⊗ C`, the rejected volume never becoming a +second representation — and it wins only while the working masks stay resident +(gate (h): 0.0019 of a rebuild), collapsing toward bandwidth parity as depth +blows the cache. **Alpha is the sparse, readable record of which part of the +potential field actually fired** — the readout plane, not plumbing. + +**The boundary rule (binding).** The three COMPOSE and never collapse: the MQ +hexagon does not become a TERNLOG immediate; the immediate does not become a +neural weight; BLASGraph is never used for Boolean elimination because a matmul +can encode it. *Topology chooses neighborhood, masks choose admissibility, BLAS +chooses magnitude.* Reads back onto §4's "same bit" interjection: mask bit = +projection bit (true by the immediate's index construction) — NEVER mask bit = +weight. + +**The consequence for the rung × G cross (#1220, D-SPG-3).** The numeric leg +can run independently per rung, `R_r × G → mask → propagation`, r ∈ 0..=9, with +alpha as the common readout plane where the ten fields overlap — so +meta-awareness observes field INTERSECTIONS instead of "running the ten rungs". +This is the frame for F5's open question (scalar `AlphaFocus` vs SIMD +`spog_masks`): the cell is a readout surface, the propagation a separate rail; +neither owns the other. + +**Falsifier.** A design in which one of the three does another's job — a +ternlog immediate carrying magnitude, a BLAS kernel doing set elimination, a +topology hop encoded as a mask constant — is the collapse this entry forbids; +the reviewer's question on every D-SPG PR is "which of the three is this, and +does it do only that". Motto as given: *"Don't compute the world. Narrow what +can matter, then spend arithmetic only there."* + +--- + +## 2026-09-07 — E-AN-EMPTY-RANGE-AFTER-A-RESET-IS-NOT-EVIDENCE-1 — the check that certified the loss it was run to prevent + +**Status:** FINDING, measured. The orphaned commit was recovered; the board it +mis-recorded is corrected in the same PR (#1217). +**Confidence:** High — `git merge-base --is-ancestor` and `git fsck` both +executed, and the recovered commit is byte-identical to what was written. + +**What happened.** `.claude/plans/nodeguid-new-repurpose-audit-v1.md` — SPEC v1 +of the 5+3 council auditing a `NodeGuid::new` repurpose — was committed +(`3dd98b2b`), then orphaned by a `git checkout -B origin/main` run +while it was still unmerged. It never reached `main`. + +**The check I ran was real, and it certified the loss.** Before the *second* +reset I ran `git log --oneline origin/main..claude/great-curie-d2ufyl`, read the +empty output as "nothing unmerged to preserve", and proceeded. The output was +empty **by construction**: an earlier reset had already re-pointed the branch AT +`origin/main`, so the range was empty precisely BECAUSE work had just been +orphaned. **The symptom of the failure is indistinguishable from the all-clear.** + +**The rule.** `origin/main..` answers "what does this branch carry that +main does not" — a question about the branch's CURRENT tip, which a reset has +already destroyed. The check has to run BEFORE the reset, or against +`git reflog `, which is the only local record that survives one. State +the same thing positively: **verify unmerged work against a ref the operation +you are about to perform cannot move.** + +**The second half — a stale record that no gate could catch.** The board then +recorded the opposite of the truth: #1201's arc entry carried a self-correction +saying that PR "merged MIXED" because the spec commit was pushed to it +afterwards. It was not; #1201 merged hygiene-only, exactly as its own body said, +and for a day `LATEST_STATE` and `PR_ARC_INVENTORY` cited a plan file that +existed nowhere. **The citation-decay gate could not see it, because the board +cited a PATH, not a SYMBOL** — an absent file reads as a valid reference where +an absent symbol does not. Same shape as the citation-decay failure on #1203, +one level up: a coordinate in a moving frame, trusted as an anchor. + +**Consequence, narrow and mechanical:** a board citation to a plan or artifact is +only as strong as something that fails when the target is gone. Until a +path-existence check exists, a PR that adds a board reference to a file should +be the same PR that adds the file — never a later one, and never a claim that a +prior PR added it. + +--- +## 2026-09-07 — E-THE-FUSED-AND3-HOP-WAS-NEVER-SHIPPED-LGJ-HOP-IS-TWO-ANDS-1 — a mapping entry cited a call site that does not exist + +**Status:** FINDING, measured (grep `ternlog|AND3` over `lance-graph-java/native/lgj-abi/src/*.rs` at lgj `dbac826`: **0 hits**; `lgj_hop` read in full, `exports.rs:1712-1860`). Corrects `E-NXG-8` (2026-09-05, below) and `.claude/knowledge/membrane-tiers.md` §"The polyfill is the worked instance" (⊘ in place, same commit). Spec that carries the correction forward: `.claude/plans/spog-alpha-channel-v1.md` §1a/§4/§8. +**Confidence:** High. The absence is a full-file read plus an exhaustive grep, not an inference. + +> **⊘ 2026-09-07 — FALSIFIED BY CURRENT LGJ HEAD `8720d1d`. The finding held only for the stale pin.** +> +> The measurement above is correct *for `dbac826`* and wrong as a statement about +> lgj. At `8720d1d` (2026-09-05, the branch tip this repo can reach), `lgj_hop` +> dispatches ONE call — +> `kernels::simd_mask_ternlog_assign::<{ kernels::ternlog::AND3 }>` (`exports.rs:1816`) +> — `kernels.rs:100` is `pub use ndarray::simd::ternlog;`, `kernels.rs:111` is the +> `simd_mask_ternlog_assign` wrapper, and **`simd_mask_and_assign` +> does not appear in `exports.rs` at all**. The two-AND → ternlog collapse shipped +> **2026-09-04** (lgj `LATEST_STATE.md`, measured 3.5–5× on the columnar-hop bench). +> +> So the correct historical statement is not *"fused `AND3` never shipped"* but +> **"fused `AND3` was absent at the stale pin `dbac826`, and shipped before this +> audit was written."** Three consequences: +> +> 1. **`E-NXG-8`'s `AND3` row is VINDICATED, not regraded.** *"`AND3` = conjunctive +> narrowing (`lgj_hop`, shipped)"* is true at HEAD. The ⊘ this entry put on its +> Confidence line is itself withdrawn (second dated note there). +> 2. **`membrane-tiers.md`'s original sentence is RESTORED.** *"`exports.rs` names +> `kernels::ternlog::AND3`"* was true; the "correction" replaced a true sentence +> with a false one — and did so four lines above that file's own Provenance +> paragraph, which names *"the two-AND→ternlog conjunction (T2 hand-composing a +> T1 op; fixed by naming the op at T1)"* as **one of the two fixes the tier +> doctrine was derived from**, dated 2026-09-04. The entry denied the doctrine's +> own founding receipt. +> 3. **"the FIRST production-shaped ternlog consumer" is wrong.** `lgj_hop` is, and +> has been since 2026-09-04. The SPOG cross would be the second. +> +> The regrade to OPPORTUNITY is withdrawn; the P3 amortization caveat survives on +> its own terms (it is about the SPOG cross's shape, not about lgj). +> +> **What survives, and it is the more useful half:** a board claim pinned to a +> foreign repo's sha decays silently, and the decay is invisible from inside this +> repo — no gate here reads lgj. Evidence is now repinned to `8720d1d`; the +> `dbac826` measurement stands as historical evidence of that commit only. This is +> the mechanism `ISS-LGJ-CROSS-REPO-CITATION-GOES-STALE-SILENTLY` (lgj's own +> ISSUES.md) names from the other side — the same defect, found independently in +> both directions within four days. + +**The claim.** `E-NXG-8` mapped the eight named ternlog immediates to cognitive homes and wrote *"`AND3` = conjunctive narrowing (`lgj_hop`, shipped)"*; `membrane-tiers.md` illustrated the T1/T2 stacking with *"`exports.rs` names `kernels::ternlog::AND3`, never `ndarray::simd` directly."* Both read as shipped code. + +**The tree.** `lgj_hop` composes `selected_f = src ∧ class_f ∧ struct_f` as TWO sequential `kernels::simd_mask_and_assign` calls (`exports.rs:1818` then `:1822`), after `simd_rowstore_u32_eq_mask` for each of `class_f` and `struct_f`. `kernels.rs` (1,409 lines, read in full) exports `simd_eq_u32_to_mask`, `simd_gt_i32_to_mask`, `simd_mask_{and,or,andnot}(_assign)`, `simd_masked_sum_i32`, `simd_popcount`, `simd_rowstore_u32_eq_mask`, `simd_rowstore_classid_mask`, `simd_rowstore_facet_match`, `masked_facet_sum` — no ternlog wrapper of any name. The named immediates ARE consumed by name in this repo, at exactly one place: `crates/lance-graph-planner/examples/probe_nxg_hist_1.rs:51-136` (`AND_ANDNOT2` as the bucket, `AND3` as its can-it-fire twin). That is a probe, not a hop. + +**Regrade.** The fused `AND3` hop is an **OPPORTUNITY** (and a measurable one — the P3 amortization reads 0.50 at K ≥ 8 only while the masks fit L2, temporal 09), not a shipped site. `E-NXG-8`'s other seven rows are untouched by this finding; only the `AND3` row's parenthetical is wrong. Consequence for the doctrine doc: a T1/T2 illustration must cite a line that exists — the corrected line in `membrane-tiers.md` now names the real stacking (`exports.rs` → `kernels::simd_mask_and_assign` → `ndarray::simd::mask_and_assign`), which is the same shape and true. + +**Why it matters beyond one sentence.** The SPOG alpha spec (`spog-alpha-channel-v1.md`) builds a rung × tenant cross on `mask_ternlog` and had inherited "the hop already does this" as a premise. It does not; the cross is the FIRST production-shaped ternlog consumer if it lands, and its gate (c) measures whether fusion pays on that shape rather than assuming it from a citation. + +## 2026-09-07 — E-A-PLAN-INVENTORY-FINDS-THE-BOARD-LAGS-THE-TREE-IN-BOTH-DIRECTIONS-1 — status cells decay at the rate of the tree, not of the file + +**Status:** FINDING, measured (five read-only Sonnet agents; every claim below re-verified by the orchestrator at a tree line, not a tag-file line). Full census: `.claude/board/PLAN-INVENTORY-2026-09-07.md`; evidence: `exec-runs/plan-inventory-2026-09-07-*.md`. +**Confidence:** High for every `file:line` row; the D-id coverage percentage is measured on the A–K half of `.claude/plans/` only. + +**The numbers.** 211 plans: 149 OPEN, 13 CLOSED, 9 SUPERSEDED, 40 AMBIGUOUS (35 with no status line at all — 22 of them the batch-landed `3DGS-*` design genre). V3 waves: W0 closed; W1 mechanism closed, adoption partial; W2 partial and self-contradictory; W3/W4 partial; W5/W6 open, W6's premise rescinded. W1a SIMD: 4/5 shipped, GATHER partial (API on every backend, x86 body a scalar polyfill). W1b: 0/5 TD entries closed, 1/7 files migrated (179 raw-intrinsic lines across five crates). W1.5: #6, #7 shipped and consumed, #8 unbuilt but ungated. + +**Direction one — docs still say Open for work on `main`.** Five `TECH_DEBT` rows said `Open` for primitives that have been on ndarray `master` for months (`simd_scalar.rs:1684,1709,1799,1887,1916`); W1.5 #7 said `Deferred` while `ndarray/src/hpc/randomized_signature.rs:292` ships it and `sigker/src/randomized.rs:124` consumes it — a THREE-way inconsistency, two knowledge docs having said SHIPPED since 2026-09-02; `STATUS_BOARD` D-LNC-5a/D-MW-P2 read `In PR #1198` with #1198 merged (`3797237b`); ENTROPY M2 said `QUEUED` nine weeks after D-PERT-1 shipped; `compiled-templates.md` said `StepMask` does not exist eight weeks after it did; `self-reasoning-substrate-v1.md:15` says "doc-only, no code" over four D-SRS rows that read Shipped with 147 tests between them. All but the last two are regraded in this PR (append-only strike-through with the tree line). + +**Direction two — docs still carry a rescinded premise or an unminted id.** `D-CCF-4` (the `0x1000` retirement) was RESCINDED on 2026-07-03 and sat on `STATUS_BOARD:950` for nine weeks while `INTEGRATION-PLAN.md:110`, `routing.md:104-106` and the primer §5 kept describing the marker as temporary with a 100 %-adoption trigger — no V3 file carried the rescission. W2a is stated two incompatible ways in ONE file (Addendum-12a: a new gated `BoardAggregates` tenant; Addendum-15: "SHIPPED as `ValueTenant::Kanban`", the per-ROW tenant its own sibling doc calls a sibling, not a substitute). `D-GRAPH-1`, `D-TRUTH-1`, `D-INFER-DEDUCTIONS-RELATION-BLIND` are cited by two plans and exist on no board row. + +**The gap the board already names, re-measured.** `ISS-PLAN-TRACKING-IS-UNENFORCED`: on the A–K half, **314 of 559 D-id citations (56 %) have no `STATUS_BOARD` row; 26 plans have zero coverage**. Two instrument traps, both caught: the regex `D-[A-Z]+(-[A-Z0-9]+)+` matches the tail of `E-READ-NOT-GREP` as `D-NOT-GREP` (81 false positives across 43 files); and the house style `D--N` is a *finding* citation, not a deliverable — "no board row" is evidence only after the id's grammar is checked. `INTEGRATION_PLANS.md` names 58 of 211 plan files nowhere. + +**The harvest was invisible from V3.** `.claude/v3/` referenced neither `.claude/nexgen/` nor the 2026-09-01 literature harvest; its every "nexgen" meant `openproject-nexgen-rs`. Nine mirrors landed (README row, primer §5/§6, INTEGRATION-PLAN, routing, compiled-templates, ENTROPY M27, COMPONENT-MAP §6, FUTURE-DESIGN, witness-lane P5) and the nexgen plan links back. + +**Verification reshaped one finding — which is why the agents' files are evidence, not verdicts.** The top-level agent reported "two cited plan paths that do not exist"; both are cross-repo citations (`INTEGRATION_PLANS.md:2018` → tesseract-rs, `:2339` → ndarray) misread as local. The agent that hedged "#7 not yet wired into sigker" was wrong in the OTHER direction — it is wired. The rule this leaves: **a status cell is a claim about the tree, so a regrade cites the tree (`file:line` on the branch), never the report that noticed it.** + +## 2026-09-07 — E-EVERY-DOMAIN-IS-A-TABLE-AND-A-CROSSWALK-IS-A-CHAIN-OF-MASKS-1 (OPERATOR-RULED) — no DataFusion joins, ever; the six blockers were read-time re-derivation + +**Status:** RULING (operator, 2026-09-07, verbatim below) + FINDING for the mechanism mapping (every site `file:line`) + CONJECTURE for the throughput claim until PROBE-CROSSWALK-MASK-1 runs (IDEAS 2026-09-07). +**Confidence:** High on the sites and on the bounds (all measured in `gemm-ternlog-mask-consolidation-v1` §12–§13 and D-GTM-0n/P3); medium on the unification until one probe joins two legs. + +**The ruling.** *"i mean every domain is just another table keyed by CUI STDID (snomed) loinc etc — its a chain effect with masking, no datafusion joins ever."* + +**What it dissolves.** Every open blocker in the SPOG / alpha / medcare / DataFusion arc is the same shape: **something decided once upstream is re-derived at read time, per row.** The ontology category is stamped into `value[96]` and read back per row (`medcare-cohorts/src/obo_store.rs:16-18,77,681`); `Domain::of_row` classifies per row (`orphanet.rs:165`, `rails.rs:432`); `FacetRegime::PerRowTui` resolves the regime per row (`domain_block.rs:259,695`, `quad_tenant.rs:169,215`); `graph_of(addr)` is right in direction (G read from the key, `contract/src/spog_tenants.rs:38`) but resolved per claim by a linear scan over tenants (`:87`); V1 external-id identity re-derives the row from an id the key already is; and Lance row identity is re-materialised by the scanner (`medcare-server/src/state.rs:900,936` `with_row_id = true`, `with_row_addr = true`). One table per G removes the first four reads (the domain IS the table); V3 lane-local addresses remove the fifth; containment removes the sixth. + +**The mechanism, named at T1.** The quad's 4×24 slots are four pre-resolved foreign keys — slot 0 the own key; CUI present in 8/8 domains as the hub; FMA the anatomy↔imaging bridge; ICD↔MONDO inside disease. A crosswalk is a chain: `eq_u32_to_mask` over table n's FK column (`ndarray/src/simd_int_ops.rs:562`), `mask_ternlog` with the incoming survivors (`:983`; `AND3` / `AND_ANDNOT2` by name, `membrane-tiers.md` T1), and the survivors' key set is the needle set of table n+1. **Nothing is joined: the mask-out of hop n IS the mask-in of hop n+1.** The one forbidden move is a mask-AND across two tables — that is a join in disguise, and it is exactly what the nexgen plan's room 18 already rejects at the seal ("a derived read that has to AND masks from two semantic families is a violation"). This is the schema-level form of the mask plan's own invariant (§11: *substrate == mask geometry == projection surface*). + +**The bounds that ride with the claim (none may be dropped when it is cited).** D-GTM-0j: masks win on Boolean relations at EVERY density (297× vs dense f32) — the boundary is TYPE, not density; a hop that must accumulate a value (evidence strength, NARS frequency) is not a mask hop and goes to the valued arm (blasgraph semirings over CSR; D-GTM-0g, the CSR SpMV arm, is unrun). D-GTM-0k: 0 bytes/step, by a counting allocator. D-GTM-0n/P3: chaining pays (`T3/T1` → 0.50 by K=8) only while the masks stay L2-resident (ratio back to 1.03 at a 512 KiB mask) and only above ~0.1 % active — a crosswalk hop that thins the survivors below that must switch to sparse. D-GTM-0l: packed-prefix routing does NOT carry long-range relations (1.08× at k=3 on physical addresses) — cross-domain hops ride the FK columns, never prefix locality between tables. `E-Q8`: six-neighbourness does no work — no neighbourhood structure between domains is assumed. + +**The unblock order (the dialogue's, confirmed against the tree).** (1) one table per domain — SPOG-aware bakes, one artifact per G; (2) V3 lane-local addresses (the mint side already bangs on V1: `E-A-V3-MINT-MUST-NEVER-DEGRADE-TO-V1-1`); (3) `ogar-r2il` gets its first consumer via `lance-graph-ogar` — today it has none (only `OGAR/Cargo.toml` names it); (4) DataFusion containment — both scanner flags off, pinned by a test, no new surface (`E-PLANNING-MIGRATES-TO-LOCO-R2IL-DATAFUSION-IS-GRACE-PERIOD-1`). Order matters: (4) before (1) leaves the consumer with no identity but the flags. + +**Falsifier.** PROBE-CROSSWALK-MASK-1: survivor SETS identical to the DataFusion path on one fixture; if they differ, the FK reading of the slots is wrong before the algebra is. + +## 2026-09-07 — E-SEVEN-HARVEST-SOURCES-ONE-OBJECT-THE-VERSION-KEYED-MASK-SET-1 — Mississippi Queen, Shannon, EWA, known unknowns, ternlogq and blasgraph are readings of `NestedBands` + +**Status:** SYNTHESIS [H] — each leg cites a measured or ruled source; the unification is unmeasured until a probe joins two legs (the first candidate: PROBE-CROSSWALK-MASK-1 + the `SettlementCell` classifier, IDEAS 2026-09-07). +**Confidence:** Medium. The legs are [G]/[H] individually; "one object" is the claim under test. + +- **Mississippi Queen** (`ndarray/.claude/plans/gemm-ternlog-mask-consolidation-v1.md` §9–§11): reveal-ahead-of-cursor (M1), tile-serves-every-boat with cache key `(mask generation, panel index)` (M1b), the ±1 lookahead ladder (M2), the coal budget for re-chaining (M3). The nexgen plan's room 10 says time travel is free because every `NestedBands` is version-keyed and never rewritten. **These are one cache: the mask generation IS the Lance version**, and the coal budget IS the rollover budget (D-NXG-5). Do not build a second invalidation scheme. The hexagon was regraded [S]→[H] and `E-Q8` shows degree-1 matches hex to four decimals at 5.5× less memory — what survives of the board is the reveal and the budget, not the tiling. +- **Shannon** (`entropy-closure-causal-ground-v1` §4; nexgen E-NXG-19): entropy measures WHERE closure is, never WHAT kind of hole (CE64 59–60) nor HOW it may be asserted (61–63); measured, entropy LAGS the popcount budget by five steps on a real shift and is the did-the-split-help read (0.834 → 0.912), not the timer. The literature harvest's greedy INFO_GAIN Ω(n/log n) bound adds: hop order by expected survivor reduction is near-optimal — a sort over popcounts, no planner. +- **EWA** (`jc/src/ewa_sandwich.rs`; `mul-ewa-trust-propagation-v1` §0a/§0b; lit-harvest #27 — three operations share the word): the sandwich is certified NUMERICALLY only (PSD ≥ 0.999, tightness 1.467×); "geometry decides WHERE, never WHAT" (F-MEP-0a) and the closed-graph monotonicity STOP (F-MEP-0d) are the fences. On a crosswalk hop the discrete Σ trace already exists: `popcount(survivors)`. EWA may rank which hop to explore; it may not elevate a survivor to a fact. +- **Known unknowns** (`entropy-closure` SettlementCells; `epistemic-quadrant-materialization-v1` §4c–§4e; `mul-ewa` "the pothole is a TYPED ABSENCE"): a known unknown is a hop whose survivor mask has popcount > 1 — alternatives = the mask, discriminators = the FK columns not yet swept, evidence needed = the sweep. Crystal / Glass / GroundedUnresolved / Fog read off `(popcount, discriminator present, FK grounded)`; ADMIT = the column exists, BUDGET = popcount, PERMIT = `ReasoningBand`, TEST = the sweep. The fork-return rule holds unchanged: only the elimination (the mask) comes back. +- **ternlogq** (`membrane-tiers.md`; OGAR #298; nexgen rooms 4/18/20): `TERNLOG 0x86` is the only surviving loco call and its value byte is the program; the eight named immediates are a complete mask ISA; room 18's family-separation rule is the mechanical "no joins". A crosswalk program = `RANK` + `TERNLOG` per hop. +- **blasgraph** (`SYNERGY-MAP-S00-S07` §8.0; D-GTM-0j): integer-only HDR semiring algebra, no splat; the boundary with masks is TYPE — Boolean relations are masks, valued relations are semirings over CSR (D-GTM-0g unrun decides where). K0..K7, the SPO 2³ triadic projections, are the eight Boolean masks of one quad row. + +**One object.** The shipped struct is version-keyed over one column with no classid: `pub struct NestedBands` at `crates/lance-graph-planner/src/nested_bands.rs:91-105`. A sealed NestedBands + overlap matrix per (classid, version) is the nexgen plan's PROPOSED room-26 shape, not the shipped D-NXG-1 key (Codex review on #1218 caught this entry's first draft implying the key was shipped) — read by each source its own way — search, monitoring, rank, basin, drift, quorum, hop order, known-unknown census (nexgen room 26 said as much before the crosswalk reading existed). **The fence that keeps it one object and not a god-field:** rung, band, plasticity and "style as a byte string of immediates" are four different things (next entry). + +## 2026-09-07 — E-RUNG-BAND-AND-PLASTICITY-ARE-THREE-AXES-NEVER-ONE-LEVEL-FIELD-1 — level of processing, level of assertion, and how content changes do not share a byte + +**Status:** FENCE (operator caution 2026-09-07 — "rung 0–9 and bits 61..63 must never be folded into one level field" — on top of two prior rulings). +**Confidence:** High — three shipped carriers with three cardinalities. + +- **Rung 0–9 = level of PROCESSING**, a temporal horizon: the `RungLevel` discriminant (`cognitive_shader.rs:157`), consumed by `EpistemicMode::for_rung` (`planner/src/temporal.rs:87-97`: 0..=4 Strict, 5..=8 Aware, 9 Retro) — it decides which versions a reader may see. Ten values. +- **`ReasoningBand` bits 61..63 = level of ASSERTION**, Tarski permission (`entropy-closure-causal-ground-v1` §4; `causal-edge::layout`) — it decides what a settled closure may be asserted as. Eight values. `ISS-RUNG-VS-BAND-CARDINALITY-COLLISION` (2026-08-26) already records that the two share endpoint names with different cardinalities, and `ISS-REASONING-BAND-GATES-NOTHING` that the band gates no control loop yet — the temptation to "just use rung" is live. +- **`PlasticityState` 3-bit S/P/O = how content CHANGES** (`causal-edge/src/plasticity.rs`); `epistemic-quadrant-materialization-v1` §4b refused "STDP = rung 3" for exactly this reason — *a rung says what content IS, a plasticity mode says how it CHANGES; different axes* — and the substrate already agrees (per-plane hot/frozen is axis-local). +- The nexgen "thinking style = a byte string of immediates" (room 4) is a **fourth** thing, a program, not a level. + +**Consequence for the chain-of-masks reading:** PERMIT is the band; the readable horizon is the rung; the mask is neither. **Falsifier / gate:** any struct, enum or lane that stores two of the three in one field, or any `level: u8` that is read as more than one of them, is a LAYOUT-BREAK-class defect (`v3-envelope-auditor` verdict); a `/v3-audit` grep for such fields is the cheap pre-commit check (not yet added — recorded so the next session adds it rather than re-deriving the fence). + +## 2026-09-07 — E-PLUG-AND-PLAY-IS-THE-DECLARATION-NOT-A-TABLE-1 — my fix rebuilt the lockstep it was closing + +**Status:** FINDING, measured. Fixed in the PR that landed this entry, #1216 (7 tests, both guards disable-verified). +**Confidence:** High — the failure mode is demonstrated by a test that goes red when the scoping is restored. + +**Operator ruling (2026-09-07):** *"plug and play already has all the domains, +you could simply make the global schema for all appids already in plug-and-play +pattern activate V3 and be silent about all others… local quad usage must mint +any V3 settings in plug and play, regardless of the settings here… otherwise I +will spend weeks until I remember that we changed it here wondering why quad +4x24 stopped working."* + +**The finding, and it is about my own two prior fixes.** +`D-BLOCKS-HOTPLUG-1` retired a central `BUILTIN_READ_MODES` row per consumer +because adding a frontend must not mean editing the substrate. The seam I built +to replace it held **`const LOCO_READ_MODES` — one hard-coded row per consumer +seat** (`0x1717` alone), answered only when the plug covered every declared +seat, and returned `&[]` otherwise. **That is the same central table, relocated +one level up.** Adding a frontend meant adding a row; every consumer outside +`0x17XX` got no reading at all. + +**Why that is worse than it sounds.** Both failures are silent AND remote. A +missing row does not break a build — it surfaces much later as a V1 tail where +V3 was expected. The quad (`LegacyOutlier::WideTriple`, G2 `4 × u24`) is a +carving of the 12-byte content-blind payload, which exists as such only under a +V3 tail; so "somebody scoped the reading in lance-graph" and "quad 4×24 stopped +working in medcare-rs" are the same event, weeks and one repo apart, with no +mechanical link between them. + +**The `&'static` decision was the root cause, and it was mine.** I typed +`Activation::read_modes` as `&'static` and argued it as "plug-and-play at +COMPILE time: a reading is looked up, not computed". The consequence I did not +weigh: a `&'static` table cannot be built per plug, so the authority can only +return a table it holds ALL of — which forces all-or-nothing, which forces a +per-seat table. **An aesthetic constraint on a type silently dictated the +architecture underneath it.** Now owned (`Vec`), so the authority answers for +exactly the ids a plug declared. + +**The rule now: being plugged in IS the declaration.** Every classid in a plug +gets [`ReadMode::PLUG_AND_PLAY_V3`] (V3 tail; `DEFAULT` stays V1 as the canon +zero-fallback for classes nobody plugged, and is unreachable from a hot-plug +lookup). `concept_override` remains for genuine per-class deviations — blockly's +seat reads `Bootstrap` because it stores an `ogar-loco` body, not cognitive +tenants — and it is *a short list of exceptions, not a roster of participants*: +a consumer absent from it is not absent from plug-and-play. The asymmetry is +the point — a forgotten entry means "no override", never "no reading". + +**The ownership guard survived the rewrite, but only because it was checked.** +Deriving readings from the plug initially dropped the consumer check codex +flagged on #1207, so an impostor could have activated blockly's seat. Restored +as `palette_seat_owner`: a CLAIMED seat is its owner's; an UNCLAIMED one is +plug-and-play for whoever plugs it. A new frontend at `0x1718` activates and +reads V3 with no edit here — which is the ruling — while `0x1717` stays +blockly's. + +**Falsifiers, both disable-verified.** Restoring the palette-only scoping turns +`a_capability_consumer_outside_the_loco_domain_also_reads_v3` (a MedCare-shaped +plug of `0x0901`/`0x0902`) red; dropping the impersonation guard turns +`another_consumer_cannot_activate_a_claimed_seat` red. The silence twin, +`an_unplugged_concept_is_silent_not_v3`, holds the other end: "V3 for all +plugged appids" must not become "V3 for everything". + +**Process note worth more than the fix.** The first run of disable 1 PASSED and +I nearly recorded the guard as non-load-bearing. `cargo fmt` had reflowed the +closure I was patching, so my `replace()` matched nothing and the disable was a +no-op — the code under test never changed. The re-run asserts the anchor exists +before writing. **A disable that does not apply is indistinguishable from a +guard that does not matter**, and this is the second time this session that a +disable silently failed to disable (the first: zeroing a constant whose guarded +quantity could go negative). + +## 2026-09-07 — E-A-DOC-COMMENT-IS-NOT-A-FAIL-CLOSED-MECHANISM-1 — hotplug could still land on V1 with a one-liner + +**Status:** FINDING, measured. Fixed in this PR (2 tests, disable-verified). +**Confidence:** High — the silent path was expressible in one line of safe, plausible-looking consumer code. + +**Operator ruling (2026-09-07), clarifying the earlier "don't pollute a +global setting":** *"I meant don't silently enforce V1 fallback in hotplug, +that's unacceptable."* + +**I had read that caution as "be conservative, leave `ReadMode::DEFAULT` +alone"** and used it to justify stopping at `mint_for`. It meant the opposite +direction: the hot-plug PATH must never silently land on V1. Recorded because +the misreading is instructive — a constraint phrased as a prohibition was +taken as a licence to stop, and the thing it actually named was still open. + +**What was still open.** `E-A-V3-MINT-MUST-NEVER-DEGRADE-TO-V1-1` closed the +`mint_for` fallback. It did NOT close the socket, where three affordances +made a silent V1 landing available and only a doc comment forbade it: + +1. `Activation::read_modes` was a **public `&'static` slice**. The whole rule + lived in prose on that field — *"an empty slice is not 'assume the + default' … a consumer that needs one must treat that as a bang"* — while + the code permitted + `act.read_modes.iter().find(…).map(…).unwrap_or(ReadMode::DEFAULT)`: one + line, compiles, reads as careful, mints legacy-tailed rows forever. +2. `Activation` derived **`Default`**, so `Activation::default()` was a + green-looking activation carrying no reading at all. +3. `lance-graph-ogar` returned `Ok(Activation { …, read_modes: })` on the non-loco path — a **successful** activation with no + reading, whose consumer then defaults. + +**The fix is mechanical, not prose.** `read_modes` is private; `Default` is +gone; the only lookup is `Activation::read_mode_for(concept) -> Result` with a new `NoReadingFor(u16)` arm. Deliberately a `Result` +and not an `Option`: an `Option` invites `.unwrap_or(ReadMode::DEFAULT)`, and +`DEFAULT` is a V1 tail. `declared_readings()` remains as the audit surface for +authority-conformance tests, named so it reads as such. + +An empty table stays legitimate — a capability-only consumer (an executor that +mints no keys) has none to declare. What the type now guarantees is that +ASKING for an absent reading bangs. + +**Falsifiers.** Both disable-verified by replacing the `ok_or` with +`ReadMode::DEFAULT`, which turns both red: +`an_undeclared_reading_bangs_instead_of_defaulting_to_v1` (two-sided on ONE +activation — the declared seat resolves, an undeclared one errors, and +`ReadMode::DEFAULT.tail_variant == V1` is pinned so the difference is measured) +and `an_empty_table_activates_but_still_refuses_to_invent_a_reading` (the +silence twin: an empty table must not fail activation, only the lookup). + +**The transferable lesson.** *A rule a caller can violate with a one-liner is +not a rule.* I wrote that doc comment as the guarantee, and it was load-bearing +in exactly the way documentation never is. When the invariant is "never +substitute a default", the test is not whether the docs say so — it is whether +the type makes the substitution inexpressible. + +**Adjacent, NOT fixed here (scope):** `lance-graph-ogar` is workspace-EXCLUDED, +so `cargo clippy --workspace` and `cargo fmt --all` never reach it and CI runs +only `cargo test --manifest-path` on it. It carries **4 pre-existing clippy doc +errors** (`bridges/mod.rs`, `rbac_impl.rs`) and had drifted out of `cargo fmt` +— measured on the unmodified tree. The fmt drift is repaired in the one file +this PR edits; the 4 lints are left, and the missing clippy/fmt CI coverage for +excluded crates is the real item. + +## 2026-09-07 — E-A-V3-MINT-MUST-NEVER-DEGRADE-TO-V1-1 — the fallback arm's own justification was falsified by D-BLOCKS-HOTPLUG-1 + +**Status:** FINDING, measured. Fixed in this PR (3 tests + a consumer-side const guard, all red-then-green). +**Confidence:** High — the reachability is a call site in two consumer repos, not an inference. + +**Operator ruling (2026-09-07):** *"A V3 needs to be assumed by default, it's +not acceptable that if you mint a V3 detection that you even remotely accept +V1 debt."* + +**The hole.** `NodeGuid::mint_for`'s `#[cfg(not(feature = "guid-v2-tail"))]` +arm silently fell back to `new` — a V1 `family:identity` u24 key — for a +caller that asked for V2/V3. Its own doc justified this as dead code: + +> *"With the feature off no classid registers a V2/V3 `tail_variant` +> (`classid_read_mode` returns V1), so the fallback arm is dead."* + +**That premise was true when written and is now false.** It assumed the +registry is the ONLY source of a tail variant. `D-BLOCKS-HOTPLUG-1` (#1207, +merged 2026-09-07) is precisely the ruling that a hot-plugged consumer's +reading rides the authority's `Activation::read_modes` instead of +`classid_read_mode`. Two live call sites pass `TailVariant::V3` with no +registry entry involved: + +- `blockly-store` — `mint_key` passes its own `READ_MODE.tail_variant` +- `medcare-cohorts/src/differential.rs:893` — `mint_for(TailVariant::V3, …)` + +So the arm is reachable, and the corruption is **unobservable at the mint**: +the tail is not recorded in the key (`decode` vs `decode_v2` is chosen by +classid alone), so a degraded key surfaces only as garbage identities later. + +**The fix, and what it deliberately does NOT do.** The arm panics instead of +falling back. `mint_for` is a `const fn`, so a const-context mint fails at +COMPILE time and a runtime mint bangs loudly. Three constraints held +(operator, same session): + +1. **No global setting polluted.** `ReadMode::DEFAULT` stays V1, `TailVariant` + keeps `#[default] V1 = 0` (the canon zero-fallback ladder), and the default + feature set is unchanged. In every default build the changed arm does not + compile at all — verified: 1321 contract lib tests pass untouched. +2. **MedCare's `4 × u24` quad identity tenant is not blocked.** That is **G2** + (`LegacyOutlier::WideTriple`, named for the 3-byte group width, not the + count) — a reading of the 12-byte content-blind VALUE payload, whose own + module says *"this is not a revival of the V1 tail model; there is no + path/tail split"*. Orthogonal to `TailVariant`; `legacy_outliers.rs` is + untouched. MedCare takes the contract's defaults, so the changed arm is not + in its build, and it is a V3 minter — the change protects it. +3. **No new dependency.** `lance-graph-contract` stays zero-dep, so a consumer + on contract + OGAR alone is unaffected. + +**Falsifiers.** `v3_never_degrades_to_v1` (compiled only when the feature is +off): V3 bangs, V2 bangs too (the guard is not V3-only), and a legitimate V1 +mint still mints with its u24 tail and drops the non-V1 `leaf` — the +can-stay-silent half, without which "refuse every mint" would pass. Consumer +side, `blockly-store` gained a `const _` block that mints in const context and +asserts identity 1 lands at bytes 14..16 and NOT at byte 13; flipping +`READ_MODE` to V1 fails the build with `E0080`. It asserts the OUTCOME (the +byte layout) rather than the feature, so a configuration that is on but +dispatching wrong is still caught. + +**The transferable lesson.** A dead-code justification is a claim about +reachability, and reachability is a property of the whole graph, not of the +file the arm lives in. The PR that made this arm live was mine, and the +justification sat three lines above the code I was editing. When a ruling +moves where a value comes from, every "unreachable because the old source +never produces it" comment in the blast radius is stale by construction. + +## 2026-09-07 — E-THE-V1-GUARD-WAS-TESTED-THE-V3-GUARD-THAT-REPLACED-IT-WAS-NOT-1 — a guard nothing proves can fire is the defect one level up + +**Status:** FINDING, measured. Fixed in this PR (3 tests, red-then-green). +**Confidence:** High — every claim is a grep or a test result, not an inference. + +**What happened.** A q2-side audit asserted that `osint-bake`'s FMA bake +silently truncates identity: `body.rs:129` passes a `u32` row into a slot the +V3 tail stores as `u16`, "no assertion guards it". **That claim is false**, and +reading the contract settles it in both directions: + +- `NodeGuid::new` (V1) — `assert!(identity <= 0x00FF_FFFF, "identity must fit + in 24 bits")` (`canonical_node.rs:209`) +- `NodeGuid::mint_for`'s V2/V3 arm — `assert!(identity <= 0xFFFF, "v2/v3 + identity must fit in 16 bits (no silent truncation)")` (`:386-389`) + +Both are plain `assert!`, live in release. There is no silent wrap on any mint +path; an over-wide identity is a loud panic naming its own width. + +**The real defect is the asymmetry.** The V1 guards have had `should_panic` +cover since they landed (`new_panics_on_family_overflow` / +`new_panics_on_identity_overflow`, `:2152-2162`). The V2/V3 guards that +supersede them had **none** — grepping their panic strings returned exactly one +hit each, the definition site. Nothing proved the newer guards could fire. + +That is this repo's own falsifiability rule turned on the guard itself: *"A +guard/channel needs a can-it-fire test — a watchdog that cannot bark is the +defect one level up."* The V1 rung was covered; the V3 rung that replaced it +inherited the assertion but not the proof. + +**What landed.** Three tests, feature-gated on `guid-v2-tail` because the V2/V3 +arm only exists under it — ungated they would compile against the V1 fallback +and assert the wrong message: + +- `mint_for_v3_panics_on_identity_overflow` (identity `0x0001_0000`) +- `mint_for_v3_panics_on_family_overflow` (family `0x0001_0000`) +- `mint_for_v3_admits_the_widest_legal_tail` — the twin the rule also demands: + `0xFFFF`/`0xFFFF` mints and reads back intact, so the guard is shown to + *discriminate* rather than to fire on everything. + +**Measured:** `cargo test -p lance-graph-contract --lib` 1318 → **1321 passed**; +`--no-default-features` **1304 passed**, the delta confirming the cfg gate +excludes them exactly where the V2/V3 arm does not exist. fmt and clippy clean. + +**The transferable part.** A guard inherited across a layout migration carries +its assertion but not its coverage. When a V-next path supersedes a V-prev one, +grep the new path's panic strings: if they appear only at the definition site +while the old path's appear in tests too, the migration dropped the proof and +kept the appearance of one. + +## 2026-09-06 — E-AN-EXCLUDED-CRATE-ON-AN-X86-ONLY-FLEET-IS-CODE-NO-CI-HAS-EVER-COMPILED-1 — un-gating one downstream suite found a second aarch64 defect that could never have built + +**Status:** FINDING, measured red-then-green locally. Fixed in this PR. +**Confidence:** High — every claim is a command output, not an inference. + +**What happened.** Un-gating q2's test suite (q2 #146, removing the +`github.repository == 'quarto-dev/q2'` guard) put `macos-latest` — Apple +Silicon, i.e. **aarch64** — in front of this workspace's code for the first +time. `crates/bgz17/src/prefetch.rs` failed with three `error[E0658]`: +`std::arch::aarch64::{_prefetch, _PREFETCH_READ, _PREFETCH_LOCALITY3}` are +gated behind the unstable `stdarch_aarch64_prefetch` feature +(rust-lang/rust#117217). On the pinned stable 1.98.1 toolchain that is a hard +compile error, not a missed optimization: **Rust 1.98.1 exposes no stable +prefetch *intrinsic* on aarch64.** The no-op is therefore this crate's stable +fallback — not the only conceivable form. Stable `asm!` IS available on +aarch64 (since 1.59), so a hand-written `prfm` is possible; it is not +warranted here for an advisory hint on a small matrix, and would need its own +measurement to justify. (Narrowed after a CodeRabbit review on #1205 flagged +the original "only correct form" as an overclaim; the flag was right.) + +**Why nothing caught it, and the reason is two independent holes:** + +1. **`bgz17` is workspace-`exclude`d** (`Cargo.toml:31`) — lance-graph's own CI + never builds it as a member. +2. **Every lance-graph runner is `ubuntu-*`** (measured: `grep -h runs-on + .github/workflows/*.yml` → 14 jobs, 0 non-ubuntu), and no job passes + `--target`. So no CI job in this repo has ever built the + `aarch64-unknown-linux-gnu` target, and on an x86 host a + `#[cfg(target_arch = "aarch64")]` block is not compiled or type-checked — + it is skipped like a comment. + +Either hole alone hides it. Both together mean **no CI job in this repository +has ever compiled this block** since it landed (#844). + +**Scoped precisely, because the looser version is false.** The claim is about +*this repo's CI*, NOT about the world: this session compiled the old code +locally for aarch64 on purpose — that is exactly how the table below was +produced — and q2's macOS runner compiled it too, which is what surfaced it. +The first draft of this entry said "never compiled by anything, ever", which +its own evidence table contradicts two lines down. Corrected after a +CodeRabbit review on #1205 caught the self-contradiction. + +**Measured, red-then-green, locally:** + +| target | old code | new code | +|---|---|---| +| `aarch64-unknown-linux-gnu` | 3× `E0658`, build fails | clean | +| `x86_64-unknown-linux-gnu` | clean | clean | + +The x86 row is the finding: the old code passes on the only architecture +anything ever built it on. + +**This is the SECOND instance in one week.** #1200 fixed `contract/src/mul.rs` +— NEON `_n_` intrinsics passed non-const shift operands and +`is_aarch64_feature_detected!` was imported from the wrong module — found the +same way, by the same un-gate. Two defects, one cause: **an architecture no +CI job builds is an architecture whose code is unverified** — the compiler +exists and cross-compiling is one flag away; nothing was pointing it there. + +**Second, independent finding in the same sweep.** `bgz17`'s example carried a +`clippy::chunks_exact_to_as_chunks` warning — the exact lint the +`rust-toolchain.toml` bump log records as swept in #1194 "at ten sites across +four crates". bgz17 was not one of the four **because it is excluded**, so the +sweep could not see it. Fixed here; the crate now passes `clippy -D warnings` +(a `CLAUDE.md` Hard Rule) on both targets for the first time. + +**Consequence — what this does NOT fix.** Both fixes are point repairs. The +holes remain: excluded crates are still unbuilt and unlinted by this repo's CI, +and there is still no aarch64 runner. Every other `#[cfg(target_arch = +"aarch64")]` block in this workspace and in `ndarray` is in exactly the state +these two were in ten minutes before they were measured — presumed fine, +never built by this repo's CI. Filed as `ISS-NO-AARCH64-RUNNER` / `ISS-EXCLUDED-CRATES-UNBUILT` +rather than fixed here, because adding a runner is a CI-policy change and an +operator call, not a drive-by. + +**The transferable rule:** a `cfg` your CI never builds is a claim, not +verified code. When a gate is removed and a new platform appears, expect the +backlog of every unbuilt branch to arrive at once — and do not read "it +compiles here" as evidence about anywhere else. The corollary this entry +learned the hard way: that rule applies to the entry's OWN prose. "Never +compiled by anything" was a stronger claim than "no CI job compiled it", and +only the weaker one was measured. + +## 2026-09-06 — E-I-CITED-THE-RIGHTMOST-REGISTER-AND-CALLED-IT-THE-ADDRESS-1 — three corrections to one entry, each because I reasoned instead of measuring + +**Status:** OPERATOR CORRECTION ×3 of my own same-day entry, superseded before +merge. Recorded as one entry because the three are the same mistake at +increasing depth. +**Confidence:** High — every claim below is a `git log` date or a line read out +of `ogar-vocab`. + +**The rulings, in the operator's words:** *"It should always be classid, which +is the namespace"* · *"the old lockstep is deprecated, namespace might be even +older"* · *"First determine the age of your source. July or older is +automatically deprecated."* · *"0005 is old shit. New is Domain on the left +side — if that's not implemented it's not the new."* + +**Correction 1 — I dated nothing.** I built a "three layers" taxonomy out of +source-file doc comments, called `hotplug` current, and proposed migrating +`UnifiedBridge` onto it as future work. That migration was +operator-ruled and **shipped 2026-07-07** (OGAR #174/#175, lance-graph #658, +tesseract-rs #13/#14 as the template consumer; C# and Python mirrors already +generated). Every source I used was pre-August; a doc comment carries no date +at all. + +**Correction 2 — the top rung was stale too.** Under the dating rule `hotplug` +is itself July. The current canon is +`E-EVERYTHING-WIRES-TO-SOA-V3-CE64-IS-ALU-LEGACY-1` (2026-09-05, operator). + +**Correction 3 — the substantive one. I named the wrong register.** I published +this table and called it "the address the classid already carries": + +| port | `APP_PREFIX` | +|---|---| +| OpenProject | `0x0001` | +| Odoo | `0x0002` | +| Healthcare | `0x0005` | +| Redmine | `0x0007` | + +Those are **classview** values — the lo u16, the per-vendor render skin, the +RIGHTMOST register. The composed classid is `0xDDCCVVVV` = +`domain : appid : classview`, so the leading register is the **domain byte**, +and it is fully implemented: `ogar_vocab::ConceptDomain` with 29 arms and +`canonical_concept_domain(id) = id >> 8` — `0x01` ProjectMgmt, `0x02` Commerce, +`0x09` Health, `0x0F` Geo, `0x17` Blocks, and the C-band `0xC0` JavaRuntime / +`0xC1` Analytics / `0xC4` BinaryLifting (reserved 2026-08-18 — **August, the +newest source in this whole thread**). + +The collision proves the error on its own terms: **`0x0005` is Healthcare's +vendor skin; Health's domain is `0x09`.** Two registers, two numbers, one word +— and I quoted the one that carries the least. + +Worse, the "NAMESPACE ↔ APP_PREFIX 1:1" pairing I drew as evidence for the +ruling **is the deprecated lockstep** — a string paired with a vendor ordinal. +I used the old thing as proof of the new one. + +**The rule this leaves.** The domain byte's magnitude encodes ALTITUDE +(`0x00`–`0x0F` business ontology, `0x17` the substrate's own tier, `0xC0`+ the +foreign-host C-band), so the first nibble is a 16-way altitude selector — one +mask, no lookup, no value decode. A register that far left is not +interchangeable with one on the right, and "the classid is the address" is only +true read left-first. + +**Method, stated so it is mechanical.** Date the source (`git log -S`); read the +board top-down, not a source file middle-out; and when citing a bit layout, +name the register position, never just the value — a bare hex number cannot say +which of `DD`, `CC` or `VVVV` it came from, which is exactly how `0x0005` got +published as an address. + +**The code change this accompanies is unaffected.** Six `pub const NAMESPACE: +&str` mirrors in `lance-graph-ogar`'s bridge modules are removed: unreachable +since birth (private modules, never `pub mod` in any commit), zero consumers +anywhere in lance-graph / OGAR / q2, on a surface last touched 2026-07-24 for +five of the six files — by the same PR #844 that created them. A string +namespace belongs to the old lockstep; that is the whole reason, and it needs no +appeal to a prefix table. + +--- + +## 2026-09-05 — E-A-SWEEP-IS-COMPLETE-ONLY-WITHIN-THE-TARGET-KINDS-ITS-GATE-COMPILES-1 — #1194 swept the whole 1.98 delta and still left two sites, because "whole" was measured through six clippy steps + +**Status:** FINDING (measured on the pinned 1.98.1: `--tests` = 9 findings, `--all-targets` = 11; the two extra are in an example no CI step compiles). **Confidence:** High — both numbers come from running the two commands back to back on the same tree; the two extra sites are the same lint, in the same release, as the ten #1194 fixed. + +**What happened.** #1194 fixed `clippy::chunks_exact_to_as_chunks` at ten sites across four crates and recorded, accurately, that this single lint "is the ENTIRE 1.98 delta across all six crates CI clippies. Nothing else fires." Landing the `TD-SUPERVISOR-CLIPPY-RED-ON-BASE-1` fix a few hours later turned up **two more sites of that same lint**, in `lance-graph-supervisor/examples/measure_wal_curve.rs`. Nothing about #1194 was careless: the supervisor is not one of the six crates CI clippies, and its examples sit behind `--features supervisor,cycle-driver`. The sweep was complete **with respect to its instrument**, and the instrument was six clippy steps. + +**The third axis of the blind-gate class.** `E-A-PER-FEATURE-CI-STEP-NAMED-LIKE-PER-CRATE-COVERAGE-1` established that one step per *crate* is not coverage when a crate has independent *features*. This adds the axis below that: one step per *feature* is not coverage either, because a clippy invocation compiles the **target kinds you name** — `--tests` reaches lib+tests and stops, `--all-targets` also reaches examples, benches and binaries. The debt row itself was written with `--tests`, so the row's own command could not have found the two sites it was opened to catalogue. Crate → feature → **target kind**: three nested ways to hold a green that was never asked the question. + +**Why examples are the reliable hiding place.** An example is compiled by nobody's default: not `cargo test`, not `cargo build`, not `cargo clippy` without `--all-targets`. It is the one target kind that can carry a lint error across a toolchain bump and several sweeps without a single gate going red — and in this repo examples are not scratch, they are the probe harnesses (`measure_wal_curve` is the WAL-curve measurement). + +**The rule.** When a lint sweep claims a delta is complete, state the *instrument* alongside the claim — which crates, which features, which target kinds — because that sentence is what a later session checks the claim against. And when arming a lint gate, arm it at `--all-targets`; anything narrower gates the parts of the crate you happened to think of. Both are done here: the supervisor step is armed at `--features supervisor,cycle-driver --all-targets -- -D warnings`, and the debt entry now carries the corrected command alongside the corrected lint name. + +**Falsifier for the "complete sweep" claim, generally:** re-run the sweep's own lint at `--all-targets` over every crate NOT in the sweep's instrument list. If that is empty, the claim is complete; here it was two sites deep. +## 2026-09-06 — E-THE-AARCH64-PATH-HAD-NEVER-BEEN-COMPILED-1 — a cfg-gated arch path is dead code until some CI targets it + +**Status:** FINDING (measured — reproduced locally on `aarch64-unknown-linux-gnu` +after a macOS runner surfaced it, then fixed and re-verified). +**Confidence:** High — three compiler errors captured before, zero after, on +both `aarch64-unknown-linux-gnu` and native `x86_64`. + +**What happened.** `AdaWorldAPI/q2`'s test suite had been gated to +`if: github.repository == 'quarto-dev/q2'` and so had never run on that fork. +Un-gating it put `lance-graph-contract` on a **macOS aarch64** runner for the +first time, and the crate did not compile: + +``` +error: cannot find macro `is_aarch64_feature_detected` in this scope + --> crates/lance-graph-contract/src/mul.rs (the aarch64 arm of the SIMD-caps probe) +error[E0435]: attempt to use a non-constant value in a constant + --> crates/lance-graph-contract/src/mul.rs (twice, in `extract_dim_pair`) +``` + +The compiler's own line numbers are deliberately replaced above with the two +function names. They were `:983` and `:1467`/`:1468` at the time, and the fix +moved both — a coordinate into a file that the fix itself edits is decayed by +construction. `citation_decay` caught exactly that on the first push of this +entry, which is the rule working rather than an inconvenience. + +Two independent defects, both in `#[cfg(target_arch = "aarch64")]` blocks: + +1. **`is_aarch64_feature_detected!` is not at the root of `std`.** Its x86 + sibling is, which is exactly why the mistake is easy: the x86 arm two lines + above compiles bare. The aarch64 macro lives under `std::arch` and must be + imported. +2. **`vshrq_n_u64` is an `_n_` intrinsic.** Its shift operand is encoded into + the instruction, so it must be a constant; `extract_dim_pair` took + `shift: i32` as a runtime argument. All eight call sites already passed + literals (36, 4, 8, 12, 56), so a `const SHIFT: i32` parameter is an exact, + mechanical fix, not a redesign. + +**The generalizable point is not either bug.** It is that `#[cfg(target_arch = +"aarch64")]` code is unparsed, untypechecked, uncompiled text on every machine +that is not aarch64 — indistinguishable from a comment. Both defects would have +been caught by the compiler the first time anything built the crate for that +architecture, and nothing ever had. The NEON path has presumably been broken +since it was written. + +**Consequence.** An arch-gated path needs a build for that arch or it is not +code, it is a plan. `cargo check --target ` costs a `rustup target add` +and, for a zero-dep crate like this one, a few seconds — cheap enough that +there is no excuse for the gap. Whether this repo's own CI should carry an +aarch64 check job is the open question this leaves; it currently does not, and +the defect reached `main` and stayed there. + +**Corroborating detail worth keeping:** the discovery came from a *consumer's* +CI, on a platform this repo does not test, on a run whose purpose was +unrelated. Un-gating a suite that has never run is a measurement, and it +returns findings that are not about the change being made. + +Cross-ref: `AdaWorldAPI/q2#146` (the un-gate, and the run that surfaced this). + +--- + +## 2026-09-05 — E-A-MACHINE-APPLICABLE-FIX-IS-A-SUGGESTION-NOT-A-PROOF-1 — clippy's own autofix did not compile, and the lint it fixes is a substrate argument + +**Status:** FINDING (measured across two repos while sweeping to Rust 1.98.1). +**Confidence:** High — reproduced in both `lance-graph` and `ndarray`, with the failing compiler error captured. + +**Three things, in ascending order of how long they will stay useful.** + +**1. `rustfix` output is not rustfmt-clean.** `cargo clippy --fix` emitted +`.as_chunks::<4>().0.iter()` on one line where rustfmt wants three. Harmless, +but a `--fix` sweep followed straight by a push turns the FORMAT job red while +the clippy job is green. Always `cargo fmt` after `--fix`. + +**2. A "machine-applicable" suggestion is a suggestion, not a proof.** Two of +ten sites failed to compile after the autofix: + +``` +error[E0277]: the trait bound `[u8; 8]: TryFrom<&[u8; 8]>` is not satisfied +``` + +because `as_chunks` yields `&[T; N]` where `chunks_exact` yielded `&[T]`. +`cargo fix` reverts the whole crate on error, so the run LOOKS like "8 fixed" +and silently leaves two crates untouched — the count is the tell, not an error +message you would notice. The hand fixes are strictly better than the original +either way: `from_le_bytes(*chunk)` takes the array directly, so each site +loses an `unwrap` that could never fail. **Rule: after any `--fix` sweep, +re-run the lint to enumerate what was reverted; do not read the Fixed lines as +a completion report.** + +**3. The lint is an argument about the substrate, and the operator supplied +it.** `chunks_exact(N)` was the right call when these buffers were 4096 and +16384 wide: at those widths the remainder is always empty, so the runtime +width check is dead weight and the `&[T]` return type loses nothing. At the +**32+96 shape** — the `classid(4B)` plus the twelve-byte content-blind facet +payload — the width is a COMPILE-TIME fact, and `as_chunks::` returns +`&[T; N]`, a type that CARRIES the width instead of re-checking it. That is +the honest representation for a fixed-width register, and it is why this +migration is not lint appeasement. + +Two `ndarray` AVX-512 kernels showed the sharper form: `asum_f32` and +`asum_f64` called `chunks_exact(N)` AND `chunks_exact(N).remainder()` +separately, where `as_chunks` returns both halves at once. Each kernel now +makes one call where it made two. + +**A measurement lesson attached to the same arc.** Before running anything I +grepped 139 `.chunks_exact(` call sites and called that the exposure. The real +count was ten, because the lint requires a const chunk size where `as_chunks` +applies. **A grep is a denominator; only the lint is the numerator.** Same +shape as the workspace's standing rule that grep locates and reading +comprehends. + +Cross-ref: PR #1194 (the ten sites), #1195 (the one-line channel bump the +sequencing bought), `ndarray` PR #302 (six sites plus a REMOVED lint, +`clippy::from_iter_instead_of_collect`, still sitting in a crate-level allow +list — a second delta this repo did not have, which is why the sweep measures +each repo instead of generalising from the first). + +## 2026-09-05 — E-PLANNING-MIGRATES-TO-LOCO-R2IL-DATAFUSION-IS-GRACE-PERIOD-1 (OPERATOR-RULED) + +**Status:** operator-ruled, BINDING (2026-09-05, verbatim intent: *"Every planning is in migration to ogar-loco and ogar-r2il, especially datafusion is out of the picture, what exists gets a grace period, nothing new will migrate to it."*) +**Confidence:** High on the ruling; the census it lands on is E-THE-UNFINISHED-UDF-WAS-NOT-THE-DEBT-1 (same day). + +**The ruling.** Planning / orchestration / execution is migrating to `ogar-loco` (the +vocabulary-agnostic call ABI: every 12-byte payload read as `(function : value)` calls +into 256×256 tables) and `ogar-r2il` (the always-on R2IL vocabulary, EXECUTED by +r2sleigh's interpreter, never pre-converted). **DataFusion is out of the picture as a +target.** What exists on DataFusion today — `datafusion_planner`, `sql_query`, the +Python bindings' `SessionContext`, `graph_table`, `rls.rs`, the `query`/`query-lite` +features — gets a **grace period**: maintained, tested, not extended. **Nothing new +migrates to it.** A plan, card, or PR that names DataFusion as the home of NEW +behaviour (a rewrite rule, a UDF, a dispatcher, a policy VM, a projection seam) is +stale on arrival. + +**Consequences, stated so they cannot blur:** +- **D-OIF-1 is ruling A (SUPERSEDED / REMOVE) with no replacement seam in DataFusion.** + The census (same day) had left one door open — "the planner's scan taking the + authorized column list" — as the legitimate place DataFusion would receive a + `ClassView × WideFieldMask` projection. That door is closed by this ruling: the + authorized projection is consumed by Lance reads and by loco programs, never by a new + DataFusion operator. `policy.rs` (`PolicyRewriter`, `ColumnMaskRewriter`, + `NotYetWiredHashUdf`, `policy_hash_v1`, the encryption/DP stubs) is a retirement + cone, and the hash-family question is moot. +- **Forward-stubs pointing at DataFusion are vacancies under grace, not backlog:** + `datafusion-dispatch` (`postgrest.rs` `parsed_query_to_plan`), `datafusion-plan` + (`audit_from_plan`), `register_policy_udfs`/`register_vsa_udfs`-style registration + helpers, `MembraneRegistry::with_rls`. They are not to be completed; they are to be + regraded and, when their grace period ends, removed with their cone. +- **`rls.rs` (`RlsRewriter`) is grace-period duplicate of `ClassRbac::row_scope`.** + Row scope is enforced on the canonical path (`authorize → {scope, mask}`) or not at + all — never by adding a second optimizer rule. +- **The Python bindings' raw `SessionContext` path is grace-period.** It is the only + shipped live-query surface today and carries no policy step; it is not the reason + to build one. +- **The layer map the D-OIF-1 census verified stands:** lifecycle = SoA-owned + Kanban/Rubicon (`try_advance_phase`); action semantics = OGAR `ActionDef`/`ActionState`; + authorization = `ClassRbac` × `ClassView` × `WideFieldMask` (transport-only today, + enforcement is the missing implementation); execution/reasoning = loco/r2il; + storage/query = Lance, with DataFusion in grace. No layer impersonates another. + +Cross-refs: `.claude/board/exec-runs/d-oif-1-census-main-thread.md` (the census that +this ruling landed on); `open-ideas-fetch-v1` (#1185, D-OIF-1 to be re-graded there); +`ogar-loco` / `ogar-r2il` crate docs (OGAR); E-LANCE-IS-UPSTREAM-AUTHORITATIVE-1 (Lance +stays; only DataFusion is in grace). + +## 2026-09-05 — E-THE-UNFINISHED-UDF-WAS-NOT-THE-DEBT-1 — D-OIF-1 re-derived: the execution model that needed `policy_hash_v1` never reached production + +**Status:** FINDING (production census 2026-09-05, four symbol groups traced from real entry points; full table in `.claude/board/exec-runs/d-oif-1-census-main-thread.md`). Ruling for #1185: **A — SUPERSEDED / REMOVE**. +**Confidence:** High — every classification is a grep-backed call-path fact, not a reading of a `pub mod`. +**Correction (2026-09-05, after #1185's reconcile pass):** two points of this census compressed "not live" into "does not exist". (1) `ColumnMaskRewriter` HAS one non-test constructor — MedCare `routes/patient.rs:150`, behind the default-off `lance-phase2-rbac` feature (no Dockerfile enables it), ending in a decoder stub that returns `None`; "no production caller" stands, "no caller" does not. (2) The remove cone is therefore the NARROWER one #1185 §2 carries: first removal = `RedactionMode::Hash` + `NotYetWiredHashUdf` only; the rest of `policy.rs`/`rls.rs` is frozen grace-period until MedCare retires its feature — not whole-module removal. Ruling A itself is unchanged. Canonical adjudication: E-THE-UNFINISHED-FUNCTION-WAS-NOT-THE-DEBT-1 (#1185); this entry is the earlier, independent census and is read through that one. + +`policy_hash_v1` sat for months as "not yet registered," and every plan (including +#1185 §2) read the missing body as the debt. The census shows the debt was upstream: +the model that made a masking UDF necessary — materialize the forbidden column, then +transform it inside DataFusion's optimizer — never acquired a production caller. The +whole `policy.rs` framework is constructed only inside `#[cfg(test)]`; no file in the +repo calls `add_optimizer_rule` / `add_analyzer_rule`; no binary or handler imports +`callcenter::policy`; the only shipped live-query surface (the Python bindings' +`SessionContext`, `graph.rs:1208,1518`) has no policy step and never asked for one; the +server binaries that could carry the chain are off by default and absent from CI. The +canonical model makes a forbidden field ABSENT from the projection (`ClassView × +WideFieldMask`, real in `ogar-doc-ir::project::field_mask`) instead of present-then- +hashed. A stub that fails loud is honest about its wiring and silent about the wiring's +reason; "loud > silent" protected a hole nobody was going to fall into. + +**Also measured:** RBAC enforcement on the canonical path is TRANSPORT ONLY — +`authorize()`, `ClassRbac`, `OgarRbac` have zero non-test callers, `field_mask` still +returns `FieldMask::FULL` (charter C1.4 retype not done), `medcare_actor.rs:100` is a +`// TODO`; there is no `ogar-rbac` crate (the machinery lives in `lance-graph-contract::rbac` ++ `lance-graph-rbac` + `lance-graph-ogar::rbac_impl`). Lifecycle is SoA-owned exactly as +ruled: the single phase write is `MailboxSoA::advance_phase` via the checked +`try_advance_phase`, applied at seal by `cycle_driver.rs`; `KanbanActor` is a tombstone; +baton/emission survive only in prose. `ogar-loco` / `ogar-r2il` touch neither RBAC nor +kanban. **Test for the next card:** before completing a stub, find the caller that would +have been harmed by its absence. No caller, no debt. + +## 2026-09-05 — E-BLW5-FIRST-MEASUREMENT-1 — the observer-effect instrument is alive, and every pre-registered gate reads SILENT + +**Status:** MEASURED (`crates/lance-graph-supervisor/tests/d_blw_5_observer.rs`, one run, 40 owners 1:1, synthetic corpus, recorded run 4 after three dry runs — all numbers below are from the recorded run; the dry runs are listed, not hidden). +**Confidence:** High on every number; High that the κ floor is the wrong observable for THIS reader (see the last paragraph); Low on anything beyond this corpus and instrument. + +The D-BLW-5 loop resumed by operator ruling ("with the belief arena reader"). The payload +is the shipped `shape₀ × rank₀` (`NestedBands::shape_rank` → `ShapeRankPayload`, sealed in +`RemeasureLedger` at V0 = `DatasetVersion(1)`), injected into each owner's `BeliefArena` as +16 shape beliefs `prior Inh band_k` (f = mass_k) plus one `subject Inh prior` per corpus +subject at **frequency 1, confidence = the prior's mass at the observed rank** (typicality — +the C2 encoding, amended once, below). The only propagation channel is `rcr_abduce` + +`close_transitive` iterated to a fixed point. Reader A = the verse's statement was revised +(contradiction > 0.05); reader B = another cohort subject has been INFERRED to carry the +verse's predicate at c ≥ 0.01 (derived, empty stamp, rung ≥ 1, no reserved term). + +| arm | typicality injected | rate_b V0→V1 | κ V0→V1 | φ V0→V1 | gate | +|---|---|---|---|---|---| +| T (rank 6, mass 6/40) | 0.150 | 0.471 → **0.885** | −0.180 → −0.254 (Δ −0.074) | −0.252 → **−0.909** | O4 SILENT at floor 0.10 | +| F+ (rank 7→12, mass 0) | 0.000 | 0.430 → 0.430 | −0.134 → −0.134 (Δ 0) | unchanged | DROP fires | +| F− (rank 8→3, mass 8/40) | 0.200 | 0.521 → **0.922** | −0.080 → −0.168 (Δ −0.087) | −0.128 → **−0.789** | O5 d = +0.087 SILENT | +| P (uniform, rank 8) | 0.0625 | 0.474 → 0.474 | −0.267 → −0.267 (Δ 0) | unchanged | O2 holds (|Δκ| = 0 < 0.10) | +| N (T payload, bloom read) | 0.150 | — | −0.110 → −0.110 | — | O3 frozen, Hamming 0 | +| CTRL (no injection) | — | 0.583 → 0.583 | −0.006 → −0.006 (Δ 0 exactly) | unchanged | idempotence holds | + +**What the pinned gates say:** O2 (placebo does not move), O3 (null instrument frozen), O1 +(remeasure guard barks and stays silent as specified), O6 (no reader identifier before the +measurement marker), O7 (1266 derived beliefs on T carry a reserved term — the payload DID +propagate; 0 of the 340 beliefs reader B accepted carry one — the firewall holds) all pass +with both twins. O4 and O5 are **SILENT at the pre-registered κ floor of 0.10** — the honest +null as written: "awareness does not reflect this statistic (at floor 0.10)". Reported, not +re-tuned. + +**What the tables show that the κ floor does not:** the reader moved by the largest amount +the instrument can express — every non-contradicted verse became B-true in T and F− (n00 +went 159 → 0 and 154 → 0), φ went from −0.25 to −0.91 — and it moved in exact proportion to +the injected TYPICALITY: 0 (F+, empty bucket) → nothing, 0.0625 (P) → nothing (c ≈ 0.003 < +C_MIN), 0.15 (T) → saturation, 0.20 (F−) → saturation. Awareness tracks the injected rank's +MASS, not its truth (F− moved more than T). That is the anchoring/Goodhart pattern the +doctrine names — but it is NOT the O5 verdict, because O5 was pinned on κ and κ barely moved: +κ is invariant to a reader that saturates, since a constant reader has no covariance. The +finding therefore reads: **this instrument's observable (Δκ) is insensitive to the effect it +was built to detect on this reader; the effect is visible in the marginals.** The next probe +pre-registers a reader-rate/φ floor BEFORE running (D-BLW-5b, queued), never by reclassifying +this run. + +**Dry runs, on the record (instrument fixes, no threshold changed):** (1) O6 self-scan +tripped on its own doc lines; `reason()` was not a fixed point (CTRL Δκ = −0.0028 with no +injection) — now bounded RCR+close to fixed point; corpus counts had period 12 (`w % {2,3,4}`) +so the 40-owner prior was 12 atoms with empty buckets (T's pooled φ landed in one: typicality +0) — now a splitmix64 fold of the window index. (2) Everything bit-identical: the typicality +was injected as a FREQUENCY below 0.5 and the arena discarded it — see the sibling entry +E-NARS-EXPECTATION-CHOICE-PREFERS-IGNORANCE-TO-A-CONFIDENT-NEGATIVE-1. (3) O7's shadow reader +could not differ from B under RCR-only reasoning — restated to what can fire (spec §10). + +Cross-refs: doctrine `.claude/knowledge/observer-effect-tfpn-doctrine.md`; spec +`.claude/board/exec-runs/d-blw-5-build-spec-main-thread.md` (§0 corrections C1/C2, §10 +addendum); E-MEASUREMENT-BURNS-THE-STATE-1; E-NXG-22 (F+'s shifted rank fell into an empty +bucket — the out-of-support saturation, now seen from the loop side). + +## 2026-09-05 — E-NARS-EXPECTATION-CHOICE-PREFERS-IGNORANCE-TO-A-CONFIDENT-NEGATIVE-1 — a derived belief with f < 0.5 loses CHOICE to a vacuous one + +**Status:** FINDING (measured in D-BLW-5 dry run 2: injected cross-subject links came back at c = 3.53e-11 instead of the computed 0.108). +**Confidence:** High — it follows from `TruthValue::expectation() = c·(f − 0.5) + 0.5` and `admit_derived`'s "replace only when expectation strictly exceeds" rule, and it reproduced on every subject pair. + +`BeliefArena::admit_derived` and `close_transitive` resolve every derivation of the same +statement by CHOICE on `expectation()`. For f < 0.5 expectation DECREASES with confidence: a +confident negative (f = 0.15, c = 0.108 → 0.462) is out-ranked by any near-vacuous path to +the same statement (c ≈ 0 → ≈ 0.5). So a low-frequency belief cannot survive in the derived +layer once closure finds any alternative route; the arena prefers "unknown" to "confidently +not". This is NARS-correct as a decision rule (higher expectation = better bet on the +statement being true) but it means **the derived layer cannot carry negative evidence with +confidence** — anything a probe wants to propagate as "weakly true" must be encoded with +f ≥ 0.5 and the strength in c (which is what D-BLW-5 now does: `subject Inh prior` at f = 1, +c = typicality). Consequence for readers: a derived-layer reader that thresholds on +confidence is blind to negations by construction; a reader that wants them must read the +grounded (observed) layer, where `revise_at` keeps `|f₁ − f₂|` as `contradiction`. + +Cross-refs: `belief.rs` S2 ("closure-internal duplicates resolve by CHOICE on +`expectation()`"); E-BLW5-FIRST-MEASUREMENT-1 (the probe that hit it); +`.claude/plans/dialectic-engine-v1.md` §1 S2. + +## 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. + +**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`); 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. + +**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. + +--- + +## 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. 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.** + +| 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-VERSIONED-GRAPH-OVERWRITES-SO-ROW-ADDRESSES-ALIAS-ACROSS-VERSIONS-1 — the D-LNC-2 probe found four wrong claims in the plan it was written to execute + +**Status:** FINDING (measured, `crates/lance-graph/tests/lance_row_identity_probe.rs`, lance 10.0.0, both disable arms verified red-then-green). +**Confidence:** High on every measured line. ⊘ **Confidence raised 2026-09-05** (this line is the one an entry may update): the lance-11 half is no longer pending — measured on #1190, `forbidden` PASS with fragments `{0}→{1}→{2}` and 0 aliased, `expected` RED at `probe.rs:372`, so both policy arms are two-sided ACROSS the bump. One addition the entry did not predict: **the fix is not retroactive.** The lance-10-written fixture reads back byte-identical under lance 11 and still carries its 2 reused ids and 2 aliased addresses, because fragment ids are written by the writer into the manifest. Correction 1 below ("sound only WITHIN one version") therefore survives the bump rather than being closed by it. Plan §5a. + +**What was believed.** `lance-convergence-staged-migration-v1` §2 said, twice, +that this codebase uses `WriteMode::{Create,Append}` only — "never +`Overwrite`" — and therefore that lance#8206 ("stop reusing fragment ids +across an overwrite", the first lance-11 breaking change) had zero API +exposure. §5 pre-registered the D-LNC-2 delete arm as "a delete between two +versions is reported by lance's delta AND by `VersionedGraph::diff`, +identically". + +**What the tree says.** `VersionedGraph::write_batch` (`graph/versioned.rs`) +matches `Dataset::open(path)` and picks `WriteMode::Overwrite` whenever the +dataset exists. Every `commit_encounter_round` after the first REPLACES all +three tables; the function's own doc comment says "appended". The +`Append`-only claim was true of `LanceCycleWriter` and was generalised to the +graph without reading it. + +**What the probe measured (lance 10).** Three overwrite rounds A→B→C plus one +real `Dataset::delete` (D): + +| overwrite | fragment ids before → after | shared | +|---|---|---| +| v1→v2 | `{0}` → `{0}` | `{0}` | +| v2→v3 | `{0}` → `{0}` | `{0}` | + +`_rowaddr` aliased to a DIFFERENT `node_id` across consecutive versions: **2** +(`0<<32|1` and `0<<32|2` name nodes 2/3 at v2 and 3/4 at v3). Cleanup with +`TimeDelta::zero()` removed 2 old versions; the tagged one survives +byte-identical, the untagged one is gone (`at_version` → Err). + +**Four corrections that fall out, each pinned in the probe:** + +1. **A row-address-keyed reader is sound only WITHIN one Lance version.** + This is the §4A rows-vs-region-mask one-truth verdict, now measured + rather than argued. lance 11's fresh fragment ids stop the COLLISION; + they do not make addresses comparable across versions. The convergence + lens is `SoaRow → RowAddress` per `DatasetVersion`, never a global map. +2. **`GraphDiff` cannot see a removal** — no `removed_nodes` field; B→C + (node 2 dropped) is an EMPTY diff. `graph_seal_check` is the one truth + for removals (`Staunen`). +3. **`diff()` couples nodes/edges/fingerprints by version NUMBER** — it + checks out edges at the nodes version. A nodes-only write (D) makes + `diff(C, D)` an `Err(DatasetNotFound …/edges.lance/_versions/4.manifest)`. + Lockstep is an invariant of `commit_encounter_round`, not of the store. + → `TD-VERSIONED-GRAPH-DIFF-LOCKSTEP-AND-NO-REMOVALS-1`. +4. **The pre-registered delta arm could never run.** lance 11's + `get_deleted_row_ids` (lance#8589) "requires stable row ids at both + endpoints"; our datasets are written with `enable_stable_row_ids: false`. + Stable row ids are decided at D-LNC-5, and cheaply first on an EPHEMERAL + dataset — the alpha overlay can turn them on at creation with no + migration, which is why the delta API fits the alpha layer before the + graph spine. + +**The rule that survives.** A plan's exposure table is a claim about the +tree, and "we never do X" must be grep'd for X's *implementation site* +(`WriteMode::`), not for the callers the author remembers. Building the +probe found four wrong claims in the plan it was written to execute; none of +the four would have surfaced from reading the plan again. + +Cross-ref: plan §7.6–7.9; `E-A-CORRECTION-CAN-SUBSTITUTE-ONE-WRONG-NOUN-FOR-ANOTHER-1` (same failure shape: a correct-sounding noun substituted for the one the source used). + +## 2026-09-05 — E-EVERYTHING-WIRES-TO-SOA-V3-CE64-IS-ALU-LEGACY-1 — operator ruling: no exceptions to the V3 substrate, and the one carve-out is named + +**Status:** RULING (operator, 2026-09-05, verbatim: "anything must be wired +into SoA V3 substrate no exceptions except the causaledge64 adjacent as ALU +legacy substrat"). +**Confidence:** High on the ruling; High that it is already the ruled state +for CausalEdge64 (M20, RESIDUAL RESOLVED 2026-07-18 — demoted, not deleted: +survives as the `MailboxSoA` baton edge `mailbox_soa.rs:92`, the perturbation +baseline, and the p64 address; only the awareness mantissa retired; the +`edges[16B]` CANON block untouched). "ALU legacy substrate" is the name for +exactly that state. + +**What it changes.** `bindspace-mailbox-soa-wiring-v1` D-BSW-2 recorded +`dispatch_busdto:281` as "EXCLUDED from the cutover pending a decision" +because it writes `set_qualia_f32` (`engine_bridge.rs:321`) and +`unbind_busdto` reads `qualia_f32_row` (`:397`) as bit-exact ground truth. Under +this ruling there is no exclusion: it WIRES, and the only open question is the +tenant. `MailboxSoA` carries an f32 scalar tenant (`energy: [f32; N]`, +`mailbox_soa.rs:66`) but no 16-dim f32 vector tenant; the candidates are the +i4 register — `atoms.rs` `I4x32/I4x64` ("byte-compatible with QualiaI4_16D and +CausalEdge64 mantissa", the ALU-adjacent carrier the ruling names) or +`QualiaI4_16D` via `set_qualia` (`:606`). Quantizing a bit-exact ground truth is +a MEASURED decision: the falsifier is the D-MTS-6 proxy triple (`|ΔE|`, +surprise agreement, descent ρ) against the f32 baseline, pre-registered before +the first run. A new f32 vector tenant fights the content-blind 4+12 byte +register and is not a candidate. + +**What it does NOT change.** The bundle algebra, the mailbox-as-owner +compile-time safety argument (E-CE64-MB-4), and the three surviving +CausalEdge64 roles are untouched. The ruling closes a loophole; it does not +open a design. + +Cross-ref: `lance-convergence-staged-migration-v1` §6 (where the consequence +is carried); D-BSW-2 (whose row now needs the "excluded" wording regraded to +"wires, tenant TBD by probe" — a plan/board diff item, the class of drift +this session caught twice). +## 2026-09-05 — E-NXG-22 — `shape × rank` is bounded by the prior's support: an out-of-support statistic saturates at the edge bucket + +**Status:** FINDING (pinned by `nested_bands::tests::shape_rank_from_real_lag1_autocorrelations`); D-NXG-4 SHIPPED into the D-BLW-5 payload. +**Confidence:** High on the mechanism; the consequence for the D-BLW-5 loop is a design question left open on purpose. + +D-NXG-4 now has its first consumer: `NestedBands::shape_rank(observed, V₀)` +produces `lance_graph_contract::shape_rank::ShapeRankPayload` — the doctrine's +`shape₀ × rank₀`, frozen at V₀, with no `f64` field by construction. The +transform lives in `jc::stats::fisher_2z` (ruled home of calibrated math), the +ladder is `calibrate_equal_width` (the D-BLW-5 design's "equal-width in 2z"), +and the remeasure guard is `RemeasureLedger::seal` (second write ERRORS). + +**The finding.** The pooled prior in the test is real: the lag-1 Pearson +autocorrelation of 92 frames of speech, `r ∈ [0.9205, 0.9917]`, i.e. +`2z ∈ [3.18, 5.48]`. The two other recordings' whole-file statistics are +`2z ≈ 1.46` (saturated) and `1.67` (quiet) — far BELOW the prior's support. +Both rank 0, and both are therefore indistinguishable from the prior's own +minimum, which also ranks 0. The first version of the test asked the two +out-of-support values to land in DIFFERENT buckets; they cannot, and the +test was restated to what is true: inside the support the ladder +discriminates (prior min → rank 0, prior max → rank 15), and outside it +saturates. **`rank` carries no "how far out".** That is partly by design — +the payload law forbids the raw scalar precisely so awareness cannot parrot +a number — but the D-BLW-5 loop's "T-silence is a reportable null" and bloom +criterion may need to know that an observation left the prior's support +entirely. The candidate fix is one bit (`out_of_support`), not a scalar; it is +a decision for the loop, which stays PAUSED, and is not made here. + +**Also measured, not claimed:** first frames of both recordings are silence +(that is why the spec's "first frame" observed statistic was wrong — it +measured leading silence, not the recording); `quantize_2z` at ×1024 keeps +three decimals of 2z and the 16 equal-width boundaries over the speech prior +differ in width by at most one unit. Gates: planner 428/428, contract +1315/1315, jc 141/141, planner + contract clippy clean; jc clippy red on +base and untouched by this arc (TD-JC-CLIPPY-RED-ON-BASE-1). + +## 2026-09-05 — E-NXG-21 — `NestedBands` sealed: the three probes became one type and twelve tests, and two of the probes' numbers were off by one row and by one sign + +**Status:** SHIPPED (`crates/lance-graph-planner/src/nested_bands.rs`, D-NXG-1; merge arm of D-NXG-5; room 3 closed by moments). +**Confidence:** High — 12/12 tests on the same three real recordings the probes used, planner lib suite green. + +`NestedBandsBuilder::{new, budget_factor, calibrate, with_boundaries}` seals a +`NestedBands` (version, boundaries, band masks, bucket masks, popcounts). +Every method is `&self`; `split` and `merge` return NEW values under a new +version and the original is asserted unchanged (data-flow rule, one writer at +build). The top band is the universe by construction (E-NXG-18 is now a type +invariant, not a probe caveat). `overflow()` is the budget test (E-NXG-19), +`collapsed()` is the merge-on-collapse arm — it fires when speech boundaries +meet the quiet recording and stays silent on the calibration epoch; `merge` +removes one boundary and the merged popcount equals the pair's sum. +`best_achievable_floor` is E-NXG-20's floor by bisection over +`gt_i32_to_mask` + popcount, no sort. + +**Two corrections the type forced on the probes' numbers.** (1) The strict +floor — the SMALLEST value whose exceedance is ≤ the rate — lands at 15 077 on +speech, not the probe's 15 072: the probe's rank floor sat one row OVER the +target (473/94 572 = 0.0050015) inside its ±1/n tolerance. A floor with a row of +slack is not "never exceeds"; the type has no slack and the test pins both the +literal and a sorted-copy reference. (2) The midpoint-σ estimator is not even +sign-stable: with the stale top boundary it over-read by 12 % (E-NXG-17); with +the last boundary as the top bucket's midpoint it under-reads by 7 % +(3 525.8 vs 3 785.8). An open-ended top bucket has no midpoint, so the +estimator has no principled value at all. The regression guard is now +direction-agnostic (|Δ|/σ > 5 %), and room 3 closes the other way: σ is exact +from the seal iff the seal stores two accumulators per bucket (`BucketMoment +{count, sum, sumsq}`, 16 B/bucket) — `sigma_exact` matches the direct σ to +1e-9. "Recoverable for free" was wrong; "recoverable for 256 bytes" is right. + +**Not done, on purpose.** D-NXG-3 (`bisect_column_by_mask`) lives inside +`NestedBands::split`, not as a named `ndarray::simd` primitive: it is a +memory-bound gather-and-popcount loop, not a lane op, and the W1a contract's +all-backends parity requirement would be ceremony for a scalar. Promotion, if +ever, is its own deliberate PR. No consumer is wired yet — the type exists, the +first caller (D-NXG-4's `shape × rank` payload) is the next unit. + +## 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). +**Confidence:** High — measured, and the defect is now asserted against. + +E-NXG-1 specifies `M_0 ⊆ M_1 ⊆ … ⊆ M_{B-1}` with `M_i = rows whose value <= +boundary_i`. It never says the LAST mask must cover everything, and +PROBE-NXG-HIST-1 could not notice: its top boundary was the maximum of its own +column, so `M_{B-1}` happened to be the universe. Under a distribution shift it +is not. With boundaries frozen on one recording (top boundary 20 634) and a +louder recording streamed against them, **55 058 of 61 995 rows — 89 % — sat +above the top boundary and were therefore in no band at all.** Both rollover +triggers stayed silent on a distribution that had moved almost entirely out of +range. That is precisely the failure the two `lacking proper bucket rollover` +comments in `lance-graph-contract` warn about, reproduced inside the design +written to fix it. + +**The correction, now part of the design:** the top band IS the universe +(all-ones), never `le(top_boundary)`. The top bucket is open-ended, every row is +always in exactly one bucket, and `sum(popcounts) == n` is asserted on the +SHIFTED epoch so the defect cannot return. Cross-ref D-NXG-1/5; the probe's +disable run A (reverting the universe band) reproduces the silence. + +## 2026-09-05 — E-NXG-19 — entropy LAGS the budget test; plan room 2 had the timer backwards + +**Status:** FINDING (PROBE-NXG-ROLL-1 C3, pre-registered form falsified). +**Confidence:** High on the measurement, High on the mechanism. + +Plan §3 room 2 claimed histogram entropy is the earlier rollover timer — +"entropy-triggered rollover fires before budget-triggered". Measured on a real +epoch shift (94 572 rows of speech followed by 61 995 rows of a six-times-louder +recording, streamed in 24 steps against frozen boundaries): **the budget test +fires at step 16, entropy only at step 21.** Budget is five steps earlier, not +later. + +**Mechanism, which is why this generalizes:** the budget test reads a LOCAL +EXTREMUM — the largest bucket, which crosses twice its equal share as soon as +one bucket swells. Normalized entropy is a GLOBAL AVERAGE over all 16 buckets +and moved only 0.166 across the entire shift (1.000000 → 0.833597). An average +lags an extremum by construction. The two are not interchangeable: budget +answers "is a bucket full", entropy answers "has the whole shape collapsed". +**D-NXG-9's rollover timer is the budget test**; entropy is a confirming shape +signal, and the plan row is regraded accordingly. One split moved entropy +0.833597 → 0.912117, so entropy remains the right read for "did the split +help", just not for "is a split due". + +## 2026-09-05 — E-NXG-20 — `k` does not name a rate: at k=3 a real column's floor is unreachable + +**Status:** FINDING (PROBE-NXG-FLOOR-1, two pre-registered forms restated). +**Confidence:** High. + +E-NXG-4 says `mu + kσ` is the wrong operating threshold. Measured on three real +columns (`|sample|` of three recordings in `data/tts-cascade/`), what an +operator actually budgets is a RATE, and `k` does not name one: + +| column | n | mu | σ | mu+3σ | its exceedance rate | +|---|---|---|---|---|---| +| speech | 94 572 | 4 034.6 | 3 785.8 | 15 392 | 0.00379 | +| saturated | 61 995 | 26 231.4 | 8 731.3 | 52 425 | **0.00000 — unreachable** | +| quiet | 24 240 | 319.4 | 903.0 | 3 028 | 0.01762 | + +The saturated column's floor sits at 52 425 while the column's physical maximum +is 32 767: **at the shipped `k = 3` that alarm can never fire.** Among the +reachable columns the rates differ 4.65×. Re-tuning `k` globally does not save +it — the `k` that puts speech exactly on target (2.9155) leaves quiet 3.80× off +and saturated still unreachable. A Gaussian would predict 0.00135 for all three; +the real columns read 0.00379 / 0.00000 / 0.01762, which is the concrete form of +the Jirak warning `rolling_floor.rs` already carries about its own σ. + +**Second restatement, against my own replacement.** The pre-registered claim was +that the rank floor hits the requested rate exactly. It does not, on a column +with atoms: the saturated recording is clipped, 32 767 is a huge tie, and no +boundary cuts inside it (achieved 0.00411 against a target of 0.00500). What is +true and is what an operator needs: **the ladder picks the BEST ACHIEVABLE +boundary** — the achieved rate never exceeds the target, and the next distinct +value below it overshoots, so no better boundary exists. Verified on all three +columns. `mu + kσ` cannot promise even that. + +## 2026-09-05 — E-NXG-17 — PROBE-NXG-HIST-1 GREEN: the nested-mask histogram reproduces the partition-point rank on 94 572 real rows + +**Status:** FINDING (measured; `crates/lance-graph-planner/examples/probe_nxg_hist_1.rs`). +**Confidence:** High on C1–C3; the σ observation is a real correction to plan §3 room 3. + +The first gate of `nexgen-mask-histogram-thresholds-v1` §5 ran on a REAL +column — `|sample|` of `data/tts-cascade/tts_real_output.wav`, 94 572 rows of +16-bit speech, 1 478 mask words, B = 16 quantile bands. Three pre-registered +claims, all PASS on the first run: **C1** the 16 band masks are nested, the 16 +bucket masks are pairwise disjoint, and their popcounts sum to exactly N; +**C2** for every one of the 94 572 rows the bucket index read off the masks +equals `boundaries.partition_point(|b| b < v)` (0 mismatches; anti-vacuity +16/16 buckets non-empty, largest 5 925 ≈ N/16); **C3** +`mask_ternlog::(M_i, M_{i-1}, M_{i-1})` is bit-identical to +`mask_andnot(M_i, M_{i-1})` and `AND3` on the same operands differs at every i +with a non-empty lower band. Two disable runs, red-then-green: bucket via +`AND3` → C1 disjoint=false, sum=715 262, C2 88 659 mismatches, C3 false; +partition point `b <= v` → C2 192 mismatches (the rows sitting exactly on a +boundary — the off-by-one is real, not vacuous). E-NXG-1/2/3 are promoted from +PROPOSAL to FINDING for the structure; the cost claims stay unmeasured. + +**What the probe corrected.** Plan §3 room 3 said σ is "recoverable from the +histogram for free" via popcount-weighted bucket midpoints. Measured: σ_hist = +4 244.9 vs σ_direct = 3 785.8, ratio 1.121. Quantile buckets are equal-mass, +not equal-width, so the top bucket (9 299..20 634) is a heavy tail whose +midpoint over-weights it. Room 3 is regraded: σ from the histogram needs +per-bucket means (one more accumulator per bucket), not midpoints, and stays an +observation until that variant is measured. The entropy preview +(`thought_atoms::normalized_entropy` over the 16 popcounts) reads 0.99999964 — +the expected ceiling for equal-mass buckets, which is why D-NXG-9's rollover +timer must be read on FIXED boundaries after the distribution moves, never on +freshly re-quantiled ones (a re-quantiled histogram is flat by construction and +carries no signal). + +**Honest scope.** The column is audio, not a facet column — no facet fixture +exists in-tree (harvest 2026-09-05). The mechanism is value-type-agnostic; the +facet rerun is the next arm. `popcount_batch_u64` exists as a named T1 primitive +(D-NXG-2's audit half-closed: present, scalar `count_ones` sum, not yet the +POPCNT lane its comment promises). Mask bytes hot at this N: 189 184 B for 16 +bands — the plan's "16 × 8 KB" was at 65 536 rows; this column is 1.44× that. + +## 2026-09-05 — E-NXG-1 — the exposure meter is a nested mask set + +**Status:** PROPOSAL (design reading of measured code; no code changed). +**Confidence:** High on the identity, unmeasured on the cost. + +Foveal ⊆ Near ⊆ Good ⊆ Weak (`ndarray/src/hpc/cascade.rs:162-176`) are four +row masks of 8 KB each at 65 536 rows; the histogram is four popcounts; bucket +i is `M_i ∧ ¬M_{i−1}` = `vpternlogq` immediate `AND_ANDNOT2 = 0x10` +(`ndarray/src/simd.rs`), one instruction per 512 rows. Belichtungsmesser, +Prozentrang, Mexican hat, basin and the mask slab cache are one sealed object. +Plan: `.claude/nexgen/plans/nexgen-mask-histogram-thresholds-v1.md` (D-NXG-1). +Harvest: `.claude/nexgen/harvest/01-*.md`. + +## 2026-09-05 — E-NXG-2 — Prozentrang exists only in doctrine; in code nothing ranks against a live distribution + +**Status:** FINDING (grep + read, `.claude/nexgen/harvest/02-*.md`). +**Confidence:** High. + +`observer-effect-tfpn-doctrine.md` §2 mandates `shape × rank`; D-BLW-5 designs a +16-bucket Fisher-2z histogram; `ndarray::hpc::statistics::percentile` is a batch +sort. No live rank mechanism exists. Under E-NXG-1 rank = index of the innermost +band mask containing the row — a partition point over nested masks, no sort +(D-NXG-4). + +## 2026-09-05 — E-NXG-3 — bucket rollover exists nowhere; it is a popcount test plus a mask split + +**Status:** FINDING on the absence; PROPOSAL on the mechanism. +**Confidence:** High / unmeasured. + +The only mentions are the two "lacking proper bucket rollover" module-doc +bullets in `crates/lance-graph-contract/src/legacy_outliers.rs` ("it saturates +silently. Give it rollover, or narrow it") and +`crates/lance-graph-contract/src/identity_quad.rs` (the codebook refuses to +exceed capacity "rather than saturating silently"). +Mechanism: when `popcount(M_i ∧ ¬M_{i−1})` exceeds budget, bisect that bucket on +the distance column (the one non-mask read) and mint the new boundary as a new +version-keyed mask; old masks are never rewritten (D-NXG-5). Merge on collapse is +the dual: drop a boundary, the merged mask is already `M_{i+1}`. + +## 2026-09-05 — E-NXG-4 — `mu + kσ` is the wrong operating threshold and the code already says so + +**Status:** FINDING (code cites the objection to itself). +**Confidence:** High. + +`cascade.rs:137` fixes `k=3`; `perturbation-sim/src/rolling_floor.rs:25-27` +states the σ is from a weakly-dependent sample and "significance is the Jirak +`n^(p/2−1)` rate, not a clean Gaussian tail". Under E-NXG-1 the reject floor is +the boundary at a chosen empirical rank read off cumulative popcounts; σ becomes +`RollingFloor::z()` diagnostic output (D-NXG-6). Cross-ref I-NOISE-FLOOR-JIRAK. + +## 2026-09-05 — E-NXG-5 — preheat by mask inheritance beats copying mu/σ + +**Status:** PROPOSAL. +**Confidence:** Medium (strictly more information for one AND; cost unmeasured). + +`stack_early_exit()` (`rolling_floor.rs:230-235`) preheats a cold fine tier by +copying two scalars from the coarse tier. `M_fine_domain = M_coarse[weak]` +carries the whole survivor set and the coarse histogram restricted to it, for one +`AND3` (D-NXG-7). + +## 2026-09-05 — E-NXG-6 — early exit is a popcount budget; search and alarm are one rule + +**Status:** PROPOSAL. +**Confidence:** Medium. + +First-Alarm exit (`rolling_floor.rs:239-247`) and kth-best tightening +(`holograph/src/width_16k/search.rs:483`) are one rule: +`popcount(survivors) ≤ k`. Top-k with k = floor is the rolling floor (D-NXG-8). + +## 2026-09-05 — E-NXG-7 — only `TERNLOG = FnIndex(0x86)` survives, and only because its value byte is the truth table + +**Status:** FINDING (OGAR #296/#298, lance-graph #1134/#1159). +**Confidence:** High. + +OGAR #298 retracted 0x87–0x8B because one band aliased three semantic families +(`E-SIX-SEMANTIC-FAMILIES-MUST-NOT-IMPERSONATE-EACH-OTHER-1`). INFO_GAIN / +SIGMA_TENSION / STANCE_ENTROPY return only as DERIVED reads over single-family +masks, never as minted calls. Any derived read that must AND masks from two +families is a violation at the seal. + +## 2026-09-05 — E-NXG-8 — the eight named immediates already have cognitive homes + +**Status:** FINDING (mapping of shipped code). +**Confidence:** High on the mapping. **⊘ 2026-09-07:** the `AND3` row's parenthetical *"(`lgj_hop`, shipped)"* is FALSE — lgj-abi has no ternlog call site; see `E-THE-FUSED-AND3-HOP-WAS-NEVER-SHIPPED-LGJ-HOP-IS-TWO-ANDS-1` (2026-09-07). The other seven rows stand. **⊘⊘ WITHDRAWN, same day:** that ⊘ was measured at the stale pin `dbac826`. At lgj HEAD `8720d1d` the row is TRUE — `lgj_hop` is one `simd_mask_ternlog_assign::` (`exports.rs:1816`), shipped 2026-09-04. **All eight rows stand.** + +`AND3` = conjunctive narrowing (`lgj_hop`, shipped); `AND_ANDNOT2` = bucket / +annulus / known-false (`domain ∧ ¬result`); `MAJ3` = quorum +(`jc::quorum::pairwise_agreement_u8`, `superposition_clean` n/2 vote at +`hdr_cascade.rs:564`); `XOR3` = disagreement (`EpistemicBassin24` agree/disagree +pair, #1129), sign side only per the TWO-ALGEBRA rule; `OR2_AND` = gated +hypothesis union for the prefetch frontier. + +## 2026-09-05 — E-NXG-9 — histogram entropy is a free threshold-health signal + +**Status:** PROPOSAL over ruled primitives. +**Confidence:** Medium. + +`H(popcounts)` via `thought_atoms::normalized_entropy` (ruled home, #1153/#1154; +popcount-histogram form already at `spectroscopy/features.rs:89`). Near zero +means one band holds everything: the threshold is mis-set or rollover is +overdue. Rollover becomes entropy-timed, not budget-timed (D-NXG-9). + +## 2026-09-05 — E-NXG-10 — the Mexican hat has no certified shape + +**Status:** FINDING. +**Confidence:** High. + +`hdr_cascade.rs:128-141` is a piecewise-linear ramp; Pillar-15 +(`ndarray/src/hpc/pillar/mexican_hat.rs:111`) is DEFERRED and returns a +placeholder `passed=true`. Under E-NXG-1 excite/inhibit are two band boundaries, +κ ∈ [1.5, 3.0] is a ratio of ranks that rollover keeps in band, and unimodality +is a finite check on the discrete histogram at seal time (D-NXG-10). + +## 2026-09-05 — E-NXG-11 — the EWA sandwich is the floor's covariance, but uncalibrated + +**Status:** FINDING on the blocker; PROPOSAL on the use. +**Confidence:** High / Medium. + +Adjacent tiers are correlated (Jirak note). A 2×2 `Σ' = MΣM` per tier pair +(`contract::sigma_propagation::ewa_sandwich` ≡ `jc::ewa_sandwich`, byte-identical +per #1160) replaces "copy σ down" with PSD-safe propagation. Blocker: +`PILLAR_6_PSD_THRESHOLD` was lowered to 0.10 because `SIGMA_STEP = 0.2` reaches +denormal in <30 hops (`ewa_sandwich_2d.rs:53-58`). D-NXG-11 is Blocked on that +calibration. + +## 2026-09-05 — E-NXG-12 — proprioception violates the payload law as written + +**Status:** FINDING. +**Confidence:** High. + +`contract/src/proprioception.rs` classifies by nearest-anchor distance over an +11-dim vector — a raw scalar, the shape the payload law forbids. Under +E-NXG-1 each anchor is a band over the window; state = popcounts × rank; +`drive_ratio` cutoffs 1.0 / 1.8 become boundaries with rollover. + +## 2026-09-05 — E-NXG-13 — the ownership and iteration shapes already exist in OGAR + +**Status:** FINDING. +**Confidence:** High. + +`BasinCodebookBuilder::seal()` (OGAR #295: build, freeze, no `&mut` after) is the +slab's ownership shape; inline `[u64;3]` `CallMask` + `set_indices()` (OGAR #288) +is its iteration shape; `resolve(0) → None` (`ogar-loco/src/basin.rs`) becomes +"an absent band mask misses". A basin is a band. + +## 2026-09-05 — E-NXG-14 — sigker has no row-level mask link and should not; the link is one level up + +**Status:** FINDING on the absence; CONJECTURE on the use. +**Confidence:** High / Low. + +No mask/popcount/HDR reference exists in `crates/sigker` or the W1.5 plan +(`.claude/nexgen/harvest/04-*.md`). A signature is over a path, not a row set. +The per-tier survivor-popcount sequence is a length-4 path in ℝ⁴; +`signature_kernel_pde` on two such paths is an order-sensitive query-narrowing +similarity for the prefetch planner. Untested. + +## 2026-09-05 — E-NXG-15 — "power kernel" does not exist in either workspace + +**Status:** FINDING (grep). +**Confidence:** High. + +Only unrelated power iteration (PCA in `ndarray/bf16_test_src/main.rs:1029`, +PageRank in `arigraph/ppr.rs:30`, SVD in `bgz-tensor/src/matryoshka.rs:304`). +Recorded so the term is not re-searched. + +## 2026-09-05 — E-NXG-16 — what is not free + +**Status:** FINDING (cost ledger for E-NXG-1..15). +**Confidence:** High. + +Popcount-derived selectivity assumes operand independence (the overlap matrix +`popcount(M_a ∧ M_b)` is the fix, D-NXG-12). 16 bands × 8 KB per histogram per +version hot; a u8 rank column is the cold form. Rollover bisection reads the +distance column. Nothing is measured; `columnar_hop_bench` is the only bench in +scope. Evidence trail for all sixteen entries: `.claude/nexgen/harvest/`. + +## 2026-09-04 — E-A-SKETCH-THAT-MISSED-TWICE-WILL-MISS-A-THIRD-TIME-1 — the W1.5 lane-type sketches are 3-for-3 wrong + +**Status:** FINDING (read directly off `crates/sigker` source this session). +**Confidence:** High — every claim below is a file:line read, not an inference. + +**The measurement.** ndarray's consumer contract +(`.claude/knowledge/vertical-simd-consumer-contract.md`, W1.5) sketches three +SIMD primitives against `crates/sigker`. Each sketch names a lane type. All +three are wrong, the same way: + +| item | doc sketch | real consumer | shipped as | +|---|---|---|---| +| W1.5-#6 signature_pde | `&[F32x16]` | `f64` (`signature.rs`) | `F64x8` (PR #293) | +| W1.5-#7 randomized | "`F32x16` state" | `f64`/`Vec` | `F64x8` (PR #294) | +| W1.5-#8 lyndon-pack | "`I16x16` state" | `Vec` (`log_signature.rs:272`) | — not built | + +#8 is the worst of the three: `I16x16` is not merely imprecise, it is the wrong +element WIDTH and the wrong SIGNEDNESS FAMILY — there is no `i16` anywhere in +`log_signature.rs`. The crate is `f64` throughout. + +**The deeper finding — #8 is not a SIMD primitive at all.** The sketch names +"pack/unpack primitives", but no such operation exists in the consumer. The real +cost centres are `bracket_expansion` (`log_signature.rs:227-256`) — recursive +Lyndon-word splitting with a sparse outer-product merge plus `sort` and coalesce +over `(usize, f64)` pairs — and the scatter-add peel in +`project_onto_lyndon_basis` (`:368-386`), whose indices are data-dependent and +non-contiguous. Branchy recursion over variable-length sparse vectors is the +OPPOSITE of the dense, fixed-lane shape that made #6 (a 2D grid sweep) and #7 +(a `k×k` GEMV) good SIMD targets. The Lyndon basis is also generated on the fly +by Duval's algorithm at call time (`:164`, `:346`) with no memoization — so there +is no caller-owned table to consume the way #7 consumes projection buffers. + +**Where the real opportunity is, if any.** `log_signature.rs:100` names the +actual bottleneck itself: the depth-N Magnus expansion in `tensor_log`, i.e. +`tensor_multiply` in `signature.rs`, O(d^(2N)). That is a different primitive +from the one W1.5-#8 describes. + +**Bonus correction — the compression headline is misquoted.** The contract doc +says "7-13× compression, lossless". `log_signature.rs`'s own test +`compression_at_shallow_depth_is_far_below_the_headline` (`:744`) is a NAMED +FALSIFIER proving that figure is asymptotic (N≥8), not typical — at d=4,N=2 it +is ~2.1×. The crate's own header (`:41` area, and `lib.rs:29-31`) already flags +this conflation as an error it corrected. Any #8 spec citing "7-13×" +uncritically propagates a claim the source crate disowns. + +**Rule.** A doc sketch that has missed twice on the same axis is not a spec, it +is a hypothesis with a measured failure rate. Read the consumer source FIRST for +every remaining W1.5 item; treat the sketch as the thing to be checked, never as +the thing to implement. + +**Recommendation:** do NOT build W1.5-#8 as sketched. Before any ndarray +primitive signature is written, either (a) profile `log_signature_truncated` at +production depths to show `bracket_expansion`/peel is a measurable fraction of +wall time versus the Magnus series, or (b) rescope onto `tensor_multiply`. + +--- +## 2026-09-04 — E-A-GATE-INHERITS-THE-BLIND-SPOT-OF-WHOEVER-WROTE-IT-1 — both board gates shipped with the exact defect they gate against + +**Status:** FINDING (measured — three review findings, each verified against +the tree before acting, on `#1167` / `#1168`, fixed in `#1170`). +**Confidence:** High — every claim below is a diff or a run, not an +impression. + +Two mechanical board gates landed on 2026-09-04. External review found a +real defect in each within minutes of merge, and **the two defects are the +same shape as the failure each gate exists to prevent.** + +| gate | defect | the shape | +|---|---|---| +| `append_only_gate.py` | `PROTECTED` **substituted** `AGENT_LOG.md` for `IDEAS.md` and kept the count at eight | a substitution that preserves the count — exactly how a lost prepend hides | +| `citation_decay.py` | `--added-lines-only` could not see a decay caused by prepending to `EPIPHANIES.md`, its own motivating case | a scope that excludes the case it was built for | + +The first is the sharper one. The canonical eight are the files +`.claude/BOOT.md`'s immutability table names and `.claude/settings.json` +denies `Edit`/`Write`/`MultiEdit` on. `IDEAS.md` is among them — a real +1204-line append-only ledger — and `AGENT_LOG.md` is not. Because the count +stayed at eight, the tuple read as correct on every pass, while +`.claude/board/**` cheerfully started the workflow on any PR that truncated +`IDEAS.md` and `check()` never looked at it. **Adding `AGENT_LOG.md` was +never the error; substituting it was.** Fixed to nine. + +The second is the more instructive. The gate's own workflow comment named +`EPIPHANIES.md` prepending as the motivating case — and the scoping made it +structurally unreachable, because the citations that decay under a prepend +sit in **other, unchanged files on unchanged lines**. Two obvious repairs +were measured and rejected: scanning unscoped fails every PR on a +148-citation backlog, and scanning changed *files* fails nearly every PR +because `EPIPHANIES.md` alone carries pre-existing decays and the +board-hygiene rule means almost every PR touches it — the +`closed_class_guess` 150/150 defect again. The correct shape is a +**regression comparison**: verdicts at `merge-base` vs HEAD, keyed by each +citation's own content plus an occurrence index (never by line number — the +citing line shifts too), failing only where a citation is decayed now and +was not at the base. + +### The three sub-findings worth keeping + +1. **A count is not a set.** Eight-of-the-right-eight and eight-with-one- + swapped are indistinguishable by the check a human actually performs. + Where a canonical list exists in the repo (here: two of them, agreeing), + the tuple should be diffed against it, not eyeballed for length. +2. **A self-test can assert nothing while printing a number.** The new + regression test printed the harness's own pass/fail under a label reading + `expect 1`, so a PASSING run printed `0` beside the word "expect 1". It + now asserts the verdict the GATE would return, and that assertion is what + goes red under the second disable — load-bearing rather than decoration. + Found by reading the worker's output, not by the test. +3. **A green CI tick is not evidence the gate ran.** The whole finding was + *a gate reporting success on the case it exists to catch*, so the job log + was pulled rather than the tick trusted: `0 new decay(s), 148 + pre-existing, 0 fixed` against a real merge base. Not a silent no-op. + +### And the process half, which is the uncomfortable one + +**`#1167`, `#1168` and `#1170` each shipped without their board hygiene +in-commit** — the retroactive-hygiene anti-pattern this file names by that +name, committed three times running by the session whose entire subject was +making board discipline mechanical rather than remembered. `#1169` recorded +the first two; this entry records the third and its own lateness. + +That is the generalizable point, and it is not about these two tools: **a +gate inherits the blind spot of whoever wrote it, and a rule the author is +actively thinking about is the rule the author still breaks.** The argument +for mechanical checks does not rest on the author being careless. It rests +on this: over one session, the same author, holding the rule in mind, +writing the tooling for the rule, broke it three times and caught it zero +times. + +### Backlog number, with its date + +148 confirmed decays across `.claude/plans` + `.claude/board` (2026-09-04), +up from 124 measured the previous day as the corpus grew. Not a correction — +a measurement with a timestamp. The 93% unverifiable rate is a finding about +the citation convention (bare basenames, which no scanner can resolve), not +about the scanner. + +Cross-ref: `E-VACUOUS-ASSERTION-IS-THE-HOUSE-STYLE-1`; +`E-ANTI-EIGENVALUE-MACHINERY-CAN-ITSELF-BECOME-THE-EIGENVALUE-1` (a guard +that fires on everything); `CLAUDE.md` § Mandatory Board-Hygiene Rule. + +## 2026-09-03 — E-A-CORRECTION-IS-ONLY-AS-GOOD-AS-ITS-MERGE-1 — an unlanded Storno leaves the falsehood standing + +**Status:** FINDING (measured on this repo's own `main`, this hour). The +actionable rule below was falsified once by its own repo-scale sweep and +corrected in place before merge — see the ⊘ block. +**Confidence:** High — the false claim, the correct fix, and the source that +settles them were all read directly. + +**The measurement.** `main` asserted, in two board files, that two ancestor +mechanisms disagreed by **58.2%**: + +| site | reading on `main` | +|---|---| +| `.claude/board/AGENT_LOG.md` under "2026-08-19 — oracle-boundary reassessment sweep" (the **58.2%** findings paragraph) | 58.2% **disagreement** | +| `.claude/board/INTEGRATION_PLANS.md:910` | 58.2% **disagreement** | + +The source says the opposite. `MedCare-rs/crates/medcare-server/src/views/atlas.rs:465` +reads `// the DAG longest path. Measured agreement: 58.2 %.` — agreement 58.2%, +disagreement 41.8%. `EPIPHANIES.md`, `LATEST_STATE.md` and `PR_ARC_INVENTORY.md` +carried it correctly, which is exactly why the inversion survived: the majority +of sites agreed with each other and with the truth, so nothing looked odd. + +**The part worth keeping.** A sibling session had *already found and fixed this* +— a well-formed Storno, source-cited, regraded in place with `⊘` blocks and +strikethrough rather than deletion, fully compliant with the append-only rule. +It sat on an unmerged branch **with no pull request**, 170 commits behind `main`, +while `main` went on asserting the claim it corrects. Measured: the branch +merges into current `main` with **zero conflicts**. + +**So the append-only discipline protects nothing on its own.** Regrading in +place, never deleting, citing the source — every rule was followed, and the +falsehood still stood on `main`, because the corrected file never landed. The +board's guarantee is about how a correction is *written*; it says nothing about +whether it is *reachable*. **A correction is only as good as its merge.** + +**And the absence of a signal read as the absence of work.** `list_pull_requests +--state open` returned `[]`. Zero open PRs is the state a workspace looks like +when it is idle *and* the state it looks like when finished work is stranded on +branches — the two are indistinguishable from the PR list alone. The cheap check +that separates them is `git ls-remote --heads` plus a per-branch +`rev-list --left-right --count` against `main`; it costs one command and it is +the only thing that would have surfaced this. + +**⊘ Both "stranded" branches were ZOMBIES, and the method that found them +was wrong twice — corrected in place before merge (operator-caught, +2026-09-03).** The first version of this entry said *"a branch ahead of `main` +with no PR is stranded."* At repo scale that returns ~200 of 526 branches; ordered +by recency it returns four. That narrowed the candidates — and then I resurrected +two of them without the check that actually decides: + +| branch | what I claimed | what the ±8 window shows | +|---|---|---| +| `…valhalla-sus9w8` (#1162, closed) | a verified correction | its numbers (352/2,048; "24-byte path"; 314/314) were measured 2026-08-19 on a bake that `MedCare-rs` **replaced** on 08-31 (`a0f81443`: veterinary-free cut, 8,319 rows out; HHTL offset corrected — MONDO strips `disease`+`human disease`, max depth 15, second register 30 nodes, >16 zero) after Posten 3 split the register on 08-21 (`00967f37`). And the 58.2 % it "corrected" (`atlas.rs:465`, written 08-18) was read off an atlas that showed **no edges at all** until that 08-31 change — meaningless in either polarity, not merely stale. | +| `…stale-4layer-index-entry` (#1164, closed) | fix landed, entries didn't | the branch IS the reverted draft: `2df6e2a6` 08-30 reverted "#1092 …three of its own inputs"; `758b9500` 08-31 landed the correct count (**two of four**) with its own entry, `E-THE-SUPERSESSION-GATE-WATCHED-TWO-OF-ITS-FOUR-INPUTS-1`. | +| `…redo-d-mar-1` | parked (`HOLD: … NOT for merge`) | correctly excluded — the one true negative | + +**The operator's word for it is exact: a zombie. Merging either would have +re-asserted a retracted count or a retired layout on `main` beside its own +correction.** The failure was not the sweep; it was treating a candidate as a +finding. A branch that stops abruptly with its fix un-PR'd is at least as likely +to be *the session the operator interrupted while catching a mistake* as it is +to be stranded work — and the corrected version then lands days later under a +different name, which is exactly what "no PR for this branch" looks like from +outside. + +**The gate, stated so it is mechanical.** After the recency sweep, for each +candidate: (1) `git log --first-parent ..origin/main` — read the +±8 merged PRs for a revert of, or a successor to, the candidate's subject; +(2) grep `main`'s board for the candidate's *claims* under any name, not its +entry ids; (3) when the candidate cites an artifact, read the log of the repo +that **owns** the artifact for the same window — the bake lived in +`MedCare-rs`, and every disqualifying commit was there, not here. Two +disqualified, one held: the sweep is a candidate generator; the window is the +finding. Also worth recording: my #1162 comment recommended "an identity gate +on the artifact" — shipped 08-21 (`dd9e7265`, `bakes.tsv` row-count gates +replacing digests). Recommending something thirteen days shipped is the same +defect in advice form. + +**Cross-refs.** The stranded-slice entries near `:1324` are a *different* +mechanism — work lost inside a rebase, not work finished and never proposed. +This is the second failure mode, and the recovery is a PR, not a re-derivation. + +--- + +## 2026-09-03 — E-A-CENSUS-IS-A-FUNCTION-OF-ITS-REGEX-SO-GATE-THE-PROPERTY-1 — three numbers, one tree + +**Status:** FINDING (all three counts measured on the same tree, same hour). +**Confidence:** High — the divergence is reproducible by swapping one pattern. + +**The measurement.** A sibling session's census reported **53 of 208** plans +carrying no D-id and proposed a CI gate so the number could not regrow. Before +building it I re-measured, and got a different answer — twice: + +| pattern | untracked / 208 | +|---|---| +| the sibling session's sweep | **53** | +| `supersession_index.py`'s own `DID` | **75** | +| a stricter form requiring a trailing number | **102** | + +Same tree, same hour, same population — the `3DGS` family counts 19 under every +pattern, so nobody was measuring a different thing. **The census is a function +of the regex**, and none of the three numbers is wrong; they answer three +slightly different questions and only one of them (the generator's) is the one +the supersession index actually uses. + +**The design consequence, which is the point.** A gate asserting *"no more than +N untracked plans"* would have been wrong on the day it landed and would have +frozen whichever regex its author happened to hold. So the gate asserts what +regex choice cannot move: **a plan ADDED in this PR cites at least one D-id.** +That stops the backlog regrowing — the stated goal — without requiring the +backlog to be agreed on, counted, or backfilled, which is a cross-session scope +call nobody has made. + +Added-only is deliberate too: gating MODIFIED plans would block whoever next +edits a pre-existing untracked plan, punishing them for a debt they did not +create. A gate that fires on innocent work gets routed around, and a +routed-around gate is worse than none. + +**A second finding, from building it.** The obvious way to share the pattern — +`from supersession_index import DID` — is wrong here: that module has **no +`if __name__ == "__main__"` guard**, so importing it runs the entire generator +and prints the index to stdout. Measured; the first version of the checker did +exactly that. Adding a guard would refactor a CI-gated tool for one caller's +convenience, so the pattern is lifted from its source text instead, with a hard +error if that definition is ever renamed or reshaped. A silent fallback to a +local copy would be the drift +`E-A-CITATION-IS-NOT-A-DEPENDENCY-AND-A-FORCED-COPY-NEEDS-A-GATE-1` was written +about — and note the contrast: there the copy was FORCED by a zero-dep boundary +and the remedy was an equivalence test; here nothing forces it, so the remedy is +to not copy at all. + +**Verified two-sided on real history, not fixtures.** The three plans actually +added in the last 30 commits all carry D-ids, so the gate passes on recent +legitimate work; the `3DGS` family — the largest untracked group — fails it. +A gate that cannot fire and a gate that fires on everything are the same +non-signal, so both halves were run. + +## 2026-09-03 — E-THE-FREE-MITIGATION-WAS-FREE-FOR-TWO-HOURS-1 — the entry's own thesis, applied to the entry + +**Status:** FINDING (observed on #1160; supersedes the mitigation half of +`E-THE-FIX-FOR-A-REVIEW-FINDING-SHIPS-UNREVIEWED-BY-DEFAULT-1`, whose Status +line is regraded in place). +**Confidence:** High for the fact (the reviewer said it in its own words); +the cause is not established. + +**What happened.** That entry, merged roughly two hours ago, offered a remedy +and graded it: *"The cheap mitigation, available today and unrelated to spend +… It costs one comment, is not rate-limited."* On #1160 the same reviewer +answered a review request with **"You have reached your Codex usage limits for +code reviews."** The other reviewer is simultaneously at its org spending cap. +**Both reviewers are now capped, and the free workaround is not free.** + +**Why this is worth its own id rather than a quiet edit.** The superseded +sentence is the exact failure mode of the entry it lives in — *a property +measured once, later read as a standing fact* — and it decayed inside the +document written to name that decay, in about two hours. The first entry's +own rule ("carry the commit it was measured at and the command that measures +it, so a reader re-runs rather than trusts") was applied there to claims about +the TREE and not to a claim about an EXTERNAL SERVICE, which is the gap: +external quotas are strictly less stable than a repo, and a remedy's +availability is not a property of the mechanism it remedies. + +**What is NOT superseded.** The trigger semantics — a push is not a review +trigger, so the commit fixing a finding is reviewed only if someone asks — is +a statement about the reviewer's contract, quoted from its own notice, and is +untouched. What changed is that asking now costs quota that is exhausted, which +makes the operator's spend decision the only remaining lever rather than one of +two. + +**Operational consequence, recorded because it is live.** As of now no +external reviewer can see any PR in this repo. Local gates (`cargo test`, +`clippy -D warnings`, `fmt`, disable-runs) are the whole verification surface +until the caps lift or are raised — which is a statement about coverage, not a +licence to merge faster. + +## 2026-09-03 — E-A-CITATION-IS-NOT-A-DEPENDENCY-AND-A-FORCED-COPY-NEEDS-A-GATE-1 — the Σ-transport kernel, verified by a crate it cannot call + +**Status:** FINDING (both implementations read; the gate is written, passing, +and disable-verified). +**Confidence:** High — the two bodies are byte-identical on inspection, and the +new test fails when either is perturbed. + +**What was found.** `lance_graph_contract::sigma_propagation::ewa_sandwich` +carried a module header claiming the math was *"verified empirically by +`crates/jc::ewa_sandwich`"*, quoting that pillar's numbers (PSD-preservation +1.000000, 10000/10000 hops). The kernel is a **byte-identical copy** of +`jc::ewa_sandwich`'s private `sandwich` — same arithmetic, same variable names, +same `0.5 * (r01 + r10)` symmetrization. + +**The duplication is FORCED, and that is the interesting part.** +`lance-graph-contract` is zero-dependency by design; its manifest forbids even +optional path deps, after one killed the whole PR pipeline on 2026-07-07. So it +structurally cannot call `jc` or share its `Spd2`. This is not a dedup target: +the copy has to exist. + +**What could not exist by citation is the certification.** A crate cannot +inherit a proof from a crate it is forbidden to depend on; naming the pillar in +a doc comment transfers no evidence. And the failure mode is quiet by +construction — **two identical copies agree until the moment one is edited**, +which is exactly when nobody is comparing them. Nothing in the tree executed +both; `grep` for a test naming them together returned nothing. + +**The fix is directional, and the direction is the whole design.** The gate +cannot live in the contract (it may never depend on `jc`). It lives in `jc`, +which already dev-depends on the contract, so it needed **zero new dependency +edges** — `jc::ewa_sandwich::tests::the_contract_copy_matches_the_certified_kernel_bit_for_bit` +runs both kernels over 1000 sampled SPD pairs and asserts **bit** equality +(`to_bits()`, not a tolerance: the two are the same arithmetic in the same order +on the same f64s, so any tolerance would hide precisely the drift the test +exists to catch). It carries an anti-vacuity guard requiring that most sampled +pairs have a non-zero off-diagonal, because diagonal inputs make the +symmetrization vanish and would agree under a wrong implementation too. +Disable-verified: dropping the symmetrization from the ABI copy fails it. + +**A structural check that nearly went unmade.** `jc` is workspace-EXCLUDED, so +`cargo test -p jc` does not work and a test there could plausibly never run. +It does: `.github/workflows/jc-proof.yml` runs +`cargo test --manifest-path crates/jc/Cargo.toml` on `crates/jc/**`. Worth +checking rather than assuming — an excluded crate's test that CI never runs is +a gate in name only. (I initially misread `"crates/jc"` in the root manifest as +membership; it is in the `exclude` list. Reading a grep hit without checking +which list it landed in is the same error shape this session hit four times +already.) + +**The generalisation.** *A citation is not a dependency.* Where an +architectural rule forces a copy, the certification does not travel with it, +and the copy needs its own executed gate — placed on the side of the boundary +that is ALLOWED to see both. The header now points at the test rather than at +the crate, which is the difference between a claim and a check. + +## 2026-09-03 — E-A-HAND-SWEEP-UNDERCOUNTS-TOWARD-DONE-AND-THE-CRITERION-IS-THE-WHOLE-DESIGN-1 — I reported 1 of 208; five defensible definitions give 32 to 125 + +**Status:** FINDING (measured, five variants, each reproducible from the +command in this entry). +**Confidence:** High on the measurements; **explicitly unresolved** on which +number is canonical — that is the point of the entry. +**Corrects:** my own claim, relayed cross-session, that +`r2il-machine-semantic-contract-v1.md` was *"the ONLY genuinely untracked +standalone plan in the tree."* + +**The error, and its direction.** I noticed five candidate plans from a +four-day `mtime` window, checked them by hand, found four declared an owner +plan and one did not, and reported **1 of 208**. The r2il session's own sweep +found **53 of 208**. Their framing is the part worth keeping: a hand sweep +*"undercounted in the direction that feels like completion."* The sample was +selected by recency, not by coverage, and the conclusion was stated about the +tree. + +**Then reconciliation failed, and that is the larger finding.** Attempting to +verify 53, five defensible readings of "untracked" were measured at +`79d82376`: + +| criterion | count | +|---|---:| +| no `D--` anywhere in the plan file | **91** | +| no `INTEGRATION_PLANS.md` entry naming the file | **61** | +| both of the above | **32** | +| no D-ids, **or** none of its D-ids on `STATUS_BOARD` | **125** | +| has D-ids but none of them on `STATUS_BOARD` | **34** | + +**None reproduces 53.** A sub-check diverges too: `3DGS-*` is **20** files +under both case-foldings, where their census reports 19. So this entry does +not claim their number is wrong — it claims the number is **not determined +until the criterion is**, and that two careful sessions produced six different +figures for one question on one tree. + +**Consequence for the CI check that was proposed** (a gate on the +`SUPERSESSION-INDEX` precedent, so the count cannot regrow): the proposal is +right, and its first deliverable is **not the workflow**. Five reasonable +definitions span **32 to 125 — a 4× range** — so the grep IS the design, and a +gate shipped before the criterion is pinned would encode an arbitrary choice +and then report a stable-looking number forever. Pin the criterion first, +state it in the workflow file, and only then write the check. + +Two constraints such a gate must satisfy, both learned here rather than +assumed: + +- **Diff-scoped, not tree-scoped.** Whatever the criterion, dozens of existing + plans fail it today. A gate that fails them turns `main` red for every + session and gets disabled within the hour. It must judge only plans a PR + ADDS or MODIFIES — stop the bleeding, do not bill the past. +- **The criterion should track DISCOVERABILITY, not tidiness.** What actually + went wrong in the r2il case is that a 1,427-line plan was invisible to a + session doing the mandatory reads, which is why its question got re-derived. + The index entry is the discovery path a session consults; + `STATUS_BOARD` rows are per-deliverable and secondary. That argues for the + `INTEGRATION_PLANS`-entry criterion (61) as the causal one — proposed, not + ruled. + +**The generalizable rule.** A census answers a question only as precisely as +its predicate is pinned. "How many plans are untracked" has no answer; "how +many plans lack an `INTEGRATION_PLANS` entry" has exactly one. When a count is +about to become a decision — a backfill, a gate, a scope call — write the +predicate down first, because otherwise every later re-run silently measures +something else and the disagreement looks like drift in the tree rather than +drift in the question. + +## 2026-09-03 — E-A-CROSS-REPO-SYMBOL-GREP-IS-ONLY-AS-FRESH-AS-THE-SIBLING-CHECKOUT-1 — the null was my clone, not their claim + +**Status:** FINDING (measured; the near-miss was real and is reproduced below). +**Confidence:** High — every step verified against a current tree, and the +stale-tree result is exactly reproducible by rewinding the sibling clone. +**Extends:** the cross-repo citation rule proposed the same day by the +`r2il-machine-semantic-contract-v1` owner session — *a citation to a removal +reads identically to a citation to the thing removed, so grep the sibling tree +for the SYMBOL, not the epiphany id.* That rule is right. This entry adds the +precondition it needs to be sound. + +**What happened.** Acting on that advice, I audited this plan's cross-repo +citations by symbol. Two greps returned zero hits for `ogar_loco::TERNLOG` — +first across `lance-graph/crates/`, then across the local OGAR checkout. Zero +hits in both trees, for a symbol a peer session had just asserted was minted +and live. The tempting write-up was ready: *a peer's central claim does not +survive verification.* + +It was my clone. `/home/user/OGAR` was **10 commits behind** `origin/main`. +`ogar-loco` exists exactly where the dependency says it does, and after a fetch +every claim verified precisely: + +| claim | verified at | +|---|---| +| `TERNLOG = FnIndex(0x86)` | `ogar-loco/src/lib.rs:607` | +| `0x87..0x8B` retracted, reserved-not-reclaimable | `lib.rs:596` | +| zero consumers | only `vocabulary.rs` arity/name registration — declared and addressable, never called | +| `BELNAP_JOIN` / `INFO_GAIN` / `STANCE_ENTROPY` / `EpistemicBassin24` | 0 hits each | + +`vocabulary.rs:1431` corroborates the retraction independently, recording a +re-pin *"to 96 (−5): only the generic TERNLOG"* — the −5 being the band. + +**The rule, stated so it does not have to be re-earned.** A cross-repo symbol +grep answers *"is this symbol in the tree I have"*, never *"does this symbol +exist"*. The two coincide only when the sibling checkout is current, and in +this workspace a sibling can be ten commits stale within a day. So: + +> **Fetch AND fast-forward the sibling tree — or grep the fetched ref +> directly (`git grep origin/main`) — then search. A zero-hit result +> on a stale working tree is a statement about your clone.** +> +> **⊘ CORRECTED pre-merge (Codex, #1157).** This rule first read *"fetch, then +> grep"*, which does not work and would not have reproduced the audit that +> produced it: `git fetch` updates remote-tracking refs and `FETCH_HEAD`, it +> does **not** touch the working tree, so a subsequent `grep` still reads the +> stale files. What actually recovered the result here was `git fetch` **plus +> `git rebase origin/main`**. A rule stated one step short of what was actually +> done is a rule that fails for its next reader — and this one was published in +> the same entry that warns against asserting from an incomplete view. + +This is the same shape as `E-A-RUNG-WRITE-PATH-ALREADY-SHIPPED-IN-A-SIBLING-REPO-1` +(below): an absence asserted from an incomplete view. That entry's failure was +not looking in the sibling repo at all; this one's would have been looking at a +stale copy of it. The correction is one line of `git fetch` in both cases, and +the cost of skipping it is asserting that a colleague's verified work does not +exist. + +**Sharpened, the cross-repo citation check is three steps, not one:** +1. `git fetch` the sibling — otherwise steps 2-3 measure your clone. +2. Grep for the **symbol**, not the epiphany id or the doc anchor. +3. Read the hit's surroundings — a symbol can survive inside a *retraction* + heading, which is the failure the original rule was written against. + +**Also verified in the same pass, and clean:** all eleven cross-repo symbols +this plan's §C cites (`ogar_loco`, `DOMAIN_FLOOR`, `ladder_program`, +`domain_stack_arity`, `ewa_sandwich`, `EvidenceMask`, `ReasoningBand`, +`CausalTopology`, `counterfactual`, `EpistemicMode`, `for_rung`) are PRESENT at +`5e2cb31d`. The September retraction did not strand any of them. Recorded +because a clean audit result is evidence too, and because the next session +should not have to re-run it blind. +## 2026-09-03 — E-THE-FIX-FOR-A-REVIEW-FINDING-SHIPS-UNREVIEWED-BY-DEFAULT-1 — the cap was the visible half + +**Status:** FINDING (measured on this PR's own review metadata). **⊘ ITS +MITIGATION IS SUPERSEDED 2026-09-03, ~2h after this entry merged** — the +paragraph below calls `@codex review` "unrelated to spend" and "not +rate-limited"; that was measured and is now FALSE. Codex returned "You have +reached your Codex usage limits for code reviews" on #1160. Both reviewers are +now capped. See `E-THE-FREE-MITIGATION-WAS-FREE-FOR-TWO-HOURS-1` (above). The +trigger-semantics MECHANISM is untouched; only the remedy's availability +changed. +**Confidence:** High for the MECHANISM (the trigger list is quoted verbatim +from the reviewer's own notice). **Medium for the coverage table**, which is an +inference from an ABSENCE: the same reviewer's stated rule is "comment when I +have suggestions, otherwise react 👍", so a missing review object proves absence +of a review *comment*, not absence of *coverage*. The two are graded apart +deliberately — conflating them is the error this entry is otherwise about. +**Prompted by:** the lance-graph-java session's flag that five consecutive PRs +merged with zero external review. + +**The visible half is a spending cap.** CodeRabbit reports 84 review attempts +in 7 days against an org cap, throttling to one review per hour, and it is why +recent PRs merged unreviewed. + +**The half nobody had named is worse, because it is not a billing setting.** +The second reviewer, Codex, is NOT capped — and it still did not see three of +the four commits on #1154. Its own notice states its triggers: opening a PR, +marking a draft ready, or an explicit `@codex review` comment. **A push is not +a trigger.** So the sequence every reviewed PR follows — + +> review lands → author fixes the finding → author pushes → merge + +— ends with **the fix for the finding as the single least-reviewed commit on +the PR.** On #1154 the reviewed commit was the one with the defect, and the +three unreviewed ones included the correction to that exact defect. Raising the +spend cap does not touch this; it is a trigger-semantics gap, and it applies to +every PR in the workspace that has ever received a finding and fixed it. + +**Why it is easy to miss.** The PR *looks* reviewed — there is a review, it +found something real, the thread is resolved, the badge is green. Review +coverage is silently attributed to the PR when it was only ever attached to one +commit. This is the same shape as the two probe findings from this same session +(`E-A-PROBE-CAN-STATE-A-MEASUREMENT-THAT-WAS-FALSE-WHEN-IT-WAS-WRITTEN-1`): a +claim measured once at one point in time, then read as a standing property of a +thing that has since changed. + +**The cheap mitigation, available today and unrelated to spend:** after pushing +a fix for a review finding, post `@codex review`. It costs one comment, is not +rate-limited, and re-points the reviewer at the head that actually contains the +fix. Done on #1154. The expensive mitigation (raise the cap) is the operator's +call and buys a different thing — breadth across PRs, not depth after a fix. + +**The mitigation is MEASURED; the gap is still INFERRED.** After that comment +the reviewer returned two P2 findings on a head it had not commented on when +that head was pushed. That is n=1 and it establishes the mitigation FIRES — it +does not establish that the push failed to trigger a review, which remains an +inference from the quoted trigger list plus absent comments. Stated apart +because the entry's own subject is a claim that outran its evidence. + +**What this does NOT claim — two independent disclaimers, both load-bearing.** +(i) No assertion that the unreviewed commits are *defective*; two are +board-only and one is a doc header. This one became MORE necessary, not less, +once the paragraph above reported that a re-triggered review found two real +defects — that result makes the "the gap caused those defects" reading +available for the first time, and it is not claimed. (ii) No assertion that an +absent review object means *not looked at*; see the Confidence line. The finding +is that the apparatus reports more coverage than it has evidence for. + +**See also** `E-A-PROBE-CAN-STATE-A-MEASUREMENT-THAT-WAS-FALSE-WHEN-IT-WAS-WRITTEN-1` +(below), which shares the abstraction *a property measured once is later read as +standing* but NOT the mechanism: that entry is about a claim decaying as the +tree changes; this one is about coverage never having attached to the commits it +is read as covering. Adjacent, not the same — do not merge them. + +## 2026-09-03 — E-THE-VACANCY-RULE-IS-NOT-ABOUT-ENTROPY-1 — a second instance on its first day, from a session that does not share the arc + +**Status:** FINDING (cross-session; the second instance was found and acted on +by another session, not by this one). +**Confidence:** **Medium-High for the rule**, **Medium for the second +instance.** The instance is a CONFIRMATION DRAW, not an independent +replication: the other session had READ this rule before applying it, same day, +same fleet, same discipline — n=2 from one primed process, not n=2 from minting +in general. And it is unverifiable here: `ogar_loco` is an external dependency, +`grep -rn TERNLOG crates/` returns **0**, so the symbol, its mint site and its +caller count are all *reported*, not measured, from this tree. (The string does +appear elsewhere in this repo — in board and knowledge prose, including this +entry — so a repo-wide grep is NOT the check; the crate-scoped one is. Prior +art for exactly this hazard: `.claude/knowledge/preflight-drift-patterns.md` +Axis 4, cross-repo PR-merge claims.) +**Generalizes:** `E-A-RULED-HOME-NEEDS-A-FIRST-CONSUMER-OR-IT-IS-A-VACANCY-1` +(entropy, same day). + +**The rule travelled.** It was written about one entropy atom with zero +callers. Within hours the lance-graph-java mask-RISC session applied it to +`ogar_loco::TERNLOG` = `FnIndex(0x86)` — minted 2026-09-01, op description +verbatim, **zero callers in either tree** — and their own plan was about to +mint an identical op kind beside it. They amended to consume the existing +address instead (lgj #70). Same shape, different domain, different repo, +different arc, no shared code: a ruled artifact that nothing calls is not a +home, and the next session's default move is to build its twin next door. + +That is worth more than a second data point. The original entry was written as +a fact about `thought_atoms`; it is really a fact about **minting**, and the +generalisation was demonstrated rather than argued — by someone with no stake +in the entropy arc. + +**A second finding from the same audit, sharper than it looks.** That session +also audited `witness_fabric` and correctly declined the tempting conclusion +(*"contradiction is already implemented, drop my verb"*): this module's +quorum/contradiction is family (1) episodic loci, theirs is family (3) +epistemic population basins, which +`E-SIX-SEMANTIC-FAMILIES-MUST-NOT-IMPERSONATE-EACH-OTHER-1` records as an +accepted vacancy. They got it right — and then observed that the module's own +header never says which family it is in. + +**They were right, and the reason is the useful part — but the first version of +this paragraph overstated it and is corrected here.** It said the distinction +was recorded *"only in a PR body."* That is FALSE: it is also on this very +board, at `EPIPHANIES.md:355` (the D-POP-2 entry), verbatim — *"No +population-basin work: family 3 stays the accepted vacancy."* The knowledge was +in TWO durable places and was still unavailable at the site of the misreading, +which makes the finding **stronger**, not weaker: the defect is not that the +boundary lived somewhere fragile, it is that **it was absent from the SOURCE**. +The next reader greps the tree, not the board's 25,000 lines and not the PR +archive. Prose that +exists to stop a future misreading has to live where the misreading will +happen — in this case, the module header, which now names family (1), quotes +the ruling, and names the specific confusion (family 3) it forecloses. + +The generalisation for this workspace: the board is where a decision is +JUSTIFIED; the source is where it must be ENFORCED. Neither a PR body nor a +board entry enforces anything at the call site. + +**Two claims, one id — and the reason is an AUDIT, not a cause.** This entry +carries the vacancy-rule generalisation and the placement finding above. They +have no common cause; they were found in one cross-session audit, and F1 +(append-only) makes a new prepended id the only lawful vehicle for either, so +splitting after the fact is not available. Signposted so a future search for +"PR body" reaches this entry rather than only the vacancy half. Prior art for +the placement claim: `.claude/board/entries/2026-08-13-e-a-figure-you-tallied-yourself-is-a-derived-figure-1.md:49-54`. + +## 2026-09-03 — E-A-PROBE-CAN-STATE-A-MEASUREMENT-THAT-WAS-FALSE-WHEN-IT-WAS-WRITTEN-1 — the census's own caller count, wrong twice + +**Status:** FINDING — a **new INSTANCE of an already-ruled pattern**, not a new +rule. `.claude/knowledge/preflight-drift-patterns.md` Axis 1 ("Stale-Claim +Verification") already names this failure mode *including its worse half*: +"…OR was never true and was an error in the planner's self-report", with the +remedy "run the actual git command… never trust the assertion". Two further +predecessors: `EPIPHANIES.md:8660` (a figure cited twice is not confirmed once) +and `:10275` (prose duplicating a machine-readable value has a half-life); +`:252` (`E-A-CORRECTION-CAN-SUBSTITUTE-ONE-WRONG-NOUN-FOR-ANOTHER-1`) is the +same shape one level up — a correction that carries a correction's authority +while being itself incomplete, which is precisely what the review finding that +prompted this entry turned out to be. +**Confidence:** High — the falsifying lines are in the probe file itself. What +is genuinely NOVEL here is narrower than the entry first implied, and it is the +credibility mechanism below, not the decay. +**Corrects:** `crates/lance-graph-planner/examples/entropy_surface_census.rs` +(the caller-census block), shipped in `e5e2520` and fixed in `abcdb0d5`. + +**What happened.** The entropy census printed, as part of its output, that +form A (`thought_atoms::normalized_entropy`) "has ZERO callers in the tree +today", citing a grep "returning nothing" as verification. A review bot caught +that the consolidation in the very next commit gave form A a production caller, +making the printed claim false. + +**Re-running the cited command found the worse half** (measured at `e5e2520`, +the census commit: the probe imported form A at line 38 and called it at line +325, and the cited grep returned **6 hits**, not nothing — pinned to that +commit because the count is exactly the kind of number this entry is about). +The claim was **already +false at the commit that introduced it**: the probe file itself imports form A +(line 38) and calls it (line 325), so the grep it cites had a non-empty result +the moment the file existed. The measurement was taken *before* the file was +written and was never re-run against the tree it then described. The reviewer +found the second staleness; the first shipped unnoticed. + +**Why an executable probe is the worst host for this.** Prose in a plan reads +as a claim. The same sentence inside a running probe reads as *output* — as +something the program checked — and this workspace's whole probe discipline +trains readers to believe measured numbers over asserted ones. A stale line in +a probe therefore borrows credibility that nothing earned. **That borrowing is +this entry's one novel contribution** — the decay itself was already ruled (see +Status). + +**The line is PROVENANCE, not subject matter.** A first version of this +paragraph ended "an unasserted `println!` is not a measurement, it is a comment +with better formatting", and that proves too much: two lines above the offending +block, the same file legitimately prints `max-min spread … reported, not +dramatized`, a value THIS RUN computed, and the file's own design comment +("assertions moved to the END because a probe that aborts early hides +evidence") presupposes that printed output IS evidence. The discriminator that +exonerates that line and still condemns the census block is **who produced the +number**: a value computed by the running probe carries the run's authority; a +value TRANSCRIBED BY THE AUTHOR into a `println!` carries none, and is a +comment wearing the run's clothes. Narrowing it to "claims about the state of +the tree" would have been the wrong axis and would have duplicated the rule +below. + +**The rule this leaves.** A claim about the STATE OF THE TREE decays the moment +the tree changes, and the commit most likely to change it is the one the claim +was written to motivate. So such a claim must carry (a) the commit it was +measured at and (b) the command that measures it, so a reader re-runs rather +than trusts — the same "measurements go in the ledger with a date, methods go +in the doc" split `CLAUDE.md` already applies to the clippy-count trap in +medcare-rs. The corrected block does exactly that, and separates the probe's +own use of a symbol from its production callers, which is the distinction the +original grep silently elided. + +**What it does NOT change.** C1/C2/C3 and their fixtures are untouched — they +assert, they run, and they still pass. Only the unasserted census line was +wrong, which is itself the point: every claim in that file that was gated by an +`assert!` survived, and the one claim printed without one did not. + +## 2026-09-03 — E-A-RULED-HOME-NEEDS-A-FIRST-CONSUMER-OR-IT-IS-A-VACANCY-1 — the entropy atom's first caller, and the one convention that had to be defended + +**Status:** FINDING (shipped; disable-verified). +**Confidence:** High — the substitution's safety was measured before it was +made, and its one unsafe edge is pinned by a test that fails when the guard +is removed. +**Follows:** `E-THE-ENTROPY-HOME-WAS-RULED-AND-LEFT-EMPTY-1` (the census that +licensed exactly this consolidation and nothing wider). + +**What shipped.** `lance_graph_planner::nars::insight::confidence_entropy` no +longer carries its own Shannon loop; it extracts a 10-bin histogram and hands +it to `lance_graph_contract::thought_atoms::normalized_entropy`. That atom — +operator-ruled 2026-08-31 as a *universal thinking atom* — had **zero +consumers** until this commit. A ruled home with no caller is not a home; it +is a vacancy that the next session re-implements beside. + +**The measurement is what made this a two-line change rather than a +hypothesis.** PROBE-ENTROPY-SURFACE-CENSUS-1 (`e5e2520`) had already +established C1: the log base is inert under normalization +(`log2/log2(10)` vs `ln/ln(10)` agreed to `0.00000000` on every fixture). So +the caller's `log2`-and-divide-by-`log2(10)` and the atom's +`ln`-and-divide-by-`ln(n)` are the same function, and the routing needed no +tolerance argument at all. + +**The one place the two disagree is the whole risk, and it is silent.** The +census's C2 falsification recorded that the caller's convention and the +atom's are OPPOSITE on zero mass: the caller returns `0.0` for an empty +arena, the atom returns `Some(1.0)` ("nothing prefers anything — +indistinguishable from uniform"). An empty arena builds an all-zero +histogram, so dropping the caller's `is_empty` early return would report +**maximal uncertainty for an arena that holds none** — and `1.0` is in range, +so nothing downstream would object. The guard is therefore load-bearing and +now says so in its own doc comment, pinned by +`an_empty_arena_has_zero_truth_entropy_not_one` (disable-verified: deleting +the early return fails that test and only that test, 13 passed / 1 failed). + +**The paired can-fire half exists because the guard test is satisfiable by a +stub.** `an_empty_arena_has_zero_truth_entropy_not_one` would also pass for a +`confidence_entropy` hardcoded to `0.0`, so +`the_routed_atom_still_spans_the_confidence_range` asserts the routed atom +covers the full range on non-trivial inputs — one occupied bin ⇒ `0.0`, ten +evenly occupied ⇒ `1.0` — and, third, that the normalization is by the **bin +count** and not the occupied count (five bins of two ⇒ `ln 5 / ln 10`). That +third assertion is the one that would catch a plausible-looking rewrite which +normalized by however many bins happened to be non-empty. + +**What is still NOT licensed, restated so the scope does not drift.** Forms +C/D/E were left alone (two live in workspace-excluded crates, so no +in-workspace caller can route to them), and forms F/G were left alone +deliberately: C3 measured them moving `92.103409` between the same +distribution at 1× and 10× mass and going negative on elements above 1, which +means they are not entropies of a distribution at all. "Fixing" them is a lab +behaviour change and needs its own gate, not this one's. + +**A convergence worth naming, because it was found twice independently.** +`rubicon-loco-rung-cognitive-fabric-v1.md` §130 (another session, merged the +same day as #1152) reached the same fragmentation finding from the opposite +direction and recorded it as *"Shannon entropy — EXISTS BUT NOT +LOCO-ADDRESSABLE — ≥6 uncoordinated `entropy()` surfaces"*; the census +measured seven. The two arcs are complementary rather than competing, and the +distinction is worth keeping sharp: that plan wants entropy to have an +**address** (a loco-addressable Frozen atom), this arc gives it a **home** +(one canonical implementation with a real caller). An address for a function +that still exists in seven copies would just name one of them. Its +accompanying rule — *"Do not rewrite good SIMD in R2IL to claim purity"* — is +the same restraint the census's F/G verdict already imposed here. + +## 2026-08-31 — E-A-CORRECTION-CAN-SUBSTITUTE-ONE-WRONG-NOUN-FOR-ANOTHER-1 — three readings of one mechanism, and the source named itself the whole time + +**Status:** FINDING (verified against source at `cc0046f8`; every claim carries +`file:line`). +**Confidence:** High — the mechanism is in-tree and self-describing. +**Corrects:** `.claude/plans/rubicon-loco-rung-cognitive-fabric-v1.md` §F.1 +(see §F.6 there for the full account). + +**The shape of the failure.** One mechanism, three readings by this session, +two of them wrong — and the second wrong one was produced *by the correction +of the first*: + +| reading | verdict | +|---|---| +| ten residual deltas sharing a 480-byte value slab | wrong — withdrawn | +| ten rows / ten tables at one address | **wrong — corrected here** | +| ten lanes over ONE `AlphaAllocation` | correct (`contract/src/alpha_tunnel.rs:73-89`) | + +`AlphaTunnel` holds `lanes: Vec>` and constructs them by +mapping `(0..LEVELS)` over a single borrowed allocation; `LEVELS = 10` +(`contract/src/rung_schedule.rs:59`). One lane costs one empty `Vec` +(`alpha_tunnel.rs:25-27`). The module states the prohibition outright: ten +lanes must not mean ten address sets, because reserving is defined as costing +zero rows and ten copies of the address set would make "reserve" cost ten +times nothing (`:22-24`, restated from the allocation's side at +`alpha.rs:454-456`). + +**"Split tunnel" was never a budget or a table count.** It names a *read/write +path split*: reads go to the baked spine, shared across all ten lanes without +a lock because `&[NodeRow]` may be shared; writes go to the overlay at the +same addresses, and that direction is a compile-time property rather than a +runtime check (`alpha_tunnel.rs:12-18`). Neither earlier reading contained +this at all, though it is what the two words literally say. + +**Two things checked rather than assumed, both of which cut against the +convenient conclusion:** + +1. **The persistence half did not migrate.** `alpha.rs:1-5` records that the + Arrow/Lance storage glue deliberately stayed with the storage crate; what + moved is the pure overlay algebra over contract types. So `lance-graph` can + now *express* a rung stamp and still cannot *persist* one — the prior + entry's persistence table remains accurate as a statement about this repo. +2. **`D-ACR-3`'s blocker survives.** A landed write path looks like it should + unblock it. `mailbox_owner()` still has zero callers outside its own + module; the only occurrence elsewhere in `crates/` is a doc-comment mention + at `alpha_tunnel.rs:33`. The tunnel enforces one-writer *structurally* via + per-lane `&mut` (`:29-38`), not through the mailbox-ownership machinery + `D-ACR-3` exists to test. + +**The rule, which is what outlives the specific mistake.** A correction that +swaps one English noun for another has not necessarily moved closer to the +truth — it has produced a second guess with the authority of a correction. +Both wrong readings here described a *shape* ("deltas", "rows") without ever +naming the *type*. The mechanism had a name, a definition, and a module doc +arguing its own design, and none of the three was cited until the third pass. +**When correcting a claim about a mechanism, cite the type's definition; do +not re-describe its shape.** Fence: `F-RLR-12` in the plan. + +**Timeline worth keeping**, because it shows the audit was load-bearing rather +than academic: the sibling-repo implementation was found 2026-08-29 +(`E-A-RUNG-WRITE-PATH-ALREADY-SHIPPED-IN-A-SIBLING-REPO-1`, below); #1112 +migrated it into the contract on 2026-08-31 as the substrate default. The +audit's own second correction was published one day before the thing it +described moved. +## 2026-09-03 — E-THE-ENTROPY-HOME-WAS-RULED-AND-LEFT-EMPTY-1 — the D-DCR-4 gate measured seven entropy surfaces: the consolidation target already exists by operator ruling, has zero consumers, and is NOT a drop-in for the caller nearest to it + +**Status:** FINDING (measured, `lance-graph-planner/examples/entropy_surface_census.rs`, two disable-runs red-then-green). **Confidence:** High for the three measured claims; the six transcribed forms are only as current as their cited `file:line`. + +**Why the probe existed.** D-DCR-4 opens with "entropy-surface CONSOLIDATION decision recorded first" and rubicon §C names "≥6 uncoordinated `entropy()` surfaces". Before measuring, the Cholesky trap was checked: does a ruling already answer this? `E-JC-IS-THE-HOME-OF-ALL-CALIBRATED-MATH-1` would send entropy to `jc` by analogy with cronbach/spearman — but `jc` carries NO entropy surface, and `thought_atoms`'s own module doc records a DIFFERENT operator ruling (2026-08-31, verbatim: *"shannon, Mengenlehre etc sind universale denk atome"*) naming that module as the landing site. **Two rulings could plausibly claim entropy; the shipped one is `thought_atoms`, and a future session lifting entropy into `jc` by analogy would be wrong.** + +**The census — seven forms, four conventions.** A `contract::thought_atoms::normalized_entropy` (÷Σw, ln, ÷ln n, `Option`); B planner `insight::confidence_entropy` (÷n, log2, ÷log2 bins); C `cognitive-shader-driver::entropy_std` (÷Σ, ln, UNNORMALIZED out); D `cognitive::distribution::entropy` (÷total, log2, unnormalized); E `cognitive::features::compute_entropy` (÷total, ln in f64, ÷ln W); F `thinking_engine::qualia::shannon_entropy` and G `thinking_engine::dto::entropy` — **neither normalizes its input at all**. + +**C1 PASS — normalization makes the log base inert.** Every normalized form agrees with a log2 twin to `0.00000000`. The ln/log2 split among A/B/E is cosmetic, so "it uses log2" is never by itself a reason two of these differ. + +**C2 FALSIFIED AS PRE-REGISTERED — and this is the finding that pays for the probe.** Pre-registered: "B is A on every non-empty fixture". Measured: B ≡ A to `0.0` exactly on all six non-degenerate fixtures, and **OPPOSITE on zero mass — A = 1.0 ("zero-sum = uniform", its own hand-math test), B = 0.0. The gap is 1.0, the entire range of a normalized entropy.** The claim was restated to what was measured, never relaxed to pass. Consequence: **routing B through A is not a drop-in.** `confidence_entropy` returns `0.0` early on an empty arena; a routing that drops that early return builds an all-zero 10-bin histogram, and the atom answers `Some(1.0)` — an empty arena's entropy silently inverts from "no uncertainty" to "maximal uncertainty". Predicted from the atom's tests before the probe ran, then measured. + +**C3 PASS — F and G are not entropies of a distribution.** Between `uniform4` and `uniform4_x10` (the SAME distribution at 10× mass) A..E are exactly invariant and F, G move by **92.103409**. They also go NEGATIVE on any input with elements > 1 (`two_point` → −3.295837), because `−Σ e·ln e` over an unnormalized vector is not an entropy. The invariance of A..E is the anti-vacuity guard — without it the claim would pass on a tree where nothing is invariant. + +**The atom is unused.** `grep -rn 'thought_atoms::' --include=*.rs crates | grep -v /target/` returns NOTHING: not just `normalized_entropy` but the entire operator-ruled module has zero consumers. The survey's §2 row S1 recorded the weaker "0 callers" for one function; the module-level fact is stronger and is what makes the consolidation live work rather than bookkeeping. + +**Two process points, both already burned once in this session.** (1) The first run PANICKED at C2 and C3 never ran — a probe that asserts inline hides the evidence behind its first failure; assertions now run at the END. (2) The `single` fixture makes B's `÷log2(1)` denominator zero and B returns NaN — an artifact of the probe's slice generalization (the source's `BINS` is a const 10 and can never be 1), pinned as C2d rather than hidden, so it cannot change silently. + +**What this licenses.** Recording the consolidation decision for D-DCR-4: the target is `thought_atoms`, not `jc`; B is the one in-workspace caller that can route to it, and only with its zero-mass early return PRESERVED and pinned. **What it does NOT license:** touching C/D/E (two live in workspace-excluded crates), or "fixing" F and G — they are consumed as a relative score inside the lab engines and changing them is a behaviour change needing its own gate, not a drive-by. + +Refs: `dismech-causal-replay-v1` D-DCR-4; `post-teardown-buildup-survey-v1` §2 S1; `E-JC-IS-THE-HOME-OF-ALL-CALIBRATED-MATH-1`; `thought_atoms.rs` module doc (operator, 2026-08-31); CLAUDE.md § The falsifiability rule. + +## 2026-09-03 — E-A-DOCUMENTED-MODULE-THAT-WAS-NEVER-`pub mod`-D-IS-DEAD-CODE-WITH-A-PARITY-CLAIM-1 — `sigker::log_signature` shipped 388 lines, a citation, and a compression table without ever being compiled; wiring it in falsified the projection AND two numbers in its own doc-comment + +**Status:** SHIPPED (code + 12 falsifiers, branch `claude/sigker-log-signature`; `witt_dimension` / `enumerate_lyndon_words` / `bracket_expansion` / `project_onto_lyndon_basis` / `log_signature_truncated`). **Confidence:** High for the algebra (the residual test is a real two-sided falsifier and it failed on the wrong convention before passing on the right one); High for the corrected ratios (recomputed independently before trusting the file). + +**The failure mode, precisely.** `crates/sigker/src/log_signature.rs` existed on `main`, tracked, 388 lines, with a Reizenstein-Graham citation and a compression table — and `crates/sigker/src/lib.rs` had **no `pub mod log_signature;`**. `lib.rs`'s module doc advertised it as item 5 ("Compression 7–13× … with NO information loss"), so every reader of the crate header believed it shipped. It had never been compiled once: `cargo build --examples` failed with `E0432: unresolved import sigker::log_signature` from `examples/depth_scaling.rs`, which imported the module the crate never declared. **A file being present, tracked, and cited is not evidence that it compiles**; the only evidence is a build, and the one build that would have caught it was the example that had been red the whole time. + +**What the compile-once exposed, in ascending order of severity.** + +1. **Four clippy findings inside the file** (`manual_implementation of is_multiple_of`, in `mobius`/`witt_component`) — invisible to every prior `cargo clippy` run, because a module that is not `pub mod`-d is not part of the crate graph and is never linted. The other 4 sigker findings (`randomized.rs`, `signature.rs`) are genuinely pre-existing and were left alone. +2. **Two wrong numbers in its own doc table**, recomputed from the Witt formula before being trusted: `d=4, N=8` was documented as `11164` (真 **11464** — transposed digits; ratio 7.6× not the claimed 7.8×), and `d=2, N=12` as `632 / 13×` (真 **747 / 11.0×**). Both are now asserted by `witt_table_matches_measured_ratios`, so a re-typo goes red instead of shipping. +3. **The projection was not the projection.** The module read `log_tensor[flat(w)]` at each Lyndon word's flat index and called the result "the Lyndon-basis coefficients" — its own doc comment conceded it "omit[ted]" the transformation matrix. But the change of basis is **unitriangular**, not identity: `P_w = w + Σ_{x>w} a_{w,x}·x` (Lothaire Thm 5.3.1), so a flat read returns `c_w + Σ_{u