From 5b37f8fd77479d218308ca549767e26ac952d515 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 28 Oct 2026 01:01:28 +0000 Subject: [PATCH 01/11] =?UTF-8?q?docs(D-DT64-6):=20DR64=20routing,=20DT64?= =?UTF-8?q?=20bind=20store,=20per-cell=20WHEN=C3=97ON=C3=97DO,=20OGIT=20re?= =?UTF-8?q?ference=20predicates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Records seven user decisions from 2026-10-28 in DECISION / SCOPE / BASIS / REVISIT WHEN form: - the three DT64 levels; - DR#3 Identity × Properties as the primary view; - WHEN×ON×DO per DR#3 cell; - DR64 = direct routing and DT64 = DTO bind store; - immutable classid → behaviour via hotplug; - global behaviour needs no classid; - OGIT read unpinned. Maps each decision onto existing code and plans with evidence states, and stages D-DT64-6-0..5: - OGIT reader reconciliation; - ogit:allowed expansion in lance-graph-ontology; - DT64 predicate registration; - consumer HotPlug access. Requests, but does not apply, an amendment to D-DT64-Q0 line 9. Docs only. No code, ABI, test, runtime or merge authorization. Board: entry, INTEGRATION_PLANS and STATUS_BOARD prepends, and the regenerated entries index. The supersession index regenerates unchanged. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01XAqKMNiyjwqFke9CfmoBgn --- .claude/board/INTEGRATION_PLANS.md | 5 + .claude/board/STATUS_BOARD.md | 13 ++ ...-28-d-dt64-6-routing-bindstore-behavior.md | 46 +++++ .claude/board/entries/README.md | 3 +- .../d-dt64-6-routing-bindstore-behavior-v1.md | 167 ++++++++++++++++++ 5 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 .claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md create mode 100644 .claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md diff --git a/.claude/board/INTEGRATION_PLANS.md b/.claude/board/INTEGRATION_PLANS.md index f25d2512a..ea55a3c74 100644 --- a/.claude/board/INTEGRATION_PLANS.md +++ b/.claude/board/INTEGRATION_PLANS.md @@ -1,3 +1,8 @@ +## 2026-10-28 — D-DT64-6: DR64 routing, DT64 bind store, per-cell WHEN×ON×DO behaviour, OGIT reference predicates → `.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md` + +**Status:** PROPOSED, docs only; nothing authorized. **Board:** [entry](entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md), [STATUS_BOARD](STATUS_BOARD.md) D-DT64-6. Records seven user decisions (three DT64 levels; primary DR#3 Identity × Properties; WHEN×ON×DO per DR#3 cell; DR64 = direct routing, DT64 = DTO bind store; immutable classid → behaviour via hotplug; global needs no classid; OGIT read unpinned) and stages D-DT64-6-0..5 (OGIT reader reconciliation, `ogit:allowed` expansion in lance-graph-ontology, DT64 predicate registration, consumer HotPlug access). Requests an amendment to D-DT64-Q0 line 9 (persistent binding store); not applied. +**Confidence:** plan row only; stages unstarted. + ## 2026-10-26 — D-TFLP v2: synergy revision → `.claude/plans/d-tflp-tflite-palette-polyfill-capstone-v2.md` **Status:** PROPOSAL, docs only; revises v1 (#1785). **Board:** [entry](entries/2026-10-26-d-tflp-v2-synergy-revision.md), [STATUS_BOARD](STATUS_BOARD.md) D-TFLP. Folds GPT's six #1785 corrections; rescopes D-TFLP-4 to the source reciprocal from #1800; splits prepared-object identity into numeric cache key + semantic receipt from #1800/#1801; adds D-TFLP-5a (intake bake-off, #1802 pattern); records boundaries with DT64-5 and DR256/DQM. diff --git a/.claude/board/STATUS_BOARD.md b/.claude/board/STATUS_BOARD.md index 86c238f33..7d59bb0e3 100644 --- a/.claude/board/STATUS_BOARD.md +++ b/.claude/board/STATUS_BOARD.md @@ -1,3 +1,16 @@ +## D-DT64-6 — DR64 routing, DT64 bind store, per-cell WHEN×ON×DO, OGIT reference predicates (2026-10-28) + +**Status:** PROPOSED / DOCS ONLY. [Plan](../plans/d-dt64-6-routing-bindstore-behavior-v1.md); [board entry](entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md). No code, ABI, test or runtime. + +| D-id | Deliverable | Status | Gate | +|---|---|---|---| +| D-DT64-6-0 | plan + board (docs) | In PR | docs review | +| D-DT64-6-1 | OGIT reader reconciliation: `ttl_parse` vs OGAR `OgitTables`, same checkout, one run, identical partition | Queued | owner approval; read-only | +| D-DT64-6-2 | expand `ogit:allowed` in lance-graph-ontology into a classid-free (src, verb, dst) table | Queued | D-DT64-6-1 green | +| D-DT64-6-3 | register OGIT verbs as DT64 predicates in 64-wide blocks | Queued | D-DT64-6-2 green | +| D-DT64-6-4 | consumer read-only access via HotPlug activation | Queued | D-DT64-6-3 green | +| D-DT64-6-5 | OGIT becomes cross-check oracle once a domain has attested predicates | Queued | one attested domain | + ## D-DT64 — DTO Tensor 64: versioned semantic predicate adapter and DR projections (2026-10-26) **Status:** PLAN / DOCS ONLY, six documentation PRs **MERGED** ([#1794](https://github.com/AdaWorldAPI/lance-graph/pull/1794)–[#1799](https://github.com/AdaWorldAPI/lance-graph/pull/1799)), no production source ingestion, no new 64-slot ABI, no runtime adapter or DT64-Q0 executable proof run. [Charter](../plans/d-dt64-holographic-predicate-capstone-v1.md); [board entry](entries/2026-10-26-dt64-holographic-interface.md). [EXO-50](https://linear.app/exo-red/issue/EXO-50) is the append-only handoff, not a production approval. diff --git a/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md b/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md new file mode 100644 index 000000000..9d7c16e85 --- /dev/null +++ b/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md @@ -0,0 +1,46 @@ +# D-DT64-6: DR64 routing, DT64 bind store, per-cell WHEN×ON×DO behaviour, OGIT reference predicates + +**Status:** PROPOSED / DOCS ONLY. Plan: [d-dt64-6-routing-bindstore-behavior-v1.md](../../plans/d-dt64-6-routing-bindstore-behavior-v1.md). +No code, ABI, test, runtime or merge authorization. Read at lance-graph `main` +`72697cc31`, odoo-rs `main` `558f12a`, OGAR `main` `6b43a48`; lance-graph #1814 +(`bbd8980`) and #1819 (`60eca64`) are OPEN docs PRs. + +## What this records + +Seven user decisions from session 2026-10-28, in DECISION / SCOPE / BASIS / +REVISIT WHEN form (plan §1): + +1. DT64 has three levels, all 64×64×64, reached by focused global→local: + DR64³ Identity(+value) × Property(+value); Identity × Property × Predicate; + Predicate³ = WHEN × ON × DO. +2. The primary view is DR#3 Identity × Properties. Identity × Identity and + Properties × Properties are optional derived views. +3. WHEN × ON × DO attaches per DR#3 cell as the registry over methods. +4. DR64 = direct routing (mapping table); DT64 = DTO bind store for all + holographic addresses; behaviour registered as classid → polyfill. +5. classid → behaviour is permanently immutable; versioned under a fixed + concept via a derived DTO classid; registration via `hotplug.rs`. +6. Global behaviour needs no classid and lives in lance-graph; consumers need + a classid through the hotplug pattern. +7. OGIT is immutable and read unpinned. + +## Findings that shaped the plan (VERIFIED-IN-CODE unless marked) + +- The merged DT64 plans use none of the ON / WHEN / DO terms (grep, zero + hits). The ON×WHEN×DO registry exists only as the odoo-rs lab design + `docs/DT64-ON-WHEN-DO-REGISTRY.md` (#44 / #45 merged, test-only) and in the + OPEN docs PRs #1814 and #1819. +- `lance-graph-ontology::ttl_parse` leaves `ogit:allowed` unexpanded + (`ttl_parse.rs:18-21`). The typed verb signature table exists only in OGAR + `OgitTables::Allowed`, and OGAR depends on lance-graph-ontology. +- "Direct routing" already names position → executable maps in + `crates/dir-rmap-probe/tests/classview_dr.rs:66`. +- `D-DT64-Q0` line 9 forbids "the persistent Binding Store"; decision 4 + needs an amendment there. Requested in plan §4, not applied. + +## Open + +Plan §6: the immutable unit; inheritance before cell lookup; collision vs +convergence for coexisting methods; WHEN has no attested source; the Q0 +amendment; the capstone's "targets" axis vs Identity × Property; 64-wide +blocks vs the #1819 256² plane; EXO-46, EXO-148 and NFR-OP-2. diff --git a/.claude/board/entries/README.md b/.claude/board/entries/README.md index 486739bb2..db67fd4fb 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. -488 entries, 2026-08-06 .. 2026-10-27. +489 entries, 2026-08-06 .. 2026-10-28. | date | entry id | finding | file | |---|---|---|---| +| 2026-10-28 | `D-DT64-6` | | [2026-10-28-d-dt64-6-routing-bindstore-behavior.md](2026-10-28-d-dt64-6-routing-bindstore-behavior.md) | | 2026-10-27 | `harvest-integration-composite-key-and-simd-scope` | | [2026-10-27-harvest-integration-composite-key-and-simd-scope.md](2026-10-27-harvest-integration-composite-key-and-simd-scope.md) | | 2026-10-26 | `D-ONNX-INTAKE-0` | | [2026-10-26-onnx-frontend-intake-bakeoff.md](2026-10-26-onnx-frontend-intake-bakeoff.md) | | 2026-10-26 | `D-DT64-0` | | [2026-10-26-dt64-holographic-interface.md](2026-10-26-dt64-holographic-interface.md) | diff --git a/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md b/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md new file mode 100644 index 000000000..7d2687e6a --- /dev/null +++ b/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md @@ -0,0 +1,167 @@ +# D-DT64-6: DR64 routing, DT64 bind store, per-cell WHEN×ON×DO behaviour and OGIT reference predicates + +**Date:** 2026-10-28. **Status:** PROPOSED / DOCS ONLY. **Parent:** [D-DT64-0](d-dt64-holographic-predicate-capstone-v1.md), [D-DT64-Q0](d-dt64-q0-borrowed-quack-binding-seam-v1.md). **Not:** code, ABI, test, runtime, or implementation authorization. + +This plan adds no code, no ABI, no test, no runtime and no merge authorization. It records decisions the user stated in session on 2026-10-28, maps them onto what exists, and stages the follow-up work. #1812 is quarantined; nothing here derives from it. + +Evidence states used below: VERIFIED-IN-CODE (file:line re-read), CURRENT-CONTRACT (merged plan text), WORKING-MODEL, PROPOSED, OPEN. A user decision is a decision, never technical truth. + +## 1. Decisions recorded + +**DECISION (2026-10-28):** DT64 has three levels, all 64×64×64, reached by focused global→local. (1) DR64³ is Identity(+value) × Property(+value); combinations are additional planes; no value is duplicated. (2) Identity × Property × Predicate. (3) Predicate³ = WHEN × ON × DO. +**SCOPE:** the logical shape of the three levels and how a reader reaches them. No physical layout is chosen. +**BASIS:** the user's statement in session, 2026-10-28 (decision, not measurement) +**REVISIT WHEN:** NFR-OP-2 (the physical DR³ third axis) is adjudicated, or a level is shown not to fit 64×64×64. + +**DECISION (2026-10-28):** The primary relational view is DR#3, Identity × Properties. Identity × Identity (causes / caused-by, a direction-flip bit, a typed inverse only when declared) and Properties × Properties (co-occurrence, covariance, derived on demand) are OPTIONAL derived views. Global selection is `DR256::WHERE` over 65,536 addresses with an 8 KiB mask. Not goals: no 65K×65K dense matrix, no eager 64-property cube, no new writer or persistence path. Persistence stays separate: resident → squash/release → coalesced dirty rows → async writer (EXO-55). +**SCOPE:** which views are primary versus derived, and what is excluded. +**BASIS:** the user's statement in session, 2026-10-28 (decision, not measurement) +**REVISIT WHEN:** a derived view is needed on a hot path, or EXO-55 changes the writer path. + +**DECISION (2026-10-28):** WHEN × ON × DO attaches per DR#3 cell, as the registry over methods. +**SCOPE:** where the method registry attaches. Not how it is stored (see §3). +**BASIS:** the user's statement in session, 2026-10-28 (decision, not measurement) +**REVISIT WHEN:** an attested WHEN source exists and shows the per-cell attachment is wrong. + +**DECISION (2026-10-28):** DR64 is direct routing: a mapping table from a position to the target bound there. DT64 is the DTO bind store for all holographic addresses, including the derived views. Behaviour is registered as a DTO: classid → polyfill over mask-risc / ndarray. DT64 gives versioned, replayable immutability for addressing behaviour. +**SCOPE:** the roles of DR64 and DT64, and how behaviour is registered. +**BASIS:** the user's statement in session, 2026-10-28 (decision, not measurement) +**REVISIT WHEN:** the Q0 amendment in §4 is refused, or a bind store proves to need copied business data. + +**DECISION (2026-10-28):** A classid's behaviour is permanently immutable. It is versioned under a fixed concept through a derived DTO classid. Registration goes through the lance-graph-contract `hotplug.rs` pattern. +**SCOPE:** the unit of immutability and the registration route. +**BASIS:** the user's statement in session, 2026-10-28 (decision, not measurement) +**REVISIT WHEN:** the open question on the immutable unit (§6, first item) is settled. + +**DECISION (2026-10-28):** Global behaviour needs no classid and lives in lance-graph. Consumers need a classid, enabled by the plug-and-play (hotplug) pattern. +**SCOPE:** who needs a classid. +**BASIS:** the user's statement in session, 2026-10-28 (decision, not measurement) +**REVISIT WHEN:** a global behaviour needs consumer-visible identity. + +**DECISION (2026-10-28):** OGIT is immutable and is read unpinned. The AdaWorldAPI OGIT fork's `master` moves when upstream PRs are merged, and readers follow it. No pins. +**SCOPE:** how OGIT is read by every reader named in §5. +**BASIS:** the user's statement in session, 2026-10-28 (decision, not measurement) +**REVISIT WHEN:** an OGIT change breaks a reader and a provenance receipt is not enough. + +## 2. Grounding table + +What exists today. "odoo-rs" (main @558f12a), "OGAR" (main @6b43a48) and "lance-graph#NNNN" (PR heads: #1814 @bbd8980, #1819 @60eca64) label other checkouts; those lines were read in a session crosswalk on 2026-10-28 and are not re-read in this file. + +| Item | Evidence state | Citation | +|---|---|---| +| `AxisKind` has `Identity`, `Property`, `Community`, `Capability` | VERIFIED-IN-CODE | `crates/dr-math-binding-probe/src/lib.rs:19-24` | +| The 64×64 bitplane is 512 B and "carries neither global ids, bag multiplicity nor provenance" | VERIFIED-IN-CODE | `crates/dr-math-binding-probe/src/lib.rs:8-10` | +| `Focus { revision }`: which 64×64 window is read; a new focus over the same frame is not a new frame | VERIFIED-IN-CODE | `crates/dr-math-binding-probe/src/lib.rs:165-170` | +| `FrameRevisions { source, relation_map, coordinates }`; `FrameStore::seal` compares frames by identity of issue (in-memory lab stand-in) | VERIFIED-IN-CODE | `crates/dr-math-binding-probe/src/lib.rs:73-109` | +| `Operand` carries validity bits with the relation bits | VERIFIED-IN-CODE | `crates/dr-math-binding-probe/src/lib.rs:187-195` | +| D-DRMC compares a guarded `Identity×Property` DR64 against `Identity²` | CURRENT-CONTRACT | `.claude/plans/dr-mathematical-compiler-v1.md:67,86` | +| "Direct routing: field position → the executable bound to it" | VERIFIED-IN-CODE (lab test) | `crates/dir-rmap-probe/tests/classview_dr.rs:66` | +| "Direct routing: method position -> fold" and "position -> executable" | VERIFIED-IN-CODE (lab tests) | `crates/dir-rmap-probe/tests/qr_focus.rs:145`, `qr_register.rs:53` (grep hit lines; not read further) | +| `hotplug.rs`: "the plug-and-play pattern EVERY consumer migrates to" | VERIFIED-IN-CODE | `crates/lance-graph-contract/src/hotplug.rs:1-2` | +| OGAR is the authority; it verifies "expected consumer, coverage both directions, ids minted exactly once" | VERIFIED-IN-CODE | `hotplug.rs:11-14` | +| The consumer "declares one `HotPlug` const naming its classids + covered capabilities, calls `activate` in its own binary/tests" | VERIFIED-IN-CODE | `hotplug.rs:15-17` | +| `HotPlug { consumer, classids: &'static [u16], covered }` | VERIFIED-IN-CODE | `hotplug.rs:54-62` | +| "A consumer composes its own full `u32` (`concept << 16 \| its app prefix`)" | VERIFIED-IN-CODE | `hotplug.rs:96-97` | +| `CapabilityAuthority::activate(&HotPlug) -> Result` | VERIFIED-IN-CODE | `hotplug.rs:722-726` | +| The `HotPlug` declaration is a compile-time const; verification is the `activate` call, run once in the consumer | WORKING-MODEL | reading of `hotplug.rs:15-17` | +| `ttl_parse` builds `LinkSpec` with placeholder subject/object types; `ogit:from-to` / `ogit:allowed` "are not yet expanded" | VERIFIED-IN-CODE | `crates/lance-graph-ontology/src/ttl_parse.rs:18-21` | +| The merged DT64 plans do not use the ON / WHEN / DO terms; the third axis is predicates | CURRENT-CONTRACT | `grep -nE "WHEN\|ON×\|ON/\|trigger\|Applicability"` over `d-dt64-holographic-predicate-capstone-v1.md`, `d-dt64-1-predicate-catalogue-source-crosswalk-v1.md`, `d-dt64-q0-borrowed-quack-binding-seam-v1.md`: zero hits | +| Capstone: "Odoo method fold" is listed as missing | CURRENT-CONTRACT | `.claude/plans/d-dt64-holographic-predicate-capstone-v1.md:102` | +| Capstone: 64×64×64 = 262,144 cells = 32 KiB dense; never eagerly allocate a cube for an 8- or 23-field question | CURRENT-CONTRACT | `.claude/plans/d-dt64-holographic-predicate-capstone-v1.md:27` | +| odoo-rs registry: lab design, "Nothing here is production code"; §1 axes of at most 64 positions per frame; §3 dispatch fold; §5 collisions; §8 OGIT counts; §10 measured results; §11 open points | CURRENT-CONTRACT (other repo, lab design doc) | `odoo-rs:docs/DT64-ON-WHEN-DO-REGISTRY.md:3,13-24,55-56,98-99,139-169,200-210,246-258` | +| lance-graph#1814 cfa-1 (OPEN, docs only): "S1 is a proposed method-analysis view, not equivalent to the existing DT64-0 logical 64-predicate catalogue" | OPEN (PR not merged) | `lance-graph#1814:docs/research/counterfactual-behavior/cfa-1-typed-incidence.md:3,8` | +| lance-graph#1819 (OPEN, docs only): ON×DO 256² presence bitmap plus borrowed Quack WHERE populations; "NOT IMPLEMENTED, MEASURED, ADMITTED OR MERGE-AUTHORIZED" | OPEN (PR not merged) | `lance-graph#1819:docs/research/on-do-watched-where-factored-dispatch-plan-20261027.md:3,9,119` | +| OGAR `KausalSpec` variants `StateGuard`, `LifecycleTrigger`, `Depends`, `Constrains`, `Onchange`, `ContextDepends`, `External` | VERIFIED-IN-CODE (other repo) | `OGAR:crates/ogar-vocab/src/lib.rs:610-652` | +| OGAR mints `action_handler` 0x0C07, `action_applicability` 0x0C08, `automation_trigger` 0x0C09; `action_capability` is RESERVED | VERIFIED-IN-CODE (other repo) | `OGAR:crates/ogar-vocab/src/lib.rs:1415-1440` | +| OGAR DO-arm lift: schema half coded; behavioural half is CONJECTURE | CURRENT-CONTRACT (other repo) | `OGAR:docs/HIRO-DO-ARM-LIFT.md:86-90,161` | +| OGAR `OgitTables` has five tables incl. `Allowed` with `src`, `verb`, `dst` as `u32` lanes; refuses a table past 65,536 rows | VERIFIED-IN-CODE (other repo) | `OGAR:crates/ogar-action-handler/src/ogit.rs:1-14,17` | +| OGAR depends on `lance-graph-ontology` (optional, feature `ontology-cache`), so the reverse edge would be a cycle | VERIFIED-IN-CODE (other repo) | `OGAR:crates/ogar-action-handler/Cargo.toml:27` | +| OGIT counts: 523 verb files, 378 used verbs, 2,894 allowed edges over 941 entities; per-class p95 10, max 123, 2 classes above 64 | CURRENT-CONTRACT (doc report, not recomputed) | `odoo-rs:docs/DT64-ON-WHEN-DO-REGISTRY.md:139-169` | +| Odoo slice 1: ON 194 × WHEN 5 × DO 219; 628 live registrations; 8 multi-method cells | CURRENT-CONTRACT (doc report of a first run; the test file pins no literals) | `odoo-rs:docs/DT64-ON-WHEN-DO-REGISTRY.md:200-210` | + +## 3. Design consequences + +Everything in this section is WORKING-MODEL or PROPOSED. None of it is decided beyond §1. + +**Address per cell, store per (class / ClassView, property).** A 64³ frame is 32 KiB (odoo-rs §1). One frame per cell of a 64×64 DR#3 tile would cost 4,096 × 32 KiB = 128 MiB. That is the eager cube the "not goals" box excludes. The registry is therefore stored once per `(class, property)` and shared by every identity in that class. odoo-rs keys it by `(class, cell)`. A DR#3 cell reaches it through its property column and its identity's class. No per-identity copy exists. (PROPOSED) + +**ON and DO live on the property axis.** odoo-rs §3: ON includes "field f changed" and DO includes "writes field f"; chaining works because DO and ON share a domain (`odoo-rs:docs/DT64-ON-WHEN-DO-REGISTRY.md:61-65`). Under D3 those field positions are DR#2 property ordinals, not a second vocabulary. Non-field events (record created) and non-field capabilities (raise, call) still need their own positions. (PROPOSED) + +**WHEN is a Quack WHERE into a guard mask G.** A guard is a condition on Identity × Property values. Over the selected population it is a Quack WHERE that yields `G`. Identity-specific behaviour comes only from `G`, never from per-identity registry rows. WHEN has no attested source data yet (odoo-rs §11), so this is a shape, not a measurement. (PROPOSED) + +**Dispatch order for a population.** + +1. `DR256::WHERE` selects the population (8 KiB mask). +2. Quack evaluates each needed guard into `G`. +3. DR64 routes each address to its classid. +4. The registry fold `OR over w in G of C[e][w]` (odoo-rs §3) gives the DO mask per event. +5. DO bits that are property writes land on DR#3 cells as resident changes, then follow the persistence path (EXO-55). + +(PROPOSED) + +**Only routing is versioned.** DR64 maps a position to a classid and changes between versions. The classid → behaviour binding in DT64 does not change. Replay "as of version v" means which classid each address routed to at v; that classid's behaviour is the same as it is today. (PROPOSED reading of D5) + +**Override = a new derived classid plus a re-route.** odoo-rs models an override as `Retract` plus `Register` at one cell. Under D5 an override registers a new classid and re-routes the cell to it. The old binding stays readable forever. A `Retract` may remove a route; it must never alter a classid's behaviour. (PROPOSED) + +**Consumer composed classid as the derived DTO classid.** For a consumer, the derived DTO classid can be its own composed `u32` (`concept << 16 | app prefix`, `hotplug.rs:96-97`). OGAR mints the concept once, the app prefix is the consumer's, and hotplug activates the pair. No new bits, no extra mint, no reuse of the render prefix. Global revisions are versioned in DT64 directly and need no classid (D6). OGAR doctrine says the low half chooses the render skin and neither half carries behaviour; DT64 stores the resolution and the classid stays an address. (PROPOSED; the doctrine is from `OGAR CLAUDE.md`, not re-read here) + +## 4. Amendment requested to D-DT64-Q0 line 9 + +Q0 line 9 reads, verbatim: + +> The binding is an *interface seam*, not a second copy of business data and not the persistent Binding Store generalized in old plans. Do not invent a FrameStore, tensor physical allocation, predicate evaluator, Odoo executor, ONNX interpreter or new RelAlg AST. + +**The conflict.** D4 makes DT64 a bind store with versioned, replayable immutability. Read literally, Q0 line 9 forbids a persistent binding store. + +**Proposed reading.** "Store" means bindings and their version log. It never means copied business data. The user's rule of "no value duplicates" (D1) supports that reading. The rest of line 9 is unchanged: no FrameStore as a data holder, no tensor allocation, no predicate evaluator, no Odoo executor, no ONNX interpreter, no new RelAlg AST. + +**Requested change.** A one-line addition to Q0 line 9 that states this reading. Until the owner accepts it, Q0 line 9 stands as written and this plan does not override it. (PROPOSED; this plan edits no other file) + +## 5. Staged work + +Each stage is docs or lab work needing its own approval. None is authorized by this plan. + +| D-id | Deliverable | Falsifier | Owner | Gate | +|---|---|---|---|---| +| D-DT64-6-0 | This plan and its board entry (docs). | A reader finds a claim without an evidence state, or a decision labelled as technical truth. | lance-graph plan author | Docs review; no code. | +| D-DT64-6-1 | OGIT reader reconciliation. Run `lance-graph-ontology` `ttl_parse` and OGAR `OgitTables` over the SAME checkout in ONE run. Both print the same partition: accepted / rejected / duplicate / unresolved. Explain 523 files / 2,894 edges (odoo-rs §8) versus 518 / 2,756 (board claim for OGAR #363, NOT VERIFIED here). Record the observed OGIT commit as a provenance receipt only, never as a gate. | Totals fail to reconcile exactly after the partition is printed; or the receipt is used as a pin. | lance-graph-ontology and OGAR owners | Owner approval before code; read-only run. | +| D-DT64-6-2 | Expand `ogit:allowed` in `lance-graph-ontology` into a global, classid-free `(src type, verb, dst type)` table, replacing the placeholder `LinkSpec`. No second registry. | Pair-for-pair equality with OGAR `OgitTables::Allowed` fails; or a rejected / unresolved file is dropped instead of reported. | lance-graph-ontology owner | D-DT64-6-1 green; owner approval. | +| D-DT64-6-3 | Register OGIT verbs as DT64 predicates in 64-wide blocks. 378 used verbs; p95 10, max 123 per class, 2 classes above 64 (odoo-rs §8). Ordinals are per frame, never global ids. | A global verb id appears in a descriptor; or a class above 64 verbs is truncated. | DT64 catalogue owner | D-DT64-6-2 green. | +| D-DT64-6-4 | Consumer read-only access to the OGIT predicates through HotPlug activation. No consumer copy. | A consumer holds its own copy of the table. | consumer owner with OGAR authority | D-DT64-6-3 green; the `activate` call as in `hotplug.rs:722-726`. | +| D-DT64-6-5 | Exit from reference-only. Once a real domain (Odoo or IAM) has source-attested predicates, OGIT becomes a cross-check oracle, not the authority. | OGIT disagrees with attested predicates and OGIT wins by default. | DT64 catalogue owner | One domain with source-attested predicates. | + +## 6. Open questions + +All OPEN. + +1. Which unit is immutable: a `(classid, DT64 binding version)` entry, or one classid per revision? The second reopens the bit-placement question. This conflicts with D5's wording "classid behaviour is permanently immutable". +2. Does per-class inheritance resolution (`_inherit`, C3 order, odoo-rs §9 P6) run before the cell lookup? +3. Coexisting methods in one cell: odoo-rs reports a "collision" (`odoo-rs:docs/DT64-ON-WHEN-DO-REGISTRY.md:98-99`); lance-graph#1819 treats convergence as normal. A polymorphism reading (classid × polyfill) is proposed: several registered mappings are normal, and "collision" applies only to equally specific registrations with no declared order. +4. WHEN has no attested source data. The Odoo corpus carries only check-method kinds. +5. The Q0 line 9 amendment in §4 is not accepted yet. +6. Laws beyond Boolean associativity (inverse, symmetric, transitive) need instance evidence before admission (odoo-rs §11). +7. EXO-46 (global↔local admission), EXO-148 (durable identities for replay) and NFR-OP-2 (physical DR³ third axis) remain open. The levels here are logical. +8. The capstone's second axis is "targets" (Identity × Identity × Predicate), while D1 level 2 says Identity × Property × Predicate. D2 reads the capstone cube as the optional derived view. The owner of DT64-1..3 must confirm. +9. Odoo slice 1 needs 194 ON and 219 DO positions, so 4 blocks of 64 each. lance-graph#1819 proposes a padded 256×256 plane instead. The two shapes are not reconciled. + +## 7. Non-goals and guards + +- No code, ABI, test, runtime or merge authorization. This is a docs-only plan. +- No 65K×65K dense matrix. No eager 64-property cube. No per-cell 32 KiB frame. +- No new writer or persistence path. Persistence stays resident → squash/release → coalesced dirty rows → async writer (EXO-55). +- No second registry. D-DT64-6-2 replaces the placeholder `LinkSpec`. +- No pins on OGIT. A provenance receipt records what was read; it never gates. +- OGIT verbs are not Ruff `PredicateRole` bits and not the merged DT64 slot ids. +- Laws (inverse, symmetric) stay unadmitted until instance evidence exists. Schema mirroring is not evidence (`OGAR:crates/ogar-action-handler/tests/ogit_schema_composition.rs:19-21`). +- The 518 / 2,756 figures are a board claim, not verified here, and are never merged with 523 / 2,894. +- The ruff role-bit names (`TRIGGERS`, `REQUIRES`, `ENABLES`, `EFFECTS`) are quoted from odoo-rs and lance-graph#1814, not checked against ruff. +- ON, WHEN and DO are not DT64-0 slot terms. The merged plans use none of them. +- `ClassView::FieldMask` stays field presence, never predicate truth (`d-dt64-holographic-predicate-capstone-v1.md:23`). +- Do not cite the quarantined item. Nothing here derives from it. + +## 8. Sources + +- lance-graph [#1760](https://github.com/AdaWorldAPI/lance-graph/pull/1760), [#1792](https://github.com/AdaWorldAPI/lance-graph/pull/1792), [#1794](https://github.com/AdaWorldAPI/lance-graph/pull/1794), [#1795](https://github.com/AdaWorldAPI/lance-graph/pull/1795), [#1796](https://github.com/AdaWorldAPI/lance-graph/pull/1796), [#1797](https://github.com/AdaWorldAPI/lance-graph/pull/1797), [#1798](https://github.com/AdaWorldAPI/lance-graph/pull/1798), [#1799](https://github.com/AdaWorldAPI/lance-graph/pull/1799), [#1814](https://github.com/AdaWorldAPI/lance-graph/pull/1814) (OPEN, docs), [#1819](https://github.com/AdaWorldAPI/lance-graph/pull/1819) (OPEN, docs). +- odoo-rs [#44](https://github.com/AdaWorldAPI/odoo-rs/pull/44), [#45](https://github.com/AdaWorldAPI/odoo-rs/pull/45), [#46](https://github.com/AdaWorldAPI/odoo-rs/pull/46) (test-only lab and harvest schema). +- OGAR [#363](https://github.com/AdaWorldAPI/OGAR/pull/363) (`ogit_schema_composition.rs`). +- Board coordination: Linear EXO-50 (append-only; coordination, not approval). From c440fab738dc76a3025bb8acad69d9aa423119af Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 28 Oct 2026 01:11:01 +0000 Subject: [PATCH 02/11] docs(D-DT64-6): cite in-repo sources by symbol and section, not line number The citation-decay gate failed on nine grounding rows. The cited lines were correct, but each row's citation sat next to the following row's backticked text, which the gate took as its anchor. Line numbers into moving files are what the gate exists to retire, so every in-repo citation now names a symbol or section heading instead. Also replaces the two grounding rows that rested on grep output with claims from full reads: the three merged DT64 plans, and the qr_focus / qr_register lab tests (whose actual wording is now quoted correctly). Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01XAqKMNiyjwqFke9CfmoBgn --- ...-28-d-dt64-6-routing-bindstore-behavior.md | 8 ++-- .../d-dt64-6-routing-bindstore-behavior-v1.md | 46 +++++++++---------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md b/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md index 9d7c16e85..25dc79569 100644 --- a/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md +++ b/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md @@ -26,15 +26,15 @@ REVISIT WHEN form (plan §1): ## Findings that shaped the plan (VERIFIED-IN-CODE unless marked) -- The merged DT64 plans use none of the ON / WHEN / DO terms (grep, zero - hits). The ON×WHEN×DO registry exists only as the odoo-rs lab design +- The merged DT64 plans use none of the ON / WHEN / DO terms (the three + plans read in full). The ON×WHEN×DO registry exists only as the odoo-rs lab design `docs/DT64-ON-WHEN-DO-REGISTRY.md` (#44 / #45 merged, test-only) and in the OPEN docs PRs #1814 and #1819. - `lance-graph-ontology::ttl_parse` leaves `ogit:allowed` unexpanded - (`ttl_parse.rs:18-21`). The typed verb signature table exists only in OGAR + (`ttl_parse.rs` module doc, "What this parser handles today"). The typed verb signature table exists only in OGAR `OgitTables::Allowed`, and OGAR depends on lance-graph-ontology. - "Direct routing" already names position → executable maps in - `crates/dir-rmap-probe/tests/classview_dr.rs:66`. + `crates/dir-rmap-probe/tests/classview_dr.rs` (doc on `type Route`). - `D-DT64-Q0` line 9 forbids "the persistent Binding Store"; decision 4 needs an amendment there. Requested in plan §4, not applied. diff --git a/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md b/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md index 7d2687e6a..021e1fe81 100644 --- a/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md +++ b/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md @@ -45,29 +45,29 @@ Evidence states used below: VERIFIED-IN-CODE (file:line re-read), CURRENT-CONTRA ## 2. Grounding table -What exists today. "odoo-rs" (main @558f12a), "OGAR" (main @6b43a48) and "lance-graph#NNNN" (PR heads: #1814 @bbd8980, #1819 @60eca64) label other checkouts; those lines were read in a session crosswalk on 2026-10-28 and are not re-read in this file. +What exists today. "odoo-rs" (main @558f12a), "OGAR" (main @6b43a48) and "lance-graph#NNNN" (PR heads: #1814 @bbd8980, #1819 @60eca64) label other checkouts; those lines were read in a session crosswalk on 2026-10-28 and are not re-read in this file. In-repo sources are cited by symbol or section heading, not by line number, so a later edit to the target does not silently re-point the citation. Every in-repo source below was read in full on 2026-10-28. | Item | Evidence state | Citation | |---|---|---| -| `AxisKind` has `Identity`, `Property`, `Community`, `Capability` | VERIFIED-IN-CODE | `crates/dr-math-binding-probe/src/lib.rs:19-24` | -| The 64×64 bitplane is 512 B and "carries neither global ids, bag multiplicity nor provenance" | VERIFIED-IN-CODE | `crates/dr-math-binding-probe/src/lib.rs:8-10` | -| `Focus { revision }`: which 64×64 window is read; a new focus over the same frame is not a new frame | VERIFIED-IN-CODE | `crates/dr-math-binding-probe/src/lib.rs:165-170` | -| `FrameRevisions { source, relation_map, coordinates }`; `FrameStore::seal` compares frames by identity of issue (in-memory lab stand-in) | VERIFIED-IN-CODE | `crates/dr-math-binding-probe/src/lib.rs:73-109` | -| `Operand` carries validity bits with the relation bits | VERIFIED-IN-CODE | `crates/dr-math-binding-probe/src/lib.rs:187-195` | -| D-DRMC compares a guarded `Identity×Property` DR64 against `Identity²` | CURRENT-CONTRACT | `.claude/plans/dr-mathematical-compiler-v1.md:67,86` | -| "Direct routing: field position → the executable bound to it" | VERIFIED-IN-CODE (lab test) | `crates/dir-rmap-probe/tests/classview_dr.rs:66` | -| "Direct routing: method position -> fold" and "position -> executable" | VERIFIED-IN-CODE (lab tests) | `crates/dir-rmap-probe/tests/qr_focus.rs:145`, `qr_register.rs:53` (grep hit lines; not read further) | -| `hotplug.rs`: "the plug-and-play pattern EVERY consumer migrates to" | VERIFIED-IN-CODE | `crates/lance-graph-contract/src/hotplug.rs:1-2` | -| OGAR is the authority; it verifies "expected consumer, coverage both directions, ids minted exactly once" | VERIFIED-IN-CODE | `hotplug.rs:11-14` | -| The consumer "declares one `HotPlug` const naming its classids + covered capabilities, calls `activate` in its own binary/tests" | VERIFIED-IN-CODE | `hotplug.rs:15-17` | -| `HotPlug { consumer, classids: &'static [u16], covered }` | VERIFIED-IN-CODE | `hotplug.rs:54-62` | -| "A consumer composes its own full `u32` (`concept << 16 \| its app prefix`)" | VERIFIED-IN-CODE | `hotplug.rs:96-97` | -| `CapabilityAuthority::activate(&HotPlug) -> Result` | VERIFIED-IN-CODE | `hotplug.rs:722-726` | -| The `HotPlug` declaration is a compile-time const; verification is the `activate` call, run once in the consumer | WORKING-MODEL | reading of `hotplug.rs:15-17` | -| `ttl_parse` builds `LinkSpec` with placeholder subject/object types; `ogit:from-to` / `ogit:allowed` "are not yet expanded" | VERIFIED-IN-CODE | `crates/lance-graph-ontology/src/ttl_parse.rs:18-21` | -| The merged DT64 plans do not use the ON / WHEN / DO terms; the third axis is predicates | CURRENT-CONTRACT | `grep -nE "WHEN\|ON×\|ON/\|trigger\|Applicability"` over `d-dt64-holographic-predicate-capstone-v1.md`, `d-dt64-1-predicate-catalogue-source-crosswalk-v1.md`, `d-dt64-q0-borrowed-quack-binding-seam-v1.md`: zero hits | -| Capstone: "Odoo method fold" is listed as missing | CURRENT-CONTRACT | `.claude/plans/d-dt64-holographic-predicate-capstone-v1.md:102` | -| Capstone: 64×64×64 = 262,144 cells = 32 KiB dense; never eagerly allocate a cube for an 8- or 23-field question | CURRENT-CONTRACT | `.claude/plans/d-dt64-holographic-predicate-capstone-v1.md:27` | +| `AxisKind` has `Identity`, `Property`, `Community`, `Capability` | VERIFIED-IN-CODE | `crates/dr-math-binding-probe/src/lib.rs`, enum `AxisKind` | +| The 64×64 bitplane is 512 B and carries no global ids, bag multiplicity or provenance | VERIFIED-IN-CODE | `crates/dr-math-binding-probe/src/lib.rs`, module doc comment | +| `Focus` (one `revision` field): which 64×64 window is read; a new focus over the same frame is not a new frame | VERIFIED-IN-CODE | `crates/dr-math-binding-probe/src/lib.rs`, struct `Focus` | +| `FrameRevisions` holds source, relation map and coordinate revisions; `FrameStore` compares frames by identity of issue (in-memory lab stand-in) | VERIFIED-IN-CODE | `crates/dr-math-binding-probe/src/lib.rs`, structs `FrameRevisions`, `FrameStore` and `FrameStore::check` | +| `Operand` carries validity bits with the relation bits | VERIFIED-IN-CODE | `crates/dr-math-binding-probe/src/lib.rs`, struct `Operand` | +| D-DRMC compares a guarded Identity×Property DR64 against Identity² | CURRENT-CONTRACT | `.claude/plans/dr-mathematical-compiler-v1.md`, sections "Staged falsifiers and review gates" (stage 1) and "Experimental success criterion" | +| Direct routing maps a field position to the executable bound to it | VERIFIED-IN-CODE (lab test) | `crates/dir-rmap-probe/tests/classview_dr.rs`, doc comment on `type Route` | +| Direct routing maps a method position to a fold, and a position on a page to an executable | VERIFIED-IN-CODE (lab tests) | `crates/dir-rmap-probe/tests/qr_focus.rs` and `crates/dir-rmap-probe/tests/qr_register.rs`, doc comments on `type Route` | +| `hotplug.rs` is the plug-and-play pattern every consumer migrates to | VERIFIED-IN-CODE | `crates/lance-graph-contract/src/hotplug.rs`, module doc comment | +| OGAR is the authority; it verifies expected consumer, coverage in both directions, and ids minted exactly once | VERIFIED-IN-CODE | `crates/lance-graph-contract/src/hotplug.rs`, module doc comment, role 2 | +| The consumer declares one `HotPlug` const naming its classids and covered capabilities, and calls `activate` in its own binary or tests | VERIFIED-IN-CODE | `crates/lance-graph-contract/src/hotplug.rs`, module doc comment, role 3 | +| `HotPlug` has fields `consumer`, `classids` (a `u16` slice) and `covered` | VERIFIED-IN-CODE | `crates/lance-graph-contract/src/hotplug.rs`, struct `HotPlug` | +| A consumer composes its own full `u32` as concept shifted left 16, OR its app prefix | VERIFIED-IN-CODE | `crates/lance-graph-contract/src/hotplug.rs`, doc comment on `Activation::read_modes` | +| `CapabilityAuthority::activate` takes a `HotPlug` and returns an `Activation` or an `ActivationDrift` | VERIFIED-IN-CODE | `crates/lance-graph-contract/src/hotplug.rs`, trait `CapabilityAuthority` | +| The `HotPlug` declaration is a compile-time const; verification is the `activate` call, run once in the consumer | WORKING-MODEL | reading of the `hotplug.rs` module doc comment, role 3 | +| `ttl_parse` builds `LinkSpec` with placeholder subject/object types; `ogit:from-to` and `ogit:allowed` are not yet expanded | VERIFIED-IN-CODE | `crates/lance-graph-ontology/src/ttl_parse.rs`, module doc section "What this parser handles today" | +| The merged DT64 plans do not use ON, WHEN or DO as terms; the third axis is predicates | CURRENT-CONTRACT | `.claude/plans/d-dt64-holographic-predicate-capstone-v1.md`, `.claude/plans/d-dt64-1-predicate-catalogue-source-crosswalk-v1.md`, `.claude/plans/d-dt64-q0-borrowed-quack-binding-seam-v1.md`, each read in full on 2026-10-28 | +| Capstone: the Odoo method fold is listed as missing | CURRENT-CONTRACT | `.claude/plans/d-dt64-holographic-predicate-capstone-v1.md`, section "Evidence and non-goals" | +| Capstone: 64×64×64 = 262,144 cells = 32 KiB dense; never eagerly allocate a cube for an 8- or 23-field question | CURRENT-CONTRACT | `.claude/plans/d-dt64-holographic-predicate-capstone-v1.md`, section "Logical capacity and materialization" | | odoo-rs registry: lab design, "Nothing here is production code"; §1 axes of at most 64 positions per frame; §3 dispatch fold; §5 collisions; §8 OGIT counts; §10 measured results; §11 open points | CURRENT-CONTRACT (other repo, lab design doc) | `odoo-rs:docs/DT64-ON-WHEN-DO-REGISTRY.md:3,13-24,55-56,98-99,139-169,200-210,246-258` | | lance-graph#1814 cfa-1 (OPEN, docs only): "S1 is a proposed method-analysis view, not equivalent to the existing DT64-0 logical 64-predicate catalogue" | OPEN (PR not merged) | `lance-graph#1814:docs/research/counterfactual-behavior/cfa-1-typed-incidence.md:3,8` | | lance-graph#1819 (OPEN, docs only): ON×DO 256² presence bitmap plus borrowed Quack WHERE populations; "NOT IMPLEMENTED, MEASURED, ADMITTED OR MERGE-AUTHORIZED" | OPEN (PR not merged) | `lance-graph#1819:docs/research/on-do-watched-where-factored-dispatch-plan-20261027.md:3,9,119` | @@ -103,7 +103,7 @@ Everything in this section is WORKING-MODEL or PROPOSED. None of it is decided b **Override = a new derived classid plus a re-route.** odoo-rs models an override as `Retract` plus `Register` at one cell. Under D5 an override registers a new classid and re-routes the cell to it. The old binding stays readable forever. A `Retract` may remove a route; it must never alter a classid's behaviour. (PROPOSED) -**Consumer composed classid as the derived DTO classid.** For a consumer, the derived DTO classid can be its own composed `u32` (`concept << 16 | app prefix`, `hotplug.rs:96-97`). OGAR mints the concept once, the app prefix is the consumer's, and hotplug activates the pair. No new bits, no extra mint, no reuse of the render prefix. Global revisions are versioned in DT64 directly and need no classid (D6). OGAR doctrine says the low half chooses the render skin and neither half carries behaviour; DT64 stores the resolution and the classid stays an address. (PROPOSED; the doctrine is from `OGAR CLAUDE.md`, not re-read here) +**Consumer composed classid as the derived DTO classid.** For a consumer, the derived DTO classid can be its own composed `u32` (`concept << 16 | app prefix`, `hotplug.rs`, doc comment on `Activation::read_modes`). OGAR mints the concept once, the app prefix is the consumer's, and hotplug activates the pair. No new bits, no extra mint, no reuse of the render prefix. Global revisions are versioned in DT64 directly and need no classid (D6). OGAR doctrine says the low half chooses the render skin and neither half carries behaviour; DT64 stores the resolution and the classid stays an address. (PROPOSED; the doctrine is from `OGAR CLAUDE.md`, not re-read here) ## 4. Amendment requested to D-DT64-Q0 line 9 @@ -127,7 +127,7 @@ Each stage is docs or lab work needing its own approval. None is authorized by t | D-DT64-6-1 | OGIT reader reconciliation. Run `lance-graph-ontology` `ttl_parse` and OGAR `OgitTables` over the SAME checkout in ONE run. Both print the same partition: accepted / rejected / duplicate / unresolved. Explain 523 files / 2,894 edges (odoo-rs §8) versus 518 / 2,756 (board claim for OGAR #363, NOT VERIFIED here). Record the observed OGIT commit as a provenance receipt only, never as a gate. | Totals fail to reconcile exactly after the partition is printed; or the receipt is used as a pin. | lance-graph-ontology and OGAR owners | Owner approval before code; read-only run. | | D-DT64-6-2 | Expand `ogit:allowed` in `lance-graph-ontology` into a global, classid-free `(src type, verb, dst type)` table, replacing the placeholder `LinkSpec`. No second registry. | Pair-for-pair equality with OGAR `OgitTables::Allowed` fails; or a rejected / unresolved file is dropped instead of reported. | lance-graph-ontology owner | D-DT64-6-1 green; owner approval. | | D-DT64-6-3 | Register OGIT verbs as DT64 predicates in 64-wide blocks. 378 used verbs; p95 10, max 123 per class, 2 classes above 64 (odoo-rs §8). Ordinals are per frame, never global ids. | A global verb id appears in a descriptor; or a class above 64 verbs is truncated. | DT64 catalogue owner | D-DT64-6-2 green. | -| D-DT64-6-4 | Consumer read-only access to the OGIT predicates through HotPlug activation. No consumer copy. | A consumer holds its own copy of the table. | consumer owner with OGAR authority | D-DT64-6-3 green; the `activate` call as in `hotplug.rs:722-726`. | +| D-DT64-6-4 | Consumer read-only access to the OGIT predicates through HotPlug activation. No consumer copy. | A consumer holds its own copy of the table. | consumer owner with OGAR authority | D-DT64-6-3 green; the `activate` call as in `hotplug.rs`, trait `CapabilityAuthority`. | | D-DT64-6-5 | Exit from reference-only. Once a real domain (Odoo or IAM) has source-attested predicates, OGIT becomes a cross-check oracle, not the authority. | OGIT disagrees with attested predicates and OGIT wins by default. | DT64 catalogue owner | One domain with source-attested predicates. | ## 6. Open questions @@ -156,7 +156,7 @@ All OPEN. - The 518 / 2,756 figures are a board claim, not verified here, and are never merged with 523 / 2,894. - The ruff role-bit names (`TRIGGERS`, `REQUIRES`, `ENABLES`, `EFFECTS`) are quoted from odoo-rs and lance-graph#1814, not checked against ruff. - ON, WHEN and DO are not DT64-0 slot terms. The merged plans use none of them. -- `ClassView::FieldMask` stays field presence, never predicate truth (`d-dt64-holographic-predicate-capstone-v1.md:23`). +- `ClassView::FieldMask` stays field presence, never predicate truth (capstone, section "Thesis and precise terminology"). - Do not cite the quarantined item. Nothing here derives from it. ## 8. Sources From c13b63ac0cdc7540000dabfafd07a7b7597055d0 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 28 Oct 2026 01:12:52 +0000 Subject: [PATCH 03/11] docs(D-DT64-6): record D8, DR64 references identity and the register copy amortizes prefetch DR64 direct routing references existing identities and mints none. The global->local prefetch holds a copy of the register (identity references and local positions only, never values), reused by every read under one frame and rebuilt when the frame check refuses. Stated against the zero-copy law's pointer-table carve-out and Q0's accounted prefetch cost. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01XAqKMNiyjwqFke9CfmoBgn --- .../2026-10-28-d-dt64-6-routing-bindstore-behavior.md | 6 +++++- .claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md | 7 +++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md b/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md index 25dc79569..9d89b76da 100644 --- a/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md +++ b/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md @@ -7,7 +7,7 @@ No code, ABI, test, runtime or merge authorization. Read at lance-graph `main` ## What this records -Seven user decisions from session 2026-10-28, in DECISION / SCOPE / BASIS / +Eight user decisions from session 2026-10-28, in DECISION / SCOPE / BASIS / REVISIT WHEN form (plan §1): 1. DT64 has three levels, all 64×64×64, reached by focused global→local: @@ -23,6 +23,10 @@ REVISIT WHEN form (plan §1): 6. Global behaviour needs no classid and lives in lance-graph; consumers need a classid through the hotplug pattern. 7. OGIT is immutable and read unpinned. +8. DR64 references existing identities and mints none. The global→local + prefetch amortizes by holding a copy of the register (identity + references and local positions only, no values), valid while its frame + is current and rebuilt when the frame check refuses. ## Findings that shaped the plan (VERIFIED-IN-CODE unless marked) diff --git a/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md b/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md index 021e1fe81..2f2608e07 100644 --- a/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md +++ b/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md @@ -43,6 +43,11 @@ Evidence states used below: VERIFIED-IN-CODE (file:line re-read), CURRENT-CONTRA **BASIS:** the user's statement in session, 2026-10-28 (decision, not measurement) **REVISIT WHEN:** an OGIT change breaks a reader and a provenance receipt is not enough. +**DECISION (2026-10-28):** DR64 direct routing references existing identities; it mints none. For the global→local register, the prefetch amortizes its cost by holding a copy: the copy is taken once per frame and reused by every read under that frame. +**SCOPE:** what the held copy contains and how long it lives. It contains identity references and local positions only (the pointer table), never business values, so it is not a data replica. It is valid only while its frame is current: a frame check that fails (source, relation map or coordinate revision moved, or a foreign store) discards it and prefetches again, never reads through it. +**BASIS:** the user's statement in session, 2026-10-28 (decision, not measurement). Consistent with the zero-copy law's single carve-out, global→local inversion materializing only the pointer table (lance-graph `CLAUDE.md`, "No millisecond results" section, bullet "There are no boundaries"), and with Q0's demand that any copy be explicit and accounted (Q0 Phase Q0 and Phase Q3, which count source read/prefetch in the cost). +**REVISIT WHEN:** a measurement shows re-prefetching per read is cheaper than holding the copy, or the copy is found to carry values. + ## 2. Grounding table What exists today. "odoo-rs" (main @558f12a), "OGAR" (main @6b43a48) and "lance-graph#NNNN" (PR heads: #1814 @bbd8980, #1819 @60eca64) label other checkouts; those lines were read in a session crosswalk on 2026-10-28 and are not re-read in this file. In-repo sources are cited by symbol or section heading, not by line number, so a later edit to the target does not silently re-point the citation. Every in-repo source below was read in full on 2026-10-28. @@ -99,6 +104,8 @@ Everything in this section is WORKING-MODEL or PROPOSED. None of it is decided b (PROPOSED) +**The held register copy is keyed to its frame (D8).** The prefetch builds the local register once: local position → reference to an existing global identity. Reads in steps 1–4 of the dispatch order above go through that copy without re-resolving identities. The copy records the frame it was built under, and every read checks the frame first, as `FrameStore::check` does in `crates/dr-math-binding-probe/src/lib.rs`. Any refusal (`ForeignFrame`, `SourceChanged`, `MapChanged`, `CoordinatesChanged`, `FrameResealed`) drops the copy and re-prefetches. A new focus over the same frame reuses the copy, because a focus is not a new frame (same file, struct `Focus`). The measured cost must include building the copy, amortized over the reads it serves (Q0 Phase Q3). (PROPOSED) + **Only routing is versioned.** DR64 maps a position to a classid and changes between versions. The classid → behaviour binding in DT64 does not change. Replay "as of version v" means which classid each address routed to at v; that classid's behaviour is the same as it is today. (PROPOSED reading of D5) **Override = a new derived classid plus a re-route.** odoo-rs models an override as `Retract` plus `Register` at one cell. Under D5 an override registers a new classid and re-routes the cell to it. The old binding stays readable forever. A `Retract` may remove a route; it must never alter a classid's behaviour. (PROPOSED) From 8c079984df39b01cf5b1afc9ad6d7330a4a8f11a Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 28 Oct 2026 01:15:09 +0000 Subject: [PATCH 04/11] docs(D-DT64-6): ground #1814 and #1819 as merged; K3 note on the dispatch fold #1814 and #1819 have merged, so the plan now cites them by section from this repo instead of as open PRs by line number. That line-number row was the one citation-decay failure on c440fab: the file did not exist locally, so the local run reported UNVERIFIABLE where CI reported DECAYED. Reading both in full showed two contradictions, now fixed: - the dispatch step's two-valued `OR over w in G` fold is restricted to candidate DO presence; selection evaluates typed guards in K3 (#1814 kill test I03); - open question 3 now follows #1819: several mappings and convergence are normal; a conflict needs incompatible source-qualified results. Also corrects the quoted Ruff role names to #1814's list. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01XAqKMNiyjwqFke9CfmoBgn --- ...-10-28-d-dt64-6-routing-bindstore-behavior.md | 7 +++++-- .../d-dt64-6-routing-bindstore-behavior-v1.md | 16 ++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md b/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md index 9d89b76da..d13d9c74a 100644 --- a/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md +++ b/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md @@ -3,7 +3,7 @@ **Status:** PROPOSED / DOCS ONLY. Plan: [d-dt64-6-routing-bindstore-behavior-v1.md](../../plans/d-dt64-6-routing-bindstore-behavior-v1.md). No code, ABI, test, runtime or merge authorization. Read at lance-graph `main` `72697cc31`, odoo-rs `main` `558f12a`, OGAR `main` `6b43a48`; lance-graph #1814 -(`bbd8980`) and #1819 (`60eca64`) are OPEN docs PRs. +and #1819 have since merged as docs and were read in full on `main`. ## What this records @@ -33,7 +33,10 @@ REVISIT WHEN form (plan §1): - The merged DT64 plans use none of the ON / WHEN / DO terms (the three plans read in full). The ON×WHEN×DO registry exists only as the odoo-rs lab design `docs/DT64-ON-WHEN-DO-REGISTRY.md` (#44 / #45 merged, test-only) and in the - OPEN docs PRs #1814 and #1819. + docs #1814 and #1819 (now merged). #1814 rules out folding WHEN as a + two-valued OR of atoms; #1819 makes convergence of several mappings + normal. The plan's dispatch fold and its collision question now follow + both. - `lance-graph-ontology::ttl_parse` leaves `ogit:allowed` unexpanded (`ttl_parse.rs` module doc, "What this parser handles today"). The typed verb signature table exists only in OGAR `OgitTables::Allowed`, and OGAR depends on lance-graph-ontology. diff --git a/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md b/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md index 2f2608e07..4f1955c75 100644 --- a/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md +++ b/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md @@ -50,7 +50,7 @@ Evidence states used below: VERIFIED-IN-CODE (file:line re-read), CURRENT-CONTRA ## 2. Grounding table -What exists today. "odoo-rs" (main @558f12a), "OGAR" (main @6b43a48) and "lance-graph#NNNN" (PR heads: #1814 @bbd8980, #1819 @60eca64) label other checkouts; those lines were read in a session crosswalk on 2026-10-28 and are not re-read in this file. In-repo sources are cited by symbol or section heading, not by line number, so a later edit to the target does not silently re-point the citation. Every in-repo source below was read in full on 2026-10-28. +What exists today. "odoo-rs" (main @558f12a), "OGAR" (main @6b43a48) and #1814 and #1819, both merged into lance-graph `main` and read in full here on 2026-10-28, are cited from this repo; the other two label other checkouts, whose lines were read in a session crosswalk on 2026-10-28 and are not re-read in this file. In-repo sources are cited by symbol or section heading, not by line number, so a later edit to the target does not silently re-point the citation. Every in-repo source below was read in full on 2026-10-28. | Item | Evidence state | Citation | |---|---|---| @@ -74,8 +74,8 @@ What exists today. "odoo-rs" (main @558f12a), "OGAR" (main @6b43a48) and "lance- | Capstone: the Odoo method fold is listed as missing | CURRENT-CONTRACT | `.claude/plans/d-dt64-holographic-predicate-capstone-v1.md`, section "Evidence and non-goals" | | Capstone: 64×64×64 = 262,144 cells = 32 KiB dense; never eagerly allocate a cube for an 8- or 23-field question | CURRENT-CONTRACT | `.claude/plans/d-dt64-holographic-predicate-capstone-v1.md`, section "Logical capacity and materialization" | | odoo-rs registry: lab design, "Nothing here is production code"; §1 axes of at most 64 positions per frame; §3 dispatch fold; §5 collisions; §8 OGIT counts; §10 measured results; §11 open points | CURRENT-CONTRACT (other repo, lab design doc) | `odoo-rs:docs/DT64-ON-WHEN-DO-REGISTRY.md:3,13-24,55-56,98-99,139-169,200-210,246-258` | -| lance-graph#1814 cfa-1 (OPEN, docs only): "S1 is a proposed method-analysis view, not equivalent to the existing DT64-0 logical 64-predicate catalogue" | OPEN (PR not merged) | `lance-graph#1814:docs/research/counterfactual-behavior/cfa-1-typed-incidence.md:3,8` | -| lance-graph#1819 (OPEN, docs only): ON×DO 256² presence bitmap plus borrowed Quack WHERE populations; "NOT IMPLEMENTED, MEASURED, ADMITTED OR MERGE-AUTHORIZED" | OPEN (PR not merged) | `lance-graph#1819:docs/research/on-do-watched-where-factored-dispatch-plan-20261027.md:3,9,119` | +| #1814 cfa-1 (merged, docs only, falsifiers not run): S1 is a proposed method-analysis view, not equivalent to the DT64-0 logical 64-predicate catalogue; WHEN is a reference to a typed guard with a three-valued result and cannot be folded as a simple OR of satisfied atoms; one cell maps to zero, one or several method identities | CURRENT-CONTRACT (research doc, not an implementation) | `docs/research/counterfactual-behavior/cfa-1-typed-incidence.md`, sections "Question", "Logical shape, no Rust ABI commitment" and "Kill tests" (I01, I03) | +| #1819 (merged, docs only, not implemented or measured): ON×DO 256² presence bitmap plus borrowed Quack WHERE populations; the 256² bitmap and the 65,536-row WHERE mask are equal-sized but different coordinate domains; several mappings onto one polyfill, and convergence of rules into one state, are normal and must all be kept | CURRENT-CONTRACT (research doc, not an implementation) | `docs/research/on-do-watched-where-factored-dispatch-plan-20261027.md`, sections "Research question", "Operator correction" and "Normal convergence of rules into a shared state" | | OGAR `KausalSpec` variants `StateGuard`, `LifecycleTrigger`, `Depends`, `Constrains`, `Onchange`, `ContextDepends`, `External` | VERIFIED-IN-CODE (other repo) | `OGAR:crates/ogar-vocab/src/lib.rs:610-652` | | OGAR mints `action_handler` 0x0C07, `action_applicability` 0x0C08, `automation_trigger` 0x0C09; `action_capability` is RESERVED | VERIFIED-IN-CODE (other repo) | `OGAR:crates/ogar-vocab/src/lib.rs:1415-1440` | | OGAR DO-arm lift: schema half coded; behavioural half is CONJECTURE | CURRENT-CONTRACT (other repo) | `OGAR:docs/HIRO-DO-ARM-LIFT.md:86-90,161` | @@ -99,7 +99,7 @@ Everything in this section is WORKING-MODEL or PROPOSED. None of it is decided b 1. `DR256::WHERE` selects the population (8 KiB mask). 2. Quack evaluates each needed guard into `G`. 3. DR64 routes each address to its classid. -4. The registry fold `OR over w in G of C[e][w]` (odoo-rs §3) gives the DO mask per event. +4. odoo-rs §3 gives the DO mask per event as the fold `OR over w in G of C[e][w]`. That fold is two-valued and treats each WHEN as one atom, which #1814 rules out (kill test I03: with `WHEN = A AND B`, A true and B false or unknown must not fire). The fold therefore stands only for candidate DO presence, the `ON_DO[e]` mask of #1819. Selection evaluates each registration's typed guard over the population in K3, and UNKNOWN never counts as FALSE. 5. DO bits that are property writes land on DR#3 cells as resident changes, then follow the persistence path (EXO-55). (PROPOSED) @@ -143,13 +143,13 @@ All OPEN. 1. Which unit is immutable: a `(classid, DT64 binding version)` entry, or one classid per revision? The second reopens the bit-placement question. This conflicts with D5's wording "classid behaviour is permanently immutable". 2. Does per-class inheritance resolution (`_inherit`, C3 order, odoo-rs §9 P6) run before the cell lookup? -3. Coexisting methods in one cell: odoo-rs reports a "collision" (`odoo-rs:docs/DT64-ON-WHEN-DO-REGISTRY.md:98-99`); lance-graph#1819 treats convergence as normal. A polymorphism reading (classid × polyfill) is proposed: several registered mappings are normal, and "collision" applies only to equally specific registrations with no declared order. +3. Coexisting methods in one cell: odoo-rs reports a "collision" (`odoo-rs:docs/DT64-ON-WHEN-DO-REGISTRY.md:98-99`). Merged #1819 settles the direction: several mappings and convergence are normal and must all be kept, and a real conflict needs incompatible source-qualified results under the same fully typed coordinate and snapshot plus an applicable domain law. Still open: whether odoo-rs's "collision" cells meet that bar or are ordinary convergence. 4. WHEN has no attested source data. The Odoo corpus carries only check-method kinds. 5. The Q0 line 9 amendment in §4 is not accepted yet. 6. Laws beyond Boolean associativity (inverse, symmetric, transitive) need instance evidence before admission (odoo-rs §11). 7. EXO-46 (global↔local admission), EXO-148 (durable identities for replay) and NFR-OP-2 (physical DR³ third axis) remain open. The levels here are logical. 8. The capstone's second axis is "targets" (Identity × Identity × Predicate), while D1 level 2 says Identity × Property × Predicate. D2 reads the capstone cube as the optional derived view. The owner of DT64-1..3 must confirm. -9. Odoo slice 1 needs 194 ON and 219 DO positions, so 4 blocks of 64 each. lance-graph#1819 proposes a padded 256×256 plane instead. The two shapes are not reconciled. +9. Odoo slice 1 needs 194 ON and 219 DO positions, so 4 blocks of 64 each. Merged #1819 proposes a padded 256×256 plane instead. The two shapes are not reconciled. ## 7. Non-goals and guards @@ -161,14 +161,14 @@ All OPEN. - OGIT verbs are not Ruff `PredicateRole` bits and not the merged DT64 slot ids. - Laws (inverse, symmetric) stay unadmitted until instance evidence exists. Schema mirroring is not evidence (`OGAR:crates/ogar-action-handler/tests/ogit_schema_composition.rs:19-21`). - The 518 / 2,756 figures are a board claim, not verified here, and are never merged with 523 / 2,894. -- The ruff role-bit names (`TRIGGERS`, `REQUIRES`, `ENABLES`, `EFFECTS`) are quoted from odoo-rs and lance-graph#1814, not checked against ruff. +- The ruff role names are quoted, not checked against ruff: #1814 lists READS, DERIVES, EFFECTS, REQUIRES, AUTHORIZES and TRIGGERS; the odoo-rs list was read in another checkout. - ON, WHEN and DO are not DT64-0 slot terms. The merged plans use none of them. - `ClassView::FieldMask` stays field presence, never predicate truth (capstone, section "Thesis and precise terminology"). - Do not cite the quarantined item. Nothing here derives from it. ## 8. Sources -- lance-graph [#1760](https://github.com/AdaWorldAPI/lance-graph/pull/1760), [#1792](https://github.com/AdaWorldAPI/lance-graph/pull/1792), [#1794](https://github.com/AdaWorldAPI/lance-graph/pull/1794), [#1795](https://github.com/AdaWorldAPI/lance-graph/pull/1795), [#1796](https://github.com/AdaWorldAPI/lance-graph/pull/1796), [#1797](https://github.com/AdaWorldAPI/lance-graph/pull/1797), [#1798](https://github.com/AdaWorldAPI/lance-graph/pull/1798), [#1799](https://github.com/AdaWorldAPI/lance-graph/pull/1799), [#1814](https://github.com/AdaWorldAPI/lance-graph/pull/1814) (OPEN, docs), [#1819](https://github.com/AdaWorldAPI/lance-graph/pull/1819) (OPEN, docs). +- lance-graph [#1760](https://github.com/AdaWorldAPI/lance-graph/pull/1760), [#1792](https://github.com/AdaWorldAPI/lance-graph/pull/1792), [#1794](https://github.com/AdaWorldAPI/lance-graph/pull/1794), [#1795](https://github.com/AdaWorldAPI/lance-graph/pull/1795), [#1796](https://github.com/AdaWorldAPI/lance-graph/pull/1796), [#1797](https://github.com/AdaWorldAPI/lance-graph/pull/1797), [#1798](https://github.com/AdaWorldAPI/lance-graph/pull/1798), [#1799](https://github.com/AdaWorldAPI/lance-graph/pull/1799), [#1814](https://github.com/AdaWorldAPI/lance-graph/pull/1814) (merged, docs), [#1819](https://github.com/AdaWorldAPI/lance-graph/pull/1819) (merged, docs). - odoo-rs [#44](https://github.com/AdaWorldAPI/odoo-rs/pull/44), [#45](https://github.com/AdaWorldAPI/odoo-rs/pull/45), [#46](https://github.com/AdaWorldAPI/odoo-rs/pull/46) (test-only lab and harvest schema). - OGAR [#363](https://github.com/AdaWorldAPI/OGAR/pull/363) (`ogit_schema_composition.rs`). - Board coordination: Linear EXO-50 (append-only; coordination, not approval). From b24b57c38fe65b2950360c019c32a62eaf90f315 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 28 Oct 2026 01:29:19 +0000 Subject: [PATCH 05/11] =?UTF-8?q?docs(D-DT64-6):=20ON=C3=97WHEN=C3=97DO=20?= =?UTF-8?q?is=20in=20merged=20research=20docs,=20not=20absent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The plan and board entry said the merged plans do not use ON / WHEN / DO. That holds only for the three DT64 plans. ON×WHEN×DO is established in merged lance-graph research docs: the D-CFA series (docs/research/counterfactual-behavior/) and the EAW series (docs/research/epistemic-awareness/), plus #1819. All twelve files read in full; the grounding row and the non-goal line now say so. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01XAqKMNiyjwqFke9CfmoBgn --- .../2026-10-28-d-dt64-6-routing-bindstore-behavior.md | 10 ++++++---- .../plans/d-dt64-6-routing-bindstore-behavior-v1.md | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md b/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md index d13d9c74a..01bd6002b 100644 --- a/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md +++ b/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md @@ -30,10 +30,12 @@ REVISIT WHEN form (plan §1): ## Findings that shaped the plan (VERIFIED-IN-CODE unless marked) -- The merged DT64 plans use none of the ON / WHEN / DO terms (the three - plans read in full). The ON×WHEN×DO registry exists only as the odoo-rs lab design - `docs/DT64-ON-WHEN-DO-REGISTRY.md` (#44 / #45 merged, test-only) and in the - docs #1814 and #1819 (now merged). #1814 rules out folding WHEN as a +- The three DT64 plans do not name ON / WHEN / DO, but ON×WHEN×DO is + established in merged lance-graph research docs: the D-CFA series + (`docs/research/counterfactual-behavior/`, incl. #1814) and the EAW + series (`docs/research/epistemic-awareness/`), plus #1819. As a registry + it exists as the odoo-rs lab design `docs/DT64-ON-WHEN-DO-REGISTRY.md` + (#44 / #45 merged, test-only). #1814 rules out folding WHEN as a two-valued OR of atoms; #1819 makes convergence of several mappings normal. The plan's dispatch fold and its collision question now follow both. diff --git a/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md b/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md index 4f1955c75..d222b26a5 100644 --- a/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md +++ b/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md @@ -70,7 +70,7 @@ What exists today. "odoo-rs" (main @558f12a), "OGAR" (main @6b43a48) and #1814 a | `CapabilityAuthority::activate` takes a `HotPlug` and returns an `Activation` or an `ActivationDrift` | VERIFIED-IN-CODE | `crates/lance-graph-contract/src/hotplug.rs`, trait `CapabilityAuthority` | | The `HotPlug` declaration is a compile-time const; verification is the `activate` call, run once in the consumer | WORKING-MODEL | reading of the `hotplug.rs` module doc comment, role 3 | | `ttl_parse` builds `LinkSpec` with placeholder subject/object types; `ogit:from-to` and `ogit:allowed` are not yet expanded | VERIFIED-IN-CODE | `crates/lance-graph-ontology/src/ttl_parse.rs`, module doc section "What this parser handles today" | -| The merged DT64 plans do not use ON, WHEN or DO as terms; the third axis is predicates | CURRENT-CONTRACT | `.claude/plans/d-dt64-holographic-predicate-capstone-v1.md`, `.claude/plans/d-dt64-1-predicate-catalogue-source-crosswalk-v1.md`, `.claude/plans/d-dt64-q0-borrowed-quack-binding-seam-v1.md`, each read in full on 2026-10-28 | +| The three DT64 plans (capstone, DT64-1, Q0) do not name ON, WHEN or DO; their third axis is predicates. ON×WHEN×DO is established in merged lance-graph research docs instead: the D-CFA series (logical ON×WHEN×DO incidence S1, a method-analysis view kept separate from the DT64-0 catalogue, with K3 WHEN guards and ablation over it) and the EAW series (Identity × Property/Edge × Predicate with ON/WHEN/DO as typed mapping roles, the logical third axis kept open under NFR-OP-2), plus #1819's factored ON×DO plane | CURRENT-CONTRACT (plans) and CURRENT-CONTRACT (research docs, not implementations) | the three plans; `docs/research/counterfactual-behavior/` (README, `cfa-1`, `cfa-2`, `cfa-4`, `thought-dependency-scratchpad`); `docs/research/epistemic-awareness/` (`eaw-1`, `eaw-2`, `eaw-5`, `eaw-6`, `eaw-10`, `dr64c-epistemic-awareness-scratchpad-20261027`); all read in full on 2026-10-28 | | Capstone: the Odoo method fold is listed as missing | CURRENT-CONTRACT | `.claude/plans/d-dt64-holographic-predicate-capstone-v1.md`, section "Evidence and non-goals" | | Capstone: 64×64×64 = 262,144 cells = 32 KiB dense; never eagerly allocate a cube for an 8- or 23-field question | CURRENT-CONTRACT | `.claude/plans/d-dt64-holographic-predicate-capstone-v1.md`, section "Logical capacity and materialization" | | odoo-rs registry: lab design, "Nothing here is production code"; §1 axes of at most 64 positions per frame; §3 dispatch fold; §5 collisions; §8 OGIT counts; §10 measured results; §11 open points | CURRENT-CONTRACT (other repo, lab design doc) | `odoo-rs:docs/DT64-ON-WHEN-DO-REGISTRY.md:3,13-24,55-56,98-99,139-169,200-210,246-258` | @@ -162,7 +162,7 @@ All OPEN. - Laws (inverse, symmetric) stay unadmitted until instance evidence exists. Schema mirroring is not evidence (`OGAR:crates/ogar-action-handler/tests/ogit_schema_composition.rs:19-21`). - The 518 / 2,756 figures are a board claim, not verified here, and are never merged with 523 / 2,894. - The ruff role names are quoted, not checked against ruff: #1814 lists READS, DERIVES, EFFECTS, REQUIRES, AUTHORIZES and TRIGGERS; the odoo-rs list was read in another checkout. -- ON, WHEN and DO are not DT64-0 slot terms. The merged plans use none of them. +- ON, WHEN and DO are not DT64-0 slot terms; the three DT64 plans do not name them. They are established in the merged D-CFA and EAW research docs and #1819 (§2), which keep S1 separate from the DT64-0 catalogue and the third axis logical. - `ClassView::FieldMask` stays field presence, never predicate truth (capstone, section "Thesis and precise terminology"). - Do not cite the quarantined item. Nothing here derives from it. From 73705caa16d629dec305a530a8254eb533759476 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 28 Oct 2026 01:32:51 +0000 Subject: [PATCH 06/11] docs(D-DT64-6): place the plan in the #1760 successor design (crai-rs CR-H0/H1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #1760's D-SAG-6 plan is unchanged since merge; its successor is the crai-rs CR-H0 / CR-H1 map (crai-rs #1, #2), which makes D-SAG-6 the motor and Ruff + DT64 the transmission. The plan now grounds both, places the per-cell ON×WHEN×DO registry as that transmission's behaviour binding, ties D5/D8 to D-SAG-6 F06, F07 and F11, and requires behaviour registrations to reference ordered effects: a DO set or deduplicated SPO bag cannot distinguish two effect orders. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01XAqKMNiyjwqFke9CfmoBgn --- .../2026-10-28-d-dt64-6-routing-bindstore-behavior.md | 7 +++++++ .claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md b/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md index 01bd6002b..2f5faff8f 100644 --- a/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md +++ b/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md @@ -39,6 +39,13 @@ REVISIT WHEN form (plan §1): two-valued OR of atoms; #1819 makes convergence of several mappings normal. The plan's dispatch fold and its collision question now follow both. +- #1760 (D-SAG-6) is carried forward by crai-rs CR-H0 / CR-H1 (crai-rs #1 + and #2, private): D-SAG-6 is the motor, Ruff + DT64 the transmission, + #1814's ON×WHEN×DO the guard ledger. The plan places DT64-6 as that + transmission's behaviour binding, applies D-SAG-6 F06 / F07 / F11 to it, + and requires a behaviour registration to reference ordered effects, + since a DO set or deduplicated SPO bag cannot separate `*x = 1; *x += 1` + from its reverse. - `lance-graph-ontology::ttl_parse` leaves `ogit:allowed` unexpanded (`ttl_parse.rs` module doc, "What this parser handles today"). The typed verb signature table exists only in OGAR `OgitTables::Allowed`, and OGAR depends on lance-graph-ontology. diff --git a/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md b/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md index d222b26a5..d4ab29e0a 100644 --- a/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md +++ b/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md @@ -83,6 +83,8 @@ What exists today. "odoo-rs" (main @558f12a), "OGAR" (main @6b43a48) and #1814 a | OGAR depends on `lance-graph-ontology` (optional, feature `ontology-cache`), so the reverse edge would be a cycle | VERIFIED-IN-CODE (other repo) | `OGAR:crates/ogar-action-handler/Cargo.toml:27` | | OGIT counts: 523 verb files, 378 used verbs, 2,894 allowed edges over 941 entities; per-class p95 10, max 123, 2 classes above 64 | CURRENT-CONTRACT (doc report, not recomputed) | `odoo-rs:docs/DT64-ON-WHEN-DO-REGISTRY.md:139-169` | | Odoo slice 1: ON 194 × WHEN 5 × DO 219; 628 live registrations; 8 multi-method cells | CURRENT-CONTRACT (doc report of a first run; the test file pins no literals) | `odoo-rs:docs/DT64-ON-WHEN-DO-REGISTRY.md:200-210` | +| D-SAG-6 (#1760, unchanged since merge): Codegraph → Mathematics → Logic → Tracert over typed read-only views; distinct node identities (SourceDefId, MIRBodyId, Method/ClassId, RecipeId among them); evidence grades kept apart; changed source SHA with retained recipe or callsite ids must invalidate or rebind (F11); the same DR ordinal in another frame is refused (F07); unexamined regions are UNKNOWN (F06) | CURRENT-CONTRACT (plan, docs only) | `.claude/plans/d-sag-6-rust-codegraph-math-logic-tracert-v1.md`, sections "Minimal graph contract" and "Falsification matrix, preregistered" | +| The successor to #1760 is crai-rs CR-H0 / CR-H1 (crai-rs #1 and #2, private repo, `main` @378a24a). It maps #1760 and #1813–#1830 onto one design: D-SAG-6 is the motor; Ruff harvest plus DT64 versioned bindings are the transmission; ON×WHEN×DO from #1814 is "source intake and guard ledger"; the deduplicated SPO view is lossy, so behaviour needs a separate ordered event lane | PROPOSED (research docs, other repo, read in full here) | `crai-rs:docs/CR-H0-CHASSIS-RETROFIT-MAP.md`, sections 1–4; `crai-rs:docs/CR-H0-RUFF-REVERSE-MOLD.md`, sections 2 and 4; `crai-rs:docs/CR-H1-SPOG-GROK-EXPORT-CROSSWALK.md`, section "The actual minimal export seam" | ## 3. Design consequences @@ -106,6 +108,10 @@ Everything in this section is WORKING-MODEL or PROPOSED. None of it is decided b **The held register copy is keyed to its frame (D8).** The prefetch builds the local register once: local position → reference to an existing global identity. Reads in steps 1–4 of the dispatch order above go through that copy without re-resolving identities. The copy records the frame it was built under, and every read checks the frame first, as `FrameStore::check` does in `crates/dr-math-binding-probe/src/lib.rs`. Any refusal (`ForeignFrame`, `SourceChanged`, `MapChanged`, `CoordinatesChanged`, `FrameResealed`) drops the copy and re-prefetches. A new focus over the same frame reuses the copy, because a focus is not a new frame (same file, struct `Focus`). The measured cost must include building the copy, amortized over the reads it serves (Q0 Phase Q3). (PROPOSED) +**DT64-6 is the binding layer of the D-SAG-6 transmission.** In the #1760 successor design (crai-rs CR-H0), Ruff harvests source structure and DT64 binds it to versioned, source-witnessed coordinates that the D-SAG-6 motor reads. This plan's per-cell ON×WHEN×DO registry is that binding for behaviour. Three D-SAG-6 gates apply to it directly: F07 (a DR ordinal from another frame is refused, which D8's frame-keyed register copy enforces), F11 (a changed source SHA under a retained recipe id must invalidate or rebind, which D5 meets by re-routing to a new derived classid rather than mutating behaviour), and F06 (an unregistered cell is UNKNOWN, never "no behaviour"). (PROPOSED) + +**A behaviour registration references ordered behaviour, never only a DO set.** CR-H0's negative mold shows two methods with the same unordered reads/writes (`*x = 1; *x += 1` versus the reverse) that give different results. A DO bitmap, or a deduplicated SPO bag, cannot tell them apart. So classid → polyfill (D4) must point at a recipe or ordered event record that carries effect order. The DO bit is only candidate presence, as #1819 already says. Under a lossy projection the honest answer is UNKNOWN. (PROPOSED) + **Only routing is versioned.** DR64 maps a position to a classid and changes between versions. The classid → behaviour binding in DT64 does not change. Replay "as of version v" means which classid each address routed to at v; that classid's behaviour is the same as it is today. (PROPOSED reading of D5) **Override = a new derived classid plus a re-route.** odoo-rs models an override as `Retract` plus `Register` at one cell. Under D5 an override registers a new classid and re-routes the cell to it. The old binding stays readable forever. A `Retract` may remove a route; it must never alter a classid's behaviour. (PROPOSED) @@ -171,4 +177,5 @@ All OPEN. - lance-graph [#1760](https://github.com/AdaWorldAPI/lance-graph/pull/1760), [#1792](https://github.com/AdaWorldAPI/lance-graph/pull/1792), [#1794](https://github.com/AdaWorldAPI/lance-graph/pull/1794), [#1795](https://github.com/AdaWorldAPI/lance-graph/pull/1795), [#1796](https://github.com/AdaWorldAPI/lance-graph/pull/1796), [#1797](https://github.com/AdaWorldAPI/lance-graph/pull/1797), [#1798](https://github.com/AdaWorldAPI/lance-graph/pull/1798), [#1799](https://github.com/AdaWorldAPI/lance-graph/pull/1799), [#1814](https://github.com/AdaWorldAPI/lance-graph/pull/1814) (merged, docs), [#1819](https://github.com/AdaWorldAPI/lance-graph/pull/1819) (merged, docs). - odoo-rs [#44](https://github.com/AdaWorldAPI/odoo-rs/pull/44), [#45](https://github.com/AdaWorldAPI/odoo-rs/pull/45), [#46](https://github.com/AdaWorldAPI/odoo-rs/pull/46) (test-only lab and harvest schema). - OGAR [#363](https://github.com/AdaWorldAPI/OGAR/pull/363) (`ogit_schema_composition.rs`). +- crai-rs #1 and #2, CR-H0 / CR-H1 (private repo; the #1760 successor map; links resolve only with access). - Board coordination: Linear EXO-50 (append-only; coordination, not approval). From 588daf0641ab40dfe0873edb6037b92bbac3931c Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 28 Oct 2026 01:36:03 +0000 Subject: [PATCH 07/11] docs(D-DT64-6): ground odoo-rs #46 as the Odoo intake to the per-cell registry Searched odoo-rs, OGAR, crai-rs, lance-graph and ndarray for the #1760 lineage. Besides crai-rs CR-H0/H1, odoo-rs #46 (Odoo Codegraph harvest schema, docs) is the one successor; OGAR and ndarray have none. Read #46's doc and schema in full. Its `dt64_candidates` array (source nodes -> existing algebra_ref, no seat mint) is the registry's Odoo intake; every emitted_by MethodId is kept; effective behaviour needs a registry_snapshot in the frame. Open question 2 (inheritance before the cell lookup) is narrowed by #46's _inherit / _inherits rules. Notes that #46's doc lists dt64_candidates as a graph layer while its schema does not. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01XAqKMNiyjwqFke9CfmoBgn --- .../2026-10-28-d-dt64-6-routing-bindstore-behavior.md | 7 +++++++ .claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md | 5 ++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md b/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md index 2f5faff8f..ae894a2b1 100644 --- a/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md +++ b/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md @@ -46,6 +46,13 @@ REVISIT WHEN form (plan §1): and requires a behaviour registration to reference ordered effects, since a DO set or deduplicated SPO bag cannot separate `*x = 1; *x += 1` from its reverse. +- odoo-rs #46 (Odoo Codegraph harvest schema, docs) is the Odoo intake: + its `dt64_candidates` array (source nodes → existing `algebra_ref`, + no seat mint) feeds the per-cell registry, every + `emitted_by` MethodId is kept (the single-emitter map lost 26 / 37 + edges), and effective behaviour needs a pinned `registry_snapshot`. + It narrows open question 2 (inheritance before the cell lookup). + Searched OGAR and ndarray too: no #1760 / D-SAG-6 successor there. - `lance-graph-ontology::ttl_parse` leaves `ogit:allowed` unexpanded (`ttl_parse.rs` module doc, "What this parser handles today"). The typed verb signature table exists only in OGAR `OgitTables::Allowed`, and OGAR depends on lance-graph-ontology. diff --git a/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md b/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md index d4ab29e0a..2b4d83b37 100644 --- a/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md +++ b/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md @@ -84,6 +84,7 @@ What exists today. "odoo-rs" (main @558f12a), "OGAR" (main @6b43a48) and #1814 a | OGIT counts: 523 verb files, 378 used verbs, 2,894 allowed edges over 941 entities; per-class p95 10, max 123, 2 classes above 64 | CURRENT-CONTRACT (doc report, not recomputed) | `odoo-rs:docs/DT64-ON-WHEN-DO-REGISTRY.md:139-169` | | Odoo slice 1: ON 194 × WHEN 5 × DO 219; 628 live registrations; 8 multi-method cells | CURRENT-CONTRACT (doc report of a first run; the test file pins no literals) | `odoo-rs:docs/DT64-ON-WHEN-DO-REGISTRY.md:200-210` | | D-SAG-6 (#1760, unchanged since merge): Codegraph → Mathematics → Logic → Tracert over typed read-only views; distinct node identities (SourceDefId, MIRBodyId, Method/ClassId, RecipeId among them); evidence grades kept apart; changed source SHA with retained recipe or callsite ids must invalidate or rebind (F11); the same DR ordinal in another frame is refused (F07); unexamined regions are UNKNOWN (F06) | CURRENT-CONTRACT (plan, docs only) | `.claude/plans/d-sag-6-rust-codegraph-math-logic-tracert-v1.md`, sections "Minimal graph contract" and "Falsification matrix, preregistered" | +| odoo-rs #46 (merged, docs plus an optional JSON Schema and example; nothing run): an Odoo Codegraph harvest view whose nodes and edges carry one of four graph partitions (`structural`, `odoo-declared`, `odoo-effective`, `documentation`) and an evidence record (basis, status, knownness). Beside them, a top-level `dt64_candidates` array maps `source_node_ids` to an `algebra_ref`, with an optional existing `predicate_ref` and status `proposed`, `needs_attestation` or `refused`. It "does not create DT64 seats or grant algebra/DO authority". (The doc's table lists `dt64_candidates` as a fifth layer; the schema's `graph` enum does not, so the two disagree.) Every `emitted_by` MethodId must be kept: `RecomputeDag::from_triples`'s single-emitter map loses 26 edges in slice 1 and 37 in slice 2 (a #44 measurement as reported). An `effective_registry_observation` export must carry a `registry_snapshot` (`observation_id`, `addon_set_digest`, `registry_fingerprint`). Missing triggers, calls or ACLs are UNKNOWN | PROPOSED (other repo, read in full here) | `odoo-rs:docs/ODOO-CODEGRAPH-DT64-HARVEST-V1.md`, sections "Proposed mapping", "Identity and inheritance are not simple name edges" and "Multiple emitters and declared compute ordering"; `odoo-rs:schemas/odoo-codegraph-harvest-v1.schema.json` | | The successor to #1760 is crai-rs CR-H0 / CR-H1 (crai-rs #1 and #2, private repo, `main` @378a24a). It maps #1760 and #1813–#1830 onto one design: D-SAG-6 is the motor; Ruff harvest plus DT64 versioned bindings are the transmission; ON×WHEN×DO from #1814 is "source intake and guard ledger"; the deduplicated SPO view is lossy, so behaviour needs a separate ordered event lane | PROPOSED (research docs, other repo, read in full here) | `crai-rs:docs/CR-H0-CHASSIS-RETROFIT-MAP.md`, sections 1–4; `crai-rs:docs/CR-H0-RUFF-REVERSE-MOLD.md`, sections 2 and 4; `crai-rs:docs/CR-H1-SPOG-GROK-EXPORT-CROSSWALK.md`, section "The actual minimal export seam" | ## 3. Design consequences @@ -110,6 +111,8 @@ Everything in this section is WORKING-MODEL or PROPOSED. None of it is decided b **DT64-6 is the binding layer of the D-SAG-6 transmission.** In the #1760 successor design (crai-rs CR-H0), Ruff harvests source structure and DT64 binds it to versioned, source-witnessed coordinates that the D-SAG-6 motor reads. This plan's per-cell ON×WHEN×DO registry is that binding for behaviour. Three D-SAG-6 gates apply to it directly: F07 (a DR ordinal from another frame is refused, which D8's frame-keyed register copy enforces), F11 (a changed source SHA under a retained recipe id must invalidate or rebind, which D5 meets by re-routing to a new derived classid rather than mutating behaviour), and F06 (an unregistered cell is UNKNOWN, never "no behaviour"). (PROPOSED) +**The Odoo intake to the registry is odoo-rs #46's `dt64_candidates` array.** A DR#3 cell's registrations come from those entries, each pointing at an existing `algebra_ref` (the polyfill of D4): one entry per source MethodId, every `emitted_by` emitter kept, never collapsed by the single-emitter map. They stay candidates until a binding is witnessed. Effective behaviour, after inheritance and module order, is admitted only under a pinned registry observation (#46's `registry_snapshot`: `observation_id`, `addon_set_digest`, `registry_fingerprint`), which belongs to the frame the D8 register copy is keyed to. (PROPOSED) + **A behaviour registration references ordered behaviour, never only a DO set.** CR-H0's negative mold shows two methods with the same unordered reads/writes (`*x = 1; *x += 1` versus the reverse) that give different results. A DO bitmap, or a deduplicated SPO bag, cannot tell them apart. So classid → polyfill (D4) must point at a recipe or ordered event record that carries effect order. The DO bit is only candidate presence, as #1819 already says. Under a lossy projection the honest answer is UNKNOWN. (PROPOSED) **Only routing is versioned.** DR64 maps a position to a classid and changes between versions. The classid → behaviour binding in DT64 does not change. Replay "as of version v" means which classid each address routed to at v; that classid's behaviour is the same as it is today. (PROPOSED reading of D5) @@ -148,7 +151,7 @@ Each stage is docs or lab work needing its own approval. None is authorized by t All OPEN. 1. Which unit is immutable: a `(classid, DT64 binding version)` entry, or one classid per revision? The second reopens the bit-placement question. This conflicts with D5's wording "classid behaviour is permanently immutable". -2. Does per-class inheritance resolution (`_inherit`, C3 order, odoo-rs §9 P6) run before the cell lookup? +2. Does per-class inheritance resolution (`_inherit`, C3 order, odoo-rs §9 P6) run before the cell lookup? odoo-rs #46 narrows it without answering it: `_inherit` without `_name` extends a model in place, `_name` plus `_inherit` is classical inheritance, and `_inherits` delegates fields but not Python methods. Each extending declaration keeps its own identity, and the effective model is known only from a pinned registry observation. So a cell's registrations would be per declaration, and resolution would need that observation as part of the frame. 3. Coexisting methods in one cell: odoo-rs reports a "collision" (`odoo-rs:docs/DT64-ON-WHEN-DO-REGISTRY.md:98-99`). Merged #1819 settles the direction: several mappings and convergence are normal and must all be kept, and a real conflict needs incompatible source-qualified results under the same fully typed coordinate and snapshot plus an applicable domain law. Still open: whether odoo-rs's "collision" cells meet that bar or are ordinary convergence. 4. WHEN has no attested source data. The Odoo corpus carries only check-method kinds. 5. The Q0 line 9 amendment in §4 is not accepted yet. From 32e8d07af0c7e559fb8a75727e8875fd2fba8aa1 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 28 Oct 2026 01:56:48 +0000 Subject: [PATCH 08/11] D-DT64-6: address review on #1831 (OGIT readers, D-DT64-6-1a, Q0 contract) - The two OGIT readers see disjoint verb sets: ttl_parse `classify` accepts the 12 rdfs:Class verbs (all WorkOrder, all ogit:from-to), OGAR `parse_verb` the 511 owl:ObjectProperty verbs, of 523. Measured over an unpinned OGIT clone (b5731a8, receipt only). - Add D-DT64-6-1a: classify every verb file in both readers first. - D-DT64-6-2 builds (src, verb, dst) from the entity ogit:allowed blocks (960 files, none in verbs/) plus the 12 from-to verbs, reads OGAR's OgitTables::Allowed instead of adding a second parser, and puts the standing parity test beside tests/ontology_cache.rs. - 518 / 2,756 is OGAR #363's reader output (eaw-5), not OGIT drift. - crai-rs CR-H0/H1 is a sidecar consumer of #1760, not its successor; its open-PR list is dated 2026-10-27. - Ruff has no Rust frontend; role names checked in ruff role.rs. - Cite D-DT64-Q0 by section, not line 9; INTEGRATION_PLANS says eight decisions. Docs only. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01XAqKMNiyjwqFke9CfmoBgn --- .claude/board/INTEGRATION_PLANS.md | 2 +- ...-28-d-dt64-6-routing-bindstore-behavior.md | 19 ++++++++--- .../d-dt64-6-routing-bindstore-behavior-v1.md | 33 +++++++++++-------- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/.claude/board/INTEGRATION_PLANS.md b/.claude/board/INTEGRATION_PLANS.md index ea55a3c74..fa01af9fd 100644 --- a/.claude/board/INTEGRATION_PLANS.md +++ b/.claude/board/INTEGRATION_PLANS.md @@ -1,6 +1,6 @@ ## 2026-10-28 — D-DT64-6: DR64 routing, DT64 bind store, per-cell WHEN×ON×DO behaviour, OGIT reference predicates → `.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md` -**Status:** PROPOSED, docs only; nothing authorized. **Board:** [entry](entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md), [STATUS_BOARD](STATUS_BOARD.md) D-DT64-6. Records seven user decisions (three DT64 levels; primary DR#3 Identity × Properties; WHEN×ON×DO per DR#3 cell; DR64 = direct routing, DT64 = DTO bind store; immutable classid → behaviour via hotplug; global needs no classid; OGIT read unpinned) and stages D-DT64-6-0..5 (OGIT reader reconciliation, `ogit:allowed` expansion in lance-graph-ontology, DT64 predicate registration, consumer HotPlug access). Requests an amendment to D-DT64-Q0 line 9 (persistent binding store); not applied. +**Status:** PROPOSED, docs only; nothing authorized. **Board:** [entry](entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md), [STATUS_BOARD](STATUS_BOARD.md) D-DT64-6. Records eight user decisions (three DT64 levels; primary DR#3 Identity × Properties; WHEN×ON×DO per DR#3 cell; DR64 = direct routing, DT64 = DTO bind store; immutable classid → behaviour via hotplug; global needs no classid; OGIT read unpinned; DR64 references existing identity and the global→local prefetch holds a frame-keyed register copy) and stages D-DT64-6-0..5 with 6-1a (classify the verb files both readers miss: lance-graph accepts 12, OGAR 511, of 523), OGIT reader reconciliation, one `(src, verb, dst)` table from the entity `ogit:allowed` blocks with no second parser, DT64 predicate registration, consumer HotPlug access. Requests an amendment to D-DT64-Q0's "One-sentence contract" (persistent binding store); not applied. **Confidence:** plan row only; stages unstarted. ## 2026-10-26 — D-TFLP v2: synergy revision → `.claude/plans/d-tflp-tflite-palette-polyfill-capstone-v2.md` diff --git a/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md b/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md index ae894a2b1..6a8eff5ad 100644 --- a/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md +++ b/.claude/board/entries/2026-10-28-d-dt64-6-routing-bindstore-behavior.md @@ -39,8 +39,8 @@ REVISIT WHEN form (plan §1): two-valued OR of atoms; #1819 makes convergence of several mappings normal. The plan's dispatch fold and its collision question now follow both. -- #1760 (D-SAG-6) is carried forward by crai-rs CR-H0 / CR-H1 (crai-rs #1 - and #2, private): D-SAG-6 is the motor, Ruff + DT64 the transmission, +- #1760 (D-SAG-6) is consumed by crai-rs CR-H0 / CR-H1 (crai-rs #1 and #2, + private), a sidecar retrofit and not a successor: D-SAG-6 is the motor, Ruff + DT64 the transmission, #1814's ON×WHEN×DO the guard ledger. The plan places DT64-6 as that transmission's behaviour binding, applies D-SAG-6 F06 / F07 / F11 to it, and requires a behaviour registration to reference ordered effects, @@ -56,14 +56,25 @@ REVISIT WHEN form (plan §1): - `lance-graph-ontology::ttl_parse` leaves `ogit:allowed` unexpanded (`ttl_parse.rs` module doc, "What this parser handles today"). The typed verb signature table exists only in OGAR `OgitTables::Allowed`, and OGAR depends on lance-graph-ontology. +- The two OGIT readers see disjoint verb sets. Of 523 verb files (OGIT + `b5731a8`, receipt only), `ttl_parse` `classify` accepts the 12 + `rdfs:Class` verbs (all WorkOrder, all with `ogit:from-to`) and OGAR + `parse_verb` the 511 `owl:ObjectProperty` verbs. `ogit:allowed` sits in + 960 entity-side files and in no verb file, so the `(src, verb, dst)` + table comes from entity blocks. 518 / 2,756 is OGAR #363's reader output + (eaw-5), a reader difference, not OGIT drift. Hence D-DT64-6-1a, and + D-DT64-6-2 reads OGAR's table instead of adding a second parser. +- Ruff has no Rust frontend (`ruff_*_spo`: C++, C#, MeTTa, Python, Ruby, + SQLAlchemy); the role names #1814 cites are `PredicateRole` bits in + `ruff_spo_triplet/src/role.rs`. - "Direct routing" already names position → executable maps in `crates/dir-rmap-probe/tests/classview_dr.rs` (doc on `type Route`). -- `D-DT64-Q0` line 9 forbids "the persistent Binding Store"; decision 4 +- `D-DT64-Q0`'s "One-sentence contract" forbids "the persistent Binding Store"; decision 4 needs an amendment there. Requested in plan §4, not applied. ## Open Plan §6: the immutable unit; inheritance before cell lookup; collision vs convergence for coexisting methods; WHEN has no attested source; the Q0 -amendment; the capstone's "targets" axis vs Identity × Property; 64-wide +contract amendment; the capstone's "targets" axis vs Identity × Property; 64-wide blocks vs the #1819 256² plane; EXO-46, EXO-148 and NFR-OP-2. diff --git a/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md b/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md index 2b4d83b37..49701a177 100644 --- a/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md +++ b/.claude/plans/d-dt64-6-routing-bindstore-behavior-v1.md @@ -70,6 +70,9 @@ What exists today. "odoo-rs" (main @558f12a), "OGAR" (main @6b43a48) and #1814 a | `CapabilityAuthority::activate` takes a `HotPlug` and returns an `Activation` or an `ActivationDrift` | VERIFIED-IN-CODE | `crates/lance-graph-contract/src/hotplug.rs`, trait `CapabilityAuthority` | | The `HotPlug` declaration is a compile-time const; verification is the `activate` call, run once in the consumer | WORKING-MODEL | reading of the `hotplug.rs` module doc comment, role 3 | | `ttl_parse` builds `LinkSpec` with placeholder subject/object types; `ogit:from-to` and `ogit:allowed` are not yet expanded | VERIFIED-IN-CODE | `crates/lance-graph-ontology/src/ttl_parse.rs`, module doc section "What this parser handles today" | +| `ttl_parse` `classify` makes a subject a verb only for `a rdfs:Class` plus `rdfs:subClassOf ogit:Verb`. A verb written `a owl:ObjectProperty; rdfs:subPropertyOf ogit:Verb` falls to `SubjectKind::Other` and yields no proposal | VERIFIED-IN-CODE | `crates/lance-graph-ontology/src/ttl_parse.rs`, fn `classify` | +| OGAR's verb reader is the exact complement: `parse_verb` returns `None` unless the file contains `a owl:ObjectProperty`, so the `rdfs:Class` verbs are rejected there. `extract_allowed_block` reads one `[ verb target ]` pair per line from the first `ogit:allowed (`…`)`; `OgitTables::load` keeps a tuple only when both verb and target resolve, and reports the rest as `Unresolved` | VERIFIED-IN-CODE (other repo) | `OGAR:crates/ogar-from-schema/src/sgo.rs`, fn `parse_verb`; `OGAR:crates/ogar-from-schema/src/ttl.rs`, fn `extract_allowed_block`; `OGAR:crates/ogar-action-handler/src/ogit.rs`, fn `OgitTables::load` | +| OGIT verb files: 523. Of these, 12 are `a rdfs:Class; rdfs:subClassOf ogit:Verb`, all under `NTO/WorkOrder/verbs/` and all carrying `ogit:from-to`; 511 are `a owl:ObjectProperty; rdfs:subPropertyOf ogit:Verb`. `ogit:allowed` occurs in 960 files, none under a `verbs/` directory. So neither reader sees every verb: lance-graph sees 12, OGAR 511 | MEASURED (`find -path '*/verbs/*.ttl'` plus per-pattern file counts over an unpinned OGIT clone, commit `b5731a8`, receipt only; three sample files read in full) | AdaWorldAPI/OGIT, `NTO/WorkOrder/verbs/Assigned.ttl`, `NTO/Compliance/verbs/financiallySupports.ttl`, `NTO/MARS/entities/Machine.ttl` | | The three DT64 plans (capstone, DT64-1, Q0) do not name ON, WHEN or DO; their third axis is predicates. ON×WHEN×DO is established in merged lance-graph research docs instead: the D-CFA series (logical ON×WHEN×DO incidence S1, a method-analysis view kept separate from the DT64-0 catalogue, with K3 WHEN guards and ablation over it) and the EAW series (Identity × Property/Edge × Predicate with ON/WHEN/DO as typed mapping roles, the logical third axis kept open under NFR-OP-2), plus #1819's factored ON×DO plane | CURRENT-CONTRACT (plans) and CURRENT-CONTRACT (research docs, not implementations) | the three plans; `docs/research/counterfactual-behavior/` (README, `cfa-1`, `cfa-2`, `cfa-4`, `thought-dependency-scratchpad`); `docs/research/epistemic-awareness/` (`eaw-1`, `eaw-2`, `eaw-5`, `eaw-6`, `eaw-10`, `dr64c-epistemic-awareness-scratchpad-20261027`); all read in full on 2026-10-28 | | Capstone: the Odoo method fold is listed as missing | CURRENT-CONTRACT | `.claude/plans/d-dt64-holographic-predicate-capstone-v1.md`, section "Evidence and non-goals" | | Capstone: 64×64×64 = 262,144 cells = 32 KiB dense; never eagerly allocate a cube for an 8- or 23-field question | CURRENT-CONTRACT | `.claude/plans/d-dt64-holographic-predicate-capstone-v1.md`, section "Logical capacity and materialization" | @@ -82,10 +85,11 @@ What exists today. "odoo-rs" (main @558f12a), "OGAR" (main @6b43a48) and #1814 a | OGAR `OgitTables` has five tables incl. `Allowed` with `src`, `verb`, `dst` as `u32` lanes; refuses a table past 65,536 rows | VERIFIED-IN-CODE (other repo) | `OGAR:crates/ogar-action-handler/src/ogit.rs:1-14,17` | | OGAR depends on `lance-graph-ontology` (optional, feature `ontology-cache`), so the reverse edge would be a cycle | VERIFIED-IN-CODE (other repo) | `OGAR:crates/ogar-action-handler/Cargo.toml:27` | | OGIT counts: 523 verb files, 378 used verbs, 2,894 allowed edges over 941 entities; per-class p95 10, max 123, 2 classes above 64 | CURRENT-CONTRACT (doc report, not recomputed) | `odoo-rs:docs/DT64-ON-WHEN-DO-REGISTRY.md:139-169` | +| OGAR #363's reader: 939 types, 518 verbs, 2,756 allowed edges, 4,861 chainable verb pairs; 102 rejected files and 508 unresolved references, which are UNKNOWN coverage, never negative edges. A different reader output, not an OGIT change: never merged with 523 / 2,894 | CURRENT-CONTRACT (doc report, not recomputed) | `docs/research/epistemic-awareness/eaw-5-odoo-ogit-law-and-learning-reality-check.md`, the OGAR #363 paragraph | | Odoo slice 1: ON 194 × WHEN 5 × DO 219; 628 live registrations; 8 multi-method cells | CURRENT-CONTRACT (doc report of a first run; the test file pins no literals) | `odoo-rs:docs/DT64-ON-WHEN-DO-REGISTRY.md:200-210` | | D-SAG-6 (#1760, unchanged since merge): Codegraph → Mathematics → Logic → Tracert over typed read-only views; distinct node identities (SourceDefId, MIRBodyId, Method/ClassId, RecipeId among them); evidence grades kept apart; changed source SHA with retained recipe or callsite ids must invalidate or rebind (F11); the same DR ordinal in another frame is refused (F07); unexamined regions are UNKNOWN (F06) | CURRENT-CONTRACT (plan, docs only) | `.claude/plans/d-sag-6-rust-codegraph-math-logic-tracert-v1.md`, sections "Minimal graph contract" and "Falsification matrix, preregistered" | | odoo-rs #46 (merged, docs plus an optional JSON Schema and example; nothing run): an Odoo Codegraph harvest view whose nodes and edges carry one of four graph partitions (`structural`, `odoo-declared`, `odoo-effective`, `documentation`) and an evidence record (basis, status, knownness). Beside them, a top-level `dt64_candidates` array maps `source_node_ids` to an `algebra_ref`, with an optional existing `predicate_ref` and status `proposed`, `needs_attestation` or `refused`. It "does not create DT64 seats or grant algebra/DO authority". (The doc's table lists `dt64_candidates` as a fifth layer; the schema's `graph` enum does not, so the two disagree.) Every `emitted_by` MethodId must be kept: `RecomputeDag::from_triples`'s single-emitter map loses 26 edges in slice 1 and 37 in slice 2 (a #44 measurement as reported). An `effective_registry_observation` export must carry a `registry_snapshot` (`observation_id`, `addon_set_digest`, `registry_fingerprint`). Missing triggers, calls or ACLs are UNKNOWN | PROPOSED (other repo, read in full here) | `odoo-rs:docs/ODOO-CODEGRAPH-DT64-HARVEST-V1.md`, sections "Proposed mapping", "Identity and inheritance are not simple name edges" and "Multiple emitters and declared compute ordering"; `odoo-rs:schemas/odoo-codegraph-harvest-v1.schema.json` | -| The successor to #1760 is crai-rs CR-H0 / CR-H1 (crai-rs #1 and #2, private repo, `main` @378a24a). It maps #1760 and #1813–#1830 onto one design: D-SAG-6 is the motor; Ruff harvest plus DT64 versioned bindings are the transmission; ON×WHEN×DO from #1814 is "source intake and guard ledger"; the deduplicated SPO view is lossy, so behaviour needs a separate ordered event lane | PROPOSED (research docs, other repo, read in full here) | `crai-rs:docs/CR-H0-CHASSIS-RETROFIT-MAP.md`, sections 1–4; `crai-rs:docs/CR-H0-RUFF-REVERSE-MOLD.md`, sections 2 and 4; `crai-rs:docs/CR-H1-SPOG-GROK-EXPORT-CROSSWALK.md`, section "The actual minimal export seam" | +| crai-rs CR-H0 / CR-H1 (crai-rs #1 and #2, private repo, `main` @378a24a) are a consumer of #1760, not its successor: a sidecar retrofit around the D-SAG-6 motor, which stays owned by D-SAG-6 and its plans. CR-H0 lists #1813–#1830 as open "as checked 2026-10-27"; #1814 and #1819 have merged since, so that list is dated. It maps #1760 and #1813–#1830 onto one design: D-SAG-6 is the motor; Ruff harvest plus DT64 versioned bindings are the transmission; ON×WHEN×DO from #1814 is "source intake and guard ledger"; the deduplicated SPO view is lossy, so behaviour needs a separate ordered event lane | PROPOSED (research docs, other repo, read in full here) | `crai-rs:docs/CR-H0-CHASSIS-RETROFIT-MAP.md`, sections 1–4; `crai-rs:docs/CR-H0-RUFF-REVERSE-MOLD.md`, sections 2 and 4; `crai-rs:docs/CR-H1-SPOG-GROK-EXPORT-CROSSWALK.md`, section "The actual minimal export seam" | ## 3. Design consequences @@ -109,7 +113,7 @@ Everything in this section is WORKING-MODEL or PROPOSED. None of it is decided b **The held register copy is keyed to its frame (D8).** The prefetch builds the local register once: local position → reference to an existing global identity. Reads in steps 1–4 of the dispatch order above go through that copy without re-resolving identities. The copy records the frame it was built under, and every read checks the frame first, as `FrameStore::check` does in `crates/dr-math-binding-probe/src/lib.rs`. Any refusal (`ForeignFrame`, `SourceChanged`, `MapChanged`, `CoordinatesChanged`, `FrameResealed`) drops the copy and re-prefetches. A new focus over the same frame reuses the copy, because a focus is not a new frame (same file, struct `Focus`). The measured cost must include building the copy, amortized over the reads it serves (Q0 Phase Q3). (PROPOSED) -**DT64-6 is the binding layer of the D-SAG-6 transmission.** In the #1760 successor design (crai-rs CR-H0), Ruff harvests source structure and DT64 binds it to versioned, source-witnessed coordinates that the D-SAG-6 motor reads. This plan's per-cell ON×WHEN×DO registry is that binding for behaviour. Three D-SAG-6 gates apply to it directly: F07 (a DR ordinal from another frame is refused, which D8's frame-keyed register copy enforces), F11 (a changed source SHA under a retained recipe id must invalidate or rebind, which D5 meets by re-routing to a new derived classid rather than mutating behaviour), and F06 (an unregistered cell is UNKNOWN, never "no behaviour"). (PROPOSED) +**DT64-6 is the binding layer of the D-SAG-6 transmission.** In the crai-rs CR-H0 sidecar design around #1760, Ruff harvests source structure and DT64 binds it to versioned, source-witnessed coordinates that the D-SAG-6 motor reads. This plan's per-cell ON×WHEN×DO registry is that binding for behaviour. Three D-SAG-6 gates apply to it directly: F07 (a DR ordinal from another frame is refused, which D8's frame-keyed register copy enforces), F11 (a changed source SHA under a retained recipe id must invalidate or rebind, which D5 meets by re-routing to a new derived classid rather than mutating behaviour), and F06 (an unregistered cell is UNKNOWN, never "no behaviour"). Ruff has no Rust frontend: its SPO crates on `main` are C++, C#, MeTTa, Python, Ruby and SQLAlchemy (`ruff:crates/`, `ruff_*_spo`), so for Rust sources this transmission has no harvester yet. (PROPOSED) **The Odoo intake to the registry is odoo-rs #46's `dt64_candidates` array.** A DR#3 cell's registrations come from those entries, each pointing at an existing `algebra_ref` (the polyfill of D4): one entry per source MethodId, every `emitted_by` emitter kept, never collapsed by the single-emitter map. They stay candidates until a binding is witnessed. Effective behaviour, after inheritance and module order, is admitted only under a pinned registry observation (#46's `registry_snapshot`: `observation_id`, `addon_set_digest`, `registry_fingerprint`), which belongs to the frame the D8 register copy is keyed to. (PROPOSED) @@ -121,17 +125,17 @@ Everything in this section is WORKING-MODEL or PROPOSED. None of it is decided b **Consumer composed classid as the derived DTO classid.** For a consumer, the derived DTO classid can be its own composed `u32` (`concept << 16 | app prefix`, `hotplug.rs`, doc comment on `Activation::read_modes`). OGAR mints the concept once, the app prefix is the consumer's, and hotplug activates the pair. No new bits, no extra mint, no reuse of the render prefix. Global revisions are versioned in DT64 directly and need no classid (D6). OGAR doctrine says the low half chooses the render skin and neither half carries behaviour; DT64 stores the resolution and the classid stays an address. (PROPOSED; the doctrine is from `OGAR CLAUDE.md`, not re-read here) -## 4. Amendment requested to D-DT64-Q0 line 9 +## 4. Amendment requested to D-DT64-Q0, section "One-sentence contract" -Q0 line 9 reads, verbatim: +The Q0 contract sentence reads, verbatim: > The binding is an *interface seam*, not a second copy of business data and not the persistent Binding Store generalized in old plans. Do not invent a FrameStore, tensor physical allocation, predicate evaluator, Odoo executor, ONNX interpreter or new RelAlg AST. -**The conflict.** D4 makes DT64 a bind store with versioned, replayable immutability. Read literally, Q0 line 9 forbids a persistent binding store. +**The conflict.** D4 makes DT64 a bind store with versioned, replayable immutability. Read literally, the Q0 contract forbids a persistent binding store. -**Proposed reading.** "Store" means bindings and their version log. It never means copied business data. The user's rule of "no value duplicates" (D1) supports that reading. The rest of line 9 is unchanged: no FrameStore as a data holder, no tensor allocation, no predicate evaluator, no Odoo executor, no ONNX interpreter, no new RelAlg AST. +**Proposed reading.** "Store" means bindings and their version log. It never means copied business data. The user's rule of "no value duplicates" (D1) supports that reading. The rest of the contract is unchanged: no FrameStore as a data holder, no tensor allocation, no predicate evaluator, no Odoo executor, no ONNX interpreter, no new RelAlg AST. -**Requested change.** A one-line addition to Q0 line 9 that states this reading. Until the owner accepts it, Q0 line 9 stands as written and this plan does not override it. (PROPOSED; this plan edits no other file) +**Requested change.** A one-line addition to the Q0 contract that states this reading. Until the owner accepts it, the contract stands as written and this plan does not override it. (PROPOSED; this plan edits no other file) ## 5. Staged work @@ -140,8 +144,9 @@ Each stage is docs or lab work needing its own approval. None is authorized by t | D-id | Deliverable | Falsifier | Owner | Gate | |---|---|---|---|---| | D-DT64-6-0 | This plan and its board entry (docs). | A reader finds a claim without an evidence state, or a decision labelled as technical truth. | lance-graph plan author | Docs review; no code. | -| D-DT64-6-1 | OGIT reader reconciliation. Run `lance-graph-ontology` `ttl_parse` and OGAR `OgitTables` over the SAME checkout in ONE run. Both print the same partition: accepted / rejected / duplicate / unresolved. Explain 523 files / 2,894 edges (odoo-rs §8) versus 518 / 2,756 (board claim for OGAR #363, NOT VERIFIED here). Record the observed OGIT commit as a provenance receipt only, never as a gate. | Totals fail to reconcile exactly after the partition is printed; or the receipt is used as a pin. | lance-graph-ontology and OGAR owners | Owner approval before code; read-only run. | -| D-DT64-6-2 | Expand `ogit:allowed` in `lance-graph-ontology` into a global, classid-free `(src type, verb, dst type)` table, replacing the placeholder `LinkSpec`. No second registry. | Pair-for-pair equality with OGAR `OgitTables::Allowed` fails; or a rejected / unresolved file is dropped instead of reported. | lance-graph-ontology owner | D-DT64-6-1 green; owner approval. | +| D-DT64-6-1a | Classify every OGIT verb file in BOTH readers before comparing them. Today lance-graph `ttl_parse` accepts the 12 `rdfs:Class` verbs and OGAR `parse_verb` the 511 `owl:ObjectProperty` verbs, so the two verb sets are disjoint. Each reader either accepts both forms or reports the other form as rejected, by file. | A verb file is in neither reader's accepted set nor its rejected report; or the two readers' verb sets differ after this step without a reported reason. | lance-graph-ontology and OGAR owners | Owner approval before code. | +| D-DT64-6-1 | OGIT reader reconciliation. Run `lance-graph-ontology` `ttl_parse` and OGAR `OgitTables` over the SAME checkout in ONE run. Both print the same partition: accepted / rejected / duplicate / unresolved. Explain 523 files / 2,894 edges (odoo-rs §8) versus 518 verbs / 2,756 edges (OGAR #363 reader, eaw-5) as two reader outputs over one tree; neither is an OGIT change. Record the observed OGIT commit as a provenance receipt only, never as a gate. | Totals fail to reconcile exactly after the partition is printed; or the receipt is used as a pin. | lance-graph-ontology and OGAR owners | D-DT64-6-1a green; owner approval before code; read-only run. | +| D-DT64-6-2 | Build the global, classid-free `(src type, verb, dst type)` table from the ENTITY files' `ogit:allowed` blocks (the 960 files that carry them; no verb file does), plus the 12 WorkOrder verbs' `ogit:from-to` pairs, with every unresolved verb or target reported. One reader owns the table. OGAR `OgitTables::Allowed` already is that table, so the default is to read it, not to grow a second expansion in `lance-graph-ontology`; the placeholder `LinkSpec` on verb proposals is replaced from it. A standing parity test belongs next to the existing cache/tables comparison in `OGAR:crates/ogar-action-handler/tests/ontology_cache.rs`. | Two parsers produce the table; or pair-for-pair equality across the two readers fails without a reported reason; or a rejected or unresolved file is dropped instead of reported. | lance-graph-ontology and OGAR owners | D-DT64-6-1 green; owner approval. | | D-DT64-6-3 | Register OGIT verbs as DT64 predicates in 64-wide blocks. 378 used verbs; p95 10, max 123 per class, 2 classes above 64 (odoo-rs §8). Ordinals are per frame, never global ids. | A global verb id appears in a descriptor; or a class above 64 verbs is truncated. | DT64 catalogue owner | D-DT64-6-2 green. | | D-DT64-6-4 | Consumer read-only access to the OGIT predicates through HotPlug activation. No consumer copy. | A consumer holds its own copy of the table. | consumer owner with OGAR authority | D-DT64-6-3 green; the `activate` call as in `hotplug.rs`, trait `CapabilityAuthority`. | | D-DT64-6-5 | Exit from reference-only. Once a real domain (Odoo or IAM) has source-attested predicates, OGIT becomes a cross-check oracle, not the authority. | OGIT disagrees with attested predicates and OGIT wins by default. | DT64 catalogue owner | One domain with source-attested predicates. | @@ -154,7 +159,7 @@ All OPEN. 2. Does per-class inheritance resolution (`_inherit`, C3 order, odoo-rs §9 P6) run before the cell lookup? odoo-rs #46 narrows it without answering it: `_inherit` without `_name` extends a model in place, `_name` plus `_inherit` is classical inheritance, and `_inherits` delegates fields but not Python methods. Each extending declaration keeps its own identity, and the effective model is known only from a pinned registry observation. So a cell's registrations would be per declaration, and resolution would need that observation as part of the frame. 3. Coexisting methods in one cell: odoo-rs reports a "collision" (`odoo-rs:docs/DT64-ON-WHEN-DO-REGISTRY.md:98-99`). Merged #1819 settles the direction: several mappings and convergence are normal and must all be kept, and a real conflict needs incompatible source-qualified results under the same fully typed coordinate and snapshot plus an applicable domain law. Still open: whether odoo-rs's "collision" cells meet that bar or are ordinary convergence. 4. WHEN has no attested source data. The Odoo corpus carries only check-method kinds. -5. The Q0 line 9 amendment in §4 is not accepted yet. +5. The Q0 contract amendment in §4 is not accepted yet. 6. Laws beyond Boolean associativity (inverse, symmetric, transitive) need instance evidence before admission (odoo-rs §11). 7. EXO-46 (global↔local admission), EXO-148 (durable identities for replay) and NFR-OP-2 (physical DR³ third axis) remain open. The levels here are logical. 8. The capstone's second axis is "targets" (Identity × Identity × Predicate), while D1 level 2 says Identity × Property × Predicate. D2 reads the capstone cube as the optional derived view. The owner of DT64-1..3 must confirm. @@ -165,12 +170,12 @@ All OPEN. - No code, ABI, test, runtime or merge authorization. This is a docs-only plan. - No 65K×65K dense matrix. No eager 64-property cube. No per-cell 32 KiB frame. - No new writer or persistence path. Persistence stays resident → squash/release → coalesced dirty rows → async writer (EXO-55). -- No second registry. D-DT64-6-2 replaces the placeholder `LinkSpec`. +- No second registry and no second `ogit:allowed` parser. D-DT64-6-2 replaces the placeholder `LinkSpec` from the one table. - No pins on OGIT. A provenance receipt records what was read; it never gates. - OGIT verbs are not Ruff `PredicateRole` bits and not the merged DT64 slot ids. - Laws (inverse, symmetric) stay unadmitted until instance evidence exists. Schema mirroring is not evidence (`OGAR:crates/ogar-action-handler/tests/ogit_schema_composition.rs:19-21`). -- The 518 / 2,756 figures are a board claim, not verified here, and are never merged with 523 / 2,894. -- The ruff role names are quoted, not checked against ruff: #1814 lists READS, DERIVES, EFFECTS, REQUIRES, AUTHORIZES and TRIGGERS; the odoo-rs list was read in another checkout. +- The 518 / 2,756 figures are OGAR #363's reader output (eaw-5) and are never merged with 523 / 2,894. +- The ruff role names cited by #1814 (READS, DERIVES, EFFECTS, REQUIRES, AUTHORIZES, TRIGGERS) are `PredicateRole` bits in `ruff:crates/ruff_spo_triplet/src/role.rs` on ruff `main`, read there; `DO_ARM` is EFFECTS | TRIGGERS and `PRECONDITION` is REQUIRES | AUTHORIZES. - ON, WHEN and DO are not DT64-0 slot terms; the three DT64 plans do not name them. They are established in the merged D-CFA and EAW research docs and #1819 (§2), which keep S1 separate from the DT64-0 catalogue and the third axis logical. - `ClassView::FieldMask` stays field presence, never predicate truth (capstone, section "Thesis and precise terminology"). - Do not cite the quarantined item. Nothing here derives from it. @@ -180,5 +185,5 @@ All OPEN. - lance-graph [#1760](https://github.com/AdaWorldAPI/lance-graph/pull/1760), [#1792](https://github.com/AdaWorldAPI/lance-graph/pull/1792), [#1794](https://github.com/AdaWorldAPI/lance-graph/pull/1794), [#1795](https://github.com/AdaWorldAPI/lance-graph/pull/1795), [#1796](https://github.com/AdaWorldAPI/lance-graph/pull/1796), [#1797](https://github.com/AdaWorldAPI/lance-graph/pull/1797), [#1798](https://github.com/AdaWorldAPI/lance-graph/pull/1798), [#1799](https://github.com/AdaWorldAPI/lance-graph/pull/1799), [#1814](https://github.com/AdaWorldAPI/lance-graph/pull/1814) (merged, docs), [#1819](https://github.com/AdaWorldAPI/lance-graph/pull/1819) (merged, docs). - odoo-rs [#44](https://github.com/AdaWorldAPI/odoo-rs/pull/44), [#45](https://github.com/AdaWorldAPI/odoo-rs/pull/45), [#46](https://github.com/AdaWorldAPI/odoo-rs/pull/46) (test-only lab and harvest schema). - OGAR [#363](https://github.com/AdaWorldAPI/OGAR/pull/363) (`ogit_schema_composition.rs`). -- crai-rs #1 and #2, CR-H0 / CR-H1 (private repo; the #1760 successor map; links resolve only with access). +- crai-rs #1 and #2, CR-H0 / CR-H1 (private repo; a sidecar consumer of #1760; links resolve only with access). - Board coordination: Linear EXO-50 (append-only; coordination, not approval). From 57c58adecf406aa1a8c0e808f4f20ec1eb3b80f2 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 28 Oct 2026 02:06:21 +0000 Subject: [PATCH 09/11] D-DT64-6: align STATUS_BOARD rows with the revised plan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the D-DT64-6-1a row and restate D-DT64-6-2 as reading OGAR OgitTables::Allowed rather than a second expansion in lance-graph-ontology, matching plan §5 after the #1831 review. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01XAqKMPWTwovjYJEUMuGPb4 --- .claude/board/STATUS_BOARD.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.claude/board/STATUS_BOARD.md b/.claude/board/STATUS_BOARD.md index 7d59bb0e3..2ca080c0d 100644 --- a/.claude/board/STATUS_BOARD.md +++ b/.claude/board/STATUS_BOARD.md @@ -5,8 +5,9 @@ | D-id | Deliverable | Status | Gate | |---|---|---|---| | D-DT64-6-0 | plan + board (docs) | In PR | docs review | -| D-DT64-6-1 | OGIT reader reconciliation: `ttl_parse` vs OGAR `OgitTables`, same checkout, one run, identical partition | Queued | owner approval; read-only | -| D-DT64-6-2 | expand `ogit:allowed` in lance-graph-ontology into a classid-free (src, verb, dst) table | Queued | D-DT64-6-1 green | +| D-DT64-6-1a | classify every OGIT verb file in both readers (today `ttl_parse` accepts the 12 `rdfs:Class` verbs, OGAR `parse_verb` the 511 `owl:ObjectProperty` verbs) | Queued | owner approval | +| D-DT64-6-1 | OGIT reader reconciliation: `ttl_parse` vs OGAR `OgitTables`, same checkout, one run, identical partition | Queued | D-DT64-6-1a green; owner approval; read-only | +| D-DT64-6-2 | classid-free (src, verb, dst) table from entity `ogit:allowed` blocks plus the 12 `ogit:from-to` verbs; default source OGAR `OgitTables::Allowed`, no second parser | Queued | D-DT64-6-1 green | | D-DT64-6-3 | register OGIT verbs as DT64 predicates in 64-wide blocks | Queued | D-DT64-6-2 green | | D-DT64-6-4 | consumer read-only access via HotPlug activation | Queued | D-DT64-6-3 green | | D-DT64-6-5 | OGIT becomes cross-check oracle once a domain has attested predicates | Queued | one attested domain | From 3a689c0fb11434efff0516740a845ca663833b78 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 30 Oct 2026 01:57:34 +0000 Subject: [PATCH 10/11] probe(dr-math): D-DRCA-3 DR #4 method routing falsifier Two methods on one cell with equal read/write sets and a different effect order stay two routed entries; so do two methods whose effects commute. A declared guard without its witness refuses. DT-owned values (method key, guard witness, effect-order reference) are carried opaque; the test's DT stub and the ported ndarray #395 order law are the oracle. Lab only: no DT resolver (D-CMH-1 owns it), no MethodKey mint, no contract change. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01XAqKMNiyjwqFke9CfmoBgn --- .../plans/d-drca-3-dr4-method-routing-v1.md | 85 +++ crates/dr-math-binding-probe/src/dr4.rs | 275 ++++++++++ crates/dr-math-binding-probe/src/lib.rs | 4 + .../tests/dr4_method_routing.rs | 513 ++++++++++++++++++ 4 files changed, 877 insertions(+) create mode 100644 .claude/plans/d-drca-3-dr4-method-routing-v1.md create mode 100644 crates/dr-math-binding-probe/src/dr4.rs create mode 100644 crates/dr-math-binding-probe/tests/dr4_method_routing.rs diff --git a/.claude/plans/d-drca-3-dr4-method-routing-v1.md b/.claude/plans/d-drca-3-dr4-method-routing-v1.md new file mode 100644 index 000000000..1dde8874d --- /dev/null +++ b/.claude/plans/d-drca-3-dr4-method-routing-v1.md @@ -0,0 +1,85 @@ +# D-DRCA-3: DR #4 method routing falsifier (lab) + +**Date:** 2026-10-30. **Status:** PROPOSED → implemented as a lab probe in +`crates/dr-math-binding-probe` (`src/dr4.rs`, `tests/dr4_method_routing.rs`). +**Parent:** D-DRDT (`d-drdt-dr-dt-ownership-amendment-v1.md`, #1835) §5 "Handoff: +DR #4", first falsifier. **Not:** a DT resolver, a MethodKey mint, an ABI, a +contract change, or method execution. + +## Overview + +#1835 §5 defines DR #4 as the route from a mapped coordinate set to a method +operation, and fixes what it must preserve and refuse. Its first falsifier: +*two methods on one cell with the same read/write sets and different effect +order must stay distinct through routing, and a dropped guard must refuse.* + +DR stores neither a method's meaning nor its effects (#1835 §1). So the lab +treats every DT-owned value as **opaque**: the method key, the signature +revision, the guard witness and the effect-order reference are carried, never +interpreted. The meaning lives in the test's DT stub, which is also the +oracle that proves two routed methods really are different. + +### Ownership boundaries kept + +- **Method identity is DT's, and is not minted here.** D-CMH + (`class-method-schema-hotplug-v1.md` §2.1, decision ledger item 2) leaves the + 16-byte `MethodKey` to the OGAR owner. The lab uses a test-minted + `[u8; 16]`, named as such. +- **The DT resolver is D-CMH-1's `PreparedClass`, not this probe.** No second + resolver, no contract type. `Resolution` here is a lab stand-in for DT's + answer, constructed only by the test. +- **The effect-order law is #395's** (ndarray `examples/pof_antennas/order_law.rs`: + `Effect`, `run_effects`, `commutes`, `check_reorder`), ported verbatim into + the test as the oracle. DR does not decide commutation. + +## Checklist + +- [x] Read the parent contract (#1835 §4–§5), D-CMH (§2.1, §7), the #395 order law, + and the existing lab API (`lib.rs`, `where_dr3.rs`, `hhtl16.rs`). +- [x] Tests first (`tests/dr4_method_routing.rs`), confirmed red before the module exists. +- [x] `src/dr4.rs`: `route` over one admitted `BoundDr64` and one `Resolution`. +- [x] Disable runs, each red on a named test. +- [x] README section, board entry, STATUS_BOARD row, entries index. + +## Contract under test + +`route(store, register, resolution, op, observed_guards) -> Result` + +**Preserves** (one output entry per input method, in input order): method key, +signature revision, read and write field sets, guard witness, effect-order +reference, and the register's frame. + +**Refuses**, in this order: + +| refusal | when | +|---|---| +| `Frame(Refusal)` | the register's frame is not its store's current seal | +| `ResolvedUnderOtherFrame` | DT resolved the methods under another frame issue (another revision, a reseal or another store, even at equal numbers) | +| `ForeignClass` | the resolution or a method belongs to another class than the register | +| `DuplicateMethod` | one method key appears twice (two keys with equal sets are fine) | +| `OutOfRegister` | the operation's coordinates are outside 64 × 64 | +| `UnsupportedAlgebra` | the method declares an algebra DR does not have (a numeric fold) | +| `NotBoolean` | a presence method over a three-valued register | +| `GuardDropped` / `GuardMismatch` | a declared guard has no witness, or another one | + +## Falsifiers + +1. Two methods, equal read/write sets, effects `[Set(1), Add(1)]` vs + `[Add(1), Set(1)]`: the oracle gives 2 vs 1 and `check_reorder` refuses the + swap; routing returns two entries with their own effect references. +2. Commuting effects (`[Add(2), Add(3)]` vs reversed): the oracle gives equal + results and the swap is legal; routing **still** returns two entries. + Merging is not DR's decision. +3. A required guard with no witness refuses; a different witness refuses; the + right witness is carried into the output. An unguarded method needs none. +4. Stale register frame, stale resolution, foreign store at equal numbers, + foreign class, duplicate key, out-of-register, numeric algebra, presence over + three-valued: each refuses with its own variant. +5. Values equal an independent scalar loop for cell, row and column, two- and + three-valued (K3 value masked by validity). + +## Not done + +DT resolver (D-CMH-1); MethodKey mint; guard evaluation (DR only carries +witnesses); effect execution; DR #4 over a `LocalSelection` (D-DRCA-2) or a +`Chain` composition; production placement. diff --git a/crates/dr-math-binding-probe/src/dr4.rs b/crates/dr-math-binding-probe/src/dr4.rs new file mode 100644 index 000000000..167d40db7 --- /dev/null +++ b/crates/dr-math-binding-probe/src/dr4.rs @@ -0,0 +1,275 @@ +//! D-DRCA-3: DR #4, method routing over one admitted register (lab only). +//! +//! DR #4 is the route from a mapped coordinate set to a method operation +//! (D-DRDT §5, lance-graph #1835). DR owns the coordinates and the fold; DT +//! owns what a method means. So every DT-owned value here is **opaque**: +//! +//! - [`MethodKey`]: the method's identity. Minted by the DT owner (D-CMH +//! §2.1); this lab never mints one and never derives one from a name. +//! - [`GuardWitness`]: evidence that DT's guard was evaluated. DR compares it +//! for equality and never evaluates a guard. +//! - [`EffectOrderRef`]: DT's reference to the method's ordered effects. DR +//! never runs, reorders or compares effects by meaning. +//! +//! # What routing preserves +//! +//! One [`RoutedMethod`] per input method, in input order: the key, the +//! signature revision, the read and write field sets, the guard witness and +//! the effect-order reference. Two methods with equal read/write sets and a +//! different effect order are two entries. So are two methods whose effects +//! commute: whether they may be merged is decided by the law owner, not by +//! routing. +//! +//! # What routing refuses +//! +//! In order: a stale register frame, a resolution made under another frame +//! issue, a foreign class, a duplicate key, coordinates outside 64 × 64, an +//! algebra DR does not have, a presence read over a three-valued register, +//! and a guard that was declared but not witnessed (or witnessed differently). +//! See [`Dr4Refusal`]. +//! +//! # What this module does not do +//! +//! It is not a DT resolver (that is D-CMH-1's `PreparedClass`), it stores +//! nothing, and it executes no effect. [`Resolution`] is DT's answer, handed +//! in by the caller. + +use lance_graph_contract::class_view::ClassId; + +use crate::hhtl16; +use crate::{BoundDr64, Frame, FrameStore, Population, Refusal, Truth}; + +/// A method's identity, minted by the DT owner. Opaque to DR. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct MethodKey(pub [u8; 16]); + +/// Evidence that a method's guard was evaluated. Opaque to DR. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct GuardWitness(pub [u8; 16]); + +/// DT's reference to a method's ordered effects. Opaque to DR. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct EffectOrderRef(pub [u8; 16]); + +/// The algebra a method declares for its operation over the register. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum Algebra { + /// Boolean presence over a two-valued, distinct register. + Presence, + /// Value and validity, three-valued; a two-valued register is known + /// everywhere. + PresenceK3, + /// A numeric fold. DR has no admitted numeric fold over DR64, so this + /// refuses. + NumericFold, +} + +/// Whether DT declared a guard for the method, and which. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum GuardDecl { + Unguarded, + Required(GuardWitness), +} + +/// One method as DT resolved it, as DR receives it. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct MethodRef { + pub class: ClassId, + pub key: MethodKey, + pub signature_rev: u32, + /// Field positions read and written (a `FieldMask`-width lab view). + pub reads: u64, + pub writes: u64, + pub guard: GuardDecl, + pub effects: EffectOrderRef, + pub algebra: Algebra, +} + +/// DT's answer for one class, and the frame it was resolved under. +#[derive(Clone, Debug)] +pub struct Resolution { + pub class: ClassId, + pub under: Frame, + pub methods: Vec, +} + +/// The operation routed over the register's coordinates. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Op { + Cell { x: u8, y: u8 }, + Row { x: u8 }, + Column { y: u8 }, +} + +/// What one method's algebra produced at the routed coordinates. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Value { + Bool(bool), + Mask(u64), + /// `value` is masked by `known`: an UNKNOWN cell never reads TRUE. + K3 { + value: u64, + known: u64, + }, +} + +/// One routed method: its DT references, unchanged, and its value. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct RoutedMethod { + pub key: MethodKey, + pub signature_rev: u32, + pub reads: u64, + pub writes: u64, + /// The witness the guard was checked against; `None` when unguarded. + pub guard: Option, + pub effects: EffectOrderRef, + pub value: Value, +} + +/// The routing result. No public constructor. +#[derive(Clone, Debug)] +pub struct Routed { + frame: Frame, + op: Op, + entries: Vec, +} + +impl Routed { + /// The frame the result was computed under. + pub fn frame(&self) -> &Frame { + &self.frame + } + pub fn op(&self) -> Op { + self.op + } + /// One entry per input method, in input order. + pub fn entries(&self) -> &[RoutedMethod] { + &self.entries + } +} + +/// Why a route was refused. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Dr4Refusal { + /// The register's frame is not its store's current seal. + Frame(Refusal), + /// DT resolved the methods under another frame issue. + ResolvedUnderOtherFrame, + /// The resolution, or one of its methods, is for another class. + ForeignClass, + /// One method key appears twice. + DuplicateMethod, + /// Coordinates outside 64 × 64. + OutOfRegister, + /// The method declares an algebra DR does not have. + UnsupportedAlgebra, + /// A presence read over a three-valued or bag register. + NotBoolean, + /// A declared guard has no witness. + GuardDropped, + /// A declared guard was witnessed with another value. + GuardMismatch, +} + +/// Route DT's methods for one class over one admitted register. +/// +/// `observed` holds the guard witnesses the caller obtained, keyed by method. +pub fn route( + store: &FrameStore, + register: &BoundDr64<'_>, + resolution: &Resolution, + op: Op, + observed: &[(MethodKey, GuardWitness)], +) -> Result { + store.check(®ister.frame).map_err(Dr4Refusal::Frame)?; + if !resolution.under.same_issue(®ister.frame) { + return Err(Dr4Refusal::ResolvedUnderOtherFrame); + } + let class = register.method.owner_class; + if resolution.class != class || resolution.methods.iter().any(|m| m.class != class) { + return Err(Dr4Refusal::ForeignClass); + } + for (i, m) in resolution.methods.iter().enumerate() { + if resolution.methods[..i].iter().any(|p| p.key == m.key) { + return Err(Dr4Refusal::DuplicateMethod); + } + } + let in_range = match op { + Op::Cell { x, y } => x < 64 && y < 64, + Op::Row { x } => x < 64, + Op::Column { y } => y < 64, + }; + if !in_range { + return Err(Dr4Refusal::OutOfRegister); + } + let boolean = register.method.truth == Truth::TwoValued + && register.method.population == Population::Distinct; + + let mut entries = Vec::with_capacity(resolution.methods.len()); + for m in &resolution.methods { + let value = match m.algebra { + Algebra::NumericFold => return Err(Dr4Refusal::UnsupportedAlgebra), + Algebra::Presence if !boolean => return Err(Dr4Refusal::NotBoolean), + Algebra::Presence => presence(register, op), + Algebra::PresenceK3 => presence_k3(register, op), + }; + let guard = match m.guard { + GuardDecl::Unguarded => None, + GuardDecl::Required(want) => { + let got = observed + .iter() + .find(|(k, _)| *k == m.key) + .map(|(_, w)| *w) + .ok_or(Dr4Refusal::GuardDropped)?; + if got != want { + return Err(Dr4Refusal::GuardMismatch); + } + Some(got) + } + }; + entries.push(RoutedMethod { + key: m.key, + signature_rev: m.signature_rev, + reads: m.reads, + writes: m.writes, + guard, + effects: m.effects, + value, + }); + } + Ok(Routed { + frame: register.frame.clone(), + op, + entries, + }) +} + +/// Boolean read; coordinates are already in range. +fn presence(r: &BoundDr64<'_>, op: Op) -> Value { + match op { + Op::Cell { x, y } => Value::Bool((r.rows[x as usize] >> y) & 1 == 1), + Op::Row { x } => Value::Mask(r.rows[x as usize]), + Op::Column { y } => Value::Mask(hhtl16::column(r.rows, y).unwrap_or(0)), + } +} + +/// Value and validity; a two-valued register is known everywhere. +fn presence_k3(r: &BoundDr64<'_>, op: Op) -> Value { + let all = [u64::MAX; 64]; + let validity = r.validity.unwrap_or(&all); + let (value, known) = match op { + Op::Cell { x, y } => { + let k = (validity[x as usize] >> y) & 1; + ((r.rows[x as usize] >> y) & k, k) + } + Op::Row { x } => (r.rows[x as usize], validity[x as usize]), + Op::Column { y } => ( + hhtl16::column(r.rows, y).unwrap_or(0), + hhtl16::column(validity, y).unwrap_or(0), + ), + }; + Value::K3 { + value: value & known, + known, + } +} diff --git a/crates/dr-math-binding-probe/src/lib.rs b/crates/dr-math-binding-probe/src/lib.rs index b1cb70372..fd7100549 100644 --- a/crates/dr-math-binding-probe/src/lib.rs +++ b/crates/dr-math-binding-probe/src/lib.rs @@ -290,3 +290,7 @@ pub mod relcomp; /// projected into one table's 64-slot frame and read over DR#3, with every /// reuse re-admitted against its guards. pub mod where_dr3; + +/// D-DRCA-3: DR #4 method routing over one admitted register. DT-owned +/// method key, guard witness and effect order are carried opaque. +pub mod dr4; diff --git a/crates/dr-math-binding-probe/tests/dr4_method_routing.rs b/crates/dr-math-binding-probe/tests/dr4_method_routing.rs new file mode 100644 index 000000000..7abe11ffb --- /dev/null +++ b/crates/dr-math-binding-probe/tests/dr4_method_routing.rs @@ -0,0 +1,513 @@ +//! D-DRCA-3: the DR #4 falsifier (D-DRDT §5, lance-graph #1835). +//! +//! Two methods on one cell with the same read/write sets and a different effect +//! order must stay distinct through routing, and a dropped guard must refuse. +//! +//! DR carries method references as opaque values. Their meaning lives in the +//! DT stub below, which is also the oracle: it shows that two references DR +//! keeps apart really are different methods. The effect-order law is ndarray +//! #395's (`examples/pof_antennas/order_law.rs`), ported verbatim. + +use dr_math_binding_probe::dr4::{ + Algebra, Dr4Refusal, EffectOrderRef, GuardDecl, GuardWitness, MethodKey, MethodRef, Op, + Resolution, Value, route, +}; +use dr_math_binding_probe::{ + Axis, AxisKind, BoundDr64, Focus, FrameRevisions, FrameStore, Guards, MethodSignature, Operand, + Refusal, Scope, Truth, bind_dr64, +}; +use lance_graph_contract::class_view::ClassId; +use sha2::{Digest, Sha256}; + +// ── #395 order law, verbatim (ndarray examples/pof_antennas/order_law.rs) ── + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +enum Effect { + Set(i64), + Add(i64), + Mul(i64), +} + +impl Effect { + fn apply(&self, cell: i64) -> Option { + match *self { + Effect::Set(v) => Some(v), + Effect::Add(v) => cell.checked_add(v), + Effect::Mul(v) => cell.checked_mul(v), + } + } +} + +fn run_effects(init: i64, effs: &[Effect]) -> Option { + effs.iter().try_fold(init, |cell, e| e.apply(cell)) +} + +fn commutes(a: &Effect, b: &Effect) -> bool { + match (*a, *b) { + (Effect::Add(x), Effect::Add(y)) => !((x < 0 && y > 0) || (x > 0 && y < 0)), + (Effect::Mul(x), Effect::Mul(y)) => { + x == y || x == 1 || y == 1 || (x.unsigned_abs() >= 2 && y.unsigned_abs() >= 2) + } + (Effect::Set(x), Effect::Set(y)) => x == y, + _ => false, + } +} + +#[derive(Debug, PartialEq, Eq)] +struct OrderRefusal { + first: usize, + second: usize, +} + +fn check_reorder(effs: &[Effect], order: &[usize]) -> Result<(), OrderRefusal> { + let n = effs.len(); + assert_eq!(order.len(), n); + let mut pos = vec![usize::MAX; n]; + for (k, &orig) in order.iter().enumerate() { + assert_eq!(pos[orig], usize::MAX, "not a permutation"); + pos[orig] = k; + } + for i in 0..n { + for j in (i + 1)..n { + if !commutes(&effs[i], &effs[j]) && pos[i] > pos[j] { + return Err(OrderRefusal { + first: i, + second: j, + }); + } + } + } + Ok(()) +} + +// ── DT stub: the meaning DR never sees ── + +const CLASS: ClassId = 7; +const OTHER_CLASS: ClassId = 8; + +/// One method as DT would hold it. DR receives only `to_ref()`. +struct DtMethod { + key: [u8; 16], + reads: u64, + writes: u64, + guard: Option<&'static str>, + effects: Vec, + algebra: Algebra, +} + +fn digest16(bytes: &[u8]) -> [u8; 16] { + let h = Sha256::digest(bytes); + let mut out = [0u8; 16]; + out.copy_from_slice(&h[..16]); + out +} + +fn effect_ref(effs: &[Effect]) -> EffectOrderRef { + let mut enc = Vec::new(); + for e in effs { + let (tag, v) = match *e { + Effect::Set(v) => (0u8, v), + Effect::Add(v) => (1u8, v), + Effect::Mul(v) => (2u8, v), + }; + enc.push(tag); + enc.extend_from_slice(&v.to_le_bytes()); + } + EffectOrderRef(digest16(&enc)) +} + +fn guard_witness(guard: &str) -> GuardWitness { + GuardWitness(digest16(guard.as_bytes())) +} + +impl DtMethod { + fn to_ref(&self, class: ClassId) -> MethodRef { + MethodRef { + class, + key: MethodKey(self.key), + signature_rev: 1, + reads: self.reads, + writes: self.writes, + guard: match self.guard { + Some(g) => GuardDecl::Required(guard_witness(g)), + None => GuardDecl::Unguarded, + }, + effects: effect_ref(&self.effects), + algebra: self.algebra, + } + } +} + +fn method(key: u8, effects: Vec, guard: Option<&'static str>) -> DtMethod { + DtMethod { + key: [key; 16], + reads: 0b0110, + writes: 0b1000, + guard, + effects, + algebra: Algebra::Presence, + } +} + +// ── register fixture ── + +fn revisions(n: u64) -> FrameRevisions { + FrameRevisions { + source: n, + relation_map: 10, + coordinates: 20, + } +} + +fn signature(truth: Truth) -> MethodSignature { + let id = Axis { + class: CLASS, + kind: AxisKind::Identity, + }; + let prop = Axis { + class: CLASS, + kind: AxisKind::Property, + }; + let mut s = MethodSignature::presence(CLASS, 3, id, prop); + s.truth = truth; + s +} + +fn rows_fixture() -> [u64; 64] { + core::array::from_fn(|x| (x as u64).wrapping_mul(0x9E37_79B9_7F4A_7C15) ^ (1 << (x % 64))) +} + +fn validity_fixture() -> [u64; 64] { + core::array::from_fn(|x| !((x as u64).wrapping_mul(0xD6E8_FEB8_6659_FD93)) | 1) +} + +const FOCUS: Focus = Focus { revision: 1 }; +const SCOPE: Scope = Scope { id: 2 }; + +fn bind<'a>( + store: &FrameStore, + truth: Truth, + rows: &'a [u64; 64], + validity: Option<&'a [u64; 64]>, +) -> BoundDr64<'a> { + let sig = signature(truth); + let guards = Guards { + frame: store.seal(), + focus: FOCUS, + scope: SCOPE, + }; + bind_dr64( + store, + sig, + sig, + &guards, + (FOCUS, SCOPE), + Operand { rows, validity }, + ) + .unwrap() +} + +fn resolution(store: &FrameStore, methods: &[&DtMethod]) -> Resolution { + Resolution { + class: CLASS, + under: store.seal(), + methods: methods.iter().map(|m| m.to_ref(CLASS)).collect(), + } +} + +/// The witnesses a caller observed, one per guarded method. +fn witnesses(methods: &[&DtMethod]) -> Vec<(MethodKey, GuardWitness)> { + methods + .iter() + .filter_map(|m| m.guard.map(|g| (MethodKey(m.key), guard_witness(g)))) + .collect() +} + +// ── 1. the falsifier ── + +#[test] +fn same_read_write_sets_different_effect_order_stay_distinct() { + let a = method(1, vec![Effect::Set(1), Effect::Add(1)], None); + let b = method(2, vec![Effect::Add(1), Effect::Set(1)], None); + // Anti-vacuity: the two methods are different by the oracle and look + // identical by everything DR could compare except their opaque refs. + assert_eq!((a.reads, a.writes), (b.reads, b.writes)); + assert_ne!(run_effects(0, &a.effects), run_effects(0, &b.effects)); + assert_eq!( + check_reorder(&a.effects, &[1, 0]), + Err(OrderRefusal { + first: 0, + second: 1 + }) + ); + + let store = FrameStore::new(revisions(1)); + let rows = rows_fixture(); + let reg = bind(&store, Truth::TwoValued, &rows, None); + let res = resolution(&store, &[&a, &b]); + let routed = route(&store, ®, &res, Op::Cell { x: 5, y: 9 }, &[]).unwrap(); + + assert_eq!(routed.entries().len(), 2); + let (ea, eb) = (&routed.entries()[0], &routed.entries()[1]); + assert_eq!(ea.key, MethodKey(a.key)); + assert_eq!(eb.key, MethodKey(b.key)); + assert_eq!(ea.effects, effect_ref(&a.effects)); + assert_eq!(eb.effects, effect_ref(&b.effects)); + assert_ne!(ea.effects, eb.effects); + assert_eq!((ea.reads, ea.writes), (eb.reads, eb.writes)); + // Same algebra over the same cell: same value, still two entries. + assert_eq!(ea.value, eb.value); + assert!(routed.frame().same_issue(®.frame)); +} + +#[test] +fn commuting_effects_are_still_not_merged() { + let a = method(1, vec![Effect::Add(2), Effect::Add(3)], None); + let b = method(2, vec![Effect::Add(3), Effect::Add(2)], None); + assert_eq!(run_effects(0, &a.effects), run_effects(0, &b.effects)); + assert_eq!(check_reorder(&a.effects, &[1, 0]), Ok(())); + // The ported law, both ways: equal-magnitude-class products commute, + // a product across a sum does not. + assert!(commutes(&Effect::Mul(2), &Effect::Mul(3))); + assert!(!commutes(&Effect::Mul(2), &Effect::Add(1))); + assert_ne!( + run_effects(1, &[Effect::Mul(2), Effect::Add(1)]), + run_effects(1, &[Effect::Add(1), Effect::Mul(2)]) + ); + + let store = FrameStore::new(revisions(1)); + let rows = rows_fixture(); + let reg = bind(&store, Truth::TwoValued, &rows, None); + let res = resolution(&store, &[&a, &b]); + let routed = route(&store, ®, &res, Op::Column { y: 3 }, &[]).unwrap(); + assert_eq!(routed.entries().len(), 2); + assert_ne!(routed.entries()[0].effects, routed.entries()[1].effects); +} + +// ── 2. guards ── + +#[test] +fn a_dropped_guard_refuses() { + let a = method(1, vec![Effect::Set(1)], Some("state == draft")); + let store = FrameStore::new(revisions(1)); + let rows = rows_fixture(); + let reg = bind(&store, Truth::TwoValued, &rows, None); + let res = resolution(&store, &[&a]); + assert_eq!( + route(&store, ®, &res, Op::Cell { x: 0, y: 0 }, &[]).err(), + Some(Dr4Refusal::GuardDropped) + ); +} + +#[test] +fn a_different_guard_witness_refuses() { + let a = method(1, vec![Effect::Set(1)], Some("state == draft")); + let store = FrameStore::new(revisions(1)); + let rows = rows_fixture(); + let reg = bind(&store, Truth::TwoValued, &rows, None); + let res = resolution(&store, &[&a]); + let wrong = [(MethodKey(a.key), guard_witness("state == posted"))]; + assert_eq!( + route(&store, ®, &res, Op::Cell { x: 0, y: 0 }, &wrong).err(), + Some(Dr4Refusal::GuardMismatch) + ); +} + +#[test] +fn the_right_guard_witness_is_carried_and_unguarded_needs_none() { + let a = method(1, vec![Effect::Set(1)], Some("state == draft")); + let b = method(2, vec![Effect::Add(1)], None); + let store = FrameStore::new(revisions(1)); + let rows = rows_fixture(); + let reg = bind(&store, Truth::TwoValued, &rows, None); + let res = resolution(&store, &[&a, &b]); + let routed = route( + &store, + ®, + &res, + Op::Cell { x: 0, y: 0 }, + &witnesses(&[&a, &b]), + ) + .unwrap(); + assert_eq!( + routed.entries()[0].guard, + Some(guard_witness("state == draft")) + ); + assert_eq!(routed.entries()[1].guard, None); +} + +// ── 3. frame, class, identity ── + +#[test] +fn a_stale_register_frame_refuses() { + let a = method(1, vec![Effect::Set(1)], None); + let mut store = FrameStore::new(revisions(1)); + let rows = rows_fixture(); + let reg = bind(&store, Truth::TwoValued, &rows, None); + let res = resolution(&store, &[&a]); + store.advance(revisions(2)); + assert_eq!( + route(&store, ®, &res, Op::Cell { x: 0, y: 0 }, &[]).err(), + Some(Dr4Refusal::Frame(Refusal::SourceChanged)) + ); +} + +#[test] +fn a_resolution_under_another_frame_refuses() { + let a = method(1, vec![Effect::Set(1)], None); + let mut store = FrameStore::new(revisions(1)); + let old = resolution(&store, &[&a]); + store.advance(revisions(2)); + let rows = rows_fixture(); + let reg = bind(&store, Truth::TwoValued, &rows, None); + assert_eq!( + route(&store, ®, &old, Op::Cell { x: 0, y: 0 }, &[]).err(), + Some(Dr4Refusal::ResolvedUnderOtherFrame) + ); + // Equal numbers in another store are another frame. + let other = FrameStore::new(revisions(2)); + let foreign = resolution(&other, &[&a]); + assert_eq!( + route(&store, ®, &foreign, Op::Cell { x: 0, y: 0 }, &[]).err(), + Some(Dr4Refusal::ResolvedUnderOtherFrame) + ); +} + +#[test] +fn a_foreign_class_refuses() { + let a = method(1, vec![Effect::Set(1)], None); + let store = FrameStore::new(revisions(1)); + let rows = rows_fixture(); + let reg = bind(&store, Truth::TwoValued, &rows, None); + let mut res = resolution(&store, &[&a]); + res.class = OTHER_CLASS; + assert_eq!( + route(&store, ®, &res, Op::Cell { x: 0, y: 0 }, &[]).err(), + Some(Dr4Refusal::ForeignClass) + ); + let mut res = resolution(&store, &[&a]); + res.methods[0].class = OTHER_CLASS; + assert_eq!( + route(&store, ®, &res, Op::Cell { x: 0, y: 0 }, &[]).err(), + Some(Dr4Refusal::ForeignClass) + ); +} + +#[test] +fn a_duplicate_key_refuses_but_equal_sets_do_not() { + let a = method(1, vec![Effect::Set(1)], None); + let a2 = method(1, vec![Effect::Add(1)], None); + let store = FrameStore::new(revisions(1)); + let rows = rows_fixture(); + let reg = bind(&store, Truth::TwoValued, &rows, None); + let res = resolution(&store, &[&a, &a2]); + assert_eq!( + route(&store, ®, &res, Op::Cell { x: 0, y: 0 }, &[]).err(), + Some(Dr4Refusal::DuplicateMethod) + ); +} + +#[test] +fn out_of_register_and_unsupported_algebra_refuse() { + let mut a = method(1, vec![Effect::Set(1)], None); + let store = FrameStore::new(revisions(1)); + let rows = rows_fixture(); + let reg = bind(&store, Truth::TwoValued, &rows, None); + let res = resolution(&store, &[&a]); + assert_eq!( + route(&store, ®, &res, Op::Cell { x: 64, y: 0 }, &[]).err(), + Some(Dr4Refusal::OutOfRegister) + ); + assert_eq!( + route(&store, ®, &res, Op::Column { y: 64 }, &[]).err(), + Some(Dr4Refusal::OutOfRegister) + ); + a.algebra = Algebra::NumericFold; + let res = resolution(&store, &[&a]); + assert_eq!( + route(&store, ®, &res, Op::Cell { x: 0, y: 0 }, &[]).err(), + Some(Dr4Refusal::UnsupportedAlgebra) + ); +} + +// ── 4. values against an independent scalar loop ── + +fn bit(rows: &[u64; 64], x: usize, y: usize) -> bool { + (rows[x] >> y) & 1 == 1 +} + +#[test] +fn boolean_values_match_the_scalar_oracle() { + let a = method(1, vec![Effect::Set(1)], None); + let store = FrameStore::new(revisions(1)); + let rows = rows_fixture(); + let reg = bind(&store, Truth::TwoValued, &rows, None); + let res = resolution(&store, &[&a]); + let mut seen = (false, false); + for x in 0..64u8 { + for y in [0u8, 1, 31, 63] { + let v = route(&store, ®, &res, Op::Cell { x, y }, &[]).unwrap(); + let want = bit(&rows, x as usize, y as usize); + assert_eq!(v.entries()[0].value, Value::Bool(want), "cell {x},{y}"); + if want { + seen.0 = true; + } else { + seen.1 = true; + } + } + let r = route(&store, ®, &res, Op::Row { x }, &[]).unwrap(); + assert_eq!(r.entries()[0].value, Value::Mask(rows[x as usize])); + } + assert!(seen.0 && seen.1, "fixture has no TRUE or no FALSE cell"); + for y in 0..64u8 { + let want = (0..64).fold(0u64, |m, x| m | (u64::from(bit(&rows, x, y as usize)) << x)); + let c = route(&store, ®, &res, Op::Column { y }, &[]).unwrap(); + assert_eq!(c.entries()[0].value, Value::Mask(want), "column {y}"); + } +} + +#[test] +fn presence_over_three_valued_refuses_and_k3_masks_by_validity() { + let mut a = method(1, vec![Effect::Set(1)], None); + let store = FrameStore::new(revisions(1)); + let rows = rows_fixture(); + let validity = validity_fixture(); + let reg = bind(&store, Truth::ThreeValued, &rows, Some(&validity)); + let res = resolution(&store, &[&a]); + assert_eq!( + route(&store, ®, &res, Op::Column { y: 2 }, &[]).err(), + Some(Dr4Refusal::NotBoolean) + ); + a.algebra = Algebra::PresenceK3; + let res = resolution(&store, &[&a]); + let mut unknown_true_payload = false; + for y in 0..64u8 { + let (mut value, mut known) = (0u64, 0u64); + for x in 0..64 { + let k = bit(&validity, x, y as usize); + let v = bit(&rows, x, y as usize); + known |= u64::from(k) << x; + value |= u64::from(k && v) << x; + unknown_true_payload |= !k && v; + } + let c = route(&store, ®, &res, Op::Column { y }, &[]).unwrap(); + assert_eq!( + c.entries()[0].value, + Value::K3 { value, known }, + "column {y}" + ); + } + // Anti-vacuity: some UNKNOWN cell carries a 1 payload bit that must not + // read as TRUE. + assert!(unknown_true_payload); + // A two-valued register under K3 is known everywhere. + let reg2 = bind(&store, Truth::TwoValued, &rows, None); + let c = route(&store, ®2, &res, Op::Row { x: 4 }, &[]).unwrap(); + assert_eq!( + c.entries()[0].value, + Value::K3 { + value: rows[4], + known: u64::MAX + } + ); +} From cc7b9d6b5cfb6ce2d3451683dc928484e5fb34f1 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 30 Oct 2026 01:59:34 +0000 Subject: [PATCH 11/11] board(D-DRCA-3): README section, board entry, STATUS_BOARD, plan index STATUS_BOARD: D-DRCA-1 and D-DRCA-2 marked Shipped (#1834, #1836); D-DRCA-3 In PR. Entries index regenerated (503 rows). Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01XAqKMNiyjwqFke9CfmoBgn --- .claude/board/INTEGRATION_PLANS.md | 5 +++++ .claude/board/STATUS_BOARD.md | 6 +++--- .../2026-10-30-d-drca-3-dr4-method-routing.md | 18 ++++++++++++++++++ .claude/board/entries/README.md | 3 ++- crates/dr-math-binding-probe/README.md | 15 +++++++++++++++ 5 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 .claude/board/entries/2026-10-30-d-drca-3-dr4-method-routing.md diff --git a/.claude/board/INTEGRATION_PLANS.md b/.claude/board/INTEGRATION_PLANS.md index 560ef3cb5..c4a1a52fc 100644 --- a/.claude/board/INTEGRATION_PLANS.md +++ b/.claude/board/INTEGRATION_PLANS.md @@ -1,3 +1,8 @@ +## 2026-10-30 — D-DRCA-3: DR #4 method routing falsifier (lab) → `.claude/plans/d-drca-3-dr4-method-routing-v1.md` + +**Status:** lab probe in `dr-math-binding-probe` (`src/dr4.rs`, `tests/dr4_method_routing.rs`); first DR #4 falsifier of D-DRDT §5. **Board:** [entry](entries/2026-10-30-d-drca-3-dr4-method-routing.md), [STATUS_BOARD](STATUS_BOARD.md) D-DRCA-3. DT-owned method key, guard witness and effect order are carried opaque; the effect-order oracle is ndarray #395's order law. No DT resolver (D-CMH-1), no MethodKey mint, no contract change. +**Confidence:** 12 tests, 7 disable runs red; lab only. + ## 2026-10-28 — D-DRDT: DR = HHTL16 Cartesian direct routing, DT = ClassId binding store → `.claude/plans/d-drdt-dr-dt-ownership-amendment-v1.md` **Status:** PROPOSED, docs only; amends D-DT64-6 §1 (per-cell WHEN×ON×DO, DR#3) and supersedes the DT64 "tensor register" noun of Bardioc-rs #9. **Board:** [entry](entries/2026-10-28-d-drdt-dr-dt-ownership-amendment.md), [STATUS_BOARD](STATUS_BOARD.md) D-DRDT. Records the DR/DT contract, reads the DR64/DR256 overview against existing pieces, gives the reuse/gap table for Cartesian and relational fold operators (proof: #1834, D-DRCA-1) and hands off DT method identity / guard / effect order and the DR #4 interface. diff --git a/.claude/board/STATUS_BOARD.md b/.claude/board/STATUS_BOARD.md index 81e013c18..c6f17c9d6 100644 --- a/.claude/board/STATUS_BOARD.md +++ b/.claude/board/STATUS_BOARD.md @@ -5,9 +5,9 @@ | D-id | Deliverable | Status | Gate | |---|---|---|---| | D-DRDT-0 | amendment: DR/DT ownership, reuse/gap analysis, DT and DR #4 handoff (docs) | In PR | docs review | -| D-DRCA-1 | HHTL16 Cartesian projection proof in `dr-math-binding-probe` (12 tests, 6 disable runs, stage costs) | In PR (#1834) | review; lab only | -| D-DRCA-2 | DR256::WHERE × DR#3 and the stay / rebind / masked-read choice | Queued | D-DRCA-1 merged | -| D-DRCA-3 | DR #4 falsifier: two methods, same read/write sets, different effect order, stay distinct; dropped guard refuses | Queued | DT MethodId contract (D-DRDT §4) | +| D-DRCA-1 | HHTL16 Cartesian projection proof in `dr-math-binding-probe` (12 tests, 6 disable runs, stage costs) | Shipped (#1834) | review; lab only | +| D-DRCA-2 | DR256::WHERE × DR#3 and the stay / rebind / masked-read choice | Shipped (#1836) | lab only | +| D-DRCA-3 | DR #4 falsifier: two methods, same read/write sets, different effect order, stay distinct; dropped guard refuses | In PR (lab: `dr4.rs`, 12 tests, 7 disable runs; [entry](entries/2026-10-30-d-drca-3-dr4-method-routing.md)) | lab uses a test-minted method key; the real key and the DT resolver stay with D-CMH (MethodKey mint, D-CMH-1) | ## D-DT64-6 — DR64 routing, DT64 bind store, per-cell WHEN×ON×DO, OGIT reference predicates (2026-10-28) diff --git a/.claude/board/entries/2026-10-30-d-drca-3-dr4-method-routing.md b/.claude/board/entries/2026-10-30-d-drca-3-dr4-method-routing.md new file mode 100644 index 000000000..835d744e6 --- /dev/null +++ b/.claude/board/entries/2026-10-30-d-drca-3-dr4-method-routing.md @@ -0,0 +1,18 @@ +# D-DRCA-3: DR #4 method routing falsifier + +**Status:** TEST-PINNED, lab only. Code: `crates/dr-math-binding-probe/src/dr4.rs`, test `tests/dr4_method_routing.rs`; plan `.claude/plans/d-drca-3-dr4-method-routing-v1.md`. Contract: D-DRDT §5 (#1835). + +## Result + +- Two methods on one cell with equal read/write sets and effects `[Set(1), Add(1)]` vs `[Add(1), Set(1)]` (oracle 2 vs 1; `check_reorder` refuses the swap) stay two routed entries, each with its own effect-order reference. Two methods whose effects commute also stay two entries: merging is not DR's decision. +- A declared guard with no witness refuses (`GuardDropped`), a different witness refuses (`GuardMismatch`), the right witness is carried; an unguarded method needs none. +- Refused, each with its own variant: stale register frame, resolution under another frame issue (including another store at equal numbers), foreign class, duplicate key, coordinates outside 64 × 64, numeric fold, presence over a three-valued register. +- Cell, row and column values equal a scalar loop; K3 value is masked by validity (the fixture has UNKNOWN cells with a 1 payload). +- DT-owned values (method key, guard witness, effect-order reference) are opaque to DR. The effect-order law is ndarray #395's, ported verbatim into the test as the oracle. +- 12 tests; 7 disable runs, each red on its named test. + +## Open + +- The method key is test-minted; the real one is DT's (D-CMH §2.1, decision ledger item 2). The DT resolver is D-CMH-1's `PreparedClass`, not built here. +- DT gaps of D-DRDT §4 stay with the contract owner: no MethodId independent of name (`ActionDef.predicate`), single `field == value` guard, no effect order, no single lookup. +- DR #4 over a `LocalSelection` or a `Chain` composition is untested. diff --git a/.claude/board/entries/README.md b/.claude/board/entries/README.md index 56f735fd6..5aa3b5cea 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. -502 entries, 2026-08-06 .. 2026-10-29. +503 entries, 2026-08-06 .. 2026-10-30. | date | entry id | finding | file | |---|---|---|---| +| 2026-10-30 | `D-DRCA-3` | | [2026-10-30-d-drca-3-dr4-method-routing.md](2026-10-30-d-drca-3-dr4-method-routing.md) | | 2026-10-29 | `palette512-turbovec9-nsl-worksteal` | | [2026-10-29-palette512-turbovec9-nsl-worksteal.md](2026-10-29-palette512-turbovec9-nsl-worksteal.md) | | 2026-10-28 | `thought-layers-nan-skip` | | [2026-10-28-thought-layers-nan-skip.md](2026-10-28-thought-layers-nan-skip.md) | | 2026-10-28 | `lane-layout-from-classview` | | [2026-10-28-lane-layout-from-classview.md](2026-10-28-lane-layout-from-classview.md) | diff --git a/crates/dr-math-binding-probe/README.md b/crates/dr-math-binding-probe/README.md index b5fddf871..bdb59a4ad 100644 --- a/crates/dr-math-binding-probe/README.md +++ b/crates/dr-math-binding-probe/README.md @@ -135,3 +135,18 @@ One WHERE halves the fresh read. Warm reuse breaks even at N = 1 and pays from N - A negated selection costs its own WHERE, which is the price of `NOT UNKNOWN` staying UNKNOWN. - One 64-slot frame per table; no larger focus, no DR256 resident register, no reuse of a scattered (`ScatterOrU32`) mask. - `project` is 64 scalar probes (~1 µs); admission (~76–82 ns) is not broken down. + +## D-DRCA-3: DR #4 method routing (`dr4`) + +The first DR #4 falsifier of D-DRDT §5 (#1835): two methods on one cell with the same read/write sets and a different effect order must stay distinct through routing, and a dropped guard must refuse. Module `src/dr4.rs`, test `tests/dr4_method_routing.rs`, plan `.claude/plans/d-drca-3-dr4-method-routing-v1.md`. + +- **DR carries DT's values opaque.** `MethodKey`, `GuardWitness` and `EffectOrderRef` are 16-byte references that `route` compares for equality and never interprets. The method key is DT's to mint (D-CMH §2.1); the test mints its own, named as such. `Resolution` (class, frame, methods) is DT's answer handed in by the caller; this crate has no DT resolver (that is D-CMH-1's `PreparedClass`). +- **One entry per input method, in input order.** Key, signature revision, read and write field sets, guard witness and effect-order reference pass through unchanged, with the register's frame on the result. Nothing is merged: two methods whose effects commute are still two entries, because merging is the law owner's decision. +- **Refusals, in order:** a stale register frame (`Frame(..)`); a resolution made under another frame issue, including another store at equal numbers (`ResolvedUnderOtherFrame`); the resolution or a method for another class (`ForeignClass`); a duplicate key (`DuplicateMethod`; equal read/write sets are not a duplicate); coordinates outside 64 × 64 (`OutOfRegister`); a numeric fold (`UnsupportedAlgebra`); a presence read over a three-valued register (`NotBoolean`); a declared guard with no witness (`GuardDropped`) or another one (`GuardMismatch`). DR checks witnesses; it evaluates no guard. +- **Values** come from the existing register reads: cell, row and column presence, and K3 value + validity with the value masked by validity. + +Oracle: the DT stub in the test holds each method's real effects and guard. The effect-order law is ndarray #395's `Effect` / `run_effects` / `commutes` / `check_reorder` (`examples/pof_antennas/order_law.rs`), ported verbatim. In the core fixture `[Set(1), Add(1)]` and `[Add(1), Set(1)]` give 2 and 1 and the swap is refused, so the two references DR keeps apart are provably different methods; the commuting control `[Add(2), Add(3)]` and its reverse give equal results and the swap is legal, and routing still keeps both. Values are compared against plain scalar loops over the register words. + +Twelve tests; seven disable runs, each restored from the commit and each turning its named test red: entries collapsed by equal read/write sets (3 tests red), a dropped guard accepted, a mismatched witness accepted, the resolution frame not checked, a method's class not checked, a duplicate key accepted, the K3 value not masked by validity. + +**Not done.** The DT resolver (D-CMH-1), a minted `MethodKey`, guard evaluation, effect execution, DR #4 over a `LocalSelection` (D-DRCA-2) or a `Chain` composition, production placement.