Skip to content

Commit ddb3017

Browse files
authored
Merge pull request #253 from AdaWorldAPI/claude/vsa16k-f32-carrier-type
feat(contract): Vsa16kF32 switchboard carrier + 16K algebra
2 parents 4ad06d0 + dc56586 commit ddb3017

4 files changed

Lines changed: 246 additions & 3 deletions

File tree

.claude/board/EPIPHANIES.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,18 @@ stay as historical references.
6666
## Entries (reverse chronological)
6767

6868

69+
## 2026-04-24 — Vsa16kF32 switchboard carrier shipped (CrystalFingerprint::Vsa16kF32 + 16K algebra)
70+
71+
**Status:** FINDING
72+
**Owner scope:** @family-codec-smith, @truth-architect
73+
74+
`CrystalFingerprint::Vsa16kF32(Box<[f32; 16_384]>)` (64 KB) is now a first-class enum variant in `crystal/fingerprint.rs`, together with six algebra primitives: `vsa16k_zero`, `binary16k_to_vsa16k_bipolar`, `vsa16k_to_binary16k_threshold`, `vsa16k_bind`, `vsa16k_bundle`, `vsa16k_cosine`. 7 new tests (16 total in module). This is the Click switchboard carrier per CLAUDE.md §The Click: inside-BBB only, 1:1 bit-addressable with Binary16K (dim i = bit i), bipolar projection lossless under threshold inverse. The 10K-D `to_vsa10k_f32()` downcast is also wired (similarity-preserving, stride copy with surplus-dim averaging into base 10K).
75+
76+
**Why it matters:** This is expansion-list item #1 from the first SoAReview sweep (PR #252 §6). The carrier type must exist before `FingerprintColumns.cycle` can migrate from `Box<[u64]>` (Binary16K) to the f32 carrier. Next step: PR B migrates the `cognitive-shader-driver::bindspace::FingerprintColumns.cycle` field + `engine_bridge.rs` write path to use this carrier.
77+
78+
Cross-ref: TECH_DEBT 2026-04-24 ghost-columns entry, unified-integration-v1 §6 ranked expansion list, `.claude/agents/soa-review.md` reference run #4 (Grammar-Markov: SCATTERED-NOT-UNIFIED).
79+
80+
6981
## 2026-04-24 — I1 Codec Regime Split is the unified answer to Pearl 2³ + CAM-PQ across SPO / AriGraph / archetype
7082

7183
**Status:** FINDING

.claude/board/LATEST_STATE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Types that EXIST — do NOT re-propose them:
3131

3232
**`grammar/`**: `FailureTicket`, `PartialParse`, `CausalAmbiguity`, `TekamoloSlots`, `TekamoloSlot`, `WechselAmbiguity`, `WechselRole`, `FinnishCase`, `finnish_case_for_suffix`, `NarsInference`, `inference_to_style_cluster`, `ContextChain` (with coherence_at / total_coherence / replay_with_alternative / disambiguate / DisambiguationResult / WeightingKernel), `RoleKey` + 47 `LazyLock<RoleKey>` instances + `Tense` enum + `finnish_case_key / tense_key / nars_inference_key` lookups, **`RoleKey::bind/unbind/recovery_margin`** (slice-masked XOR), **`Vsa10k`** + `VSA_ZERO` + `vsa_xor` + `vsa_similarity`, **`GrammarStyleConfig`** + **`GrammarStyleAwareness`** + `revise_truth` + `ParseOutcome` + `divergence_from`, **`FreeEnergy`** + **`Hypothesis`** + **`Resolution`** (Commit / Epiphany / FailureTicket) + `from_ranked` + thresholds.
3333

34-
**`crystal/`**: `Crystal` trait, `CrystalKind`, `TruthValue`, `UNBUNDLE_HARDNESS_THRESHOLD = 0.8`, `CrystalFingerprint` (Binary16K / Structured5x5 / Vsa10kI8 / Vsa10kF32), `Structured5x5`, `Quorum5D`, `SentenceCrystal`, `ContextCrystal`, `DocumentCrystal`, `CycleCrystal`, `SessionCrystal`, sandwich layout constants.
34+
**`crystal/`**: `Crystal` trait, `CrystalKind`, `TruthValue`, `UNBUNDLE_HARDNESS_THRESHOLD = 0.8`, `CrystalFingerprint` (Binary16K / Structured5x5 / Vsa10kI8 / Vsa10kF32 / **Vsa16kF32**), `Structured5x5`, `Quorum5D`, `SentenceCrystal`, `ContextCrystal`, `DocumentCrystal`, `CycleCrystal`, `SessionCrystal`, sandwich layout constants, **`vsa16k_zero` / `binary16k_to_vsa16k_bipolar` / `vsa16k_to_binary16k_threshold` / `vsa16k_bind` / `vsa16k_bundle` / `vsa16k_cosine`** (Click switchboard carrier + algebra, 64 KB, inside-BBB only).
3535

3636
**`cognitive_shader`**: `ShaderDispatch`, `ShaderResonance`, `ShaderBus`, `ShaderCrystal`, `MetaWord` (u32 packed), `MetaFilter`, `ColumnWindow`, `StyleSelector`, `RungLevel`, `EmitMode`, `ShaderSink` trait, `CognitiveShaderDriver` trait.
3737

crates/lance-graph-contract/src/crystal/fingerprint.rs

Lines changed: 228 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,30 @@
11
//! CrystalFingerprint — polymorphic carrier of crystal semantic content.
22
//!
3-
//! Four native forms:
3+
//! Five native forms:
44
//!
55
//! | Variant | Size | Role |
66
//! |------------------|-------|----------------------------------------------|
77
//! | `Binary16K` | 2 KB | Compact semantic (Hamming similarity). |
88
//! | `Structured5x5` | 3 KB | Rich native form (5×5×5×5×5 cells). |
99
//! | `Vsa10kI8` | 10 KB | lancedb-native VSA (int8). |
1010
//! | `Vsa10kF32` | 40 KB | lancedb-native VSA (f32). |
11+
//! | `Vsa16kF32` | 64 KB | Click-native switchboard carrier (f32, 16_384-D).|
12+
//!
13+
//! ## Vsa16kF32 — the inside-BBB switchboard carrier
14+
//!
15+
//! Per CLAUDE.md §The Click and the I-VSA-IDENTITIES iron rule, the
16+
//! 16,384-dimensional f32 VSA is the **switchboard carrier** for
17+
//! role-indexed bundle (Markov) and role-key bind/unbind on the
18+
//! semantic kernel. It is 1:1 bit-addressable with `Binary16K`
19+
//! (dimension i corresponds to bit i) and supports lossless bipolar
20+
//! projection in both directions via [`binary16k_to_vsa16k_bipolar`]
21+
//! and [`vsa16k_to_binary16k_threshold`].
22+
//!
23+
//! **BBB membrane status:** `Vsa16kF32` is INSIDE-BBB only. It does
24+
//! NOT cross the `ExternalMembrane` — the Arrow-scalar commit tier
25+
//! uses the 2 KB `Binary16K` projection (Index regime) or the 6 B
26+
//! CAM-PQ scent (Argmax regime). See I1 codec regime split
27+
//! (ADR-0002).
1128
//!
1229
//! ## Passthrough to 10,000-D
1330
//!
@@ -52,6 +69,11 @@ pub enum CrystalFingerprint {
5269

5370
/// 10,000-D VSA, f32 components (lancedb-native, 40 KB).
5471
Vsa10kF32(Box<[f32; 10_000]>),
72+
73+
/// 16,384-D VSA, f32 components — the Click switchboard carrier (64 KB).
74+
/// One-to-one with `Binary16K` dimensions via bipolar projection.
75+
/// Inside-BBB only; never crosses `ExternalMembrane`.
76+
Vsa16kF32(Box<[f32; 16_384]>),
5577
}
5678

5779
/// Five-dimensional quorum: consensus along each of the 5^5 axes.
@@ -216,6 +238,20 @@ impl CrystalFingerprint {
216238
Self::Vsa10kF32(v) => {
217239
out.copy_from_slice(&v[..]);
218240
}
241+
Self::Vsa16kF32(v) => {
242+
// 16_384 → 10_000 downcast: similarity-preserving stride copy
243+
// with interleaved averaging of the surplus 6_384 dims into
244+
// the base 10_000. Not lossless — reserved for cases where a
245+
// 10K-surface consumer needs the 16K carrier's content. For
246+
// lossless projection, stay on the 16K carrier.
247+
for i in 0..10_000 {
248+
out[i] = v[i];
249+
}
250+
for j in 10_000..16_384 {
251+
let i = j - 10_000;
252+
out[i] = (out[i] + v[j]) * 0.5;
253+
}
254+
}
219255
}
220256
out
221257
}
@@ -297,6 +333,7 @@ impl CrystalFingerprint {
297333
Self::Structured5x5 { .. } => 3125 + 5 * 4, // ~3 KB
298334
Self::Vsa10kI8(_) => 10_000, // 10 KB
299335
Self::Vsa10kF32(_) => 40_000, // 40 KB
336+
Self::Vsa16kF32(_) => 65_536, // 64 KB
300337
}
301338
}
302339
}
@@ -357,6 +394,93 @@ pub fn vsa_cosine(a: &[f32; 10_000], b: &[f32; 10_000]) -> f32 {
357394
if denom < 1e-12 { 0.0 } else { dot / denom }
358395
}
359396

397+
// ── Vsa16kF32 — the Click switchboard carrier ──────────────────────────
398+
//
399+
// One-to-one bit-addressable with Binary16K (dim i ↔ bit i). Bipolar
400+
// ±1 projection is lossless in both directions under strict-threshold
401+
// inverse. Supports the semantic-kernel algebra (role-indexed bundle
402+
// for Markov, element-wise bind for role-key slice assignment) on the
403+
// f32 carrier. 64 KB per vector; inside-BBB only.
404+
405+
/// Allocate a zero-valued Vsa16kF32 carrier.
406+
#[inline]
407+
pub fn vsa16k_zero() -> Box<[f32; 16_384]> {
408+
Box::new([0.0f32; 16_384])
409+
}
410+
411+
/// Project a `Binary16K` (256 × u64 = 16_384 bits) into a bipolar
412+
/// `Vsa16kF32`: bit i set → +1.0 at dim i; bit i clear → -1.0.
413+
///
414+
/// Lossless under the inverse [`vsa16k_to_binary16k_threshold`].
415+
pub fn binary16k_to_vsa16k_bipolar(bits: &[u64; 256]) -> Box<[f32; 16_384]> {
416+
let mut out = Box::new([0.0f32; 16_384]);
417+
for w in 0..256 {
418+
let word = bits[w];
419+
for b in 0..64 {
420+
let dim = w * 64 + b;
421+
out[dim] = if (word >> b) & 1 == 1 { 1.0 } else { -1.0 };
422+
}
423+
}
424+
out
425+
}
426+
427+
/// Threshold a `Vsa16kF32` carrier back to a `Binary16K`: dim > 0.0 → bit set.
428+
///
429+
/// Inverse of [`binary16k_to_vsa16k_bipolar`] for any vector whose signs
430+
/// survived bundling / binding (does not require strict ±1 values —
431+
/// any positive value decodes to 1, any non-positive to 0).
432+
pub fn vsa16k_to_binary16k_threshold(v: &[f32; 16_384]) -> Box<[u64; 256]> {
433+
let mut bits = Box::new([0u64; 256]);
434+
for w in 0..256 {
435+
let mut word = 0u64;
436+
for b in 0..64 {
437+
let dim = w * 64 + b;
438+
if v[dim] > 0.0 {
439+
word |= 1u64 << b;
440+
}
441+
}
442+
bits[w] = word;
443+
}
444+
bits
445+
}
446+
447+
/// Element-wise multiply (bind) on the 16K carrier: assigns a role key
448+
/// to content. Self-inverse for ±1 bipolar keys (key² = 1 elementwise).
449+
pub fn vsa16k_bind(a: &[f32; 16_384], b: &[f32; 16_384]) -> Box<[f32; 16_384]> {
450+
let mut out = Box::new([0.0f32; 16_384]);
451+
for i in 0..16_384 {
452+
out[i] = a[i] * b[i];
453+
}
454+
out
455+
}
456+
457+
/// Element-wise add (bundle / superposition) on the 16K carrier.
458+
/// Per I-SUBSTRATE-MARKOV, this is the Chapman-Kolmogorov-safe
459+
/// merge mode for state-transition paths. Do NOT substitute XOR.
460+
pub fn vsa16k_bundle(vectors: &[&[f32; 16_384]]) -> Box<[f32; 16_384]> {
461+
let mut out = Box::new([0.0f32; 16_384]);
462+
for v in vectors {
463+
for i in 0..16_384 {
464+
out[i] += v[i];
465+
}
466+
}
467+
out
468+
}
469+
470+
/// Cosine similarity between two 16K carriers.
471+
pub fn vsa16k_cosine(a: &[f32; 16_384], b: &[f32; 16_384]) -> f32 {
472+
let mut dot = 0.0f32;
473+
let mut norm_a = 0.0f32;
474+
let mut norm_b = 0.0f32;
475+
for i in 0..16_384 {
476+
dot += a[i] * b[i];
477+
norm_a += a[i] * a[i];
478+
norm_b += b[i] * b[i];
479+
}
480+
let denom = norm_a.sqrt() * norm_b.sqrt();
481+
if denom < 1e-12 { 0.0 } else { dot / denom }
482+
}
483+
360484
#[cfg(test)]
361485
mod tests {
362486
use super::*;
@@ -500,4 +624,107 @@ mod tests {
500624
assert!(sim_a > 0.5, "bundle should be similar to input a");
501625
assert!(sim_b > 0.0, "bundle should be positively similar to b");
502626
}
627+
628+
#[test]
629+
fn vsa16k_byte_size_is_64k() {
630+
let fp = CrystalFingerprint::Vsa16kF32(Box::new([0.0f32; 16_384]));
631+
assert_eq!(fp.byte_size(), 65_536);
632+
}
633+
634+
#[test]
635+
fn binary16k_to_vsa16k_bipolar_roundtrip_is_lossless() {
636+
let mut bits = Box::new([0u64; 256]);
637+
for i in 0..256 {
638+
bits[i] = 0xDEAD_BEEF_CAFE_BABEu64.wrapping_mul(i as u64 + 1);
639+
}
640+
let v = binary16k_to_vsa16k_bipolar(&bits);
641+
let back = vsa16k_to_binary16k_threshold(&v);
642+
for i in 0..256 {
643+
assert_eq!(back[i], bits[i],
644+
"word {i}: expected {:#018x} got {:#018x}", bits[i], back[i]);
645+
}
646+
}
647+
648+
#[test]
649+
fn vsa16k_bipolar_values_are_unit() {
650+
let bits = Box::new([0xAAAA_AAAA_AAAA_AAAAu64; 256]);
651+
let v = binary16k_to_vsa16k_bipolar(&bits);
652+
for i in 0..16_384 {
653+
assert!(v[i] == 1.0 || v[i] == -1.0,
654+
"dim {i} is {} — must be strict ±1", v[i]);
655+
}
656+
}
657+
658+
#[test]
659+
fn vsa16k_bind_is_self_inverse_for_bipolar() {
660+
let key = {
661+
let mut k = Box::new([0.0f32; 16_384]);
662+
for i in 0..16_384 {
663+
k[i] = if i % 3 == 0 { -1.0 } else { 1.0 };
664+
}
665+
k
666+
};
667+
let content = {
668+
let mut c = Box::new([0.0f32; 16_384]);
669+
for i in 0..16_384 {
670+
c[i] = (i as f32 / 16_384.0) * 2.0 - 1.0;
671+
}
672+
c
673+
};
674+
let bound = vsa16k_bind(&content, &key);
675+
let unbound = vsa16k_bind(&bound, &key);
676+
for i in 0..16_384 {
677+
assert!((unbound[i] - content[i]).abs() < 1e-5,
678+
"dim {i}: expected {} got {}", content[i], unbound[i]);
679+
}
680+
}
681+
682+
#[test]
683+
fn vsa16k_bundle_preserves_similarity_to_inputs() {
684+
let a = {
685+
let mut v = Box::new([0.0f32; 16_384]);
686+
for i in 0..16_384 { v[i] = 1.0; }
687+
v
688+
};
689+
let b = {
690+
let mut v = Box::new([0.0f32; 16_384]);
691+
for i in 0..16_384 { v[i] = if i < 8_192 { 1.0 } else { -1.0 }; }
692+
v
693+
};
694+
let bundled = vsa16k_bundle(&[&*a, &*b]);
695+
assert!(vsa16k_cosine(&bundled, &a) > 0.5);
696+
assert!(vsa16k_cosine(&bundled, &b) > 0.0);
697+
}
698+
699+
#[test]
700+
fn vsa16k_bundle_then_unbind_recovers_role_content() {
701+
// Two role slots, each with its own bipolar key; content bound to
702+
// each; bundled; unbind by multiplying with the role key recovers
703+
// the matching content above the noise floor.
704+
let role_a = binary16k_to_vsa16k_bipolar(&Box::new([0xF0F0_F0F0_F0F0_F0F0u64; 256]));
705+
let role_b = binary16k_to_vsa16k_bipolar(&Box::new([0x0F0F_0F0F_0F0F_0F0Fu64; 256]));
706+
let content_a = binary16k_to_vsa16k_bipolar(&Box::new([0xAAAA_AAAA_AAAA_AAAAu64; 256]));
707+
let content_b = binary16k_to_vsa16k_bipolar(&Box::new([0x5555_5555_5555_5555u64; 256]));
708+
let bound_a = vsa16k_bind(&content_a, &role_a);
709+
let bound_b = vsa16k_bind(&content_b, &role_b);
710+
let bundled = vsa16k_bundle(&[&*bound_a, &*bound_b]);
711+
let recovered_a = vsa16k_bind(&bundled, &role_a);
712+
let recovered_b = vsa16k_bind(&bundled, &role_b);
713+
assert!(vsa16k_cosine(&recovered_a, &content_a)
714+
> vsa16k_cosine(&recovered_a, &content_b),
715+
"unbind(role_a) must favour content_a over content_b");
716+
assert!(vsa16k_cosine(&recovered_b, &content_b)
717+
> vsa16k_cosine(&recovered_b, &content_a),
718+
"unbind(role_b) must favour content_b over content_a");
719+
}
720+
721+
#[test]
722+
fn vsa16k_to_vsa10k_projection_is_finite() {
723+
let fp = CrystalFingerprint::Vsa16kF32(Box::new([1.0f32; 16_384]));
724+
let v10 = fp.to_vsa10k_f32();
725+
for i in 0..10_000 {
726+
assert!(v10[i].is_finite(),
727+
"vsa16k→vsa10k must produce finite values; dim {i} is {}", v10[i]);
728+
}
729+
}
503730
}

crates/lance-graph-contract/src/crystal/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,11 @@ pub mod document;
6868
pub mod cycle;
6969
pub mod session;
7070

71-
pub use fingerprint::{CrystalFingerprint, Structured5x5, Quorum5D};
71+
pub use fingerprint::{
72+
CrystalFingerprint, Structured5x5, Quorum5D,
73+
vsa16k_zero, binary16k_to_vsa16k_bipolar, vsa16k_to_binary16k_threshold,
74+
vsa16k_bind, vsa16k_bundle, vsa16k_cosine,
75+
};
7276
pub use sentence::SentenceCrystal;
7377
pub use context::ContextCrystal;
7478
pub use document::DocumentCrystal;

0 commit comments

Comments
 (0)