You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs(plans/poc): §16 — WoA Python original integrates Odoo via cheap ontology schema lookup module
User question: how should the WoA Python original proceed when
integrating Odoo, while aligning with the plans — especially
around a "cheap Odoo Ontology Schema lookup store"?
Architecture: build-time-extracted Python lookup module
(woa-ontology-lookup) that mirrors the TTL files Rust's
lance-graph-ontology::OntologyRegistry already consumes. Same
TTL source feeds both languages; each gets a native reader; no
Odoo runtime dependency on either side.
§16 NEW — covers:
§16.1 Architecture diagram showing the same TTL files in
lance-graph/data/ontologies/ feeding both the Rust hydrators
(per PR-407/408) and a new Python build script that emits a
flat _data.py module with module-level constants. The Python
lookup module is READ-ONLY DATA generated at build time;
never parses TTL at request time.
§16.2 Cost table for "cheap": O(1) dict access; ~1-5 MB
resident; one pip install dep; ZERO additional runtime deps;
~5-30s build-time CPU. Stefan's deployment gets one
pip install. No new services / ports / workers.
§16.3 Four-phase Python rollout (~5-6 days total):
- P1 bootstrap (~1 day): woa-ontology-lookup package skeleton
+ build_lookup.py consuming OGIT WoA + DOLCE + PROV-O + QUDT
TTL files (already shipped post-PR-407).
- P2 Odoo integration (~1 day, gated on D-ODOO-2/3 Rust-side):
extend build script to consume Odoo base extraction +
alignment files. lookup adds odoo_equivalent field.
- P3 runtime integration (~1-2 days, gated on P2): add helper
methods to WoA models; REST API responses include JSON-LD
@context; structured logging carries ontology URIs.
- P4 federation surface (~2 days, gated on P3): /api/<entity>/
<id>/rdf endpoints emit Turtle/JSON-LD/N-Triples via rdflib;
optional /sparql endpoint.
§16.4 Concrete Python package shape: dataclass OntologyMapping;
lookup(table, column) → Optional[OntologyMapping]; module-level
LOOKUP, TABLE_TO_OGIT_URI, OGIT_URI_TO_FIBO, CONTEXT_JSONLD
constants in _data.py. ~250 entries covering all WoA entities.
§16.5 Ownership map:
- lance-graph (this repo): source-of-truth TTL +
python/woa_ontology_lookup/ sub-tree with build script;
publishes versioned package.
- WoA Python: single requirements.txt line; pure consumer.
- woa-rs: already consumes via OntologyRegistry. Both
languages are native readers of one source of truth.
§16.6 Payoffs for WoA Python BEFORE Rust port replaces anything:
1. Schema-conscious API responses (JSON-LD @context)
2. Odoo parity drift checks at build time
3. Federation via standard linked-data tools
4. Schema-drift detection earlier in pipeline than
WoaMysqlReconciler catches it
5. Cognitive-model preparation: Python exports via federation
surface; Rust cognitive cascade ingests; two-version bridge
from Odoo distillation §"The two-version bridge".
§16.7 What this DOES NOT do:
- Does NOT change WoA's data model (Iron Rule №5 preserved)
- Does NOT add Odoo runtime deps (no odoo-bin, XML-RPC, ORM)
- Does NOT introduce reasoning into Python (no OWL reasoner,
no SPARQL engine, no SHACL validator at runtime)
- Does NOT compete with woa-rs
§16.8 Cross-references to §14.5 D-ODOO-1..10, §4.2/4.6/4.7
governance, the Odoo work-steal distillation §"The two-version
bridge", and the woa-rs/CLAUDE.md Iron Rules envelope.
The constraint envelope: WoA Python stays canonical (Iron Rule
№2); doesn't break the source repo (Iron Rule №5); gets schema
awareness via build-time extraction; ships independently of
the Rust port progress; benefits Stefan even before woa-rs
PR-5 lands.
Copy file name to clipboardExpand all lines: .claude/plans/lance-graph-business-logic-poc-via-woa-rs-v1.md
+189Lines changed: 189 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -498,3 +498,192 @@ This is what makes the POC achievable in ~7-8 days net per §12.6 — the substr
498
498
499
499
> Odoo and Palantir Foundry converge on a typed-object semantic surface that reduces to OWL/SHACL/SKOS+PROV-O; OGIT/OWL/DOLCE is positioned to host both as projections (Odoo via extraction + alignment; Foundry via SPARQL/SHACL projection). The long-run lessons are six: typed-object surface IS a projection not a separate ontology; operational vocabulary needs an extraction source; DOLCE-as-root is the load-bearing structural decision; alignment TTL authoring workflow matters; per-OGIT-storage + read-only-spine + CAM-bar-codes compose into a self-reinforcing pattern; PROV-O is non-optional for any regulated domain. WoA work-steals ~80% of its Customer + Tenant + User + Vorgang + Position + Logbook + Dokument entity shapes from Odoo's `base` + `account` + `mail.thread` modules; ~80% of its consumer-crate scaffolding (woa-bridge, woa-ontology, unified-bridge constructor, reconciler shell, agent ensemble) from smb-office-rs's templates. The actual invention surface is ~5 deliverables, ~250 LOC. The 6 months of lance-graph substrate + sister-consumer-plan harvest + Odoo OWL glue + RFC v02-006 codegen collectively cover ~90% of what WoA's POC PR-5 needs.
500
500
501
+
502
+
---
503
+
504
+
## 16 — WoA Python original: Odoo integration via cheap ontology schema lookup store (2026-05-21, same session)
505
+
506
+
User question: how should the WoA Python original proceed when integrating Odoo, while aligning with the plans — especially around a "cheap Odoo Ontology Schema lookup store"?
507
+
508
+
**Constraint reminder.** WoA Python (`AdaWorldAPI/WoA`, Stefan's deployment at localhost + Railway) is **canonical**: per `woa-rs/CLAUDE.md` Iron Rule №2, "Python is the spec; behavioural parity is the spec," and Iron Rule №5, "do not break the source repo." Stefan's Python WoA runs in production; the Rust port mirrors it. So Python-side Odoo integration must NOT change WoA's data model, NOT add Odoo runtime dependencies (`odoo-bin`, XML-RPC, ORM imports), NOT break Stefan's deployment, and MUST stay parity-safe so the Rust port can keep mirroring.
509
+
510
+
The right architecture: a **build-time-extracted Python lookup module** that gives Python WoA the same ontology awareness `lance-graph-ontology::OntologyRegistry` gives the Rust side at runtime. Same TTL source feeds both; each language gets a native reader; no Odoo runtime dependency on either side.
511
+
512
+
### 16.1 Architecture — the build-time-extracted Python lookup module
The Python lookup module is **read-only data** generated from the same TTL files the Rust hydrators consume. Both languages get the same view. Updates flow through the source TTL → rerun build → ship a new lookup version → Python consumer upgrades. **The Python side never parses TTL at request time.**
556
+
557
+
### 16.2 What "cheap" means concretely
558
+
559
+
| Cost dimension | Target |
560
+
|---|---|
561
+
| Runtime CPU per lookup | O(1) dict access. No string parsing, no graph traversal, no Odoo XML-RPC, no SPARQL. |
562
+
| Runtime memory |~1-5 MB resident for the full lookup dict (~9 entity tables × ~30 fields × ~10-field mapping shape). |
563
+
| Build-time CPU |~5-30 s to extract once when TTL/alignment changes. Runs at `pip install` or `make ontology-lookup`. |
564
+
| Deps added to WoA Python |**One** package: `woa-ontology-lookup`. **ZERO** additional runtime deps. Optional: `rdflib` (~2 MB) only if §16.3 P4 federation surface ships. |
565
+
| Stefan's deployment impact |`pip install woa-ontology-lookup`. No new services, no new ports, no background workers. Flask restart. |
566
+
| Failure modes | Lookup miss returns `None` (silent passthrough). Build-time errors caught at extraction, never at runtime. |
567
+
568
+
This matches the "cheap" the user named. WoA stays a Flask+SQLAlchemy app with one extra `pip install`. No architectural surgery.
569
+
570
+
### 16.3 The four-phase Python rollout
571
+
572
+
Each phase ships independently. Python phases gate on Rust-side D-ODOO-* deliverables landing but ship without coordinating release cycles.
|**P1 — bootstrap**| Create `woa-ontology-lookup` Python package: skeleton + extraction script (`build_lookup.py`) consuming OGIT WoA + DOLCE + PROV-O + QUDT TTL files (already shipped post-PR-407/408). Emit `_data.py` with module-level constants. Pure read-only API in `__init__.py`. Tests on the constant shape. | None — TTL already exists in `lance-graph/data/ontologies/`. |~1 day |`from woa_ontology_lookup import lookup`; `lookup('customer', 'firma')` returns the OGIT URI for the Customer.firma field. |
577
+
|**P2 — Odoo integration**| Once D-ODOO-2 (Odoo `base` extraction) + D-ODOO-3 (alignment files) land in `lance-graph`, extend the build script to consume them. Adds `lookup('customer', 'firma').odoo_equivalent` etc. | D-ODOO-2 + D-ODOO-3 (Rust-side; ~1 weekend + 1 evening per §14.5). |~1 day Python-side |`customer.odoo_equivalent_of('firma')` returns `'odoo:res.partner.name'`. Schema-parity check against Odoo's source-of-truth field names becomes a one-line lookup. |
578
+
|**P3 — runtime integration**| Add helper methods to WoA Python's models (`models.Customer.ogit_uri()`, `.fibo_equivalent_of(field)`, `.as_jsonld_context()`). Update REST API responses to include the JSON-LD `@context` derived from the lookup. Optional: structured-logging fields carry ontology URIs alongside table/column names. | P2 done. |~1-2 days Python-side | API responses include `"@context": { "firma": "fibo:hasLegalName", ... }`. Linked-data tools can consume WoA's REST API natively. |
579
+
|**P4 — federation surface**| Add `/api/<entity>/<id>/rdf` endpoints that return the record as RDF triples in the shared ontology (Turtle / JSON-LD / N-Triples via content negotiation). Uses `rdflib` to emit; the lookup module supplies the predicate URIs. Optional `/sparql` read-only endpoint for federated queries. | P3 done. |~2 days Python-side | Federated tools (linked-data clients, Foundry-shape ETL, external XBRL/XRechnung validators) consume WoA records natively. |
580
+
581
+
**Total Python-side effort: ~5-6 days for all four phases.** Stefan benefits from P3 (richer API responses) even before woa-rs PR-5 ships — i.e., the Python WoA gets schema-conscious before the Rust port does anything customer-visible.
582
+
583
+
584
+
### 16.4 The minimal package shape — concrete code skeleton
585
+
586
+
```python
587
+
# woa_ontology_lookup/__init__.py
588
+
from ._data importLOOKUP, TABLE_TO_OGIT_URI, OGIT_URI_TO_FIBO, CONTEXT_JSONLD
589
+
590
+
from dataclasses import dataclass
591
+
from typing import Optional
592
+
593
+
@dataclass(frozen=True)
594
+
classOntologyMapping:
595
+
ogit_uri: str# canonical OGIT URI
596
+
fibo_equivalent: Optional[str] # fibo-be-le-lp:LegalEntity#hasLegalName if applicable
597
+
odoo_equivalent: Optional[str] # odoo:res.partner.name if applicable
598
+
vcard_equivalent: Optional[str] # vcard:Kind#fn if applicable
# User + Mahnung + Logbook + Dokument + Setting × ~30 fields each
638
+
}
639
+
640
+
TABLE_TO_OGIT_URI= {
641
+
'customer': 'ogit.WorkOrder:Customer',
642
+
'workorder': 'ogit.WorkOrder:WorkOrder',
643
+
'position': 'ogit.WorkOrder:Position',
644
+
'mandant': 'ogit.WorkOrder:Tenant',
645
+
# ...
646
+
}
647
+
648
+
CONTEXT_JSONLD= { ... } # per-table @context blob
649
+
```
650
+
651
+
### 16.5 Where this lives, who owns it
652
+
653
+
| Repository | Role | What lives here |
654
+
|---|---|---|
655
+
|**`lance-graph`** (this repo) | source-of-truth TTL + alignment + extraction script |`data/ontologies/*.ttl` (incl. Odoo extraction output once D-ODOO-2 lands); a `python/woa_ontology_lookup/` sub-tree with `build_lookup.py` that converts TTL → `_data.py`. Build artifacts versioned + published to a Python index (PyPI or private) as `woa-ontology-lookup-<sha>.tar.gz`. |
656
+
|**`WoA`** (Python original, Stefan's source-of-truth app) | consumer | Single `requirements.txt` line: `woa-ontology-lookup~=1.0`. Use the package in models / routes / API responses. NO TTL files, NO build script — pure consumer. |
657
+
|**`woa-rs`** (Rust port) | consumer | Already gets the same data via `lance-graph-ontology::OntologyRegistry` per the POC plan. The Python lookup module and the Rust OntologyRegistry are **two language-native readers of one source of truth**. |
658
+
659
+
This matches §4.6 read-only spine governance verbatim: writes flow through `MappingProposal::sha256()`-keyed dedup into the TTL files in `lance-graph`; both languages read; neither mutates. The Python package is the Python-language reader, analogous to the Rust `OntologyRegistry` being the Rust-language reader.
660
+
661
+
### 16.6 What this UNLOCKS for WoA Python
662
+
663
+
Concrete payoffs Stefan sees in WoA Python BEFORE the Rust port replaces anything:
664
+
665
+
1.**Schema-conscious API responses.** WoA's REST routes return JSON-LD `@context` per response, so any linked-data client (or a Foundry-style ingest pipeline) reads WoA's API output as semantic data without a separate mapping step. ~1 day of Python work after P3.
666
+
2.**Odoo parity checks at build time.** When Odoo updates `l10n_de_skr04` and the Rust side picks up the change via D-ODOO-6, the Python lookup regenerates; any WoA field that drifts from the canonical Odoo shape is flagged at build time. CI gate.
667
+
3.**Federation via standard tools.**`/api/customer/<kdnr>/rdf` returns Turtle / JSON-LD / N-Triples. Stefan's accountant runs an external XBRL validator or XRechnung tool against WoA output without manual format conversion. Removes a class of "but Odoo does X, WoA doesn't" friction.
668
+
4.**Drift detection before the Rust reconciler ships.**`python manage.py check-ontology-drift` spot-checks WoA's sqlalchemy schema against the OGIT WoA TTL. New columns missing from the TTL get flagged. Catches what `WoaMysqlReconciler` would catch at runtime — but earlier.
669
+
5.**Cognitive-model preparation.** Once the Rust side's cognitive substrate is wired (per §14.7 D-ODOO-10 end-state), Python WoA EXPORTS records via the federation surface (`/api/<entity>/<id>/rdf`) and the Rust cognitive cascade reasons about them natively. This is the "Python ERP layer + Rust core" two-version bridge from `b9531cf3-odoo_work_steal_distillation.md` §"The two-version bridge" — Python doesn't change; Rust ingests via the federation surface.
670
+
671
+
### 16.7 What this does NOT do
672
+
673
+
-**Does NOT change WoA Python's data model.** The lookup module is a side-table — it says what URI corresponds to a field; it doesn't change what fields exist. Iron Rule №5 (don't break the source repo) preserved.
674
+
-**Does NOT add Odoo runtime dependencies.** No `odoo-bin`, no XML-RPC, no SQLAlchemy-on-Odoo's-PostgreSQL. Odoo information is EXTRACTED at build time and FROZEN into the Python module. Pure cache.
675
+
-**Does NOT introduce ontology reasoning into WoA Python.** No OWL reasoner, no SPARQL engine, no SHACL validator running in the Python process. Reasoning stays in the Rust cognitive substrate where it belongs.
676
+
-**Does NOT compete with woa-rs.** The Python lookup module and the Rust `OntologyRegistry` serve different processes; both read the same TTL. WoA Python keeps doing what it does; woa-rs ships the cognitive integration; the lookup module is shared schema awareness between them.
677
+
678
+
### 16.8 Cross-references
679
+
680
+
- §14.5 (D-ODOO-1..10) — the Rust-side Odoo extraction this Python phase consumes.
-`unified-bridge-consumer-migration-v1.md` §4.6 (read-only spine + controlled write path) — governance applies to the Python lookup module verbatim: it reads, never mutates.
683
+
-`unified-bridge-consumer-migration-v1.md` §4.7 (per-OGIT storage) — Python lookup is organized by table-as-G-slot-analog; one dict subset per OGIT family.
-`woa-rs/CLAUDE.md` Iron Rule №2 + №5 — the constraint envelope this proposal stays inside.
686
+
687
+
### 16.9 One-line summary
688
+
689
+
> WoA Python integrates Odoo via a build-time-extracted Python lookup module (`woa-ontology-lookup`) that mirrors the TTL files Rust's `lance-graph-ontology::OntologyRegistry` already consumes — same source, two language-native readers, no Odoo runtime dependency. ~5-6 days of Python work across 4 phases delivers: schema-conscious REST API responses (JSON-LD `@context`), build-time Odoo-parity drift checks, federation surface (`/api/<entity>/<id>/rdf`) for external linked-data tools, and the substrate the Rust cognitive cascade ingests over for the two-version-bridge end-state. WoA's data model stays untouched (Iron Rule №5 preserved); Stefan's deployment gets one `pip install`. Python phases gate on Rust-side D-ODOO-2 + D-ODOO-3 landing but ship independently after.
0 commit comments