-
Notifications
You must be signed in to change notification settings - Fork 0
feat(odoo-spo): FK target/inverse_name (P1) + deep reads_field (P0) corpus enrichment #523
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,22 @@ | |
| **The leptonica epiphany:** leptonica is an *install*, not a transcode. It is only a *link* dep of the C++ oracle harness — never in the Rust path (the unicharset path is text parsing, never touches `Pix`). Transcoding leptonica (~250k LOC of pointer-heavy C image-processing, the hand-port category) is the far-off zero-C end-state, NOT a prerequisite to prove the pipeline. The whole "we need the operator's leptonica host" framing collapsed to one `apt-get`. | ||
|
|
||
| **Scope (honest):** this proves the unicharset adapter's id↔unichar bijection + content-store tier at byte-parity — the doctrine's designated falsifier (`PROBE-OGAR-ADAPTER-UNICHARSET`), now FINDING. The `classid → ClassView → UnifiedStep` dispatch wiring is mechanical remainder; each future method-body leaf is its own parity check, but the core-first adapter pattern is no longer a conjecture. Cross-ref: `core-first-transcode-doctrine.md` § falsifier RESULT; `transcode-extend-core-probe-v1.md` § BYTE-PARITY ACHIEVED. | ||
| ## 2026-06-17 — E-ODOO-FK-DEEP-READS — P1 FK-target is the prerequisite for P0 deep-`reads_field`; the cross-language predicate shape (ruff#18) is ratified, and the audit's MISSED-1 is an ordering EDGE, not a cycle | ||
|
|
||
| **Status:** FINDING (shipped on branch `claude/odoo-spo-fk-target-deep-reads`). The Odoo SPO corpus (`graph/spo/odoo_ontology.spo.ndjson`) gains two additive predicate families via `tools/odoo-blueprint-extractor/odoo_blueprint_extractor/spo_enrich.py`: **618 `target` + 102 `inverse_name`** (P1) and **736 deep `reads_field`** (P0). 22 245 → 23 701 triples. lance-graph-side: 9 `odoo_ontology` tests green (incl. 2 new enrichment tests); extractor: 14 new `spo_enrich` unit tests + the existing uom smoke test green. Idempotent (re-run adds 0). | ||
|
|
||
| **The coupling (the structural insight).** P0 (deep `reads_field`) is **not independent of** P1 (FK `target`) — it is *built on* it. To lift `@api.depends('line_ids.amount_residual')` into a deep read on the right model, the generator must resolve `line_ids → account.move.line` — which IS the P1 target map. So the work order is forced: P1 first (build the relation map), then P0 resolves dotted depends paths through it. A session that tries P0 alone re-derives P1 implicitly and worse. | ||
|
|
||
| **The predicate shape is cross-language-ratified, not invented.** `AdaWorldAPI/ruff#18` lifted Rails `belongs_to :owner, class_name:'User'` into a sibling triple `(WorkPackage.owner, class_name, "User")` — a triple keyed by the relation IRI whose object is the *raw* target class string. We match that shape exactly: `(odoo:account_move.line_ids, target, "account.move.line")` + `(…, inverse_name, "move_id")`. Object is the raw Odoo dotted model name (NOT an `odoo:` IRI), so `od-ontology::RelationMap::from_corpus` reads it directly. The wishlist's named phantom-target case (`invoice_line_ids`, whose `<parent>_<stem>` convention misses `account.move.line`) is fixed by the same emission. | ||
|
|
||
| **The honest correction — MISSED-1 is an ordering edge, not a cycle (cross-repo-verified).** The task framing expected the deep-read lift to make odoo-rs's `slice_2_compute_subset_no_cross_model_cycle` test's no-cycle assertion *fail* (a cycle appears). It does **NOT**, and faking it would be wrong. Verified locally against `od_ontology::RecomputeDag` on a slice-2-scoped enriched fixture: | ||
| - **Baseline (surface reads):** 0 cross-model compute edges. `_compute_amount`'s only relevant read is the relation `account_move.line_ids` (no emitter → no edge). The line→move dependency is structurally invisible. | ||
| - **Enriched (deep reads):** the edge `account_move_line._compute_amount_residual → account_move._compute_amount` IS present (27 compute edges total). This is **exactly the wishlist's P0 acceptance** — the cross-model recompute-ordering dependency becomes a structural annotation, retiring the hand-audit ritual. | ||
| - **But still acyclic.** The dependency is *unidirectional*: `account.move._compute_amount` reads line fields; `account.move.line._compute_amount_residual` reads only same-model line fields and never reads back any field `_compute_amount` emits (verified: no method reads any `_compute_amount` output). The audit's "logically circular" framing is a *semantic* circularity (filtering by a computed `reconciled` field inside the body), not a `reads_field`↔`emitted_by` structural back-edge. So `RecomputeDag` correctly sees an ordering edge (line-before-move), not a cycle, and the no-cycle assertion legitimately still holds. | ||
|
Comment on lines
+9
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
rg -n "account_move_line\\._compute_amount_residual|account_move\\._compute_amount|RecomputeDag|slice-2|27 compute edges|MISSED-1" \
crates tools .claude/boardRepository: AdaWorldAPI/lance-graph Length of output: 14845 🏁 Script executed: # Check if the 27-edge count is validated in any test
rg -n "27.*compute.*edge|edge.*count|compute_edges|RecomputeDag" \
--type rust --type python crates tools .claude/board -A 2 | head -100Repository: AdaWorldAPI/lance-graph Length of output: 98 🏁 Script executed: # Look for test files related to RecomputeDag in odoo-rs (might be referenced)
fd -type f \( -name "*test*" -o -name "*spec*" \) crates tools | grep -i odooRepository: AdaWorldAPI/lance-graph Length of output: 238 🏁 Script executed: # Check if spo_enrich.py or its tests validate the edge enrichment
cat -n tools/odoo-blueprint-extractor/tests/test_spo_enrich.py | grep -i "27\|edge\|comput" | head -20Repository: AdaWorldAPI/lance-graph Length of output: 618 🏁 Script executed: # Search for edge count validation in tests and source
rg "27" tools/odoo-blueprint-extractor/tests/test_spo_enrich.pyRepository: AdaWorldAPI/lance-graph Length of output: 49 🏁 Script executed: # Check the actual test file to understand what it validates
head -50 tools/odoo-blueprint-extractor/tests/test_spo_enrich.pyRepository: AdaWorldAPI/lance-graph Length of output: 1570 🏁 Script executed: # Search for RecomputeDag tests in odoo-rs references or any test that validates the graph
rg -i "no.*cycle|acyclic|topolog" crates tools .claude/boardRepository: AdaWorldAPI/lance-graph Length of output: 50380 🏁 Script executed: # Check if there's a reference to the odoo-rs repository commit or test in the board
rg -i "d8a270d|odoo-rs.*commit" .claude/boardRepository: AdaWorldAPI/lance-graph Length of output: 5307 Point to a reproducible test or fixture that validates the 27-edge + no-cycle claim. The enrichment generator (
The board doc (AGENT_LOG.md) captures the findings, but not in a form a reviewer can re-run. 🤖 Prompt for AI Agents |
||
|
|
||
| **Consequence for the consumer.** odoo-rs should adopt the enriched corpus (`RelationMap::from_corpus` becomes whole-corpus, the 14-row hand-crafted `slice_2.relations.ndjson` obsolete), and re-frame its P0 expectation from "catch a cycle" to "emit `DEFINE FUNCTION`/`DEFINE EVENT` in the topological order the new cross-model edges now impose." Their adoption is their call (silence-is-alignment); no odoo-rs change was committed. | ||
|
|
||
| **Generation-path finding.** The corpus's documented original generator (`emit_ontology2.py` over `methods.parquet`) is **absent from the tree** — only its output is committed. The blueprint extractor (`tools/odoo-blueprint-extractor`) emits typed Rust `OdooEntity` consts into `lance-graph-ontology`, a *separate* artifact from the SPO ndjson. The enrichment therefore runs over the shipped corpus + the present Odoo source (`/home/user/odoo/addons`), which is the same tree the extractor parses — additive, deterministic, idempotent. This is the right stage given the missing regenerator. | ||
|
|
||
| ## 2026-06-17 — E-MATERIALIZED-AWARENESS-2 — the driver wire is live (provenance-only); the four vocabularies are one 2-axis structure | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Scope claim is too narrow.
This entry says the PR is "lance-graph only", but the shipped list also includes the Python extractor and its test suite. Please widen the scope text so the board log matches the actual diff surface.
🤖 Prompt for AI Agents