Skip to content

Commit 1a87bc0

Browse files
committed
feat(callcenter): odoo savant families + Layer-2 axioms + style wiring (D-ODOO-SAV-1/2/3)
Picks up the cross-repo handover boundary declared in .claude/odoo/SAVANTS.md §"lance-graph handover boundary": the woa-rs session defined the 25-Savant roster + delegation tuples; this lands the lance-graph side's first three deliverables. Reasoner impls (D-ODOO-SAV-4) are scoped in the plan and deferred to a follow-up PR. Integration plan: - .claude/plans/odoo-savant-reasoners-v1.md (new) + INTEGRATION_PLANS.md prepend, per board-hygiene. D-ODOO-SAV-1 — two new OGIT families: - FAMILY_PRODUCT_CATALOG = 0x64 (100), FAMILY_HR_FOUNDATION = 0x90 (144) in odoo_alignment.rs + family_registry.ttl rows. - CORRECTION of the SAVANTS.md proposal: it named 0x63 for ProductCatalog, but 0x63 (=99) is already ogit:MRORepair in the authoritative registry. lance-graph is authoritative for the registry, so ProductCatalog gets the next free commercial-cluster byte 0x64 (=100). Documented on the constant + in family_registry.ttl + guarded by a test. - Seed rows: product.pricelist→schema:PriceSpecification, product.pricelist.item→schema:UnitPriceSpecification, uom.uom→qudt:Unit (ties into the bO-4 QUDT spine), hr.employee→vcard:Individual, hr.department→org:OrganizationalUnit, hr.job→org:Role, hr.contract→fibo:Contract (base only; payroll is Enterprise/absent). - product.template / product.product STAY on BillingCore 0x61 (billable items, not catalogue structure) — no drift of the existing seed/tests. D-ODOO-SAV-2 — Layer-2 alignment axioms (data/ontologies/odoo/alignment/ odoo-to-foundation.ttl, new): - Honest semantic alignment for account.account.tag → skos:Concept. - Documented-None-with-rationale for the genuinely cross-cutting classes (stock.move/rule/orderpoint, account.analytic.distribution.model): no foundry family minted (Option B — None stays None without an honest pivot), matching their family=None status in the savant roster. - Public OWL vocabularies referenced, never modified. D-ODOO-SAV-3 — StyleCluster wiring: - family_default_style(OgitFamily) -> Option<StyleCluster> + resolve_odoo_style(class). Pins 0x60→Direct, 0x61/0x62/0x64→Analytical, 0x80/0x90→Empathic, 0x81→Direct per SAVANTS.md inherited-style map. - dolce_odoo gains a `uom.` → Quality suffix rule. Tests: 144 lance-graph-callcenter tests pass (19 odoo_alignment incl. 9 new: new family bytes free in registry, catalogue→ProductCatalog, billable-items- stay-BillingCore deviation guard, hr→HRFoundation, live-table end-to-end for both basins, classes-still-None-after-D1, family_default_style pins, resolve_odoo_style chains, uom dolce rule). Updated the pre-existing unmapped_classes_return_none test (hr.employee no longer None). Clippy clean (only pre-existing CausalEdge64 deprecations elsewhere).
1 parent c6aa31d commit 1a87bc0

5 files changed

Lines changed: 534 additions & 1 deletion

File tree

.claude/board/INTEGRATION_PLANS.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
## 2026-05-27 — odoo-savant-reasoners-v1 (lance-graph side of the Odoo richness harvest: 2 new OGIT families + Layer-2 axioms + StyleCluster wiring + 5 Reasoner impls)
2+
3+
**Status:** PROPOSAL (picks up the cross-repo handover boundary in `.claude/odoo/SAVANTS.md` §"lance-graph handover boundary"). woa-rs defined the 25-Savant roster + delegation tuples; lance-graph implements (a) Reasoner impls, (b) 2 new families + Layer-2 alignment axioms for the `None` classes, (c) StyleCluster wiring.
4+
**Confidence:** HIGH on (b)/(c) — additive extensions of `odoo_alignment.rs` seed + alignment TTLs. MED on (a) — Reasoner dispatch shape (one impl per ReasoningKind vs savant-config registry) pinned but needs a review pass.
5+
**Plan file:** `.claude/plans/odoo-savant-reasoners-v1.md`
6+
**Predecessors:** PR #412 (odoo hydrator + dolce_odoo classifier + ODOO slot 50), PR #413 (briefing pack).
7+
**Anchored iron rules:** I-VSA-IDENTITIES (savant = Layer-2 role catalogue), AGI-as-glove, board-hygiene, Iron Rule 1 (no brain-crate in customer binary), Iron Rule 7 (verhaltens-bewahrend — reasoner output is suggestion-only).
8+
9+
### Scope
10+
Group B — `0x63 ProductCatalog` (Analytical) + `0x90 HRFoundation` (Empathic) families + Layer-2 alignment axioms for `stock.*` / `account.analytic.distribution.model` / `account.account.tag` (land on existing pivot where honest, else documented `None`). Group C — `StyleCluster` per family (field-or-sidecar). Group A — `SavantConclusion` + 5 `Reasoner` impls (one per `ReasoningKind`) in lance-graph-callcenter, dispatching on evidence + family style, `InferenceType::default_strategy()` → QueryStrategy, NarsTruth evidence fusion.
11+
12+
### Deliverables
13+
D-ODOO-SAV-1 two new families + seed rows + family_registry.ttl · D-ODOO-SAV-2 Layer-2 alignment axioms TTL · D-ODOO-SAV-3 StyleCluster per family · D-ODOO-SAV-4 5 Reasoner impls (gated on dispatch-shape review, own PR).
14+
15+
### Execution
16+
D-ODOO-SAV-1/2/3 additive + low-risk → first PR (this session). D-ODOO-SAV-4 → follow-up PR after `/code-review` on dispatch shape. Plan + INTEGRATION_PLANS prepend land with D-ODOO-SAV-1.
17+
18+
### Invariants
19+
Option B (inherit existing slots; new families are genuine basins not per-class mints; `None` stays `None` w/o honest pivot) · public OWL pristine (axioms are NEW TTL) · savant = Layer-2 catalogue · reasoner output = suggestion (guard stays in woa-rs) · impls in callcenter behind contract `Reasoner` trait.
20+
21+
---
22+
123
## 2026-05-27 — atom-mailbox-substrate-v1 (ladder-serves-mailbox: atoms→styles→personas, quorum projection, counterfactual mantissa, AriGraph hot/cold/tombstone)
224

325
**Status:** PROPOSAL (implements `EPIPHANIES.md` E-LADDER-SERVES-MAILBOX; extends `rung-persona-orchestration-v1` D-PERSONA-1 downward into the atom layer and outward into the mailbox lifecycle).
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# odoo-savant-reasoners-v1 — lance-graph side of the Odoo richness harvest
2+
3+
> **Status:** PROPOSAL. Picks up the explicit cross-repo handover boundary
4+
> declared in `lance-graph/.claude/odoo/SAVANTS.md` §"lance-graph handover
5+
> boundary": the woa-rs session defined the 25-Savant roster + delegation
6+
> tuples + call sites + evidence schemas (all contract-level, BBB-allowed);
7+
> the **lance-graph side** must now implement (a) the `Reasoner` impls, (b)
8+
> the two new OGIT families + Layer-2 alignment axioms for the `None`
9+
> classes, (c) the `StyleCluster` wiring.
10+
>
11+
> **Confidence:** HIGH on (b)/(c) — concrete additive extensions of the
12+
> existing `odoo_alignment.rs` seed table + alignment TTLs. MED on (a) — the
13+
> `Reasoner` dispatch shape is an architectural decision (one impl per
14+
> `ReasoningKind` vs a savant-config registry) that this plan pins but which
15+
> needs a review pass before the larger build.
16+
>
17+
> **Predecessors:** PR #412 (odoo hydrator + `dolce_odoo` classifier + ODOO
18+
> slot 50), PR #413 (briefing pack import). Reads on:
19+
> `lance-graph-contract::reasoning` (Reasoner / ReasoningKind / ReasoningContext),
20+
> `lance-graph-callcenter::{family_table, odoo_alignment, unified_bridge}`,
21+
> `lance-graph-contract::thinking::StyleCluster`.
22+
>
23+
> **Anchored iron rules:** I-VSA-IDENTITIES (savant = Layer-2 role catalogue,
24+
> content in tables not bundles), the AGI-as-glove doctrine (savant dispatch
25+
> rides `MetaColumn`/`EdgeColumn`, no new service), board-hygiene.
26+
27+
## Scope
28+
29+
Three deliverable groups, matching SAVANTS.md (a)/(b)/(c):
30+
31+
### Group B — two new OGIT families + Layer-2 alignment axioms (lowest risk, first)
32+
33+
The roster needs homes for classes that resolve to `None` today:
34+
35+
- **`0x63 ProductCatalog`** (basin: product catalogue + pricelist + UoM;
36+
default style **Analytical**). Lands `product.template`,
37+
`product.pricelist`, `product.pricelist.item`, `uom.uom`,
38+
`product.category`. Currently `product.*` inherits `0x61 BillingCore`
39+
slot 1 via the prefix fallback — ProductCatalog promotes the
40+
catalogue/pricing concepts to their own basin so L8's
41+
`PricelistAssignmentAgent` has a real family instead of `None`.
42+
- **`0x90 HRFoundation`** (basin: employee / org; default style
43+
**Empathic**). Lands `hr.employee``vcard:Individual`,
44+
`hr.department``org:OrganizationalUnit`, `hr.job`, `hr.contract` (base
45+
only — payroll engine is Enterprise/absent, flagged). All `hr.*`
46+
resolve `None` today.
47+
- **Layer-2 alignment axioms** for the remaining `None` classes that do
48+
NOT get a new family (they stay cross-cutting): `stock.*` (stock.move,
49+
stock.rule, stock.warehouse.orderpoint), `account.analytic.distribution.model`,
50+
`account.account.tag`. These get `owl:equivalentClass` / `rdfs:subClassOf`
51+
rows in `data/ontologies/odoo/alignment/` pointing at existing pivots
52+
(e.g. `stock.move``schema:MoveAction`-style, analytic→`fibo:CostCenter`)
53+
so `resolve_odoo` can land them on an existing family rather than minting
54+
one. Where no honest pivot exists, the class stays `None` and the plan
55+
records WHY (genuinely cross-cutting, needs a runtime SPO-G edge not a
56+
static family).
57+
58+
### Group C — StyleCluster wiring
59+
60+
`FamilyEntry` carries `dolce_marker` + `owl_characteristics` but NOT the
61+
default `StyleCluster`. SAVANTS.md inherits the style from the family. Add a
62+
`default_style: StyleCluster` field to `FamilyEntry` (or a sidecar
63+
`family_style(OgitFamily) -> StyleCluster` map if adding a field churns too
64+
many call sites — decide in review). Seed:
65+
0x60→Direct, 0x61→Analytical, 0x62→Analytical, 0x63→Analytical,
66+
0x80→Empathic, 0x81→Direct, 0x90→Empathic.
67+
68+
### Group A — Reasoner impls (largest, scoped here, built in a follow-up PR)
69+
70+
The 25 savants collapse onto **5 `ReasoningKind` discriminants** ×
71+
**5 `InferenceType` strategies**. Decision to pin: implement **one
72+
`Reasoner` per `ReasoningKind`** (CustomerCategory, PostingAnomaly,
73+
NextBestAction, InvoiceCompleteness, Other) that dispatches on
74+
`ReasoningContext.evidence` + the resolved family's style, rather than 25
75+
separate impls. Each `reason()` selects its `QueryStrategy` from
76+
`InferenceType::default_strategy()` (already mapped:
77+
Deduction→CamExact, Induction→CamWide, Abduction→DnTreeFull,
78+
Revision→BundleInto, Synthesis→BundleAcross) and fuses evidence via the
79+
savant's `SemiringChoice` (NarsTruth = the common case). Conclusion type:
80+
a truth-weighted `SavantConclusion { suggestion, confidence: NarsTruth,
81+
rationale }` that woa-rs applies as a **suggestion only**, never an
82+
un-guarded write (Iron Rule 7, verhaltens-bewahrend). Home crate:
83+
`lance-graph-callcenter` (BBB-allowed, already owns `odoo_alignment.rs`).
84+
85+
## Deliverables
86+
87+
- **D-ODOO-SAV-1** (Group B): `0x63 ProductCatalog` + `0x90 HRFoundation`
88+
family constants + seed rows in `odoo_alignment.rs`; `data/family_registry.ttl`
89+
family declarations; product.*/hr.* seed rows. Tests: resolve
90+
product.template→0x63, hr.employee→0x90, end-to-end against live table.
91+
- **D-ODOO-SAV-2** (Group B): Layer-2 alignment axioms TTL for stock.*,
92+
analytic.distribution.model, account.account.tag — land on an existing
93+
pivot where honest, else documented `None`-with-rationale. Tests: the
94+
newly-aligned classes resolve; the genuinely-cross-cutting ones still
95+
return `None` with a recorded reason.
96+
- **D-ODOO-SAV-3** (Group C): `StyleCluster` per family. Field-or-sidecar
97+
decision in review; seed the 7 families; test each family→cluster.
98+
- **D-ODOO-SAV-4** (Group A): `SavantConclusion` + 5 `Reasoner` impls in
99+
`lance-graph-callcenter`, dispatching on `ReasoningKind` + evidence +
100+
family style. Per-impl tests with synthetic `EvidenceRef` batches.
101+
**Gated on a review pass of the dispatch shape.** Its own PR.
102+
103+
## Execution
104+
105+
D-ODOO-SAV-1/2/3 are additive + low-risk → ship together in the first PR
106+
(this session). D-ODOO-SAV-4 (Reasoner impls) is the architectural piece →
107+
scoped here, built in a follow-up PR after a `/code-review` pass on the
108+
dispatch shape. Board-hygiene: this plan + INTEGRATION_PLANS prepend land
109+
in the same commit as D-ODOO-SAV-1.
110+
111+
## Invariants
112+
113+
- Option B holds: odoo classes INHERIT existing slots via OWL pivot; new
114+
families 0x63/0x90 are genuine new basins (product catalogue, HR), not
115+
per-class mints. `None` stays `None` when no honest pivot exists.
116+
- Public OWL/RDF sources stay pristine — alignment axioms are NEW TTL in
117+
`data/ontologies/odoo/alignment/`, not edits to upstream vocabs.
118+
- Savant = Layer-2 role catalogue (I-VSA-IDENTITIES): identity in the
119+
family table, content (evidence/rules) in Arrow/SPO, never bundled.
120+
- Reasoner output is a suggestion; the deterministic guard stays in woa-rs
121+
(verhaltens-bewahrend). lance-graph implements the ambiguous core only.
122+
- No brain-crate in the customer binary (Iron Rule 1): impls live in
123+
`lance-graph-callcenter` behind the contract `Reasoner` trait.

crates/lance-graph-callcenter/data/family_registry.ttl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,16 @@ ogit:MRORepair
161161
ogit.meta:superDomain "WorkOrderBilling" ;
162162
ogit.meta:familyId "99"^^xsd:unsignedByte .
163163

164+
# ProductCatalog 0x64 — product catalogue + pricelist + UoM basin (odoo
165+
# richness harvest, plan odoo-savant-reasoners-v1 D-ODOO-SAV-1). NOTE: the
166+
# woa-rs SAVANTS.md proposal named 0x63 for this, but 0x63=99 is already
167+
# MRORepair above; the lance-graph authoritative registry assigns the next
168+
# free commercial-cluster byte 0x64=100 instead.
169+
ogit:ProductCatalog
170+
a ogit:FamilyNamespace ;
171+
ogit.meta:superDomain "WorkOrderBilling" ;
172+
ogit.meta:familyId "100"^^xsd:unsignedByte .
173+
164174
# ── OSINT basins 0x70..=0x74 ─────────────────────────────────────────────────
165175

166176
ogit:OsintMaltego
@@ -198,6 +208,16 @@ ogit:SmbFoundryTaxDeclaration
198208
ogit.meta:superDomain "SMB" ;
199209
ogit.meta:familyId "130"^^xsd:unsignedByte .
200210

211+
# ── HR basin 0x90 ────────────────────────────────────────────────────────────
212+
# HRFoundation 0x90 — employee / org / job / base-contract basin (odoo
213+
# richness harvest, plan odoo-savant-reasoners-v1 D-ODOO-SAV-1). hr.* resolve
214+
# None today; this basin gives them a home. Payroll ENGINE is odoo Enterprise
215+
# (absent) — only the hr base data/structure is aligned here.
216+
ogit:HRFoundation
217+
a ogit:FamilyNamespace ;
218+
ogit.meta:superDomain "HR" ;
219+
ogit.meta:familyId "144"^^xsd:unsignedByte .
220+
201221
# ── SMB BSON-shape basins 0xA0..=0xAD ────────────────────────────────────────
202222
# OQ-4 resolution (locked 2026-05-13): ogit.SMB.bson: sub-namespace carries the
203223
# 14 BSON-shape entities. Slot range 0xA0..=0xAD (160..=173) is unconflicted

0 commit comments

Comments
 (0)