Commit acb403d
committed
feat(odoo): style_recipe — D-Atom interpretation step (typed SoA → cognitive fingerprint)
The Odoo-static interpretation layer that reads typed `OdooEntity` /
`OdooMethod` / `OdooField` SoA into per-method `StyleRecipe` records:
sparse weighted vectors over 12 D-Atom basis vectors + regulatory
anchors + dispatch hints. This is the bridge between the PR #426 typed
extraction and the upcoming askama bucket-dispatch codegen.
## Where this fits
```
Odoo source
│ (Stage 1, PR #426 — odoo-blueprint-extractor)
▼
Typed Rust SoA ← extracted/{account,sale,…}.rs (OdooEntity[ ])
│ (THIS COMMIT — interpretation, no triplets stored)
▼
StyleRecipe[ ] ← cognitive fingerprint per method
│ (atom weights + regulatory anchors + dispatch hints)
▼
Askama bucket templates (next commit) → Rust Ops + const recipes
│
▼
PaletteCompose SpMV at runtime (cognitive-shader-driver path)
```
## The user-anchored rule
> "Business logic stays in the triplets, but you have to interpret it.
> The interpretation of Odoo lies in Odoo-static [code] that needs to
> be ported."
The triplets (`lance_graph::graph::spo::odoo_ontology` + typed SoA)
stay lossless — we do NOT emit a `has_recipe` triple. The recipe is
re-derived deterministically every codegen run. That's the
"interpretation" half of the rule. Belongs in `lance-graph-ontology`'s
`odoo_blueprint` because that's where Odoo-static interpretation lives;
a Rails frontend writes its own `style_recipe.rs` targeting the same
downstream SoC compiler.
## What lands
- **`DAtom` (12 variants)** — closed basis-vector catalogue: Entity,
Law, FiscalCtx, EmitAmount, ApplyRate, Quantity, Money, Event,
Action, Compute, Validate, Onchange. The architecture diagram excerpt
showed 9; extended by 3 for Odoo-specific dispatch (Onchange cascade,
Compute-vs-Validate split, Helper utility).
- **`StyleRecipe`** — `{ method_id, atoms: Vec<(DAtom, u8)>,
regulation_iris, return_kind, recipe_id: u32 }`. `recipe_id` is a
content-addressed FNV-1a 32-bit digest over the sorted atom-weight
tuples — equivalent methods collapse to one recipe (the dispatcher
exploits this).
- **`derive_style_recipe(&OdooEntity, &OdooMethod) -> StyleRecipe`** —
7-rule deterministic cascade (kind → return_kind → triggers →
field cross-ref → regulation_iri → state_machine participation).
Atom weights are `max`-merged; zero-weight atoms drop out.
- **`derive_corpus_recipes(&[&OdooEntity]) -> Vec<StyleRecipe>`** —
walks an entity corpus, sorted by `method_id` ascending, byte-
deterministic across runs.
## Tests (12 today)
Synthetic fixtures: every D-Atom anchor case + recipe_id determinism
+ atom collapse + corpus sort. Shipped-corpus test
(`shipped_corpus_resolves_kind_driven_atoms_today`) pins both halves of
the Stage-1 reality:
- **must fire today**: Entity, Compute, Validate, Onchange, Action
(kind-driven; resolvable from current extractor output).
- **must NOT fire today**: Money, Quantity, ApplyRate, EmitAmount,
Event, FiscalCtx (need Stage-2 extractor enrichment —
`OdooMethod::return_kind` is mostly Unit, `triggers` empty,
`state_machine` None, `OdooField::computed` cross-refs sparse).
When Stage-2 lands the second list shrinks; the test asks reviewers to
flip atoms from `stage2` to `must` as enrichment lands.
## Architecture invariants
- `lance-graph-ontology` stays light (no new external deps; serde-only
not needed because StyleRecipe doesn't serialise — it's the in-process
codegen IR).
- `lance-graph` itself untouched (Odoo-specific interpretation belongs
in `lance-graph-ontology` per the layering split).
## Review pattern
Built with `/// work` markers → opus-4.8 reviewer (code-only, no
cargo) → orchestrator-run cargo verify.1 parent 0e5ab98 commit acb403d
3 files changed
Lines changed: 768 additions & 0 deletions
File tree
- .claude/board
- crates/lance-graph-ontology/src/odoo_blueprint
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
1 | 15 | | |
2 | 16 | | |
3 | 17 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
76 | 76 | | |
77 | 77 | | |
78 | 78 | | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
79 | 87 | | |
80 | 88 | | |
81 | 89 | | |
| |||
0 commit comments