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 — Register128 signed readings on branch `ccr-b2e415d9-4jfvyk-register-readings` (unmerged)

- Contract delta (additive): `hotplug::SlabReading::{RegisterI4x32(law), RegisterI8x16(law)}` (tags 2..=7, `to_tag`), `Activation::{with_register_laws, register_law_for}`, `ResolvedReading::bind_signed_register(&activation, rails)`, `ActivationDrift::{NotSignedRegister, NoRegisterLawFor, RegisterLawMismatch}`; `register128::{RegisterCarving, RegisterLaw, SignedRegisterLanes, SignedRegisterRefusal}`; `atoms::I4x32::{from_bytes, as_bytes}`. No layout change. Entry: `entries/2026-10-08-register128-signed-readings.md`.

## 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`.
Expand Down
78 changes: 78 additions & 0 deletions .claude/board/entries/2026-10-08-register128-signed-readings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# 2026-10-08 — Register128 signed readings (32×i4, 16×i8) with a per-family law

**Status:** CURRENT-CONTRACT, TEST-PINNED. Branch
`ccr-b2e415d9-4jfvyk-register-readings`, commits `14831543` and `96304b88`
(law authority, after Codex P2 on #1410).

## What landed

The carrier is unchanged: the `Register0` / `Register1` rails (16 B each), no
classid in the payload, no layout change.

- **Carving and recorded law, declared by the slab.**
`SlabReading::RegisterI4x32(law)` (32 × i4, dim `2k` = low nibble of byte
`k`, the `atoms::I4x32` layout) and `SlabReading::RegisterI8x16(law)` (16 ×
i8, dim `k` = byte `k`). Envelope tags 2..=7 (`to_tag` inverts `from_tag`).
The law is the one the writer actually wrote with.
- **Concept law, declared by the authority.** `Activation::with_register_laws`
/ `register_law_for` (fail-closed: `NoRegisterLawFor`).
- **Binding checks agreement.** `ResolvedReading::bind_signed_register(&activation,
rails)` takes no law; it refuses `RegisterLawMismatch` when the slab's law and
the concept's differ. A writer and a reader of one population therefore hold
the same law. The returned `SignedRegisterLanes` carry concept, rails, carving
and law. `RegisterLaw::{RelativeOffset, AxisPosition, Support}`.
- **Checked on every access.** `read_i4x32` / `read_i8x16` / `write_i4x32` /
`write_i8x16` take the law the caller expects and refuse, in order, an absent
rail, a different carving, a different law. An i4 outside `-8..=7` is refused,
never saturated. A refused write leaves the row unchanged.
- **Separation from the unsigned reading.** `bind_register128` (4 × u32 words)
is unchanged and refuses the signed carvings; `bind_signed_register` refuses
`Register128`, `Facet96` and undeclared slabs.
- **EpistemicState5 has no law here.** It stays on CE64 bits 59..63.

## Inventory of the 24×i4 families on `main` (2026-10-08)

| family | on `main` | law it would bind |
|---|---|---|
| Temporal / anaphora | `CausalWitness` tenant 14, Facet96 read as G24N4 (24 i4 window pointers). EXPERIMENTAL. The only resident 24×i4 lane. | `RelativeOffset` |
| Evidence (Tarski) | Probe only: `probe_four_plane_causal_medium.rs` (G24N4 as support/falsifier). | `Support` |
| Taxonomy axes | Fixture only: `entries/2026-10-04-coresearch-evidence-stance-dependence.md` (Mammal: `terrestrial`, `placental`). | `AxisPosition` |
| Episodic basin | `EpisodicBasin` tenant 15: 32 B of references, not i4. | none (not a signed family) |
| 32×i4 carrier | `atoms::I4x32`; now also the i4 carving's layout. | — |
| 16×i8 | `ndarray` SIMD `I8x16` only. | — |

`CausalWitness` is NOT moved onto a register by this change: it is a Facet96
lane with its own classid, and re-homing it is a separate decision.

## Tests and disable runs

Hotplug: `signed_rails_need_a_signed_carving_and_an_agreeing_law`; tag test now
accepts 2 and 3. Register128: round trip of every i4 value in every dim with the
nibble layout pinned; i8 dim-k-is-byte-k; the same bytes differ under the two
carvings; law mismatch (all 3×3 pairs, both carvings) refused and writes
nothing; carving mismatch refused; out-of-range i4 in the last dim refused
before writing; writes stay inside their rail.

| disable | caught by |
|---|---|
| law check removed | `a_different_law_is_refused_and_writes_nothing` |
| carving check removed | `a_different_carving_is_refused` |
| rail check removed | `signed_writes_stay_inside_their_rail` |
| i4 range check removed | `an_out_of_range_i4_is_refused_before_writing` |
| binding accepts `Register128` as i4 | `signed_rails_need_a_signed_carving_and_an_agreeing_law` |
| binding swaps the carvings | same |
| binding skips the schema check | same |
| law mismatch check removed | `signed_rails_need_a_signed_carving_and_an_agreeing_law` |
| concept law ignored (slab law used) | same |
| `to_tag` shifts the I8x16 tags | `an_unsupported_physical_reading_fails_closed` |
| `from_tag` drops the law | same |

## OPEN

- No OGAR authority populates `with_register_laws` yet (`lance-graph-ogar`
builds its `Activation` without laws), so in production every concept still
refuses to bind signed registers. That is fail-closed, not a gap in the check.
- Lane or reading per family is undecided until measured: 32×i4 vs 16×i8 on
KJV anaphora and the mammal fixture. The rule "outside the local window →
basin edge" is not changed by `RelativeOffset` under `I8x16`.
- No production writer or reader.
3 changes: 2 additions & 1 deletion .claude/board/entries/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

270 entries, 2026-08-06 .. 2026-10-08.
271 entries, 2026-08-06 .. 2026-10-08.

| date | entry id | finding | file |
|---|---|---|---|
| 2026-10-08 | `register128-signed-readings` | | [2026-10-08-register128-signed-readings.md](2026-10-08-register128-signed-readings.md) |
| 2026-10-08 | `rbac-nested-scope-path` | | [2026-10-08-rbac-nested-scope-path.md](2026-10-08-rbac-nested-scope-path.md) |
| 2026-10-08 | `rbac-membership-scope` | | [2026-10-08-rbac-membership-scope.md](2026-10-08-rbac-membership-scope.md) |
| 2026-10-08 | `rbac-hotplug-socket` | | [2026-10-08-rbac-hotplug-socket.md](2026-10-08-rbac-hotplug-socket.md) |
Expand Down
2 changes: 1 addition & 1 deletion .claude/v3/soa_layout/tenants.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Offsets are FULL-ROW; subtract 32 for slab-relative.
| 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 |
| 17 | Register1 | U8 × 16 | 16 B | [268,284) | Second independent `Register128` rail, same contract as Register0. Both rails can instead be declared signed: `SlabReading::RegisterI4x32(law)` / `RegisterI8x16(law)`, bound by `bind_signed_register`, which requires the slab's recorded `RegisterLaw` to equal the concept's (2026-10-08) |
| 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 |
Expand Down
13 changes: 13 additions & 0 deletions crates/lance-graph-contract/src/atoms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,19 @@ impl I4x32 {
/// The all-zero style vector (every lane neutral).
pub const ZERO: Self = Self { bytes: [0u8; 16] };

/// Wrap 16 already-packed bytes. No conversion: dim `2k` is the low
/// nibble of byte `k`, dim `2k+1` the high nibble.
#[must_use]
pub const fn from_bytes(bytes: [u8; 16]) -> Self {
Self { bytes }
}

/// The 16 packed bytes, in the layout [`from_bytes`](Self::from_bytes) takes.
#[must_use]
pub const fn as_bytes(&self) -> &[u8; 16] {
&self.bytes
}

/// Pack 32 signed dims into the i4 CAM carrier, saturating to `[−8, 7]`.
///
/// The carrier is a **sparse, deterministic 32×CAM address** (128-bit) — the non-zero
Expand Down
Loading
Loading