diff --git a/.claude/board/entries/2026-10-22-pal256-immutable-needle-distribution-probe.md b/.claude/board/entries/2026-10-22-pal256-immutable-needle-distribution-probe.md new file mode 100644 index 000000000..37cfb2e8b --- /dev/null +++ b/.claude/board/entries/2026-10-22-pal256-immutable-needle-distribution-probe.md @@ -0,0 +1,19 @@ +# Palette256 is a frozen needle; Palette256:Palette256 is a distribution + +Status: **lab-only test contract**. No codebook rebake, CE64 layout change, new engine, or production certification. + +## Existing ownership + +- `.claude/knowledge/reference-frame-vs-motion.md`: corpus/calibration is versioned and immutable within a reference snapshot; attention, belief updates, and learning are overlays. +- `.claude/board/entries/2026-08-26-e-palette256-is-a-needle-the-colon-is-the-distribution-1.md`: a single palette index answers *which*; pairwise calibrated LUT answers *how related*. +- `bgz-tensor::fisher_z::FisherZTable`: already implements frozen `256 x 256 x i8 + FamilyGamma`. Do **not** add another distance table. + +## Falsifiers and next boundary + +1. Replaying 64 lookup rounds may never mutate the LUT or its calibration bytes. +2. A `u8` identity cannot be ranked as semantic similarity by sorting the IDs. +3. The pairwise diagonal is not a substitute for address equality; if a caller needs self-identity, answer from the addressing layer. +4. Rebuilding calibrated references requires a **new version and digest**. Future work: attest codebook identity + family-gamma bytes at BIND time and reject stale codebooks. +5. The documented Spearman 0.9998 is *pair-ranking agreement on sampled pairs*, not a probability of correctness and not a multi-hop theorem. + +Run: `cargo test --manifest-path crates/bgz-tensor/Cargo.toml --test palette256_reference_contract`. diff --git a/.claude/board/entries/README.md b/.claude/board/entries/README.md index 3d349a7f8..0a47f23e5 100644 --- a/.claude/board/entries/README.md +++ b/.claude/board/entries/README.md @@ -25,10 +25,11 @@ index row, (3) no duplicate entry id. Checks 1 and 2 are deliberately opposite directions; the stranding this convention prevents shows up in exactly one of them, never both. -431 entries, 2026-08-06 .. 2026-10-22. +433 entries, 2026-08-06 .. 2026-10-22. | date | entry id | finding | file | |---|---|---|---| +| 2026-10-22 | `pal256-immutable-needle-distribution-probe` | | [2026-10-22-pal256-immutable-needle-distribution-probe.md](2026-10-22-pal256-immutable-needle-distribution-probe.md) | | 2026-10-22 | `pal256-3sigma-statistical-gate` | | [2026-10-22-pal256-3sigma-statistical-gate.md](2026-10-22-pal256-3sigma-statistical-gate.md) | | 2026-10-22 | `math-compiler-stage-b-e1` | | [2026-10-22-math-compiler-stage-b-e1.md](2026-10-22-math-compiler-stage-b-e1.md) | | 2026-10-22 | `math-compiler-gap-matrix` | | [2026-10-22-math-compiler-gap-matrix.md](2026-10-22-math-compiler-gap-matrix.md) | diff --git a/crates/bgz-tensor/tests/palette256_reference_contract.rs b/crates/bgz-tensor/tests/palette256_reference_contract.rs new file mode 100644 index 000000000..036199dc7 --- /dev/null +++ b/crates/bgz-tensor/tests/palette256_reference_contract.rs @@ -0,0 +1,46 @@ +//! Immutable reference vs relational value: lab contract for Palette256. +//! A palette byte is an address, never a relationship or a confidence score. +//! Pairwise distribution values live in the frozen, family-calibrated LUT. +//! No hot-path API or memory layout is changed by this regression probe. +use bgz_tensor::fisher_z::FisherZTable; + +#[test] +fn baked_pairwise_table_is_stable_across_repeated_reads_and_roundtrip() { + let representatives = vec![vec![1.0_f32, 0.0], vec![0.8, 0.6], vec![-0.6, 0.8]]; + let table = FisherZTable::build(&representatives, 3); + let baked = table.to_bytes(); + assert_eq!(baked.len(), 3 * 3 + 8); + for _thought in 0..64 { + for a in 0..3_u8 { + for b in 0..3_u8 { + assert_eq!( + table.lookup_i8(a, b), + table.entries[a as usize * 3 + b as usize] + ); + } + } + assert_eq!( + table.to_bytes(), + baked, + "lookup cannot rewrite calibrated reference" + ); + } + let restored = FisherZTable::from_bytes(&baked, 3); + assert_eq!(restored.to_bytes(), baked); + assert_eq!(restored.lookup_i8(0, 1), table.lookup_i8(0, 1)); +} + +#[test] +fn needle_identity_is_not_the_same_question_as_relation_strength() { + let representatives = vec![vec![1.0_f32, 0.0], vec![0.0, 1.0], vec![-1.0, 0.0]]; + let table = FisherZTable::build(&representatives, 3); + let needle: u8 = 1; + assert_eq!( + needle, 1, + "the address names an entry without measuring distance" + ); + assert_ne!(table.lookup_i8(0, 1), table.lookup_i8(0, 2)); + // Do not infer self-cosine == 1 from the calibrated diagonal. The diagonal + // consumes family gamma whose calibration excludes self-pairs by design. + assert_eq!(table.lookup_i8(1, 1), table.entries[4]); +}