Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .claude/board/LATEST_STATE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2026-10-08 — HHTL / NARS / Moore value tenants on branch `ccr-b2e415d9-4jfvyk-tenants` (unmerged)

- Contract delta (additive): `ValueTenant::{Nars16x8 = 18, MoorePalettePairs = 19, MooreNars16 = 20}` at row [284,332), in `ValueSchema::Full` only; new module `contract::moore_tenant::{MooreSlot, MooreNars16, DirectionReading, DirectionRefusal, MooreRefusal, MooreTenantView, MooreTenantMut}`. BoardAggregates reservation re-based to 21. Entry: `entries/2026-10-08-hhtl-nars-moore-value-tenants.md`.

## 2026-10-08 — RBAC hot-plug socket on branch `ccr-0455e606-wmtsor` (unmerged)

- Contract delta (additive): new module `contract::rbac_plug::{RbacPlug, RbacAuthority, RbacBinding, RbacDrift, ActorSource, PluggedRbac, verify_concepts_against_mirror}`. Entry: `entries/2026-10-08-rbac-hotplug-socket.md`.
Expand Down
72 changes: 72 additions & 0 deletions .claude/board/entries/2026-10-08-hhtl-nars-moore-value-tenants.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# 2026-10-08 — HHTL / NARS / Moore value tenants (ordinals 18–20)

**Status:** physical layout RATIFIED and TEST-PINNED; MooreNars16 semantics
CANDIDATE. Branch `ccr-b2e415d9-4jfvyk-tenants`, commit `28ec7c0`.

## What landed

Three append-only value tenants after `Register1`. Layout-preserving: `NodeRow`
stays 512 B, tenants 0..17 and every CE64 field are unchanged, no
`ENVELOPE_LAYOUT_VERSION` bump.

| ord | tenant | kind | row bytes | slab bytes |
|---|---|---|---|---|
| 18 | `Nars16x8` | U16 × 8, LE | [284,300) | [252,268) |
| 19 | `MoorePalettePairs` | U8 × 16 | [300,316) | [268,284) |
| 20 | `MooreNars16` | U16 × 8, LE | [316,332) | [284,300) |

- Lane `i` = Moore slot `i`, order `NW,N,NE,W,E,SW,S,SE` (the probes' order).
- Pair byte `2i` = first Palette256 operand, `2i+1` = second; the law address
is `(first << 8) | second`, the #1336 `PairAddress` orientation.
- `MooreNars16` = `Pearl3 | Energy4 | Plasticity3 | Polarity1 | Epi5`
(bits 0..2, 3..6, 7..9, 10, 11..15), the #1406 reading.
- `ValueSchema::Full` carries all three; no narrower preset does, because no
consumer materialises them yet. Full total 252 -> 300 B.
- `BoardAggregates` reservation re-based 18 -> 21 (canonical_node comment and
the stale `band_reading.rs` note).

`contract::moore_tenant::{MooreSlot, MooreNars16, DirectionReading,
DirectionRefusal, MooreRefusal, MooreTenantView, MooreTenantMut}`: lane access
goes through `ValueTenant::value_offset()`, no literal offset.

## Refusals

- A sign-triple consumer refuses a Moore direction:
`DirectionReading::require_sign_triple` returns `DirectionRefusal` for
`Moore { slot, polarity }`.
- `MooreTenantMut::lift_ce64` refuses mixed witnesses and Epi5 codes 24..31,
checking all eight lanes before writing any.
- The witness is not stored in these bytes; the lift returns it to the owner.

## Tests (A–L)

`moore_tenant.rs` (12 tests: A, B, C, D, E, G ×2, H, I, K, L);
`cognitive-shader-driver/tests/moore_palette_pairs_lut.rs` (F);
`lance-graph-planner/tests/moore_tenant_isa_equivalence.rs` (J, 2 tests:
256 tenants × 8 lanes × 5 ops, 0 divergences on every field except the sign
triple; restoring the wrong witness diverges).

Disable runs, each red then restored:

| disable | caught by |
|---|---|
| slot order E/W swapped | E, I |
| u16 lanes big-endian | D, I |
| pair bytes read swapped | F |
| witness check removed | I |
| refused lift writes a lane first | I |
| Moore direction passes as sign triple | H |
| energy read as 3 bits | J |
| `ce64_upper` drops the witness | J |
| `Nars16x8` descriptor U8 × 16 | A |
| `Full` drops `MooreNars16` | compile-time assert |

## OPEN

- The `Nars16x8` lane reading is not declared anywhere.
- No `SlabReading` variant declares these tenants, so `ResolvedReading`
cannot yet gate a consumer on them the way `bind_register128` does.
- No production writer or reader. The production Simpson detector still takes
bare edges and cannot refuse a Moore direction (pinned in #1406).
- J uses `forward` as it is on `main`; #1407 (unmerged) changes it to return
`Result`, and J follows when that lands.
3 changes: 2 additions & 1 deletion .claude/board/entries/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ 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.

268 entries, 2026-08-06 .. 2026-10-08.
269 entries, 2026-08-06 .. 2026-10-08.

| date | entry id | finding | file |
|---|---|---|---|
Expand All @@ -34,6 +34,7 @@ exactly one of them, never both.
| 2026-10-08 | `rbac-hotplug-socket` | | [2026-10-08-rbac-hotplug-socket.md](2026-10-08-rbac-hotplug-socket.md) |
| 2026-10-08 | `moore-nars16-isa-visible-representation` | | [2026-10-08-moore-nars16-isa-visible-representation.md](2026-10-08-moore-nars16-isa-visible-representation.md) |
| 2026-10-08 | `D-MOORE-NARS-0` | | [2026-10-08-moore-nars-0-recipe-learning-gomoku.md](2026-10-08-moore-nars-0-recipe-learning-gomoku.md) |
| 2026-10-08 | `hhtl-nars-moore-value-tenants` | | [2026-10-08-hhtl-nars-moore-value-tenants.md](2026-10-08-hhtl-nars-moore-value-tenants.md) |
| 2026-10-08 | `coresearch-ce64-moore-masking-wiring` | | [2026-10-08-coresearch-ce64-moore-masking-wiring.md](2026-10-08-coresearch-ce64-moore-masking-wiring.md) |
| 2026-10-07 | `tinker-janus-fold-harvest` | TinkerPop bulk = K (GroupReduce), ONE_BULK = S, GValue pinning = bundle invalidation; JanusGraph slice = OrderedLaneWitness→Range (30–38×); no new V4 op | [2026-10-07-tinker-janus-fold-harvest.md](2026-10-07-tinker-janus-fold-harvest.md) |
| 2026-10-07 | `selector-seq-aware-coverage` | | [2026-10-07-selector-seq-aware-coverage.md](2026-10-07-selector-seq-aware-coverage.md) |
Expand Down
19 changes: 19 additions & 0 deletions .claude/v3/soa_layout/le-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,25 @@ reading is trusted in any downstream claim. This is the statistical
mirror of the field-isolation matrix: layout tests prove bytes don't
move; jc pillars prove the READING preserves the semantics.

### §3c Non-facet value tenants: Moore lanes (2026-10-08)

Not every value tenant is a 4+12 facet. Register0/1 carry no classid, and
the three Moore tenants (`Nars16x8`, `MoorePalettePairs`, `MooreNars16`,
ordinals 18–20) are eight lanes each, one per Moore slot in canonical order
`NW,N,NE,W,E,SW,S,SE`. Their LE contract is the descriptor itself:

- `Nars16x8` and `MooreNars16` are `ColumnKind::U16 × 8`, little-endian.
- `MoorePalettePairs` is `ColumnKind::U8 × 16`: byte `2i` is the first
Palette256 operand and `2i+1` the second. It is two bytes, not a `u16`.
- Offsets are only in `VALUE_TENANTS`; consumers use
`ValueTenant::value_offset()` (and `moore_tenant::MooreTenantView`), never
a literal.

The physical layout is RATIFIED. The MooreNars16 field reading is CANDIDATE
and is a different reading from the CE64 register it lifts: direction is
`(slot, polarity)`, not the S/P/O sign triple, and the witness is
tenant-scoped. See `tenants.md` §2 rows 18–20.

## §4 Relation to the CANON node and the envelope

- The CANON node (`CLAUDE.md` § Minimal SoA node, locked 2026-06-13)
Expand Down
20 changes: 16 additions & 4 deletions .claude/v3/soa_layout/tenants.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Tenant Lanes — the value-slab catalogue (code ground truth 2026-07-02, refreshed 2026-08-22)
# Tenant Lanes — the value-slab catalogue (code ground truth 2026-07-02, refreshed 2026-10-08)

> READ BY: v3-envelope-auditor (mandatory), anyone reading/writing a tenant
> lane, adding a ValueSchema, or wiring a consumer. Byte atom + payload
Expand Down Expand Up @@ -33,7 +33,7 @@
every downstream tenant offset. Every tenant below carries its OWN LE
contract nested in the envelope's (le-contract.md §3b).

## §2 The 16 value tenants (`ValueTenant`, canonical_node.rs:828-943; `VALUE_TENANTS`, canonical_node.rs:935-1105)
## §2 The 21 value tenants (`ValueTenant` + `VALUE_TENANTS` in canonical_node.rs)

Discriminant = FieldMask bit = VALUE_TENANTS index (compile-asserted).
Offsets are FULL-ROW; subtract 32 for slab-relative.
Expand All @@ -56,9 +56,21 @@ Offsets are FULL-ROW; subtract 32 for slab-relative.
| 13 | Tekamolo | U8 × 16 | 16 B | [188,204) | TEKAMOLO facet lane — 16 B content-blind V3 4+12 facet (`classid(4) + 6×(u8:u8)`), read G4D3 as `temporal · kausal · modal · lokal` (when/why/how/where circumstance-frame). All-zero = unaddressed |
| 14 | CausalWitness | U8 × 16 | 16 B | [204,220) | CausalWitness facet lane — 16 B content-blind V3 4+12 facet read as **G24N4** (24 signed i4 loci, a lane shape name, never a `CascadeShape` variant); each nibble is a context pointer (signed ±8 window offset), not a strength. Slots 16..24 reserved-zero. **Status: EXPERIMENTAL — not in the operator-locked §3 catalogue** (per its own doc-comment) |
| 15 | EpisodicBasin | U8 × 32 | 32 B | [220,252) | **D-ACR-6 rail** — a promoted basin as REFERENCES: `subject` u16 · `member_count` u16 · `self_code` 12 B (Cam96 centroid) · `version_from`/`version_to` u64. Members are reached by following `(subject, [from,to))` into the triple stream, never inlined — the fat-concept guard `§3a` names. Width is NOT stored (recomputable through the references) |
| 16 | Register0 | U8 × 16 | 16 B | [252,268) | **D-LXC-29** 128-bit working register, NO classid in the payload; read as `Register128` only when the slab declares `SlabReading::Register128` (`ResolvedReading::bind_register128` refuses otherwise). All-zero = empty accumulator |
| 17 | Register1 | U8 × 16 | 16 B | [268,284) | Second independent `Register128` rail, same contract as Register0 |
| 18 | Nars16x8 | U16 × 8 (LE) | 16 B | [284,300) | One `u16` per Moore slot (`NW,N,NE,W,E,SW,S,SE`). Layout RATIFIED; the `u16` reading is CANDIDATE and NOT declared by this tenant. Never shares bytes or a reading with MooreNars16 |
| 19 | MoorePalettePairs | U8 × 16 | 16 B | [300,316) | One Palette256 `(u8:u8)` pair per Moore slot: byte `2i` = first operand, `2i+1` = second, addressing a 256×256 law as `(first << 8) \| second` (the #1336 `PairAddress` orientation). Two separate bytes, never one widened `u16` |
| 20 | MooreNars16 | U16 × 8 (LE) | 16 B | [316,332) | One `MooreNars16` per Moore slot: `Pearl3 \| Energy4 \| Plasticity3 \| Polarity1 \| Epi5` (bits 0..2, 3..6, 7..9, 10, 11..15). Direction = `(slot, polarity)`, never the S/P/O sign triple (`DirectionReading::require_sign_triple` refuses it); one witness for all eight lanes, held by the owner, not in these bytes (`MooreTenantMut::lift_ce64` refuses mixed W). Epi5 24..31 reserved. Layout RATIFIED, semantics CANDIDATE |

> **2026-10-08 refresh.** Rows 16–20 added. Register0/Register1 (#1336-era,
> D-LXC-29) had shipped without a row here — the same drift the 2026-07-28
> note describes. Tenants 18–20 come with `moore_tenant.rs` (slot order,
> zero-copy lane access through `value_offset()`, the MooreNars16 reading
> and its refusals). The BoardAggregates reservation re-bases to **21**.
> Full now spans `[32,332)`: 300 B of 480, 180 B headroom.

`ValueSchema::Full`'s `field_mask()` (canonical_node.rs:1132-1162, as read
2026-07-28) lists all 15 tenants 0–14 (Meta … `CausalWitness`), spanning row
2026-07-28) lists all 15 tenants 0–14 (Meta … `CausalWitness`) as of 2026-07-28, spanning row
range `[32,220)` — 188 B of the 480-byte value slab consumed (`220 − 32`;
`VALUE_SLAB_ROW_OFFSET = 32`, §1) — **292 B headroom, RESERVE-DON'T-RECLAIM**
(compile-asserted ≤ 480, canonical_node.rs:1197).
Expand All @@ -85,7 +97,7 @@ range `[32,220)` — 188 B of the 480-byte value slab consumed (`220 − 32`;
| Bootstrap = 0 (default) | none (FieldMask::EMPTY) | zero-fallback ladder |
| Cognitive = 1 | Meta, Qualia, Fingerprint, Energy, Plasticity, EntityType, Kanban (7) | thinking rows |
| Compressed = 2 | Fingerprint, HelixResidue, TurbovecResidue, EntityType (4) | baked/search rows (q2 bakes) |
| Full = 3 | all 15 tenants 0–14 (Meta … `CausalWitness`) | superset; count compile-asserted `== VALUE_TENANTS.len()` |
| Full = 3 | all 21 tenants 0–20 (Meta … `MooreNars16`) | superset; count compile-asserted `== VALUE_TENANTS.len()`. Tenants 15–20 are in Full only |

## §4 The classid → tenant resolution (ReadMode registry)

Expand Down
80 changes: 80 additions & 0 deletions crates/cognitive-shader-driver/tests/moore_palette_pairs_lut.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
//! Test F: the `MoorePalettePairs` tenant addresses the #1336 Palette256 law
//! the same way `PairAddress` does.
//!
//! Byte `2i` of the tenant is the first operand and byte `2i + 1` the second,
//! so the law entry for slot `i` is `lut[(first << 8) | second]`. The test
//! reads each pair through the contract's tenant view and checks it against
//! the shipped `PaletteLut::at` and `Quad8::palette_pairs` on the same bytes.

use cognitive_shader_driver::palette_perturbation::{
PairAddress, PaletteLut, PaletteState, PALETTE_LUT_LEN,
};
use cognitive_shader_driver::quad8::Quad8;
use lance_graph_contract::canonical_node::{ValueTenant, VALUE_SLAB_LEN};
use lance_graph_contract::moore_tenant::{MooreSlot, MooreTenantMut, MooreTenantView};

/// An asymmetric law, so swapping the operands changes the answer.
fn law() -> Box<[u8; PALETTE_LUT_LEN]> {
let mut t = vec![0u8; PALETTE_LUT_LEN].into_boxed_slice();
for a in 0..256usize {
for b in 0..256usize {
t[a * 256 + b] = (a * 31 + b * 7 + (a ^ b)) as u8;
}
}
t.try_into().expect("64 KiB")
}

fn next(x: &mut u64) -> u8 {
*x = x
.wrapping_mul(6364136223846793005)
.wrapping_add(1442695040888963407);
(*x >> 56) as u8
}

#[test]
fn tenant_pairs_address_the_lut_like_pair_address() {
let entries = law();
let lut = PaletteLut::new(&entries);
let mut seed = 0x1336u64;
let mut swapped_differs = 0;
for _ in 0..512 {
let mut slab = [0u8; VALUE_SLAB_LEN];
let mut m = MooreTenantMut::new(&mut slab);
for slot in MooreSlot::ALL {
m.set_palette_pair(slot, next(&mut seed), next(&mut seed));
}
let view = MooreTenantView::new(&slab);
for slot in MooreSlot::ALL {
let (first, second) = view.palette_pair(slot);
let addr = PairAddress::new(PaletteState(first), PaletteState(second));
assert_eq!(addr.0, (u16::from(first) << 8) | u16::from(second));
let via_tenant = entries[(usize::from(first) << 8) | usize::from(second)];
assert_eq!(
lut.at(PaletteState(first), PaletteState(second)).0,
via_tenant
);
assert_eq!(lut.at_address(addr).0, via_tenant);
if lut.at(PaletteState(second), PaletteState(first)).0 != via_tenant {
swapped_differs += 1;
}
}
// Two adjacent slots' four bytes, read as the #1336 Quad8, give the
// same two addresses the tenant gives.
let base = ValueTenant::MoorePalettePairs.value_offset();
for k in [0usize, 2, 4, 6] {
let b = &slab[base + 2 * k..base + 2 * k + 4];
let (p0, p1) = Quad8::from_bytes([b[0], b[1], b[2], b[3]]).palette_pairs();
let (a0, a1) = (
view.palette_pair(MooreSlot::ALL[k]),
view.palette_pair(MooreSlot::ALL[k + 1]),
);
assert_eq!(p0, PairAddress::new(PaletteState(a0.0), PaletteState(a0.1)));
assert_eq!(p1, PairAddress::new(PaletteState(a1.0), PaletteState(a1.1)));
}
}
// Anti-vacuity: the orientation is load-bearing on this law.
assert!(
swapped_differs > 3000,
"swapped orientation differed only {swapped_differs} times"
);
}
2 changes: 1 addition & 1 deletion crates/lance-graph-contract/src/band_reading.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ pub enum BandPresence {
/// static-substrate attention lands as an alpha-layer entry, dynamic-substrate
/// attention as the row's own Lance-version history — the discriminator names
/// the kind either way. The Hole becomes a target here once `HoleV3` lands
/// (blocked on the `BoardAggregates = 15` mint).
/// (blocked on the `BoardAggregates` mint, reserved at discriminant 21).
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum WitnessKind {
/// No witness reference — grading stands alone.
Expand Down
Loading
Loading