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
18 changes: 18 additions & 0 deletions .claude/board/AGENT_LOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
## 2026-06-17 — odoo SPO corpus enrichment: P1 FK-target + P0 deep-reads_field (UPSTREAM_WISHLIST)

**Main thread (Opus) — single implementer**, branch `claude/odoo-spo-fk-target-deep-reads`. Implements the odoo-rs `UPSTREAM_WISHLIST` P1 (FK `target`/`inverse_name`) + coupled P0 (deep `reads_field`) corpus enrichment, lance-graph only.

**Shipped:**
- `tools/odoo-blueprint-extractor/odoo_blueprint_extractor/spo_enrich.py` (new, stdlib-only): builds a `(model, field) → (comodel, inverse)` relation map from `/home/user/odoo/addons` via `ast`, then (P1) emits `target`/`inverse_name` sibling triples keyed by the relation IRI (ruff#18 shape, raw dotted comodel object) for every relational field on a corpus-declared model, and (P0) resolves each dotted `@api.depends` path through the map and lifts a deep `reads_field` onto the field's emitting method. Additive, deterministic, idempotent (`(s,p,o)` dedup); self-loops dropped; unknown-hop paths skipped + counted. CLI: `python3 -m odoo_blueprint_extractor.spo_enrich --corpus … --addons …`.
- `crates/lance-graph/src/graph/spo/odoo_ontology.spo.ndjson` regenerated: 22 245 → **23 701** triples (**+618 `target`, +102 `inverse_name`, +736 deep `reads_field`**; 567 dotted-path skips for unknown hops).
- `crates/lance-graph/src/graph/spo/odoo_ontology.rs`: module-doc updated (new predicates + provenance/regeneration note), triple-count test 22 245→23 701, histogram test extended (`target`=618, `inverse_name`=102, `reads_field`=2 831), 2 new tests (`enrichment_emits_fk_target_and_inverse_name`, `enrichment_emits_cross_model_deep_reads_field`).
- `tools/odoo-blueprint-extractor/tests/test_spo_enrich.py` (new): 14 unittest cases (path resolution, P1/P0 emission, dedup/idempotence, self-loop drop, unknown-model guard).

Comment on lines +3 to +10

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 | 🟡 Minor | ⚡ Quick win

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
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/AGENT_LOG.md around lines 3 - 10, The scope description in the
first line stating the work is "lance-graph only" is inaccurate because the
shipped components include both the Python extractor module
(tools/odoo-blueprint-extractor/odoo_blueprint_extractor/spo_enrich.py) and its
test suite (tools/odoo-blueprint-extractor/tests/test_spo_enrich.py) in addition
to the lance-graph changes. Update the scope text to accurately reflect that
this work spans both the Python extraction tooling and the lance-graph corpus
enrichment, removing the "lance-graph only" restriction so the board log matches
the actual diff surface.

**Tests:** lance-graph `cargo test -p lance-graph --lib odoo_ontology` 9/9 green; `action_emitter`/`spo` green (no regression — function count 3 328 unchanged, `_ =>{}` dispatch absorbs new predicates). Extractor `python3 -m unittest tests.test_spo_enrich` 14/14 + `tests/test_smoke_uom.py` green. `cargo fmt` + `cargo clippy -p lance-graph --lib` clean.

**Cross-repo validation (LOCAL ONLY, no odoo-rs commit):** built a slice-2-scoped enriched fixture, ran `od_ontology::RecomputeDag` from a throwaway `origin/main` worktree. **Baseline:** 0 cross-model compute edges, edge `_compute_amount_residual → _compute_amount` ABSENT. **Enriched:** 27 compute edges, that cross-model edge PRESENT — the wishlist's P0 ask (visible cross-model ordering) is delivered. **Correction:** the graph stays acyclic; the MISSED-1 dependency is an *ordering edge*, not a cycle (move depends on line; line does not depend back on move's totals), so odoo-rs's `slice_2_compute_subset_no_cross_model_cycle` no-cycle assertion legitimately still holds. Reported, not faked. Worktree removed.

**Finding:** the corpus's original generator (`emit_ontology2.py` over `methods.parquet`) is absent from the tree; the blueprint extractor emits typed Rust `OdooEntity` consts (separate artifact). Enrichment runs over shipped corpus + present Odoo source — the correct additive stage. See `EPIPHANIES.md` E-ODOO-FK-DEEP-READS.

---

## 2026-06-17 — W3+W4a atomic read/write shim landed (BindSpace→MailboxSoA migration, first behaviour-touching step)

**Main thread (Opus) — single implementer**, on branch `claude/bindspace-mailbox-soa-w3-w4a` (plan v2 already committed). Sole-owner working tree; ran cargo freely against the shared `target/`.
Expand Down
16 changes: 16 additions & 0 deletions .claude/board/EPIPHANIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

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 | 🟡 Minor

🧩 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/board

Repository: 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 -100

Repository: 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 odoo

Repository: 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 -20

Repository: 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.py

Repository: 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.py

Repository: 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/board

Repository: 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/board

Repository: 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 (tools/odoo-blueprint-extractor/spo_enrich.py) and its unit tests are auditable, but the entry's "verified locally" claim lacks a persistent reference. The local worktree validation was discarded. Add either:

  • A test fixture within this repo (slice-2-scoped enriched corpus + a validation script that asserts edge count and acyclicity), or
  • A cross-repo reference to odoo-rs's test suite (once they adopt the enriched corpus) that validates the no-cycle assertion against RecomputeDag.

The board doc (AGENT_LOG.md) captures the findings, but not in a form a reviewer can re-run.

🤖 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/EPIPHANIES.md around lines 9 - 12, The document claims 27
compute edges and no-cycle acyclicity that were verified locally but the
verification cannot be reproduced. Add a persistent test fixture or validation
mechanism: either create a slice-2-scoped enriched corpus within this repo with
a validation script that runs the enrichment generator and asserts both the edge
count and acyclicity using RecomputeDag, or add a documented cross-repo
reference to odoo-rs's test suite that validates these claims against the
no-cycle assertion. This makes the claim auditable and re-runnable by future
reviewers instead of relying on discarded local worktree validation.


**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

Expand Down
2 changes: 2 additions & 0 deletions .claude/board/LATEST_STATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

---

> **2026-06-17 — IN PR (branch `claude/odoo-spo-fk-target-deep-reads`)** — Odoo SPO corpus enrichment (odoo-rs `UPSTREAM_WISHLIST` P1 + coupled P0). The corpus `crates/lance-graph/src/graph/spo/odoo_ontology.spo.ndjson` now carries **two new predicate families** (was 7 predicates: `depends_on / emitted_by / has_function / raises / rdf:type / reads_field / traverses_relation`): **`target`** (618) + **`inverse_name`** (102) — the relational comodel/inverse keyed by the relation IRI, ruff#18 sibling-triple shape `(odoo:account_move.line_ids, target, "account.move.line")`; and **+736 deep `reads_field`** (so `reads_field` 2 095 → 2 831) — each `@api.depends('rel.leaf', …)` resolved through the new target map and lifted onto the field's emitting method as a transitive read. Corpus 22 245 → **23 701** triples. New stdlib-only generator `tools/odoo-blueprint-extractor/odoo_blueprint_extractor/spo_enrich.py` (+14 unit tests) reads `/home/user/odoo/addons` (the same source the ORM extractor parses) to build the `(model, field) → (comodel, inverse)` map; additive, deterministic, idempotent. `odoo_ontology.rs` doc + tests updated (count 23 701, histogram incl. new predicates, 2 new enrichment tests); `action_emitter`/`spo` unaffected (function count 3 328 unchanged). **Cross-repo finding (verified, not faked):** the deep reads make the cross-model recompute-ordering edge `account_move_line._compute_amount_residual → account_move._compute_amount` *visible* to `od_ontology::RecomputeDag` (baseline: 0 cross-model compute edges → enriched: 27), delivering the wishlist's P0 ask — but the audit's MISSED-1 is a unidirectional *ordering edge*, NOT a cycle, so odoo-rs's `slice_2_compute_subset_no_cross_model_cycle` no-cycle assertion legitimately still holds (the "circularity" is semantic, not a `reads_field`↔`emitted_by` back-edge). The corpus's original generator (`emit_ontology2.py`/`methods.parquet`) is absent from the tree — only its output is committed; enrichment runs at the correct additive stage over the shipped corpus + present source. See `EPIPHANIES.md` E-ODOO-FK-DEEP-READS.

> **2026-06-17 — IN PR (branch `claude/bindspace-mailbox-soa-w3-w4a`)** — W3+W4a atomic read/write shim, the first behaviour-touching step of the BindSpace→MailboxSoA migration. New `cognitive-shader-driver::backing` module (`pub(crate)`): `BackingStore<'a>` (read) + `BackingStoreWrite<'a>` (write) — an enum with a `Singleton(&BindSpace)` arm (live default) and a `#[cfg(feature = "mailbox-thoughtspace")] Mailbox(&MailboxSoA<1024>)` arm. New Cargo feature **`mailbox-thoughtspace`** — **default-OFF, NOT in `lab`**; production stays singleton-read+write until W7. `driver.run()` keeps ONE body: all six dispatch reads (meta_prefilter / qualia17d / content_row / edge / entity_type / len) re-pointed through a `self.backing()` selector (`const DEFAULT_MAILBOX: MailboxId = 0`, `debug_assert!(mailboxes.len() <= 1)`, singleton fallback when no mailbox registered); `ontology()` stays on the singleton (re-home is W4b). Gates: **W2 differential** (`tests/w2_differential.rs`, 4 tests) asserts the WHOLE `ShaderCrystal` bit-identical (`f32::to_bits()`) across both arms incl. a non-zero-window case + non-vacuity; firewall CI lint (`tests/firewall.rs`) bars the two `CausalEdge64` twins (`ndarray::hpc::causal_diff` / `thinking_engine::layered`) from `src/`; field-isolation matrix + cycle-drop footprint (~6 KB/row vs ~71.6 KB) in `mailbox_soa.rs`. `unbind_busdto` C5 downgrade: cycle-plane index recovery feature-gated OUT under `mailbox-thoughtspace` (cycle plane never migrated — D-DIST-5), headline survives via `qualia[9]`; singleton build keeps bit-exact recovery. Tests: default **97 lib + 2 firewall + 2 e2e**; feature-on **98 lib + 2 firewall + 2 e2e + 4 w2**; clippy `--all-targets` (both cfgs) + fmt clean on touched files. **Pre-existing P0 surfaced (NOT introduced, NOT fixed here):** the `with-engine` build does not compile on `main`/HEAD (`engine_bridge.rs:259` uses `QUALIA_DIMS` without importing it); the busdto round-trip tests have never run, and (separately) the D-CSV-5b i4-qualia cutover breaks the `codebook_index` round-trip (stored in i4 `qualia[9]`, ±7 range, cannot hold a u16). Left untouched to keep scope to W3+W4a — flagged for operator. Plan: `.claude/plans/bindspace-mailbox-soa-w3-w4a-impl-v1.md`.
>
> **2026-06-16 — MERGED #512** (perturbation-sim review fixes + **core-first transcode doctrine**): +591/-5 across 11 files. **Code fixes (review of #511):** `examples/calibrate.rs` divide-by-zero guard on degenerate grid; `src/hhtl.rs::basin_lambda2` `assert_eq!(keys.len(), grid.n, …)` precondition (silent corruption→loud panic); `TECH_DEBT.md` MD018 reflow. **Doctrine (the structural delivery):** new mandatory-read `core-first-transcode-doctrine.md` (218 LOC) + 3 new agent cards (`core-first-architect`, `core-gap-auditor`, `adapter-shaper`) + `BOOT.md`/`README.md` wires + EPIPHANIES entry + CLAUDE.md (+21 LOC, doctrine wire-up — NEW content unread by this session). Likely directly aligned with the ontology-first stance the operator locked on odoo-rs. Branch `claude/happy-hamilton-0azlw4`, merge `1e23c410`. 75 lib tests + clippy + fmt clean.
Expand Down
Loading
Loading