11//! Role keys — canonical deterministic `[start:stop]`-slice VSA role bindings.
22//!
3- //! Each role owns a **disjoint contiguous slice** of the 10,000 -dim VSA
3+ //! Each role owns a **disjoint contiguous slice** of the 16,384 -dim VSA
44//! space (compatible with `CrystalFingerprint::Binary16K`). Only the bits
55//! in that slice are set to a deterministic pseudo-random pattern seeded
66//! from FNV-64 of the label; all other bits are zero. This is the
1010//! only affects that role's slice, and bundles of different role-bindings
1111//! don't contaminate each other.
1212//!
13- //! ## Space layout (10,000 total dims)
13+ //! ## Space layout (16,384 total dims — LF-2 resize from 10,000 )
1414//!
1515//! ```text
16- //! [ 0 .. 2000) SUBJECT_KEY
17- //! [ 2000 .. 4000) PREDICATE_KEY
18- //! [ 4000 .. 6000) OBJECT_KEY
19- //! [ 6000 .. 7500) MODIFIER_KEY
20- //! [ 7500 .. 9000) CONTEXT_KEY
21- //! [ 9000 .. 9200) TEMPORAL_KEY
22- //! [ 9200 .. 9400) KAUSAL_KEY
23- //! [ 9400 .. 9500) MODAL_KEY
24- //! [ 9500 .. 9650) LOKAL_KEY
25- //! [ 9650 .. 9750) INSTRUMENT_KEY
26- //! [ 9750 .. 9780) BENEFICIARY_KEY
27- //! [ 9780 .. 9810) GOAL_KEY
28- //! [ 9810 .. 9840) SOURCE_KEY
29- //! [ 9840 .. 9910) Finnish 15 cases — ~4-5 dims each
30- //! [ 9910 .. 9970) 12 tense keys — 5 dims each
31- //! [ 9970 .. 10000) 7 NARS inference keys — ~4 dims each
16+ //! [ 0 .. 2000) SUBJECT_KEY
17+ //! [ 2000 .. 4000) PREDICATE_KEY
18+ //! [ 4000 .. 6000) OBJECT_KEY
19+ //! [ 6000 .. 7500) MODIFIER_KEY
20+ //! [ 7500 .. 9000) CONTEXT_KEY
21+ //! [ 9000 .. 9200) TEMPORAL_KEY
22+ //! [ 9200 .. 9400) KAUSAL_KEY
23+ //! [ 9400 .. 9500) MODAL_KEY
24+ //! [ 9500 .. 9650) LOKAL_KEY
25+ //! [ 9650 .. 9750) INSTRUMENT_KEY
26+ //! [ 9750 .. 9780) BENEFICIARY_KEY
27+ //! [ 9780 .. 9810) GOAL_KEY
28+ //! [ 9810 .. 9840) SOURCE_KEY
29+ //! [ 9840 .. 9910) Finnish 15 cases — ~4-5 dims each
30+ //! [ 9910 .. 9970) 12 tense keys — 5 dims each
31+ //! [ 9970 .. 10000) 7 NARS inference keys — ~4 dims each
32+ //! [10000 .. 10512) SMB KUNDE_KEY (customer)
33+ //! [10512 .. 11024) SMB SCHULDNER_KEY (debtor)
34+ //! [11024 .. 11536) SMB MAHNUNG_KEY (dunning)
35+ //! [11536 .. 12048) SMB RECHNUNG_KEY (invoice)
36+ //! [12048 .. 12560) SMB DOKUMENT_KEY (document)
37+ //! [12560 .. 13072) SMB BANK_KEY (banking)
38+ //! [13072 .. 13584) SMB FIBU_KEY (financial accounting)
39+ //! [13584 .. 14096) SMB STEUER_KEY (tax)
40+ //! [14096 .. 16384) headroom (reserved for future SMB keys)
3241//! ```
3342
3443use std:: sync:: LazyLock ;
3544
3645use super :: finnish:: FinnishCase ;
3746use super :: inference:: NarsInference ;
3847
39- /// VSA vector width in `u64` words. Matches `ndarray::hpc::vsa::VSA_WORDS` .
40- /// 157 × 64 = 10,048 bits, covering the 10,000 VSA dims with 48 slack bits .
41- pub const VSA_WORDS : usize = 157 ;
48+ /// VSA vector width in `u64` words. 256 × 64 = 16,384 bits .
49+ /// Matches `CrystalFingerprint::Binary16K` and `ndarray::hpc::vsa::VSA_WORDS` .
50+ pub const VSA_WORDS : usize = 256 ;
4251
4352/// VSA vector width in dimensions (bits actually used).
44- pub const VSA_DIMS : usize = 10_000 ;
45-
46- // NOTE: The `Vsa10k = [u64; 157]` bitpacked type alias, `VSA_ZERO` constant,
47- // and `RoleKey::{bind, unbind, recovery_margin}` methods that existed in
48- // early 2026-04-21 session work were REMOVED in the cleanup commit
49- // `cd5c049...`. That code used GF(2)/XOR algebra which is the
50- // Binary16K Hamming-comparison format, not the real-valued VSA bundling
51- // format. Correct VSA substrate is `Vsa10kF32 = Box<[f32; 10_000]>`
52- // (existing) or `Vsa16kF32 = Box<[f32; 16_384]>` (pending rescale), with
53- // element-wise multiply/add via existing `crystal::fingerprint::{vsa_bind,
54- // vsa_bundle, vsa_cosine}`.
55- //
56- // See `CHANGELOG.md` § VSA format switches and
57- // `.claude/knowledge/vsa-switchboard-architecture.md` for the full
58- // three-layer architecture. Role keys (this module) are Layer-2 catalogue
59- // ONLY — identity slice boundaries. Algebra lives in Layer-1 `crystal/`.
53+ /// Resized from 10,000 → 16,384 (LF-2) to accommodate SMB domain
54+ /// role keys in [10000..14096) with 2,288 dims headroom.
55+ pub const VSA_DIMS : usize = 16_384 ;
56+
57+ // NOTE: bind/unbind/recovery_margin methods removed (see CHANGELOG.md).
58+ // Role keys are Layer-2 catalogue ONLY — identity slice boundaries.
59+ // Algebra lives in Layer-1 `crystal/` and in ndarray.
6060
6161/// A role key owns a contiguous slice of the VSA space.
6262/// Outside the slice, **all bits are zero**.
@@ -301,6 +301,19 @@ pub fn nars_inference_key(inf: NarsInference) -> &'static RoleKey {
301301 & NARS_KEYS [ idx]
302302}
303303
304+ // ---------------------------------------------------------------------------
305+ // SMB domain role keys — [10000 .. 14096), 512 dims each (LF-2)
306+ // ---------------------------------------------------------------------------
307+
308+ pub static KUNDE_KEY : LazyLock < RoleKey > = LazyLock :: new ( || RoleKey :: generate ( "smb.kunde" , 10_000 , 10_512 ) ) ;
309+ pub static SCHULDNER_KEY : LazyLock < RoleKey > = LazyLock :: new ( || RoleKey :: generate ( "smb.schuldner" , 10_512 , 11_024 ) ) ;
310+ pub static MAHNUNG_KEY : LazyLock < RoleKey > = LazyLock :: new ( || RoleKey :: generate ( "smb.mahnung" , 11_024 , 11_536 ) ) ;
311+ pub static RECHNUNG_KEY : LazyLock < RoleKey > = LazyLock :: new ( || RoleKey :: generate ( "smb.rechnung" , 11_536 , 12_048 ) ) ;
312+ pub static DOKUMENT_KEY : LazyLock < RoleKey > = LazyLock :: new ( || RoleKey :: generate ( "smb.dokument" , 12_048 , 12_560 ) ) ;
313+ pub static BANK_KEY : LazyLock < RoleKey > = LazyLock :: new ( || RoleKey :: generate ( "smb.bank" , 12_560 , 13_072 ) ) ;
314+ pub static FIBU_KEY : LazyLock < RoleKey > = LazyLock :: new ( || RoleKey :: generate ( "smb.fibu" , 13_072 , 13_584 ) ) ;
315+ pub static STEUER_KEY : LazyLock < RoleKey > = LazyLock :: new ( || RoleKey :: generate ( "smb.steuer" , 13_584 , 14_096 ) ) ;
316+
304317// ---------------------------------------------------------------------------
305318// Tests
306319// ---------------------------------------------------------------------------
@@ -323,6 +336,12 @@ mod tests {
323336 for k in FINNISH_KEYS . iter ( ) { v. push ( ( k. slice_start , k. slice_end , k. label ) ) ; }
324337 for k in TENSE_KEYS . iter ( ) { v. push ( ( k. slice_start , k. slice_end , k. label ) ) ; }
325338 for k in NARS_KEYS . iter ( ) { v. push ( ( k. slice_start , k. slice_end , k. label ) ) ; }
339+ for k in [
340+ & * KUNDE_KEY , & * SCHULDNER_KEY , & * MAHNUNG_KEY , & * RECHNUNG_KEY ,
341+ & * DOKUMENT_KEY , & * BANK_KEY , & * FIBU_KEY , & * STEUER_KEY ,
342+ ] {
343+ v. push ( ( k. slice_start , k. slice_end , k. label ) ) ;
344+ }
326345 v
327346 }
328347
0 commit comments