Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
222 changes: 222 additions & 0 deletions .claude/ATTENTION_MASK_AUDIT_2026_08_21.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
# D-ACR-0 — `attention_mask` audit against piece E

> **Deliverable:** `alpha-channel-rung-overlay-v1.md` §4, `D-ACR-0`.
> **Scope:** report only, no code — as the deliverable specifies.
> **Falsifier:** *"the audit names a caller, or records EXISTS-UNCALLED."*
> **Verdict: EXISTS-UNCALLED — and the shipped type is a DIFFERENT MECHANISM
> wearing the name.** Both halves matter; the second is the load-bearing one.
>
> Every claim below is a read of the file named, this session. Every "absent"
> is a grep that returned nothing, with the grep stated.

## 1. The question D-ACR-0 asks

Piece E of §1 graded `cognitive-shader-driver/src/attention_mask.rs` +
`attention_mask_actor.rs` as *"shipped; **unaudited for this use**"* — the use
being the operator's **eye-tracking residue carrier**: *"record WHERE the eye
looked, not what it saw"*, an ephemeral overlay whose rows are the addresses a
search visited.

So the audit's question is not "does it work" but **"is the shipped mask a
residue carrier, or something else wearing the name?"**

## 2. Callers — measured

```
grep -rn "AttentionMask|attention_mask" --include=*.rs . # workspace, minus target/

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Run the caller search with alternation enabled

The recorded command cannot reproduce this audit: ordinary grep treats | as a literal unless -E is supplied, so this exact invocation returns no matches rather than the three reported hits; it also does not exclude target/ despite the comment. Because the EXISTS-UNCALLED verdict is the deliverable's main falsifier, record the actual reproducible search, such as rg --glob '*.rs' --glob '!target/**' 'AttentionMask|attention_mask', before marking the audit shipped.

Useful? React with 👍 / 👎.

```

Three hits outside the two files themselves. All three are non-consumers:

| hit | what it actually is |
|---|---|
| `lib.rs:93` `pub mod attention_mask;` | module declaration |
| `lib.rs:94` `pub mod attention_mask_actor;` | module declaration |
| `mailbox_soa.rs:11` | a **doc comment stating the opposite**: *"wrap, **NO AttentionMask/LRU**, NO cross-cycle rollup — those are W6's"* |

Sibling repos, same grep: `MedCare-rs` 0 files · `OGAR` 0 files ·
`ndarray` 0 files.

**No caller exists anywhere.** The one file that names it in code-adjacent
prose does so to declare that it does *not* use it. `EXISTS-UNCALLED` is
recorded, per the falsifier's second branch.

## 3. What the type actually is

`AttentionMaskSoA` (`attention_mask.rs:46`):

```rust
pub struct AttentionMaskSoA {
pub entries: Vec<AttentionMaskEntry>, // (mailbox_id, w_slot, active, last_touched_cycle, plasticity_residual)
pub max_active: usize,
pub current_cycle: u32,
}
```

Its whole surface is `touch` / `evict_lru` / `tick` / `active_count` /
`is_active` / `entries`. Read plainly: **an LRU admission-control table keyed
by `MailboxId`, holding a 6-bit `w_slot` per entry.**

Three properties decide the verdict:

- **Keyed by mailbox, not by row or address.** The key is `MailboxId`
(`= u32`, from `contract::collapse_gate`). There is no `NodeGuid`, no
`NiblePath`, no classid, no row index anywhere in the file.
- **It is not a mask.** `entries: Vec<_>` with `.iter().find(...)` in `touch`,
`.iter().filter(...).min_by_key(...)` in `evict_lru`, `.iter().filter().count()`
in `active_count`, `.iter().any()` in `is_active` — **every operation is an
O(n) linear scan over a `Vec`.** No bitset, no set algebra, no
union/intersect/andnot.
- **It records occupancy, never a trajectory.** `last_touched_cycle` is
overwritten on each `touch` (`:88`). The previous value is gone. A residue
carrier must answer *"where did the eye look"* — this type can only answer
*"is this mailbox currently claimed, and how stale."*

## 4. The name collision, traced to its origin

The shipped type is not a half-built residue carrier. It is a **complete
implementation of a different design**, and that design is on the board:
`causaledge64-mailbox-rename-soa-v1.md` §4 —
Comment on lines +77 to +79

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not classify the partial table as a rename register

When a later CE64 implementation session relies on this classification, it will incorrectly treat the rename mechanism as already implemented. AttentionMaskSoA::touch accepts both a MailboxId and an already-selected w_slot; it never allocates a slot, maps a WitnessId/StyleId/OGIT identity, or provides the plan's bind/lookup/resolve operations. The audit itself acknowledges the required slot tables and actor binding are absent in §5, so describe this as a partial LRU association scaffold rather than a complete implementation of the rename-register design.

Useful? React with 👍 / 👎.


> *"**AttentionMask SoA — the session-ephemeral rename register file.**"*

Its job there is the exact inverse of a residue overlay:

| | rename register file (what shipped) | residue carrier (piece E) |
|---|---|---|
| direction | **wide identity → narrow slot** | **visited address → recorded** |
| why LRU | slots are **scarce** (5-bit G / 6-bit W / 8-bit style) and must be recycled | — nothing is scarce; the overlay is discardable whole |
| keyed by | `MailboxId` | the graph's own address (`NodeGuid`/`NiblePath`) |
| answers | *"which slot currently holds this identity"* | *"where did rung-n look"* |
| history | none — `last_touched_cycle` is overwritten | the point of the thing |

The originating plan is explicit that CE64 needs this because a `u32` OGIT
domain cannot fit in 5 bits: the rename table is what lets a wide identity ride
in a narrow field. **That is a compression concern, not an attention concern.**
The word "attention" in the name refers to *which identities are currently
resident in the scarce slot file* — a cache-occupancy sense, not the
eye-tracking sense §0 uses.

This is the **fourth homonym collision** this arc has had to separate, after
§3a's four "witness" surfaces, §3k's four "nibble" encodings, and §3l's three
"hydration" meanings. Same discipline applies: the shared word is not evidence
of a shared mechanism.

**The dependency map already warned about exactly this**
(`bindspace-mailbox-soa-dependency-map-v1.md:108`, `:191`):

> *"`attention_mask.rs` / `attention_mask_actor.rs` define their OWN
> `AttentionMaskSoA` — share only the `MailboxId`/`w_slot` vocabulary.
> **Do NOT conflate** with `MailboxSoA<N>`."*
> *"independent `AttentionMaskSoA`; do not fold into the migration."*

That warning was aimed at a different conflation (vs `MailboxSoA`), but it
generalises, and it is the reason piece E's grade was *"unaudited"* rather
than *"shipped for this"*.

## 5. Incompleteness even against its OWN spec

Worth recording so a future session does not read "shipped" as "finished":

| the rename-SoA plan §4 specifies | what shipped |
|---|---|
| `g_slots: [Option<u32>; 32]` (5-bit OGIT domain) | **absent** |
| `w_slots: [Option<WitnessId>; 64]` (6-bit witness palette) | present only as a bare `w_slot: u8` field — no `WitnessId`, no slot table |
| `style_slots: [Option<StyleId>; 256]` (8-bit style) | **absent** |
| fixed-size arrays (the point — a register FILE) | a growable `Vec` |
| *"Owned by a singleton ractor actor `AttentionMaskActor`"* | trait scaffold only — `attention_mask_actor.rs:2`: *"concrete ractor binding is sprint-12+ work"* |

Two further dead surfaces, both measured:

- **`plasticity_residual: u8`** — *"reserved for sprint-12+ learning signal"*.
Grep across the workspace returns exactly two hits: its declaration
(`:36`) and its initialisation to `0` (`:98`). **It is never read and never
written non-zero.** A field that only ever holds its zero value carries no
information — the same shape as the `closed_class_guess` 150/150 defect the
falsifiability rule names.
- **`AttentionMaskMsg::BindReply`** — its handler is
`AttentionMaskOutcome::NoOp` (`actor:97`). The variant exists, carries three
fields, and does nothing. `reply_to: u32` is discarded via `..` in the one
pattern that matches it.

## 6. The singleton problem — the design predates a ruling that killed it

§4 of the originating plan says the actor is a **singleton** ("one global
instance per session"). That is the shape the V3 mailbox ruling removed:
**no singleton CollapseGate; one mailbox = one kanban board as tenant**
(`CLAUDE.md` ★ V3 entry point; `E-CE64-MB-4` one-writer-per-mailbox).

So the unfinished ractor binding is not merely unfinished — **finishing it as
specified would rebuild a singleton the substrate deliberately eliminated.**
Anyone picking `attention_mask_actor.rs` up should treat "sprint-12+ work" as
superseded, not queued.
Comment on lines +149 to +152

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep the actor queued until its own ruling is superseded

The cited V3 ruling forbids a singleton CollapseGate/shared thoughtspace and enforces one writer per mailbox; it does not state that a session-scoped rename registry is forbidden. In fact, the active rename plan still explicitly specifies the singleton actor, and STATUS_BOARD.md still lists D-CE64-MB-5-impl as queued. Telling implementers to treat it as superseded therefore contradicts the repository's active plan and can cause required rename work to be skipped; this conclusion needs an explicit ruling that supersedes D-CE64-MB-5, or it should be removed.

Useful? React with 👍 / 👎.


## 7. Consequences for `D-ACR-1`

The audit's purpose is to tell `D-ACR-1` what it can reuse. The answer is
**nothing structural**, and that is a cleaner starting position than a partial
fit would have been:

1. **Do not extend `AttentionMaskSoA`.** It is a correct implementation of a
different contract, uncalled, keyed by the wrong thing, and O(n) per
operation. Extending it would fold two mechanisms into one type — the
conflation §3a/§3k/§3l each had to unpick.
2. **Do not reuse the name.** A fifth homonym is avoidable here at zero cost:
`RowFocusMask` is already the board's own name for the primitive (S3.1b),
and it says what it is — a mask, over rows.
3. **The governing choice rules out the shipped shape anyway.** §3k's
operator-stated default is
`Mask × ClassView/WideFieldMask → Mask`, bulk, *"never per-row, never
per-frontier-size"*. `AttentionMaskSoA` is a per-entry linear scan — the
precise shape `lance-graph-java`'s `Predicate.java` doc calls
*"catastrophic"* (*"64,000 objects and 64,000 crossings for 64,000
entities"*). It is not a starting point that can be optimised into
compliance; it is the anti-pattern named.

### A measured constraint `D-ACR-1` must design around

`D-ACR-1`'s scope line says *"composable with `WideFieldMask` per S3.1b"*.
Measured this session (`class_view.rs:221`, `:251`, `:510`):

- `WideFieldMask` positions are **`u8`** — the universe is **capped at 256**,
with a loud refusal (`WideMaskCapError::UniverseExceedsSocCap`) above it,
*"never a silent drop or truncation."*
- It has real set algebra (`union`, `intersect`, `with`, `has`,
`from_positions`, `EMPTY`).
- Its sibling `FieldMask` is `u64` with `MAX_FIELDS = 64`, and positions
`>= 64` are **silently dropped** by `from_positions` / `with` (`:88`,
`:100`) — documented as deliberate, but a trap if confused with the wide
form.

**So "composable" cannot mean "the same type".** `WideFieldMask` addresses
**field positions** (≤ 256 of them); a `RowFocusMask` addresses **rows**
(a population, unbounded). These are two different bases, and composing them
is precisely the latent-third-basis problem the plan already parked:

> §6 **Y2** — *"`RowFocusMask × WideFieldMask` basis collision — the HTT
> **X4** latent-third-basis problem applies verbatim the moment a focus mask
> meets a field mask"* — *"X4 is audited, not solved, deliberately."*

The audit's contribution is to make that concrete rather than latent: the
collision is not a subtle semantic worry, it is a **cardinality mismatch with
a hard, loud cap on one side.** `D-ACR-1` must state which basis it is in and
what the composition operator means, before it composes anything — otherwise
the first `RowFocusMask` over a population > 256 either refuses loudly (if it
borrows `WideFieldMask`'s cap) or drops silently (if it borrows `FieldMask`'s
rule). Neither is a design; both are an inherited accident.

## 8. Verdict

| question | answer |
|---|---|
| Does a caller exist? | **No.** `EXISTS-UNCALLED`, workspace-wide + three sibling repos. |
| Is it a residue carrier? | **No.** It is a **rename register file** (`causaledge64-mailbox-rename-soa-v1.md` §4) — wide identity → scarce narrow slot, LRU because slots are scarce. |
| Is it a mask? | **No.** `Vec` + linear scan; no bitset, no set algebra. |
| Is it complete against its own spec? | **No.** 2 of 3 slot tables absent; `Vec` not fixed array; ractor binding never built; one field write-once-zero; one message variant a NoOp. |
| Can `D-ACR-1` build on it? | **No** — and it should not try. Piece D stays what §1 called it: *"the only one that is a missing primitive."* |

**Piece E's grade is corrected from *"shipped; unaudited for this use"* to
*"shipped for a DIFFERENT use; uncalled; not a basis for piece D."*** Six of
nine pieces still exist or are planned (§1's count is unchanged — E existing
was never the claim that E fits); what changes is that E is now known not to
serve D, so `D-ACR-1` starts clean instead of starting from an assumed reuse.
81 changes: 81 additions & 0 deletions .claude/board/EPIPHANIES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,84 @@
## 2026-08-21 — E-ATTENTION-MASK-IS-A-RENAME-REGISTER-FILE-NOT-A-RESIDUE-CARRIER-1 — the fourth homonym collision of this arc, and the only one where the shipped type is COMPLETE for a different contract

**Status:** FINDING (D-ACR-0, report-only deliverable; every claim a read of
the file named or a stated grep). **Confidence:** High — the caller count is a
workspace-wide grep plus three sibling repos; the origin is the shipped type's
own originating plan, quoted.

`alpha-channel-rung-overlay-v1.md` §1 piece E graded
`cognitive-shader-driver/src/attention_mask.rs` + `attention_mask_actor.rs`
*"shipped; unaudited for this use"* — the use being the operator's
eye-tracking residue carrier. The audit
(`.claude/ATTENTION_MASK_AUDIT_2026_08_21.md`) returns **both** branches of the
falsifier at once, and the second is the load-bearing one.

**EXISTS-UNCALLED.** Three hits outside the two files, all non-consumers: two
`pub mod` lines in `lib.rs`, and `mailbox_soa.rs:11` — a doc comment stating
the *opposite* (*"wrap, **NO AttentionMask/LRU**, NO cross-cycle rollup"*).
`MedCare-rs` / `OGAR` / `ndarray`: 0 files each.

**And it is a different mechanism wearing the name.** The shipped type is a
complete implementation of `causaledge64-mailbox-rename-soa-v1.md` §4 —
*"AttentionMask SoA — the session-ephemeral **rename register file**"*: wide
identity (`u32` OGIT domain / `WitnessId` / `StyleId`) → scarce narrow slot
(5-bit G / 6-bit W / 8-bit style), LRU **because slots are scarce**. That is a
COMPRESSION concern. "Attention" there means *which identities are currently
resident in the slot file* — cache occupancy, not where the eye looked. A
residue carrier runs the opposite direction (visited address → recorded), is
keyed by the graph's own address rather than `MailboxId`, and is discardable
whole precisely because nothing is scarce.

Three properties settle it independently of provenance: keyed by `MailboxId`
(no `NodeGuid`/`NiblePath`/classid anywhere in the file); **not a mask** —
`Vec<AttentionMaskEntry>` with `.iter().find` / `.min_by_key` / `.filter().count`,
i.e. O(n) linear scan per operation, no bitset, no set algebra; and it records
occupancy, never a trajectory (`last_touched_cycle` is overwritten on each
`touch`, so the previous look is gone).

**Why this one is worse than the three homonyms before it.** §3a separated four
"witness" surfaces, §3k four "nibble" encodings, §3l three "hydration"
meanings — in each, the collision was between things that plainly did
different jobs once named. Here the shipped type is *finished and correct for
its own contract*, so it reads as available. The near-miss is the trap:
"shipped" invited reuse, and reuse would have folded a compression register
file into an attention overlay.

**Consequence, recorded so D-ACR-1 does not re-derive it:** piece E regrades
from *"shipped; unaudited for this use"* to ***"shipped for a DIFFERENT use;
uncalled; not a basis for piece D."*** §1's six-of-nine count is unchanged —
E existing was never the claim that E fits. `D-ACR-1` starts clean, which is a
better position than a partial fit; and the governing choice rules the shipped
shape out anyway, since a per-entry linear scan is the exact
*"64,000 objects and 64,000 crossings"* shape `lance-graph-java`'s
`Predicate.java` calls catastrophic, not a starting point that optimises into
`Mask × ClassView/WideFieldMask → Mask` compliance.

**Two dead surfaces measured in passing**, both matching shapes the
falsifiability rule already names: `plasticity_residual: u8` is declared and
initialised to `0` and **never read, never written non-zero** (two grep hits
total) — a field that only holds its zero value carries no information, the
`closed_class_guess` 150/150 shape; and `AttentionMaskMsg::BindReply` carries
three fields to a handler that returns `NoOp`.

**One superseded plan step, flagged rather than queued:** the originating §4
specifies a **singleton** actor (*"one global instance per session"*), and
`attention_mask_actor.rs:2` still calls the concrete ractor binding
*"sprint-12+ work"*. Finishing it as written would rebuild the singleton the
V3 mailbox ruling removed (`E-CE64-MB-4`, one-writer-per-mailbox). Treat that
line as superseded, not pending.

**A measured constraint this hands to D-ACR-1.** Its scope says *"composable
with `WideFieldMask`"*. Measured: `WideFieldMask` positions are `u8` —
universe capped at **256**, with a loud `UniverseExceedsSocCap` refusal above
it; its sibling `FieldMask` is `u64`/`MAX_FIELDS = 64` and **silently drops**
positions `>= 64`. A row population is neither. So "composable" cannot mean
"the same type", and §6 **Y2**'s parked `RowFocusMask × WideFieldMask` basis
collision is not a subtle semantic worry — it is a **cardinality mismatch with
a hard, loud cap on one side**. D-ACR-1 must state its basis and its
composition operator before composing, or it inherits one of two accidents:
loud refusal past 256 (borrowing the wide cap) or silent truncation past 64
(borrowing the narrow rule).

## 2026-08-21 — E-HHTL-IS-MINTED-IN-THE-ARTIFACT-NOBODY-CITES-1 — "zero on every baked row in both production bakes" is precise about the two it names and silent about the third, where the five OBO namespaces are 100% minted

**Status:** FINDING (measured directly on the pinned `.soa` bytes, SHA-256
Expand Down
4 changes: 2 additions & 2 deletions .claude/board/STATUS_BOARD.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ the rest.

| D-id | Scope | Status | Falsifier |
|---|---|---|---|
| D-ACR-0 | Audit `attention_mask.rs`/`attention_mask_actor.rs`: residue carrier, or a name collision? Report only | **Next** | names a caller, or records EXISTS-UNCALLED |
| D-ACR-1 | `RowFocusMask` — the one missing primitive (S3.1b names it; no crate contains it) | Queuedgates on D-ACR-0 | can-fire AND can-stay-silent on non-trivial input |
| D-ACR-0 | Audit `attention_mask.rs`/`attention_mask_actor.rs`: residue carrier, or a name collision? Report only | **Shipped** 2026-08-21 — `.claude/ATTENTION_MASK_AUDIT_2026_08_21.md`. Verdict **EXISTS-UNCALLED** + a name collision: the shipped type is a *rename register file* (`causaledge64-mailbox-rename-soa-v1.md` §4), not a residue carrier | recorded EXISTS-UNCALLED (0 callers workspace-wide + 3 sibling repos); piece E regraded — not a basis for D-ACR-1 |
| D-ACR-1 | `RowFocusMask` — the one missing primitive (S3.1b names it; no crate contains it) | **Next** — D-ACR-0 cleared it; starts clean (no reuse of `AttentionMaskSoA`). Must state its basis first: `WideFieldMask` is `u8`-capped at 256 positions (loud refusal above), `FieldMask` silently drops `>= 64` — a row population is neither | can-fire AND can-stay-silent on non-trivial input |
| D-ACR-3 | The one-way invariant as a test: no ontology-owned write traces to a patient-tagged read through ANY call path (corrected from write-authorization-only after CodeRabbit found a session-derived value can flow to the ontology owner via a shared parameter/return, then be written as the owner's own act) | Queued — gates on D-ACR-1 | a write whose call graph includes a session-tagged read is the bug, even if the write itself is authored by the ontology owner |
| D-ACR-2 | Mint the Rung-ladder rail | Queued — gates on operator mint decision (HTT §8 Q3) | `rail_carving` gains its first non-default consumer |
| D-ACR-4 | Second-order row at the same address, separate table | Queued | a rung-2 read reconstructs where rung-1 looked, on a fixture with an independent answer |
Expand Down