Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .claude/board/INTEGRATION_PLANS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
## 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)

**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.
**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.
**Plan file:** `.claude/plans/odoo-savant-reasoners-v1.md`
**Predecessors:** PR #412 (odoo hydrator + dolce_odoo classifier + ODOO slot 50), PR #413 (briefing pack).
**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).

### Scope
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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Correct ProductCatalog family byte from 0x63 to 0x64.

This entry currently documents 0x63 ProductCatalog, which conflicts with the current assignment (0x64) and can propagate the wrong constant into follow-up work.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/board/INTEGRATION_PLANS.md at line 10, The documented ProductCatalog
family byte is incorrect: change the `ProductCatalog` family byte value from
`0x63` to `0x64` in the entry that currently reads "Group B — `0x63
ProductCatalog`", updating any mention of `0x63 ProductCatalog` to `0x64
ProductCatalog`; ensure related references in the same paragraph (e.g., any
layer-2 alignment axioms or Family labels) reflect `0x64` so the constant
matches the current assignment.


### Deliverables
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).

### Execution
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.

### Invariants
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.

---

## 2026-05-27 — atom-mailbox-substrate-v1 (ladder-serves-mailbox: atoms→styles→personas, quorum projection, counterfactual mantissa, AriGraph hot/cold/tombstone)

**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).
Expand Down
123 changes: 123 additions & 0 deletions .claude/plans/odoo-savant-reasoners-v1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# odoo-savant-reasoners-v1 — lance-graph side of the Odoo richness harvest

> **Status:** PROPOSAL. Picks up the explicit cross-repo handover boundary
> declared in `lance-graph/.claude/odoo/SAVANTS.md` §"lance-graph handover
> boundary": the woa-rs session defined the 25-Savant roster + delegation
> tuples + call sites + evidence schemas (all contract-level, BBB-allowed);
> the **lance-graph side** must now implement (a) the `Reasoner` impls, (b)
> the two new OGIT families + Layer-2 alignment axioms for the `None`
> classes, (c) the `StyleCluster` wiring.
>
> **Confidence:** HIGH on (b)/(c) — concrete additive extensions of the
> existing `odoo_alignment.rs` seed table + alignment TTLs. MED on (a) — the
> `Reasoner` dispatch shape is an architectural decision (one impl per
> `ReasoningKind` vs a savant-config registry) that this plan pins but which
> needs a review pass before the larger build.
>
> **Predecessors:** PR #412 (odoo hydrator + `dolce_odoo` classifier + ODOO
> slot 50), PR #413 (briefing pack import). Reads on:
> `lance-graph-contract::reasoning` (Reasoner / ReasoningKind / ReasoningContext),
> `lance-graph-callcenter::{family_table, odoo_alignment, unified_bridge}`,
> `lance-graph-contract::thinking::StyleCluster`.
>
> **Anchored iron rules:** I-VSA-IDENTITIES (savant = Layer-2 role catalogue,
> content in tables not bundles), the AGI-as-glove doctrine (savant dispatch
> rides `MetaColumn`/`EdgeColumn`, no new service), board-hygiene.

## Scope

Three deliverable groups, matching SAVANTS.md (a)/(b)/(c):

### Group B — two new OGIT families + Layer-2 alignment axioms (lowest risk, first)

The roster needs homes for classes that resolve to `None` today:

- **`0x63 ProductCatalog`** (basin: product catalogue + pricelist + UoM;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Update all ProductCatalog references from 0x63 to 0x64.

The plan still pins ProductCatalog to 0x63; this conflicts with the corrected allocation and creates a spec mismatch across deliverables/tests. Please normalize all references in this file to 0x64.

Also applies to: 65-65, 87-87, 114-114

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/plans/odoo-savant-reasoners-v1.md at line 35, Update every
occurrence that pins ProductCatalog to the old identifier 0x63 to the corrected
0x64: search for the token "0x63" and any "0x63 ProductCatalog" references in
this plan and replace them with "0x64" (and "0x64 ProductCatalog" where
appropriate), ensuring all mentions (including the other occurrences flagged)
are normalized so the ProductCatalog identifier is consistently 0x64 throughout.

default style **Analytical**). Lands `product.template`,
`product.pricelist`, `product.pricelist.item`, `uom.uom`,
`product.category`. Currently `product.*` inherits `0x61 BillingCore`
slot 1 via the prefix fallback — ProductCatalog promotes the
catalogue/pricing concepts to their own basin so L8's
`PricelistAssignmentAgent` has a real family instead of `None`.
- **`0x90 HRFoundation`** (basin: employee / org; default style
**Empathic**). Lands `hr.employee`→`vcard:Individual`,
`hr.department`→`org:OrganizationalUnit`, `hr.job`, `hr.contract` (base
only — payroll engine is Enterprise/absent, flagged). All `hr.*`
resolve `None` today.
- **Layer-2 alignment axioms** for the remaining `None` classes that do
NOT get a new family (they stay cross-cutting): `stock.*` (stock.move,
stock.rule, stock.warehouse.orderpoint), `account.analytic.distribution.model`,
`account.account.tag`. These get `owl:equivalentClass` / `rdfs:subClassOf`
rows in `data/ontologies/odoo/alignment/` pointing at existing pivots
(e.g. `stock.move`→`schema:MoveAction`-style, analytic→`fibo:CostCenter`)
so `resolve_odoo` can land them on an existing family rather than minting
one. Where no honest pivot exists, the class stays `None` and the plan
records WHY (genuinely cross-cutting, needs a runtime SPO-G edge not a
static family).

### Group C — StyleCluster wiring

`FamilyEntry` carries `dolce_marker` + `owl_characteristics` but NOT the
default `StyleCluster`. SAVANTS.md inherits the style from the family. Add a
`default_style: StyleCluster` field to `FamilyEntry` (or a sidecar
`family_style(OgitFamily) -> StyleCluster` map if adding a field churns too
many call sites — decide in review). Seed:
0x60→Direct, 0x61→Analytical, 0x62→Analytical, 0x63→Analytical,
0x80→Empathic, 0x81→Direct, 0x90→Empathic.

### Group A — Reasoner impls (largest, scoped here, built in a follow-up PR)

The 25 savants collapse onto **5 `ReasoningKind` discriminants** ×
**5 `InferenceType` strategies**. Decision to pin: implement **one
`Reasoner` per `ReasoningKind`** (CustomerCategory, PostingAnomaly,
NextBestAction, InvoiceCompleteness, Other) that dispatches on
`ReasoningContext.evidence` + the resolved family's style, rather than 25
separate impls. Each `reason()` selects its `QueryStrategy` from
`InferenceType::default_strategy()` (already mapped:
Deduction→CamExact, Induction→CamWide, Abduction→DnTreeFull,
Revision→BundleInto, Synthesis→BundleAcross) and fuses evidence via the
savant's `SemiringChoice` (NarsTruth = the common case). Conclusion type:
a truth-weighted `SavantConclusion { suggestion, confidence: NarsTruth,
rationale }` that woa-rs applies as a **suggestion only**, never an
un-guarded write (Iron Rule 7, verhaltens-bewahrend). Home crate:
`lance-graph-callcenter` (BBB-allowed, already owns `odoo_alignment.rs`).

## Deliverables

- **D-ODOO-SAV-1** (Group B): `0x63 ProductCatalog` + `0x90 HRFoundation`
family constants + seed rows in `odoo_alignment.rs`; `data/family_registry.ttl`
family declarations; product.*/hr.* seed rows. Tests: resolve
product.template→0x63, hr.employee→0x90, end-to-end against live table.
- **D-ODOO-SAV-2** (Group B): Layer-2 alignment axioms TTL for stock.*,
analytic.distribution.model, account.account.tag — land on an existing
pivot where honest, else documented `None`-with-rationale. Tests: the
newly-aligned classes resolve; the genuinely-cross-cutting ones still
return `None` with a recorded reason.
- **D-ODOO-SAV-3** (Group C): `StyleCluster` per family. Field-or-sidecar
decision in review; seed the 7 families; test each family→cluster.
- **D-ODOO-SAV-4** (Group A): `SavantConclusion` + 5 `Reasoner` impls in
`lance-graph-callcenter`, dispatching on `ReasoningKind` + evidence +
family style. Per-impl tests with synthetic `EvidenceRef` batches.
**Gated on a review pass of the dispatch shape.** Its own PR.

## Execution

D-ODOO-SAV-1/2/3 are additive + low-risk → ship together in the first PR
(this session). D-ODOO-SAV-4 (Reasoner impls) is the architectural piece →
scoped here, built in a follow-up PR after a `/code-review` pass on the
dispatch shape. Board-hygiene: this plan + INTEGRATION_PLANS prepend land
in the same commit as D-ODOO-SAV-1.

## Invariants

- Option B holds: odoo classes INHERIT existing slots via OWL pivot; new
families 0x63/0x90 are genuine new basins (product catalogue, HR), not
per-class mints. `None` stays `None` when no honest pivot exists.
- Public OWL/RDF sources stay pristine — alignment axioms are NEW TTL in
`data/ontologies/odoo/alignment/`, not edits to upstream vocabs.
- Savant = Layer-2 role catalogue (I-VSA-IDENTITIES): identity in the
family table, content (evidence/rules) in Arrow/SPO, never bundled.
- Reasoner output is a suggestion; the deterministic guard stays in woa-rs
(verhaltens-bewahrend). lance-graph implements the ambiguous core only.
- No brain-crate in the customer binary (Iron Rule 1): impls live in
`lance-graph-callcenter` behind the contract `Reasoner` trait.
20 changes: 20 additions & 0 deletions crates/lance-graph-callcenter/data/family_registry.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,16 @@ ogit:MRORepair
ogit.meta:superDomain "WorkOrderBilling" ;
ogit.meta:familyId "99"^^xsd:unsignedByte .

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

# ── OSINT basins 0x70..=0x74 ─────────────────────────────────────────────────

ogit:OsintMaltego
Expand Down Expand Up @@ -198,6 +208,16 @@ ogit:SmbFoundryTaxDeclaration
ogit.meta:superDomain "SMB" ;
ogit.meta:familyId "130"^^xsd:unsignedByte .

# ── HR basin 0x90 ────────────────────────────────────────────────────────────
# HRFoundation 0x90 — employee / org / job / base-contract basin (odoo
# richness harvest, plan odoo-savant-reasoners-v1 D-ODOO-SAV-1). hr.* resolve
# None today; this basin gives them a home. Payroll ENGINE is odoo Enterprise
# (absent) — only the hr base data/structure is aligned here.
ogit:HRFoundation
a ogit:FamilyNamespace ;
ogit.meta:superDomain "HR" ;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Map the HR family to a recognized super-domain

When loading family_registry.ttl, load_seed() only inserts rows whose ogit.meta:superDomain is accepted by parse_super_domain_name; that matcher does not include "HR", and unknown names are silently skipped. As a result, the newly added family id 0x90 is left as SuperDomain::Unknown in the hydrated family table even though resolve_odoo("hr.employee") now returns FAMILY_HR_FOUNDATION, so HR-aligned classes lose their intended domain/RBAC partition at runtime. Either add an HR super-domain mapping or place the family under an existing recognized super-domain.

Useful? React with 👍 / 👎.

ogit.meta:familyId "144"^^xsd:unsignedByte .

# ── SMB BSON-shape basins 0xA0..=0xAD ────────────────────────────────────────
# OQ-4 resolution (locked 2026-05-13): ogit.SMB.bson: sub-namespace carries the
# 14 BSON-shape entities. Slot range 0xA0..=0xAD (160..=173) is unconflicted
Expand Down
Loading
Loading