Skip to content

Commit 4837a97

Browse files
committed
docs: relocate Odoo/Redmine landing plan to docs/ (durable; per .claude/AGENTS.md §Forbidden) — addresses Codex P1 on #133
1 parent ab165f5 commit 4837a97

1 file changed

Lines changed: 171 additions & 0 deletions

File tree

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# Odoo + Redmine/OpenProject — ERP/planning landing plan (OGAR)
2+
3+
> **Companion to `docs/OGAR-TRANSPILE-SUBSTRATE.md`** (the per-class transpile
4+
> machine — lift + mint + emit — landed in OGAR #132). This is the durable
5+
> ERP/planning *landing plan*: how Odoo (ERP) + Redmine/OpenProject (planning)
6+
> land in OGAR in the *best native-yet-agnostic-yet-truthful* shape — "Odoo"/
7+
> "Redmine" are **labels**; the **ontology** is the canonical ERP/planning
8+
> form, and lance-graph is the Foundry it executes on. (Relocated from
9+
> `.claude/handovers/` per `.claude/AGENTS.md` §Forbidden — durable docs live
10+
> in `docs/`.)
11+
12+
---
13+
14+
## 0. The frame (do not re-derive)
15+
16+
- **OGAR = the transpiler** (transpile-time): `ogar-from-*` parse a source AST →
17+
the SPO/`ModelGraph` IR → classids, `ClassView`s, facets. It *produces shapes*.
18+
- **lance-graph = the Palantir-Foundry-shaped execution** (runtime): where those
19+
shapes run / store / think. Consumers (medcare-rs, woa, smb, and the
20+
ERP/planning apps) **execute on lance-graph**.
21+
- **Connecting tissue** (BBB-allowed in any consumer binary): `lance-graph-contract`
22+
/ `-ontology` / `-ogar` / `-callcenter`. The BBB bars only the **brain/engine**
23+
crates (planner, cognitive engine).
24+
- **"Odoo" / "Redmine" are render labels** (the hi-u16 `AppPrefix`): Odoo=`0x0002`,
25+
OpenProject=`0x0001`, Redmine=`0x0007`. The **lo-u16 canonical concept** is the
26+
shared, agnostic identity. Same concept across apps ⇒ same lo-u16.
27+
28+
## 1. Mission: native + agnostic + truthful
29+
30+
- **Native:** faithful to the source's real model (Odoo's ORM fields/associations/
31+
methods; Rails/AR `belongs_to`/`has_many`/`validates`/`acts_as_*`).
32+
- **Agnostic:** the landed shape is the **universal ERP/planning ontology**, not an
33+
Odoo/Rails-specific struct. The label drops; the concept stays.
34+
- **Truthful (lossless):** nothing dropped. Each member lands in an ontology target
35+
(below); the 16-byte facet is just the content-addressed index over it.
36+
- **Adjacent (drift-free):** ontologically-related concepts share a `part_of:is_a`
37+
prefix; identity is by **reference** (one ClassView / one adapter, never copies);
38+
the canonical codebook is single-source ("pull, never re-mint").
39+
40+
## 2. The import contract (per member — the truthful shape)
41+
42+
| source member | lands as | drift-proofing |
43+
|---|---|---|
44+
| `has_field` | a `ClassView` slot | reference |
45+
| `field_type` | the **type's** `ClassView` (recursive — types are classes) | reference, not copy |
46+
| `has_function` / Odoo method / AR callback | **ActionDef/KausalSpec ontology + a consumer wrapper over reusable OGAR adapters** (logic *extracted as ontology*, not reimplemented; for ERP this is the posting/validation behaviour) | shared adapter |
47+
| object type | the **shared codebook concept id** | canonical id |
48+
| ERP ontology glue (the ICD-analogue) | **FIBO** (finance grounding) + **DOLCE** (upper) + **SKR03/04** + l10n_de regulation IRIs (HGB/UStG/GoBD) | hierarchy / pivot |
49+
50+
> Over-cap classes (`>= 256` members — Odoo has god-models) **branch** via the SoC
51+
> lint (`ruff_spo_address::soc` / `soc_branches`): data → ClassView(s) (paginate via
52+
> class hierarchy if `> 64` distinct types), behaviour → ActionDefs/adapters. Branch,
53+
> never widen.
54+
55+
## 3. What already exists (grounded — build on it, don't reinvent)
56+
57+
**odoo-rs** (private):
58+
- `od-ontology` — SPO triple corpus (`triple.rs`, ~13 predicates × 4 NARS bands);
59+
`schema_to_classes` / `emit_via_ogar` (`ogar_bridge.rs`) lower Odoo → `ogar_vocab::Class`
60+
(pulls classids via `OdooPort`, a pure static lookup — no bridge object/registry).
61+
- `od-posting`**GoBD double-entry** posting host (gapless Belegnummer +
62+
inalterability hash chain). This is the ERP *behaviour* arm.
63+
- `alignment::ODOO_SEED` (`pivot_uri` + DOLCE + `label_uri`, keyed by odoo_class) +
64+
`data/ontologies/odoo/alignment/odoo-to-fibo.ttl` — the FIBO pivot already exists
65+
on the Odoo side.
66+
67+
**lance-graph** (`crates/lance-graph-ontology/src/odoo_blueprint/`):
68+
- ~404 curated + huge auto-extracted `OdooEntity` consts (`account` 685 KB, `stock`
69+
383 KB, `l10n_de_chart` 864 KB / SKR03-04 **2466 rows** + **37 UStVA Kennzahlen**),
70+
with fields, methods, state machines, German `regulation_iri` anchors.
71+
- `class_signature.rs` `StructuralSignature` / `shape_families` (FNV-1a histogram) —
72+
**the route/form duplication clustering** (collapse identical-shape classes to one
73+
shared ClassView).
74+
- `hydrators/{odoo,dolce_odoo,fibo}.rs` — Odoo hydrated as `OGIT::ODOO_V1` inheriting
75+
`FIBOFND_V1` (FIBO Foundations).
76+
77+
**OGAR** (the transpiler): `ogar-from-ruff` (Python/Odoo SPO frontend),
78+
`ogar-from-rails` (Rails/AR), `docs/{ODOO-TRANSCODING,ODOO-DIGEST-TO-OGIT,FOUNDRY-ODOO-MARS-LENS}.md`.
79+
80+
**ruff** (the SPO frontends + mint):
81+
- `ruff_spo_triplet` — closed **60-predicate** vocab, the neutral `ModelGraph` IR,
82+
`expand``reassemble` (NOTE: `reassemble` is **C++-projection-only today** — a
83+
general reassembler is the first build item if you round-trip Python/Ruby).
84+
- `ruff_spo_address` — the 16-byte facet mint (`mint_with_classid(triples, classid_of)`),
85+
`soc` + `soc_branches` (the SoC lint, ruff PR #33).
86+
- `ruff_ruby_spo` — Ruby/Rails frontend (lib-ruby-parser, `app/models`, **27
87+
OpenProject AR predicates**); `NAMESPACE="openproject"`.
88+
- `ruff_python_dto_check` — Python harvester (→ JSON bundles; needs a `bundle →
89+
ModelGraph` adapter to enter the same IR door).
90+
91+
**lance-graph-contract** (the tissue):
92+
- `ogar_codebook.rs``CODEBOOK` (`0xDDCC` concept ids), `canonical_concept_id`,
93+
`AppPrefix`, `render_classid`. **The cross-app join key.**
94+
- `class_view.rs``ClassView` (trait), `FieldMask`, `RenderRow`, `FieldRef`.
95+
- `facet.rs` + `facet_schema.rs` (lance-graph PR #619, **merged**) — the 16-byte
96+
facet with classid-selected format (`6×2` cascade | `4×3` SPO | `2×48`).
97+
98+
**Convergence proof (the agnostic identity, already wired):**
99+
`crates/lance-graph-ogar/tests/bridge_codebook_convergence.rs` — OpenProject
100+
`WorkPackage` & Redmine `Issue``project_work_item 0x0102`; `TimeEntry` /
101+
`Stundenzettel` / Odoo `account.analytic.line``billable_work_entry 0x0103`;
102+
Odoo `account.move`+`sale.order``commercial_document 0x0202`; `product.template`
103+
`product 0x0207`; `account.account``accounting_account 0x0208`.
104+
105+
## 4. Redmine / OpenProject (the parallel landing — same methodology)
106+
107+
- Frontend: `ogar-from-rails` / `ruff_ruby_spo` over `app/models` (the AR shape:
108+
`belongs_to`/`has_many`/`validates`/`acts_as_list`/callbacks → the 27 AR predicates).
109+
- Identity: `WorkPackage`/`Issue``0x0102`; `TimeEntry``0x0103` (shared with Odoo
110+
— that 0x0103 convergence is the planner↔ERP billable-hours pin).
111+
- Render: the **"17-year Redmine QueryColumn evolution"** lands as the `ClassView` +
112+
`FieldMask` line-view (`ogar-render-askama::list_view`, `render_rows`) — the same
113+
field-view primitive medcare's views use.
114+
115+
## 5. The cross-domain map (the Foundry payoff — LATER, easy once truthful)
116+
117+
ERP ↔ planning ↔ health align at the **ontology plane**, by:
118+
- **shared lo-u16 codebook concept** (the de-facto `owl:equivalentClass`, expressed
119+
as a u16) — *the only mechanism wired today*;
120+
- **FIBO/DOLCE pivots** (Odoo already has `odoo-to-fibo.ttl`; author the symmetric
121+
twins so domains inherit a common FIBO/DOLCE category via `ContextBundle.inherits_from`).
122+
123+
## 6. Gaps the session must close (from the ontology-preservation verification)
124+
125+
1. **Carry the codebook concept through the mint** — always stamp `facet_classid`
126+
via the OGAR resolver; **never ship `classid=0`** (no join key, no ontology).
127+
2. **Promote groundings to typed data** — give each `CODEBOOK` row an optional
128+
`{ogit_uri, dolce_category, fibo_equivalent_class}` (lift today's doc-comment
129+
annotations), and thread it through the mint (don't drop it at the `_ =>` arm).
130+
3. **FK facet → registry** — put the concept u16 on `MappingRow` (O(1) facet →
131+
`OntologyRegistry`; today it's indirect `ogit_uri` string-match).
132+
4. **Fix the OWL hydrator** — store subject→object edges so `rdfs:subClassOf` is
133+
reconstructable (today it flattens s/p/o into one `iri_to_id`; TTL export hardcodes
134+
a flat `rdfs:subClassOf ogit:Entity`).
135+
5. **Behaviour arm** — land Odoo methods / AR callbacks as `ActionDef` ontology +
136+
reusable adapter, **not** reimplemented (od-posting's GoBD logic is the test case).
137+
6. **Land `odoo_blueprint` extracted entities as OGAR `Class`** via
138+
`od-ontology::schema_to_classes` (the future `od-ontology-bridge` binary).
139+
140+
## 7. Hard constraints
141+
142+
- Lossless + truthful **now**; cross-domain tissue **later** (don't let mapping drive
143+
the import shape).
144+
- OGAR = transpiler; lance-graph = Foundry execution. Tissue crates in the binary;
145+
brain/engine crates out (BBB).
146+
- Canonical codebook is single-source: **pull, never re-mint** (drift-guarded by
147+
`codebook_ids_match_ogar_vocab`).
148+
- SoC lint fires at `>= 256` members → branch.
149+
- No German PII; **no model/session identifier in any committed artifact**; audit
150+
never egresses.
151+
152+
## 8. First moves (ordered)
153+
154+
1. Land **one Odoo model end-to-end** (e.g. `account.move``0x0202`): SPO →
155+
`ModelGraph``Class` (via `schema_to_classes`) → mint with classid → facet,
156+
with its FIBO/DOLCE grounding **retained** (Gap #2). Round-trip it.
157+
2. Do the **OpenProject twin** (`WorkPackage``0x0102`) — prove the agnostic
158+
convergence (same concept, two app labels) on a real model, not just the test.
159+
3. Promote the grounding tuple on `CODEBOOK` (Gap #2) + the `MappingRow` FK (Gap #3).
160+
4. Then scale `odoo_blueprint` (the 404 entities) through the same path.
161+
162+
## 9. References
163+
164+
- Merged: lance-graph #619 (`facet_schema`), ruff #32 (polyglot AST RFC), OGAR #130
165+
(V3-transpiler ADR), lance-graph #620 (node-block layout — resolved: flexible
166+
per-classid, first GUID already encodes location+relations).
167+
- In-flight: ruff #33 (`soc` + `soc_branches`, SoC lint).
168+
- Verification: ontology-preservation (workflow over ruff/lance-graph/odoo-rs);
169+
the cross-domain mapping is codebook-keyed today, FIBO/DOLCE pivots aspirational.
170+
- medcare-rs board `EPIPHANIES` E-7…E-19 (the substrate clarifications; E-18→E-19
171+
correct the OGAR-transpiler / lance-graph-Foundry polarity).

0 commit comments

Comments
 (0)