|
20 | 20 | //! gated steps: `.claude/plans/bindspace-singleton-to-mailbox-soa-v1.md`. |
21 | 21 |
|
22 | 22 | use causal_edge::CausalEdge64; |
| 23 | +use lance_graph_contract::cognitive_shader::MetaWord; |
23 | 24 | use lance_graph_contract::collapse_gate::{CollapseGateEmission, MailboxId, MergeMode}; |
| 25 | +use lance_graph_contract::qualia::QualiaI4_16D; |
24 | 26 |
|
25 | 27 | /// Spatial-temporal accumulator for per-row baton receipts. |
26 | 28 | /// |
@@ -57,6 +59,29 @@ pub struct MailboxSoA<const N: usize> { |
57 | 59 | /// if `last_emission_cycle[row] == current_cycle`, emission is suppressed. |
58 | 60 | pub last_emission_cycle: [u32; N], |
59 | 61 |
|
| 62 | + // ── NEW: migrated thoughtspace columns (per-mailbox owned, D-MBX-A1) ── |
| 63 | + |
| 64 | + /// Per-row LE baton edge (`CausalEdge64`, 8 B/row). |
| 65 | + /// Migrated from `BindSpace.edges` (EdgeColumn). |
| 66 | + /// This IS the LE contract / baton edge for this mailbox row. |
| 67 | + pub edges: [CausalEdge64; N], |
| 68 | + |
| 69 | + /// Per-row affective role vector (`QualiaI4_16D`, 8 B/row). |
| 70 | + /// Migrated from `BindSpace.qualia` (QualiaI4Column). |
| 71 | + /// 16 signed i4 dimensions (arousal/valence/tension/…); 9× compression vs f32. |
| 72 | + pub qualia: [QualiaI4_16D; N], |
| 73 | + |
| 74 | + /// Per-row packed meta word (`MetaWord`, 4 B/row). |
| 75 | + /// Migrated from `BindSpace.meta` (MetaColumn). |
| 76 | + /// Layout: `thinking(6) + awareness(4) + nars_f(8) + nars_c(8) + free_e(6)`. |
| 77 | + pub meta: [MetaWord; N], |
| 78 | + |
| 79 | + /// Per-row OGIT entity-type index (`u16`, 2 B/row). |
| 80 | + /// Migrated from `BindSpace.entity_type`. |
| 81 | + /// 1-based index into the shared (immutable) ontology registry. |
| 82 | + /// The registry itself stays `Arc<OntologyRegistry>` (cold Zone-2, not owned here). |
| 83 | + pub entity_type: [u16; N], |
| 84 | + |
60 | 85 | /// Monotonic cycle stamp; advanced by `tick()`. |
61 | 86 | pub current_cycle: u32, |
62 | 87 |
|
@@ -97,6 +122,11 @@ impl<const N: usize> MailboxSoA<N> { |
97 | 122 | current_cycle: 0, |
98 | 123 | w_slot, |
99 | 124 | threshold, |
| 125 | + // ── NEW thoughtspace columns — zero-initialised (D-MBX-A1) ── |
| 126 | + edges: [CausalEdge64::ZERO; N], |
| 127 | + qualia: [QualiaI4_16D::ZERO; N], |
| 128 | + meta: [MetaWord(0); N], |
| 129 | + entity_type: [0u16; N], |
100 | 130 | } |
101 | 131 | } |
102 | 132 |
|
@@ -189,6 +219,11 @@ impl<const N: usize> MailboxSoA<N> { |
189 | 219 | // Restore the "never emitted" sentinel so the row can emit immediately |
190 | 220 | // on the next cycle without triggering the same-cycle guard. |
191 | 221 | self.last_emission_cycle[row] = u32::MAX; |
| 222 | + // ── NEW thoughtspace columns reset (D-MBX-A1) ── |
| 223 | + self.edges[row] = CausalEdge64::ZERO; |
| 224 | + self.qualia[row] = QualiaI4_16D::ZERO; |
| 225 | + self.meta[row] = MetaWord(0); |
| 226 | + self.entity_type[row] = 0; |
192 | 227 | } |
193 | 228 |
|
194 | 229 | // ── Read-only inspectors ────────────────────────────────────────────────── |
@@ -227,6 +262,62 @@ impl<const N: usize> MailboxSoA<N> { |
227 | 262 | .filter(|&&e| e.abs() >= self.threshold) |
228 | 263 | .count() |
229 | 264 | } |
| 265 | + |
| 266 | + // ── Thoughtspace column accessors (D-MBX-A1) ───────────────────────────── |
| 267 | + |
| 268 | + /// Return the `CausalEdge64` baton edge for `row`. |
| 269 | + /// |
| 270 | + /// Panics (debug) / wraps (release) on out-of-bounds; callers |
| 271 | + /// should stay within `[0, N)`. |
| 272 | + #[inline] |
| 273 | + pub fn edge(&self, row: usize) -> CausalEdge64 { |
| 274 | + self.edges[row] |
| 275 | + } |
| 276 | + |
| 277 | + /// Set the `CausalEdge64` baton edge for `row`. |
| 278 | + /// |
| 279 | + /// Panics (debug) / wraps (release) on out-of-bounds; callers |
| 280 | + /// should stay within `[0, N)`. |
| 281 | + #[inline] |
| 282 | + pub fn set_edge(&mut self, row: usize, e: CausalEdge64) { |
| 283 | + self.edges[row] = e; |
| 284 | + } |
| 285 | + |
| 286 | + /// Return the packed `QualiaI4_16D` affective vector for `row`. |
| 287 | + #[inline] |
| 288 | + pub fn qualia_at(&self, row: usize) -> QualiaI4_16D { |
| 289 | + self.qualia[row] |
| 290 | + } |
| 291 | + |
| 292 | + /// Set the packed `QualiaI4_16D` affective vector for `row`. |
| 293 | + #[inline] |
| 294 | + pub fn set_qualia(&mut self, row: usize, q: QualiaI4_16D) { |
| 295 | + self.qualia[row] = q; |
| 296 | + } |
| 297 | + |
| 298 | + /// Return the packed `MetaWord` for `row`. |
| 299 | + #[inline] |
| 300 | + pub fn meta_at(&self, row: usize) -> MetaWord { |
| 301 | + self.meta[row] |
| 302 | + } |
| 303 | + |
| 304 | + /// Set the packed `MetaWord` for `row`. |
| 305 | + #[inline] |
| 306 | + pub fn set_meta(&mut self, row: usize, m: MetaWord) { |
| 307 | + self.meta[row] = m; |
| 308 | + } |
| 309 | + |
| 310 | + /// Return the OGIT entity-type index for `row` (1-based, shared ontology). |
| 311 | + #[inline] |
| 312 | + pub fn entity_type_at(&self, row: usize) -> u16 { |
| 313 | + self.entity_type[row] |
| 314 | + } |
| 315 | + |
| 316 | + /// Set the OGIT entity-type index for `row`. |
| 317 | + #[inline] |
| 318 | + pub fn set_entity_type(&mut self, row: usize, t: u16) { |
| 319 | + self.entity_type[row] = t; |
| 320 | + } |
230 | 321 | } |
231 | 322 |
|
232 | 323 | #[cfg(test)] |
|
0 commit comments