Skip to content

Commit 21ee026

Browse files
committed
feat(contract): D-ODOO-SAV-5b-v2 — canonical OGIT-URI codebook foundation + E-CODEBOOK-INHERITS-FROM-OGIT
Per the 2026-05-28 user-given doctrine (distilled across four messages): "every data is now LE-byte contract SoA in each mailbox / bitpacked is also only a desperation bucket / normally LE SoA should have codebook for everything including semantic ontology graph / inherited from OGIT because the SoA doesn't guess." Adds the canonical identity layer that supersedes the bitpacked RoleKey form shipped in feaa587: **New: crates/lance-graph-contract/src/callcenter/ogit_uris.rs (8 tests)** - SAVANT_OGIT_BASE = "https://ogit.adaworldapi.com/callcenter/savants#" - SAVANT_OGIT_URIS: LazyLock<[String; 25]> — one URI per savant, roster order - savant_ogit_uri(id) / savant_ogit_uri_by_name(name) — lookup helpers - 8 unit tests: uris_match_savant_count, uris_use_canonical_namespace, id_1_resolves_to_fiscal_position_resolver, id_16_is_absent, id_26_resolves_to_backorder_judge, id_lookup_matches_name_lookup, nonexistent_name_returns_none, every_savant_in_roster_has_a_uri Resolves through `lance-graph-ontology::registry::OntologyRegistry` (infrastructure already shipped — PR #407/#408 hydrators, PR #412 DOLCE classifier, PR #416 FIBU/FIBO alignment, the canonical lingua-franca path). The OntologyRegistry resolves the URI to a stable u32 codebook code; the LE-byte mailbox SoA columns store the code. The Baton (u16, CausalEdge64) carries the code across mailbox boundaries. **Updated: contract::callcenter::role_keys (doc-only update)** Module-level documentation now explicitly flags the bitpacked RoleKey slices as the desperation-bucket fallback per the new doctrine; canonical savant identity is via the OGIT URI in ogit_uris. Code unchanged (still compiled, 7 tests still pass) — usable for ephemeral in-mailbox Hamming compare where codebook lookup is unavailable. **Updated: contract::callcenter::mod.rs** Re-exports the new ogit_uris module + adds the two-identity-layer rationale in the module doc (canonical OGIT URI + desperation-bucket RoleKey). **Prepended: .claude/board/EPIPHANIES.md — E-CODEBOOK-INHERITS-FROM-OGIT** Captures the full doctrine across all four 2026-05-28 messages: Vsa16kF32 deprecated, LE-byte SoA per mailbox, codebook for everything, inheritance from OGIT, Kontenerkennung-style multi-dim rich codebook (parent chain + NARS confidence per link + business × transaction × form × regulation × law × entity × product), audit query layer (episodic + AriGraph SPO-G + regulation-ontology + NARS confidence threshold). **Queued (separate D-ids, captured in the EPIPHANIES entry):** - (a) data/ontologies/ogit/callcenter/savants.ttl + OntologyRegistry hydration for the 25 savants - (b) Kontenerkennung-style inheritance struct with NARS confidence per parent link - (c) regulation-ontology codebook (HGB / GoB / AO / UStG / IFRS / GoBD) - (d) audit-threshold dispatch in cognitive-shader-driver (NARS confidence vs audit_floor → CausalEdge64 emission or escalation Baton) Tests: 15 callcenter tests total (8 new ogit_uris + 7 existing role_keys); 454 prior contract lib tests unaffected. https://claude.ai/code/session_017gZ6sPRXYPj5n7uJ7NBtRv
1 parent 508d2c4 commit 21ee026

4 files changed

Lines changed: 231 additions & 8 deletions

File tree

.claude/board/EPIPHANIES.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,34 @@
1+
## 2026-05-28 — E-CODEBOOK-INHERITS-FROM-OGIT — every identity (entities, savants, atoms, ontology classes, regulation rules, accounts) lives as a codebook entry inherited from OGIT; LE-byte SoA per mailbox stores the codes; bitpacked u64 is a desperation-bucket fallback; the SoA doesn't guess
2+
3+
**Status:** FINDING (architectural correction, supersedes the role-key-as-canonical interpretation of `I-VSA-IDENTITIES`; drives the v2-step codebook foundation in `contract::callcenter::ogit_uris`).
4+
5+
**Click (the 2026-05-28 user-given doctrine, distilled across four messages):**
6+
7+
1. **`Vsa16kF32` deprecated** as cross-boundary carrier (matches CLAUDE.md "The Click" 2026-05-26 baton-scoping update). Inter-mailbox state is the `(u16, CausalEdge64)` baton; ephemeral in-mailbox compute may still use `Vsa16kF32`.
8+
2. **Every data lives as LE-byte SoA per mailbox** (`E-MAILBOX-IS-BINDSPACE`). Row content = codes; never raw bits.
9+
3. **Codebook for everything — including the semantic ontology graph.** Entities, savants, atoms, ontology classes, regulation rules, accounts (Kontenrahmen positions) all get codebook entries.
10+
4. **Inherited from OGIT, because the SoA doesn't guess.** Identities are deterministic — `OntologyRegistry` resolves OGIT URI → stable row index. No hashing, no FNV-seeded random bits, no autogenerated IDs.
11+
5. **Bitpacked u64 (RoleKey slices in `Binary16K`) is a desperation-bucket fallback.** Useful only when codebook lookup is unavailable (ephemeral Hamming compare); not canonical identity.
12+
6. **The codebook is RICH, not flat** — Kontenerkennung is the canonical example: each entry carries a parent chain (SKR03 → SKR04 → custom) + NARS-truth confidence per link + multi-dimensional dispatch over `(business type × transaction type × form × regulation × law × entity × product)`.
13+
7. **The audit query is the load-bearing read**: *"how were similar transactions / entities handled before · what patterns are required by regulation · what currently exists · what needs audit vs what is confidently repeating existing patterns"* — answered by composing episodic memory + AriGraph SPO-G audit-witness chain + regulation-ontology codebook + NARS confidence threshold + Pearl 2³ on the emitted `CausalEdge64`. High confidence → repeat (no audit); below floor → escalate.
14+
15+
**Mechanism (the codebook layer, full shape):**
16+
17+
- **Identity:** OGIT URI under `https://ogit.adaworldapi.com/<domain>#<Name>` (e.g. `callcenter/savants#FiscalPositionResolver`). `OntologyRegistry::resolve(uri)` → stable row index (u32 codebook code).
18+
- **Inheritance:** typed parent chain per entry, NARS-truth-weighted per link (deduction down a chain, revision across siblings).
19+
- **Multi-dim applicability:** each entry carries selectors over (business × transaction × form × regulation × law × entity × product); dispatch resolves the cross-product match.
20+
- **Regulation as ontology:** legal/regulatory patterns (HGB, GoB, AO, UStG, IFRS, GoBD) are themselves OGIT URIs with inheritance + applicability; floor-of-compliance is a typed predicate over them.
21+
- **Audit threshold:** NARS confidence on a `CausalEdge64` emission < `audit_floor` → escalate (LLM resolves the <25% tail per CLAUDE.md "The Click"); ≥ floor → confident pattern repetition committed to AriGraph SPO-G as both the action and its audit witness.
22+
- **Storage:** LE-byte SoA columns per mailbox store the codebook codes (u32 row indices). No bitpacked planes. The `Baton` (`(u16, CausalEdge64)`) carries the code across mailbox boundaries.
23+
24+
**Fix (what lands today + what's queued):**
25+
26+
- **Today (this commit):** `contract::callcenter::ogit_uris` ships the canonical OGIT URI per savant + `savant_ogit_uri(id) → &'static str` lookups (8 tests). `contract::callcenter::role_keys` stays compiled as the documented desperation-bucket fallback (module doc updated). `D-ODOO-BP-1b` Wave 1 (L1–L5) already shipped 4008 lines of typed `OdooEntity` content (`e4c747a`); Wave 2 (L6–L10) running in parallel.
27+
- **Queued (separate D-ids):** (a) `savants.ttl` under `data/ontologies/ogit/callcenter/` + `OntologyRegistry::hydrate_from_*` wiring for the 25 savants; (b) Kontenerkennung-style inheritance + NARS confidence per link (`CodebookEntry { uri, parent: Option<u32>, link_truth: NarsTruth, applicability: ... }`); (c) regulation-ontology codebook (HGB / GoB / AO / UStG / IFRS / GoBD as OGIT URIs); (d) audit-threshold dispatch in `cognitive-shader-driver` (NARS confidence vs `audit_floor``CausalEdge64` Pearl 2³ + AriGraph SPO-G witness OR escalation Baton).
28+
29+
**Lesson (generalizes):** "consult before guess" (CLAUDE.md §"Driving Seat") extends beyond grepping the codebase — it extends to **identity itself**. The SoA doesn't guess: every row's identity comes from a deterministic codebook lookup (OGIT → registry → row index). Inventing identities (FNV-seeded random bits in a slice, hash of a name) is the same anti-pattern as inventing types that already exist — both are 30-turn rediscovery taxes. The fix is the same: route every identity through `OntologyRegistry`.
30+
31+
**Cross-ref:** `E-MAILBOX-IS-BINDSPACE` (LE-byte SoA per mailbox), `E-BATON-1` (`(u16, CausalEdge64)` cross-boundary state), `I-VSA-IDENTITIES` (Layer-2 catalogue doctrine — clarified: catalogue is OGIT-resolved, NOT bitpacked random bits), `E-SAVANT-COMPOSITION-1` (Reasoner trait surface was wrong — codebook foundation is the canonical identity layer the typed compositions reach for), CLAUDE.md "The Click" 2026-05-26 baton-scoping update (Vsa16kF32 deprecated as carrier), CLAUDE.md INTEGRATION_PLANS line 470 (Pillar 1: "OGIT as universal SPO-G lingua franca with `ontology_context_id: u32` per named graph"), `.claude/plans/odoo-savant-reasoners-v2.md` (v2 reshape — Group F per-savant compositions now compose over OGIT-codebook identities, not RoleKey slices), `.claude/plans/odoo-business-logic-blueprint-v1.md` (BP-1b content layer is OGIT-compatible via `model_name``classify_odoo`/`hydrate_odoo`).
132
## 2026-05-28 — E-SAVANT-COMPOSITION-1 — the `Reasoner` trait surface (D-ODOO-SAV-4, PR #420) is the wrong shape: savants are typed compositions over `CausalEdge64` + `Tactic` + `callcenter/role_keys`, not service impls
233

334
**Status:** FINDING (architectural correction, drives `odoo-savant-reasoners-v2`).

crates/lance-graph-contract/src/callcenter/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,29 @@
66
//! [`crate::savants::SAVANTS`] land here as the first set of
77
//! callcenter-domain identities.
88
//!
9+
//! ## Two identity layers (2026-05-28 codebook doctrine)
10+
//!
11+
//! 1. **[`ogit_uris`] — canonical**: OGIT URI per savant, resolved
12+
//! through `lance-graph-ontology::registry::OntologyRegistry` to a
13+
//! stable row index. LE-byte mailbox SoA columns store the row
14+
//! index — the codebook is inherited from OGIT, the SoA doesn't
15+
//! guess.
16+
//! 2. **[`role_keys`] — desperation-bucket fallback**: Binary16K u64
17+
//! bitpacked role-key slices for compute contexts where the codebook
18+
//! is unavailable. **Not the canonical identity** — useful only
19+
//! for ephemeral in-mailbox Hamming compare.
20+
//!
921
//! See `.claude/knowledge/vsa-switchboard-architecture.md` for the
1022
//! three-layer Layer-2 catalogue doctrine and
1123
//! `.claude/plans/odoo-savant-reasoners-v2.md` for the broader
1224
//! composition-over-substrate reshape this module participates in.
1325
26+
pub mod ogit_uris;
1427
pub mod role_keys;
1528

29+
pub use ogit_uris::{
30+
savant_ogit_uri, savant_ogit_uri_by_name, SAVANT_OGIT_BASE, SAVANT_OGIT_URIS,
31+
};
1632
pub use role_keys::{
1733
savant_role_key, savant_role_key_by_name, SAVANT_ROLE_KEYS, SAVANT_SLICE_END,
1834
SAVANT_SLICE_START, SAVANT_SLICE_WIDTH,
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
//! Canonical OGIT-URI codebook entries for the 25 Odoo savants — the
2+
//! deterministic identity layer per the 2026-05-28 doctrine: **"LE-byte
3+
//! SoA per mailbox carries codebook entries inherited from OGIT; the
4+
//! SoA doesn't guess."**
5+
//!
6+
//! ## Layered identity
7+
//!
8+
//! Per `I-VSA-IDENTITIES` + the 2026-05-28 codebook-canonical doctrine,
9+
//! a savant has three identity layers:
10+
//!
11+
//! 1. **Canonical (this module): OGIT URI** — namespaced under
12+
//! `https://ogit.adaworldapi.com/callcenter/savants#<Name>`. Resolved
13+
//! through [`lance-graph-ontology::registry::OntologyRegistry`] to a
14+
//! stable row index (codebook code). LE-byte mailbox SoA columns
15+
//! store the row index, **never** raw bits.
16+
//! 2. **Content (in [`crate::savants`]): `Savant` struct** — dispatch
17+
//! tuple `(id, name, family, kind, inference, semiring, style, lane,
18+
//! decides)`. Read-side metadata, not identity.
19+
//! 3. **Desperation-bucket fallback (in [`super::role_keys`]):
20+
//! `RoleKey` slice** — Binary16K bitpacked u64 words in
21+
//! `[14096..16346)`. Useful for compute contexts where codebook
22+
//! lookup is unavailable (e.g. ephemeral in-mailbox Hamming
23+
//! compare); **not the canonical identity**. The 2026-05-28
24+
//! doctrine: "bitpacked is also only a desperation bucket."
25+
//!
26+
//! ## What this module ships (`D-ODOO-SAV-5b-v2` step 1)
27+
//!
28+
//! - [`SAVANT_OGIT_BASE`] — the namespace IRI all 25 URIs sit under.
29+
//! - [`SAVANT_OGIT_URIS`] — `LazyLock<[String; 25]>` with one URI per
30+
//! savant in roster order (same order as [`crate::savants::SAVANTS`]).
31+
//! - [`savant_ogit_uri`] / [`savant_ogit_uri_by_name`] — lookup helpers
32+
//! that round-trip with [`crate::savants::savant`] /
33+
//! [`crate::savants::savant_by_name`].
34+
//!
35+
//! ## What lands next
36+
//!
37+
//! - **Step 2** (out of scope this commit): a `data/ontologies/ogit/
38+
//! callcenter/savants.ttl` TTL declaring each savant as an
39+
//! `ogit:Savant` with its dispatch tuple (kind, inference, semiring,
40+
//! style, lane, decides) — hydrated through the existing
41+
//! `OwlHydrator` + `OntologyRegistry::hydrate_from_*` path.
42+
//! - **Step 3:** `MappingProposal` registration so the per-tenant
43+
//! `NamespaceBridge` projections resolve the savant URIs into the
44+
//! appropriate tenant scope.
45+
//! - **Step 4:** Kontenerkennung-style inheritance + NARS-truth
46+
//! confidence per inheritance link — the multi-dimensional dispatch
47+
//! surface (business × transaction × form × regulation × law × entity
48+
//! × product) the user named on 2026-05-28. Lands in a separate
49+
//! module sitting next to the codebook resolver, with each savant's
50+
//! `Savant::decides` becoming the leaf in a typed inheritance tree.
51+
52+
use std::sync::LazyLock;
53+
54+
use crate::savants::{savant, savant_by_name, SAVANTS};
55+
56+
/// Base OGIT IRI for the callcenter-savants namespace.
57+
///
58+
/// One stable codebook namespace; every savant URI is
59+
/// `format!("{SAVANT_OGIT_BASE}{savant_name}")`.
60+
pub const SAVANT_OGIT_BASE: &str = "https://ogit.adaworldapi.com/callcenter/savants#";
61+
62+
/// One canonical OGIT URI per savant, in roster order (same order as
63+
/// [`crate::savants::SAVANTS`]).
64+
///
65+
/// Indexing matches roster index `i` (NOT savant `id`; roster id 16 is
66+
/// intentionally absent per `SAVANTS.md`). Use the lookup helpers
67+
/// [`savant_ogit_uri`] / [`savant_ogit_uri_by_name`] rather than
68+
/// indexing this array directly.
69+
pub static SAVANT_OGIT_URIS: LazyLock<[String; 25]> = LazyLock::new(|| {
70+
core::array::from_fn(|i| format!("{}{}", SAVANT_OGIT_BASE, SAVANTS[i].name))
71+
});
72+
73+
/// Look up a savant's canonical OGIT URI by roster id.
74+
///
75+
/// Returns `None` if the id does not appear in [`SAVANTS`] (e.g. the
76+
/// intentionally-absent id 16).
77+
pub fn savant_ogit_uri(id: u8) -> Option<&'static str> {
78+
let _ = savant(id)?;
79+
SAVANTS
80+
.iter()
81+
.position(|s| s.id == id)
82+
.map(|i| SAVANT_OGIT_URIS[i].as_str())
83+
}
84+
85+
/// Look up a savant's canonical OGIT URI by name.
86+
///
87+
/// Returns `None` if the name does not match any savant in
88+
/// [`SAVANTS`].
89+
pub fn savant_ogit_uri_by_name(name: &str) -> Option<&'static str> {
90+
let _ = savant_by_name(name)?;
91+
SAVANTS
92+
.iter()
93+
.position(|s| s.name == name)
94+
.map(|i| SAVANT_OGIT_URIS[i].as_str())
95+
}
96+
97+
#[cfg(test)]
98+
mod tests {
99+
use super::*;
100+
101+
#[test]
102+
fn uris_match_savant_count() {
103+
assert_eq!(SAVANT_OGIT_URIS.len(), 25);
104+
}
105+
106+
#[test]
107+
fn uris_use_canonical_namespace() {
108+
for uri in SAVANT_OGIT_URIS.iter() {
109+
assert!(
110+
uri.starts_with(SAVANT_OGIT_BASE),
111+
"uri must sit under canonical namespace: {uri}"
112+
);
113+
}
114+
}
115+
116+
#[test]
117+
fn id_1_resolves_to_fiscal_position_resolver() {
118+
let uri = savant_ogit_uri(1).expect("id 1");
119+
assert_eq!(
120+
uri,
121+
"https://ogit.adaworldapi.com/callcenter/savants#FiscalPositionResolver"
122+
);
123+
}
124+
125+
#[test]
126+
fn id_16_is_absent() {
127+
assert!(savant_ogit_uri(16).is_none(), "roster id 16 intentionally absent");
128+
}
129+
130+
#[test]
131+
fn id_26_resolves_to_backorder_judge() {
132+
let uri = savant_ogit_uri(26).expect("id 26");
133+
assert!(
134+
uri.ends_with("BackorderJudge"),
135+
"id 26 should be BackorderJudge: {uri}"
136+
);
137+
}
138+
139+
#[test]
140+
fn id_lookup_matches_name_lookup() {
141+
let by_id = savant_ogit_uri(1).expect("id 1");
142+
let by_name =
143+
savant_ogit_uri_by_name("FiscalPositionResolver").expect("name lookup");
144+
assert_eq!(by_id, by_name);
145+
}
146+
147+
#[test]
148+
fn nonexistent_name_returns_none() {
149+
assert!(savant_ogit_uri_by_name("DoesNotExist").is_none());
150+
}
151+
152+
#[test]
153+
fn every_savant_in_roster_has_a_uri() {
154+
for s in SAVANTS.iter() {
155+
let uri = savant_ogit_uri(s.id).expect("every roster savant has a uri");
156+
assert!(uri.ends_with(s.name), "uri ends with savant name: {uri} vs {}", s.name);
157+
}
158+
}
159+
}

crates/lance-graph-contract/src/callcenter/role_keys.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,26 @@
1-
//! Savant role-key catalogue — 25 disjoint [`RoleKey`] slices, one
2-
//! identity per Odoo savant in [`crate::savants::SAVANTS`].
1+
//! Savant role-key catalogue — **desperation-bucket fallback** identity
2+
//! layer per the 2026-05-28 codebook doctrine (see
3+
//! `E-CODEBOOK-INHERITS-FROM-OGIT` in `EPIPHANIES.md`).
34
//!
4-
//! Lands in the SMB headroom `[14096..16384)` that
5-
//! [`crate::grammar::role_keys`] reserves for future SMB keys (per the
6-
//! LF-2 16K resize). Each savant gets 90 dims of pseudo-random bipolar
7-
//! identity, FNV-64-seeded from the savant's name; disjoint by
8-
//! construction.
5+
//! ## Status: not the canonical identity
6+
//!
7+
//! The canonical savant identity is the OGIT URI in [`super::ogit_uris`],
8+
//! resolved through `lance-graph-ontology::registry::OntologyRegistry`
9+
//! to a stable codebook row index. LE-byte mailbox SoA columns store
10+
//! the row index — **never the bitpacked bits here**.
11+
//!
12+
//! This module exists as the documented fallback for compute contexts
13+
//! where codebook lookup is unavailable (e.g. ephemeral in-mailbox
14+
//! Hamming compare against a pre-bound `RoleKey`). Per the
15+
//! 2026-05-28 doctrine: *"bitpacked is also only a desperation
16+
//! bucket."*
17+
//!
18+
//! ## What this module ships
19+
//!
20+
//! 25 disjoint [`RoleKey`] slices, one per Odoo savant in
21+
//! [`crate::savants::SAVANTS`], landing in the SMB headroom
22+
//! `[14096..16346)` (FNV-64-seeded pseudo-random bipolar bits, 90 dims
23+
//! each, disjoint by construction).
924
//!
1025
//! ## Layout
1126
//!
@@ -22,7 +37,9 @@
2237
//! headroom (`grammar::role_keys::VSA_DIMS = 16_384` minus STEUER_KEY's
2338
//! end at `14_096`).
2439
//!
25-
//! `D-ODOO-SAV-5b` of `odoo-savant-reasoners-v2`.
40+
//! `D-ODOO-SAV-5b` of `odoo-savant-reasoners-v2` (the desperation-bucket
41+
//! fallback; the canonical OGIT codebook foundation is `D-ODOO-SAV-5b-v2`
42+
//! in [`super::ogit_uris`]).
2643
2744
use std::sync::LazyLock;
2845

0 commit comments

Comments
 (0)