Skip to content

Commit 85b07b4

Browse files
committed
docs(plan): consolidated bindspace→mailbox_soa WIRING plan (W2→W7)
Synthesis of the 5-agent consolidation pass (sequencing / read-shim / two-path-discipline / 0-friction-swap / W2-differential). Pending the 3-brutal-critic pass before any wiring lands. Key resolutions: - W2.5 mutability-surface DECISION GATE (RwLock<HashMap> rec vs move-out) — the one operator fork; everything else determined. - Read surface: driver-local MONOMORPHIZED BackingStore enum (no &dyn, no contract change) — reconciles convergence/container/two-path; gates the owner not the function body (I-LEGACY-API-FEATURE-GATED-safe). - Feature invariants I-FG-1/2/3 (single arc, gate owner, default-OFF until W7). - D-DIST-1..5 boundaries (what stays distinct until W7 / forever). - H-DW-1/2/3 divergence hazards (atomic writer+reader flip; single-writer-per-row; Arc::get_mut→owned &mut, never make_mut). - F-CYCLE drop discipline (unbind_busdto REWRITTEN not re-pointed). - Split W4a/W4b; decouple W7 from the externally-blocked W6. - W2 asserts ShaderResonance + cycle_fingerprint + MaterializeProvenance bit-identical (f32::to_bits), entity_type==0 to neutralize ontology(). Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 40690ff commit 85b07b4

1 file changed

Lines changed: 196 additions & 0 deletions

File tree

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
# bindspace → mailbox_soa — WIRING plan (W2→W7), consolidated (v1)
2+
3+
> **Status:** CONSOLIDATED PLAN — synthesized from 5 specialist consolidation
4+
> agents (sequencing / read-shim / two-path-discipline / 0-friction-swap /
5+
> W2-differential). Pending the 3-brutal-critic pass before any wiring lands.
6+
> **Date:** 2026-06-17.
7+
> **Parent:** `bindspace-mailbox-soa-dependency-map-v1.md` (W0 map; columns W1+W1b DONE).
8+
> **Operator constraints (binding):** two paths step by step; never delete the old
9+
> before the new is tested; CausalEdge64 dedup precise; delete BindSpace LAST.
10+
> **Column migration is COMPLETE** (W1 sigma/temporal/expert; W1b content/topic/angle).
11+
> This doc is the **wiring** half — read/write re-point, feature-gate, cutover.
12+
13+
---
14+
15+
## 0. The one decision gate for the operator (W2.5 — mutability surface)
16+
17+
The write path today is `Arc::get_mut(&mut st.driver.bindspace)` (4 sites:
18+
`grpc.rs:136`, `serve.rs:150/601/692`). An **owned `&mut MailboxSoA` is unreachable**
19+
from a shared `Arc<ShaderDriver>` whose `mailboxes` is a plain field — `&mut self.mailboxes`
20+
needs `&mut ShaderDriver`, which `Arc<ShaderDriver>` cannot give. So a mutability surface
21+
must be chosen **before any write re-point (W3/W4b)**. Two clean options:
22+
23+
- **(A) `RwLock<HashMap<MailboxId, MailboxSoA<N>>>` on the driver** — mirrors the existing
24+
`planes: RwLock<…>` and `awareness: RwLock<…>` already on `ShaderDriver`; keeps the
25+
`Arc<ShaderDriver>`-shared topology intact; matches the data-flow rule's "interior
26+
mutability or built once." **Recommended** (lower blast radius, prior art in the same struct).
27+
- **(B) Move the mailbox set out of `Arc<ShaderDriver>` into the bin handler state** so the
28+
handler owns `&mut` directly — higher blast radius on `serve.rs`/`grpc.rs`.
29+
30+
**This is the only genuine fork; everything else below is determined.** Default = (A).
31+
32+
---
33+
34+
## 1. The read-surface decision (productive disagreement, RESOLVED)
35+
36+
Three agents diverged, then reconciled:
37+
- **convergence:** parameterize `run` over a read trait; extend the contract `MailboxSoaView`
38+
with `qualia()`/`content_row()`; give `BindSpace` a migration-scoped impl.
39+
- **container:** do NOT extend the contract — `&dyn MailboxSoaView` adds a per-row indirect
40+
call in the hot O(n²) Hamming loop (wrong for SIMD); content/qualia on the contract
41+
over-commits the **cold** `SurrealMailboxView`; a `BindSpace: MailboxSoaView` impl is a
42+
**sentinel lie** (`mailbox_id`/`w_slot`/`phase` are nonsense for a singleton).
43+
- **two-path:** gate the **owner**, not the function body (I-LEGACY-API-FEATURE-GATED); one
44+
`dispatch()` body written against a stable read surface, the flag picks which object is handed in.
45+
46+
**RESOLUTION — a driver-crate-local, MONOMORPHIZED read surface (no `&dyn`, no contract change):**
47+
48+
```rust
49+
// crates/cognitive-shader-driver/src/backing.rs (new, driver-local)
50+
enum BackingStore<'a> {
51+
Singleton(&'a BindSpace), // path A — live default
52+
Mailbox(&'a MailboxSoA<1024>), // path B — feature-gated
53+
}
54+
```
55+
exposing exactly the six-read dispatch surface, dispatching over **inherent accessors that
56+
already exist on both stores** (W1+W1b shipped them with identical signatures):
57+
58+
| shim method | Singleton arm | Mailbox arm | notes |
59+
|---|---|---|---|
60+
| `prefilter(win, &MetaFilter) -> Vec<u32>` | `bs.meta_prefilter(win,f)` | inline sweep over `mb.meta_raw()`, **clamped to `n_rows()`** | the one *behavior* (not data) the mailbox lacks; must be byte-identical |
61+
| `content_row(row) -> &[u64]` | `bs.fingerprints.content_row` | `mb.content_row` | byte-identical stride (`[row*256..]`, `WORDS_PER_FP=256`), proven by W1b test |
62+
| `qualia_row(row) -> QualiaI4_16D` | `bs.qualia.row` | `mb.qualia_at` | Copy |
63+
| `edge_raw(row) -> u64` | `bs.edges.get` | `mb.edge(row).0` | driver reattaches `causal_edge::CausalEdge64` ONLY; ndarray twin barred |
64+
| `entity_type(row) -> u16` | `bs.entity_type[row]` | `mb.entity_type_at` | |
65+
| `len() -> usize` | `bs.len` | `mb.n_rows()` (=N) | the prefilter bound |
66+
67+
`run()` keeps **one body**, written against `BackingStore` (or a generic `R: DriverRead`
68+
equivalent; monomorphized either way). The feature flag selects which variant is constructed,
69+
**never** `#[cfg]`-branches inside `run`. `ontology` is **NOT** a shim method — it stays a
70+
shared `Arc<OntologyRegistry>` field on the driver, resolved against the `entity_type(row)` the
71+
shim returns. **No `lance-graph-contract` change for this migration** (a contract `qualia()`
72+
lands later, gated on the *planner* consumer, per the `soa_view.rs:71` note — not here).
73+
74+
---
75+
76+
## 2. Feature-gate invariants (I-LEGACY-API-FEATURE-GATED-safe)
77+
78+
- **I-FG-1 (single arc).** ONE `mailbox-thoughtspace` feature spanning W3→W6. No per-W
79+
sub-features (a half-migration W4-on/W3-off is a silent-divergence state nobody tests).
80+
- **I-FG-2 (gate the owner).** The flag selects which `BackingStore` variant is built; it must
81+
NOT introduce `#[cfg]` branches inside `dispatch()`/`ingest_codebook_indices`/`persist_cycle`
82+
that read different columns under the same fn name. The §1 monomorphized shim is the
83+
mechanism that makes the single flag safe.
84+
- **I-FG-3 (default OFF until W7).** `default = [...]` must NOT include `mailbox-thoughtspace`
85+
until W7. Singleton stays the default-build behaviour while both paths live; the mailbox path
86+
is opt-in and differentially tested. (Contrast `causal-edge-v2-layout` = default-ON because
87+
that migration is *finished*; this one is not.)
88+
89+
---
90+
91+
## 3. Boundaries that must stay distinct (do NOT flatten early)
92+
93+
| id | distinction held | collapses at |
94+
|---|---|---|
95+
| D-DIST-1 | singleton store ≠ mailbox store (two owners, separately allocated; mailbox OWNS, never `&mut`-borrows from the singleton — `E-CE64-MB-4`) | **W7** |
96+
| D-DIST-2 | read surface ≠ write surface (`MailboxSoaView` vs `MailboxSoaOwner`; cold side read-only) | never |
97+
| D-DIST-3 | typed `causal_edge::CausalEdge64` ≠ raw `u64` column; ndarray twin **barred**; reattach points do NOT multiply | never (firewall permanent) |
98+
| D-DIST-4 | ephemeral thoughtspace ≠ calcified shared (ontology/CAM-PQ stay by `&`/`Arc`, never per-mailbox-owned) | never |
99+
| D-DIST-5 | hot mutation ≠ cold persistence (`persisted_row` is a pointer, not a re-encode; no Arrow/JSON marshalling step) | never |
100+
| membrane | `engine_bridge` `bind/unbind_busdto`/`busdto_to_binary16k` re-encode seam — the ONE thing allowed to dissolve | re-point W3; body deleted W7 |
101+
102+
---
103+
104+
## 4. Divergence hazards (the sharp risks)
105+
106+
- **H-DW-1 (headline).** W3 re-points *writers* to the mailbox while W4 still reads the
107+
singleton → the shader reasons over stale singleton rows; the two stores **diverge silently on
108+
the same row index**. **Guard:** writers+readers flip **atomically as one gated unit** (collapse
109+
W3+W4a, or keep the feature non-default-buildable between them AND run the W2 differential on
110+
every commit in the window).
111+
- **H-DW-2.** Single-writer-per-logical-row is **absolute**. No dual-write "to keep both warm"
112+
(a rounding/quantization/`temporal`-no-op disagreement → undetectable divergence). Off → singleton
113+
sole writer; on → mailbox sole writer; never both.
114+
- **H-DW-3.** The four `Arc::get_mut(&mut bindspace)` sites convert to owned `&mut MailboxSoA`
115+
(via the W2.5 surface) in the W4b unit. A surviving `get_mut`/**`make_mut`** on `bindspace` under
116+
the feature is a migration leak — `make_mut` silently **clones the whole 4096-row singleton**
117+
= an instant second diverging store.
118+
119+
---
120+
121+
## 5. The `cycle` (Vsa16kF32) plane — drop discipline
122+
123+
Singleton keeps `write_cycle_fingerprint`/`cycle_row` until **W7**; `MailboxSoA` **never** gets a
124+
`cycle`/`set_cycle`/`cycle_row` method (compile-level assertion). Under W3:
125+
- **F-CYCLE-1** `dispatch_busdto` (`engine_bridge.rs:243`) — stop writing the column; compute the
126+
Binary16K accumulator transiently for the current resonance, discard.
127+
- **F-CYCLE-3** `persist_cycle` (`engine_bridge.rs:707`) — stop the `write_cycle_fingerprint`;
128+
keep the legitimate `edges`/`meta` column writes.
129+
- **F-CYCLE-2** `unbind_busdto` (`engine_bridge.rs:334`) — **REWRITE, do not re-point.** It reads the
130+
*persisted* cycle plane back; that plane won't exist on the mailbox. Per parent-plan §2.6 it
131+
must collapse to a column read (`edges`/`qualia`/`meta`). This is the one function that cannot be
132+
mechanically migrated.
133+
- **F-CYCLE-5** `driver.rs:288` `cycle_fp` local is the CORRECT transient model (a `[u64;256]`
134+
Binary16K fold on the stack, never a column). Footprint check: hot cost ≈ 6 KB/row
135+
(content/topic/angle), NOT ≈ 71.6 KB/row (a leak of the 64 KB cycle plane).
136+
137+
---
138+
139+
## 6. The hardened W2→W7 sequence (dependency-correct)
140+
141+
```
142+
W2 read-parity differential harness (test-only) READY NOW additive ∥-safe
143+
W2.5 mailbox &mut surface — DECISION GATE (A: RwLock rec) READY NOW additive operator pick
144+
W3 engine_bridge mailbox writes (feat-gated) BLOCKED:W2.5 behaviour serial +cycle-reader audit +temporal field-isolation
145+
W4a dispatch READ re-point via BackingStore (feat-gated) BLOCKED:W2,W2.5 behaviour serial (W2-validated; flip atomic w/ W3 per H-DW-1)
146+
W4b Arc::get_mut → owned &mut (4 sites) BLOCKED:W2.5,W3 behaviour serial (fixes latent "multiple references" 500; never make_mut)
147+
W5 bins build mailbox set (feat-gated) BLOCKED:W4b behaviour serial +mailbox-set topology sub-gate (N, count, keying)
148+
W6 death→SPO-G+Lance tombstone HARD-BLOCKED (surrealdb #41) design ∥-only, NO code ← DECOUPLED from W7
149+
W7 delete BindSpace + cycle plane; drop feature gate BLOCKED:W3,W4a,W4b,W5 + §2e test migration serial LAST (NOT gated on W6)
150+
```
151+
152+
**Per-step gates:**
153+
- **W2 — READY NOW.** Differential test only; reads the **concrete** `MailboxSoA` (not the contract
154+
view). Build the mailbox with **populated rows == BindSpace `len`** so the prefilter sweeps the
155+
same set. Assert `ShaderResonance` **bit-identical** via `f32::to_bits()` (top_k row/distance/
156+
predicates/cycle_index + resonance bits, entropy bits, std_dev bits) + `cycle_fingerprint` +
157+
**`MaterializeProvenance`** (so a future read re-point can't silently drift #515's provenance);
158+
assert `gate` only with `entity_type == 0` rows (neutralizes the `ontology()` read W2 can't serve).
159+
- **W2.5 — operator decision (A vs B).** Default A (`RwLock`). The gate for the whole write arc.
160+
- **W3 — +2 mandatory in-PR gates:** (a) a `read_cycle_fingerprint`/`cycle_row` reader audit
161+
promoting "cycle→transient" from CONJECTURE to FINDING; (b) the `temporal` field-isolation matrix
162+
test (write temporal, assert edges/meta/sigma/expert unchanged) per I-LEGACY-API-FEATURE-GATED.
163+
- **W4a/W4b — split** (read re-point vs ownership-model change). W4a validated by the W2 harness;
164+
W4b changes handler error semantics (removes the "multiple references" 500).
165+
- **W5 — sub-gate:** define the mailbox-set builder (`N`, count, keying) before the bin move; do not
166+
invent the sea-star topology ad-hoc in `main()`.
167+
- **W6 — external blocker** (surrealdb #41); design proceeds as docs/contract-only, NO code.
168+
- **W7 — decoupled from W6.** Prereq is **zero singleton readers** + the two §2e singleton-bound
169+
tests (`end_to_end.rs`, `busdto_bridge_test.rs`) migrated to mailbox FIRST. Then delete
170+
`bindspace.rs` + the cycle plane + the feature flag in one PR.
171+
172+
---
173+
174+
## 7. #515 MaterializeProvenance interaction
175+
176+
`materialize_provenance` (now on `main`, `driver.rs`) is **provenance-only** — it consumes
177+
already-derived observables (`free_energy`, `std_dev`, `top_resonance`, `awareness_skill`,
178+
hits), reads **no** `BindSpace` directly → adds no new singleton reader and does not gate the
179+
migration. The one interaction: its inputs come from the dispatch read path W4a re-points, so
180+
**W2 must assert `MaterializeProvenance` byte-equality** across stores (§6 W2 gate). `ctx_id`/MUL
181+
still read `ontology()` from the shared `Arc` (not the mailbox).
182+
183+
---
184+
185+
## 8. Acceptance checks (per the operator's "test the new before delete the old")
186+
187+
- W2 differential: bit-identical `ShaderResonance` + `cycle_fingerprint` + `MaterializeProvenance`,
188+
singleton-backed vs mailbox-backed, same rows — run in BOTH the W3-landed/W4-pending state and
189+
the W4-complete state (H-DW-1 window).
190+
- Field-isolation matrix (W3): each migrated column write leaves all others byte-unchanged.
191+
- CausalEdge64 firewall (CI): `ndarray::hpc::causal_diff::CausalEdge64` has **zero** imports in
192+
`cognitive-shader-driver`; an `edges_raw()` reattach round-trips to the typed
193+
`causal_edge::CausalEdge64` it was packed from.
194+
- Cycle-drop (compile + bench): `MailboxSoA` exposes no `cycle*` symbol; hot footprint ≈ 6 KB/row.
195+
- W7 readiness: grep proves zero `self.bindspace.*` reads under feature-on; the two §2e tests pass
196+
on the mailbox path before deletion.

0 commit comments

Comments
 (0)