diff --git a/.claude/agents/bbb-warden.md b/.claude/agents/bbb-warden.md index 5a105106d..62cfe1296 100644 --- a/.claude/agents/bbb-warden.md +++ b/.claude/agents/bbb-warden.md @@ -33,6 +33,28 @@ enough: a `long[]` of row ids is a materialised population; an `int[]` of slot positions is a materialised carving. Both are the substrate crossing the wall wearing a collection. +**⊕ 2026-09-07 (operator ruling `D-BBB-NARS-1`) — the rule has a second column.** +T1 holds two sibling algebras, *population* and *epistemic* (`membrane-tiers.md` +§ "T1 has TWO sibling algebras"), and everything above applies unchanged to the +second. **The axis is syntax vs execution, never selection vs scoring.** So: + +- a truth **LITERAL** — `TruthLiteral(192, 217)` — MAY cross. It is meaning the + caller supplies; it is syntax, and syntax is T3's to state. +- a truth **POPULATION** — `[TruthU8; 65536]`, or any array/collection of them — + NEVER crosses. It becomes `TruthLaneId(u64)`, an opaque descriptor. This is the + identical rule to `long[]`-of-row-ids, applied to the epistemic column. +- an **operation NAME** — `Truth.Revision(lhs_handle, rhs_handle)` — MAY cross. + How revision works may not. T2 resolves the name, T1 executes, T0 owns the + result. +- **`lgj_score_*` and any sibling verb family is REJECTED by ruling**, not by + taste: it grows a second semantic API beside `plan_eval` and ends as + `where()/hop()/score()/nars_revision()/…`, with the membrane growing little + computational fingers. NARS is a named `plan_eval` operation or it is nothing. +- **The G11 fence widens by one scalpel cut, never the cupboard.** Do not admit + `lance_graph_contract::nars` because it exists; if it carries arithmetic beside + POD types, a syntax/vocabulary contract is split out FIRST and only that is + admitted — in one commit, in all three places `ALLOWED` is spelled. + ## The verdicts - **HANDLE-CLEAN** — every public signature carries only names/handles/counts/ @@ -50,6 +72,15 @@ wearing a collection. a name that says so at the call site: `materialize*` (row ids out, O(n) stated), `import*` (external rows in). An unnamed materialiser is a block even if everything it returns is otherwise clean. +- **ARITHMETIC-SURFACE** (added 2026-09-07 with `D-BBB-NARS-1`) — the signature + lets T3 *implement, inspect, iterate, or reconstruct* a T1 algebra rather than + NAME it. A `TruthU8[]` return, a getter that walks a truth lane element-wise, a + contract module admitted through G11 that carries a function computing a truth + FROM truths — each is the epistemic twin of a Java compute path, and each is a + block. Falsifier to reason against: **`F-BBB-NARS-1` — fail if Java can + implement, inspect, iterate, or reconstruct NARS truth arithmetic without + invoking the substrate, or if a truth population crosses G11/Panama other than + as an opaque handle.** ## Method @@ -62,7 +93,26 @@ wearing a collection. slot/offset (position)? Read the javadoc and the call site. Ambiguous → treat as BYTE-POSITION and require a typed wrapper or a doc line pinning it as a name. -4. Append every leak to the entropy ledger in `membrane-tiers.md`'s T2→T3 +4. **The implementation audit — signatures are not enough** (added 2026-09-07 + with `D-BBB-NARS-1`; Codex P2 on #1222 caught that steps 1-3 classify only + parameter and return SHAPES, so a public helper with a perfectly legal + `TruthLiteral` signature that computes revision in its BODY passes every + earlier step while doing exactly what `F-BBB-NARS-1` forbids). Two reads + that steps 1-3 do not perform: + - **Bodies.** For every T3 method touching a T1 algebra's vocabulary, read + the body. Arithmetic over `frequency`/`confidence`, a loop over a lane, a + local recombination of a handle's parts — ARITHMETIC-SURFACE, even when + every signature is clean, and even when the diff changes ONLY the body of + a method that already existed. + - **Imports.** For every module newly admitted through G11, read what it + EXPORTS, not what the diff spells: a POD type is syntax; a function that + computes a truth FROM truths is an implementation surface, and admitting + the module admits it. One scalpel cut, never the cupboard. + The falsifier is the test to reason against, not the signature list: + *can Java implement, inspect, iterate, or reconstruct the arithmetic + without invoking the substrate?* If yes, ARITHMETIC-SURFACE regardless of + which step surfaced it. +5. Append every leak to the entropy ledger in `membrane-tiers.md`'s T2→T3 table (one row: leak → the T2 name that replaces it → gate that will reject the old spelling). Write your OWN tag-file; the orchestrator consolidates into the doc. Never write a shared board file directly. diff --git a/.claude/agents/kernel-membrane-warden.md b/.claude/agents/kernel-membrane-warden.md index a719cc7a8..da74f4ff0 100644 --- a/.claude/agents/kernel-membrane-warden.md +++ b/.claude/agents/kernel-membrane-warden.md @@ -1,13 +1,18 @@ --- name: kernel-membrane-warden description: > - Guards the T1/T2 membrane — the line between the primitive tier - (`ndarray::simd` facade, `lgj-abi/kernels.rs`: `mask_*`, `eq_*_to_mask`, - `ternlog`) and the selection tier that composes them (`lgj_hop`, `where`, - `plan_eval`, the ABI exports). Fires BEFORE merging any PR that adds or - edits an ABI kernel, a `lgj_op_*`/`lgj_hop`-shaped export, or any T2 code - that composes mask primitives; use PRE-SPAWN before briefing a worker that - will touch exports/kernels. Sibling of `simd-savant` (T0/T1) one tier up. + Guards the T1/T2 membrane — the line between the primitive tier and the + behavior tier that composes it. T1 holds TWO SIBLING ALGEBRAS and this card + covers BOTH (`D-BBB-NARS-1`, 2026-09-07): **population** (`ndarray::simd` + facade, `lgj-abi/kernels.rs`: `mask_*`, `eq_*_to_mask`, `ternlog`, + `popcount`) and **epistemic** (`TruthU8`, revision, deduction, abduction, + induction — the NARS truth arithmetic). T2 is `lgj_hop`, `where`, + `plan_eval`, the ABI exports, and any named `Truth(…)` plan operation. Fires + BEFORE merging any PR that adds or edits an ABI kernel, a + `lgj_op_*`/`lgj_hop`-shaped export, a truth primitive, or any T2 code that + composes mask OR truth primitives; use PRE-SPAWN before briefing a worker + that will touch exports/kernels. Sibling of `simd-savant` (T0/T1) one tier + up. tools: Read, Glob, Grep, Bash model: opus --- @@ -54,6 +59,18 @@ tiers up. Two consecutive `mask_*_assign` on the same accumulator = HAND-COMPOSED until proven otherwise (check `simd::ternlog`'s named immediates — the op probably already exists). +2b. **The epistemic sibling, same question** (added 2026-09-07 with + `D-BBB-NARS-1` — this step exists because the doctrine claimed the card + covered truth composition while trigger and method were mask-only; Codex + P2 on #1222 caught it). For every truth operation in T2 code, ask: is this + ONE named T1 call? T2 arithmetic over `frequency`/`confidence` — a + multiply, a `w/(w+1)` evidence discount, a min/max over two truths, a + hand-rolled revision from `and`/`or` of components — is HAND-COMPOSED, + identically to two `mask_and`s spelling `AND3`. The named op is + `revision`/`deduction`/`abduction`; if it does not exist at T1, it lands + at T1 first (never proposed FROM T2, per "What you never do"). A T2 that + reads a `TruthU8`'s two bytes apart to recombine them is also + GEOMETRY-LEAK: the byte split is T0's. 3. For every byte offset in T2 code, ask: did T2 compute this, or read it from a `_lane`/`LgjLaneDesc` accessor? Computed = GEOMETRY-LEAK. 4. Enforce the import fence (abi.md §8, G11): T2 (`exports.rs`) imports SIMD diff --git a/.claude/board/EPIPHANIES.md b/.claude/board/EPIPHANIES.md index 2df8d855f..59611be4e 100644 --- a/.claude/board/EPIPHANIES.md +++ b/.claude/board/EPIPHANIES.md @@ -1,3 +1,66 @@ +## 2026-09-07 — E-T1-HAS-TWO-SIBLING-ALGEBRAS-THE-AXIS-IS-SYNTAX-VS-EXECUTION-1 — the membrane is a behavior membrane, not a selection pipeline + +**Status:** OPERATOR RULING, BINDING (2026-09-07). Ruled after a three-agent audit of the +T2/T3 barrier (`membrane-tiers.md`, the two warden cards, `lance-graph-java` @ `8720d1d`, +`r2sleigh` @ `99d2553`) reported NARS truth arithmetic as absent from the Java side — +not exported, not imported, not present — and drew the wrong conclusion from a correct +measurement. +**Confidence:** High. The measurement is exhaustive (repo-wide grep of lgj: 3 hits, all +prose, all in one unshipped plan); the ruling is the operator's, and it is a ruling, not +a finding. + +**The audit's conclusion, verbatim, and why it is wrong.** *"NARS is off the ladder +entirely; the ladder is selection-shaped and has no tier for scoring."* Descriptively +true at today's HEAD. Architecturally wrong twice over: + +1. **The axis is wrong.** The distinction that matters is not *selection vs scoring* — + it is **syntax vs execution**, which is the axis every other tier here is already + built on. `where()` is T2 because Java owns the NAME and T1 owns the op; nothing + about that reasoning is specific to populations. +2. **The remedy was wrong.** The audit proposed a new bulk verb family (`lgj_score_*`) + returning a lane instead of a mask. **Rejected.** It grows a second semantic API + beside `plan_eval`, and the end state is predictable — `where()`, `hop()`, + `score()`, `nars_revision()`, `nars_deduction()`, … with Java knowing progressively + more about the behavior graph. *The membrane starts growing little computational + fingers.* + +**The ruling.** The ladder does not need a sixth tier; **T1 was described too narrowly.** +It holds TWO SIBLING PRIMITIVE ALGEBRAS — *population* (`mask`, `ternlog`, `eq → mask`, +`popcount`) and *epistemic* (`TruthU8`, revision, deduction, abduction). Both are +primitive behavior. **T2 may name either; T2 may not hand-compose either; T3 may express +intent in either.** Every existing rule applies unchanged to the second column — +`kernel-membrane-warden`'s HAND-COMPOSED verdict covers a T2 spelling `revision` out of +smaller truth ops exactly as it covers the two-AND spelling of `AND3`. + +NARS lowers through the membrane that already exists: T3 names +`Truth.Revision(lhs_handle, rhs_handle)` and may not know how revision works; T2's +`plan_eval` resolves the name; T1 executes; T0 owns every resulting `TruthU8`. **Extend +the plan language, not the ABI surface** — `lgj_plan_eval` exists precisely so a whole +behavioral expression crosses once. + +**A wording correction the ruling forces.** `TruthU8` had been called "the canonical wire +form." Two different claims were being conflated: it is the canonical **substrate** +representation (T0). What crosses is decided separately and by SHAPE — a truth LITERAL +(`TruthLiteral(192, 217)`) is syntax the caller supplies and may cross; a truth +POPULATION (`[TruthU8; 65536]`) never crosses, it becomes `TruthLaneId(u64)`. Same rule +`bbb-warden` already applies to masks, second column. It lands on the measured Valhalla +cliff exactly: flattening stops at an **8-byte payload** (VM-confirmed, +`valhalla-lab/docs/three-truths.md`), so the handle flattens and the array could never. +**Valhalla carries the noun; Panama carries the verb; lance-graph owns the reality.** + +**Consequences, each with its site.** `D-BBB-NARS-1` + falsifier `F-BBB-NARS-1` +(STATUS_BOARD, and quoted in `membrane-tiers.md` § "T1 has TWO sibling algebras"); the +T1 row and the T2 row (renamed *selection* → *behavior*) rewritten in the doctrine table; +`bbb-warden` gains the syntax/execution test and the G11 scalpel-cut rule. **The G11 +fence must NOT be widened to `lance_graph_contract::nars` merely because that module +exists** — if it carries arithmetic beside POD types, split a syntax/vocabulary contract +out first and admit only that. One scalpel cut, never the cupboard. + +**What does NOT change: the BBB does not move.** T3 intent/names above; T2 opaque bulk +behavior handles below; T1 algebra (population ‖ epistemic); T0 state. No VSA internals, +no RoleKey, no NARS arithmetic, no byte positions, no truth arrays, no Java compute path. +Only names and capabilities. The widening makes the doctrine MORE general, not more +permissive. ## 2026-09-07 — E-A-DYNAMIC-DOMAIN-MASK-IS-A-SECOND-WITNESS-AND-ITS-ALIGNMENT-IS-CALIBRATION-1 — the "horseshoe" was a category error; the equality I called a coincidence is a known-answer target **Status:** OPERATOR RULING (2026-09-07, two messages: *"horseshoe mask is a diff --git a/.claude/board/STATUS_BOARD.md b/.claude/board/STATUS_BOARD.md index 03bdd150b..4a5ee02ea 100644 --- a/.claude/board/STATUS_BOARD.md +++ b/.claude/board/STATUS_BOARD.md @@ -1,3 +1,16 @@ +## bbb-nars-lowering (D-id minted 2026-09-07 with the operator ruling) + +`.claude/knowledge/membrane-tiers.md` § "T1 has TWO sibling algebras"; board +`E-T1-HAS-TWO-SIBLING-ALGEBRAS-THE-AXIS-IS-SYNTAX-VS-EXECUTION-1`. The axis is +syntax vs execution, not selection vs scoring; T1 holds two sibling algebras and +NARS lowers through the `plan_eval` membrane that already exists. + +| D-id | scope | status | gate / falsifier | +|---|---|---|---| +| D-BBB-NARS-1 | NARS truth arithmetic remains substrate-owned. G11/T3 may carry only typed NARS **syntax** and **opaque substrate handles**. NARS execution lowers through the existing bulk plan-evaluation membrane; no Java-side arithmetic and no materialized truth population crosses Panama. `TruthU8` is the canonical SUBSTRATE representation; cross-membrane results are handles (`TruthLaneId(u64)`). Any required G11 expansion SHALL expose syntax/vocabulary only, never an arithmetic implementation surface — one scalpel cut, never the cupboard | **Ruled 2026-09-07** (operator). Doctrine landed; no code. `lgj_score_*` explicitly REJECTED — extend the plan language, not the ABI surface | **F-BBB-NARS-1:** fail if Java can implement, inspect, iterate, or reconstruct NARS truth arithmetic without invoking the substrate, OR if a truth population crosses G11/Panama other than as an opaque handle | +| D-BBB-NARS-2 | The syntax/vocabulary contract the G11 fence would admit: split the POD/vocabulary half of `lance_graph_contract::nars` from its arithmetic half, so the fence can widen by one module without admitting an implementation surface | Queued — gates on a consumer actually needing it; **do not pre-build** | the admitted module contains no arithmetic (a function that computes a truth from truths); `ALLOWED` grows in all three spellings in ONE commit | +| D-BBB-NARS-3 | `Truth(…)` as a named `plan_eval` operation (Revision / Deduction / Abduction / …), returning `TruthLaneId`, never an array | Queued — gates on D-BBB-NARS-2 | one crossing per behavioral expression regardless of operand count (the §6 bulk-or-lifecycle law); a `[TruthU8]` return is an automatic fail | + ## spog-alpha-channel-v1 (D-ids minted 2026-09-07 with the spec) `.claude/plans/spog-alpha-channel-v1.md`. The SPOG alpha channel in MedCare-rs: domain = a mask over the combined `all-lanes.soa` image (never a per-domain file), cycle = one sealed `FixedSizeBinary(512)` append per Lance version (no row ids, no delete), rung byte = the attention rung only (`domain_rung` retired as a writer), the rung × tenant cross via `mask_ternlog` one crate out of the zero-dep contract. Operator mandate 2026-09-07 ("probe autoattended … until you get MedCare-rs SPOG alpha channel to work"). Order: 0 → 1 → 2 → 4 → 3 → 5 → 6 → 7/8. @@ -14,6 +27,7 @@ | D-SPG-7 | ogar-r2il consumer (`RANK` + `TERNLOG 0x86`) via `lance-graph-ogar` | Queued — gates on D-SPG-4 | lifted program survivor mask == hand chain bit-for-bit | | D-SPG-8 | DataFusion containment (`with_row_id`/`with_row_addr` OFF + red-if-flipped test) | ~~Queued~~ **Shipped 2026-09-07** — MedCare-rs #621 merged (`9f9b7be`). Production registers `LanceTableProvider::new(ds, /* with_row_id */ false, /* with_row_addr */ false)` (`medcare-server/src/state.rs:945`), and the red-if-flipped test OBSERVES that call site instead of building its own provider: `row_identity_columns_are_absent_from_the_registered_provider` (`:1264`) reads the schema of the table `AppState::build_session_context` actually registered, and asserts a hand-built identity-on provider over the SAME dataset carries exactly two more columns — two-sided, so the silent half is a measurement and not a statement about an empty schema. Its own doc records that an earlier draft hardcoded the flags in the test and stayed GREEN when production was flipped; the disable run is what caught it. The pre-existing grep fence `row_identity_containment::no_lance_row_identity_consumer_exists` (`:1609`) stays sharp because the test deliberately never spells either column name in code. **Gate met:** the scan schema carries neither identity column, and a flip is detectable. | scan schema carries neither `_rowid` nor `_rowaddr` | + ## lance-convergence-staged-migration-v1 (D-ids minted 2026-09-05 with the plan) `.claude/plans/lance-convergence-staged-migration-v1.md`. The staged lance diff --git a/.claude/knowledge/membrane-tiers.md b/.claude/knowledge/membrane-tiers.md index b4e1be668..c36f1c395 100644 --- a/.claude/knowledge/membrane-tiers.md +++ b/.claude/knowledge/membrane-tiers.md @@ -19,8 +19,8 @@ substrate beneath them is T0. | Tier | What it is | May know | Crosses UP as | The membrane (gate) | |---|---|---|---|---| | **T0 substrate** | bytes, lanes, Lance columns, SoA v3 rows; `simd_{avx512,avx2,neon,scalar}.rs` | strides, offsets, carvings, intrinsics, alignment | — | none; T0 is where truth lives | -| **T1 primitive** | `ndarray::simd` facade; `lgj-abi/kernels.rs`; `mask_*`, `eq_*_to_mask`, `ternlog` | `&[u64]`, `&[u8]`+`(offset,stride)`, `IMM` | a mask, a count, a lane descriptor | **polyfill rule** (simd-savant): no intrinsic, no `#[cfg(target_arch)]` above this line | -| **T2 selection** | ABI exports; `where`/`hop`/`plan_eval`; `Mask × WideFieldMask → Mask` | handles, `classid`, `FieldMask` (fields by NAME), version | a handle, a count, a status | **no hand-composed T1 op, no computed geometry** (kernel-membrane-warden) | +| **T1 primitive** | TWO SIBLING ALGEBRAS (2026-09-07, below): **population** — `ndarray::simd` facade, `lgj-abi/kernels.rs`, `mask_*`, `eq_*_to_mask`, `ternlog`, `popcount`; **epistemic** — `TruthU8`, revision, deduction, abduction, … | `&[u64]`, `&[u8]`+`(offset,stride)`, `IMM`, `TruthU8` | a mask, a count, a lane descriptor, **a truth lane DESCRIPTOR (`TruthLaneId`) — never the population** | **polyfill rule** (simd-savant): no intrinsic, no `#[cfg(target_arch)]` above this line | +| **T2 behavior** (was "selection") | ABI exports; `where`/`hop`/`plan_eval`; `Mask × WideFieldMask → Mask`; **and the epistemic siblings, named through the same `plan_eval`** | handles, `classid`, `FieldMask` (fields by NAME), version | a handle, a count, a status | **no hand-composed T1 op, no computed geometry** (kernel-membrane-warden) | | **T3 intent** | Java facade; R2IL / OGAR `ActionDef`; low-code | names: class, edge, field, version | an outcome | **no byte position** (bbb-warden + ApiSurfaceTest) | | **R2IL** | emits T3 artifacts | T3's vocabulary (names, outcomes) | an outcome | its ceiling IS T3's; door-knocker test (layer-boundary-warden) | @@ -36,6 +36,149 @@ hand-writes a compare-and-pack loop has punched T1 — the violation `simd-savant` exists to catch. lgj-abi stacks the same shape at T1/T2: `exports.rs` names `kernels::ternlog::AND3`, never `ndarray::simd` directly. +## T1 has TWO sibling algebras — the doctrine is a behavior membrane, not a selection pipeline + +**Operator ruling, 2026-09-07.** An audit found NARS truth arithmetic nowhere on +the Java side of the membrane — not exported, not imported, not present — and +concluded from that: *"NARS is off the ladder entirely; the ladder has no tier +for scoring."* **The conclusion was wrong and the diagnosis was the wrong axis.** +The distinction that matters is not *selection vs scoring*. It is **syntax vs +execution** — which is the distinction every other tier here is already built on. + +The ladder does not need a sixth tier. **T1 was described too narrowly.** It +contains two sibling primitive algebras: + +``` +T1 +├── population algebra └── epistemic algebra +│ mask TruthU8 +│ ternlog revision +│ eq → mask deduction +│ popcount abduction +``` + +Both are primitive behavior. **T2 may name either. T2 may not hand-compose +either. T3 may express intent in either.** Every rule already written applies +unchanged to the second column — `kernel-membrane-warden`'s HAND-COMPOSED +verdict covers a T2 that spells `revision` out of smaller truth ops exactly as +it covers a T2 that spells `AND3` as two `mask_and`s. + +**That claim was FALSE when first written, and is true only because the same +commit made it true.** `kernel-membrane-warden`'s trigger and its method named +masks only; a T2 hand-composing `revision` would have walked straight through +the gate this paragraph invoked. Codex caught it on #1222 (P2), and the card +now carries the epistemic algebra in its trigger and **method step 2b**. Two +sibling gaps of the same shape were closed with it: the T1 row above said a +truth LANE crosses up while the shape table below says a population never does +(now: the DESCRIPTOR, never the population), and `bbb-warden`'s method +classified only signature shapes, so a public helper with a legal +`TruthLiteral` signature computing revision in its BODY passed every step while +doing exactly what `F-BBB-NARS-1` forbids (now: method step 4, an explicit +body-and-import audit). **A doctrine sentence that names a gate must cite the +step that makes it true** — the same defect as the G11 fence being prose until +2026-09-03, found three times in one commit and fixed in the same one. + +### The lowering, end to end + +``` +T3 Java / R2IL / low-code + │ NARS operation NAME + opaque handles + ▼ +T2 plan_eval — the behavior membrane + │ resolved bulk operation + ▼ +T1 epistemic primitives (beside the population primitives) + │ substrate-native execution + ▼ +T0 TruthU8 lanes / rows / history / state +``` + +T3 may say `Truth.Revision(lhs_handle, rhs_handle)`. **It may not know how +revision works.** T2 resolves the name; T1 executes the arithmetic; T0 owns +every resulting `TruthU8`. + +### Extend the plan language, NOT the ABI surface + +The tempting fork — mint `lgj_score_*` beside `lgj_hop` — is rejected. It grows +a second semantic API next to `plan_eval`, and the end state is predictable: +`where()`, `hop()`, `score()`, `nars_revision()`, `nars_deduction()`, … with +Java knowing progressively more about the behavior graph. **The membrane starts +growing little computational fingers.** + +`lgj_plan_eval` exists precisely so a whole behavioral expression crosses ONCE. +NARS becomes another named plan operation, not another export: + +``` +Plan + ├── Select(…) + ├── Hop(…) + ├── Ternlog(…) + └── Truth(…) + ├── Revision + ├── Deduction + ├── Abduction + └── … +``` + +### `TruthU8` is the canonical SUBSTRATE representation — not automatically the wire form + +These are two different claims and the workspace had been conflating them. +`TruthU8 { frequency: u8, confidence: u8 }` +(`lance-graph-arm-discovery/src/translator.rs:25-33`) is canonical **at T0**. +What crosses is decided separately, and by shape: + +| shape | crosses? | as | +|---|---|---| +| a truth LITERAL, `TruthLiteral(192, 217)` | **yes** — it is meaning supplied by the caller, syntax, T3's to state | itself | +| a truth POPULATION, `[TruthU8; 65536]` | **never** | `TruthLaneId(u64)` — an opaque 8-byte descriptor | + +This is the same rule `bbb-warden` already enforces for masks (*"a `long[]` of +selected ids is still a materialised population"*), applied to the epistemic +column — and it lands exactly on the measured Valhalla cliff: **flattening stops +at an 8-byte payload** (VM-confirmed, `valhalla-lab/docs/three-truths.md`), so a +`TruthLaneId(u64)` flattens and a truth array could never. The JVM agrees with +the membrane about where the wall is. **Valhalla carries the noun; Panama +carries the verb; lance-graph owns the reality.** + +### The G11 widening rule: one scalpel cut, never the cupboard + +Do **not** import `lance_graph_contract::nars` through the G11 fence merely +because it exists. If that module carries arithmetic semantics together with POD +types, **split out a tiny syntax/vocabulary contract first** and admit only that. +The fence widens by one deliberate module, in one commit, in all three places +its allowlist is spelled (`tests/g11_contract_import_fence.rs`'s `ALLOWED`, +lgj `CLAUDE.md § Enforcement`, `Cargo.toml`'s comment) — the shape lgj already +requires, and the reason its own history records the fence being prose until +2026-09-03 (`ISS-LGJ-G11-FENCE-WAS-PROSE`). + +### The ruling and its falsifier + +> **D-BBB-NARS-1.** NARS truth arithmetic remains substrate-owned. G11/T3 may +> carry only typed NARS **syntax** and **opaque substrate handles**. NARS +> execution is lowered through the existing bulk plan-evaluation membrane; no +> Java-side arithmetic and no materialized truth population crosses Panama. +> `TruthU8` is the canonical substrate representation, while cross-membrane +> results are handles. Any required G11 expansion SHALL expose +> syntax/vocabulary only, never an arithmetic implementation surface. + +> **F-BBB-NARS-1.** Fail if Java can implement, inspect, iterate, or reconstruct +> NARS truth arithmetic without invoking the substrate, or if a truth population +> crosses G11/Panama other than as an opaque handle. + +The BBB does not move. It stays exactly where it is: + +``` + BBB +T3 intent / names ───────────── +T2 opaque bulk behavior handles + ↓ +T1 algebra (population ‖ epistemic) +T0 state +``` + +No VSA internals. No RoleKey. No NARS arithmetic. No byte positions. No truth +arrays. No Java compute path. **Only names and capabilities.** + ## The compile-through rule (the Entropy half) **Old code is not deleted; it is re-admitted only by compiling THROUGH the