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
13 changes: 13 additions & 0 deletions .claude/board/EPIPHANIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,19 @@ _[Original REJECTED verdict retained below, append-only, as the cautionary recor
**GATE (mint fence):** no verb-codebook row is allocated until the kind/verb A/B falsifier is green; **naming a stratum is never mint authorization** (E-VENDOR-DELTA doctrine: spec it, don't fake it). If a route classifier is ever built, it is built in **ruff** on newly-harvested discriminant facts (spec-to-ruff wishlist: HTTP verb / writes / return-shape), phase-named per OGAR-AS-IR — classifier = front-end analysis pass, verb rows = symbol-table entries, recipes = lowering passes — never op-side.

**Cross-ref:** `docs/DISCOVERY-MAP.md` D-ROUTE-KIND-VERB-STRATA (twin); E-ONE-MASK-THREE-PORTS (verb rows argued-for, mint parked); E-AR-DIRECT-SDK (DO-arm landing zone: ActionHandler + unified adapters — placement unchanged by this entry); E-OGAR-CONVERGENCE-SHAPE open seam #2 (ActionDef↔UnifiedStep); op-nexgen `.claude/handovers/2026-07-05-CAPSTONE-ar-shape-convergence.md` C5 + `2026-07-05-ogar-v3-consumer-migration-plan.md` §1/§6; op-nexgen `crates/ruff_python_dto_check/README.md` (the parked sqlx delta).
## 2026-07-06 — E-BODY-TRIAGE-ODOO-CONTROL-1 — F17 Odoo control leg measured: 94.9% order-free recoverable

**Status:** FINDING (measured; drift-fused in the odoo-rs probe)

**The measurement** (2026-07-06, `odoo-rs crates/od-ontology/tests/body_triage_probe.rs`, default build, slice_2 corpus, run verified green; the headline numbers are pinned as drift-fuses inside the probe): 393 lifecycle hooks triaged into verb-classes — guard-pure 44, compute-pure 298, self-feedback 30, write+raise 2, read-only 15, no-facts 4. Headline over the behavioural arm (guards + computes: 357 hooks, 354 resolved): **PASS 336 (94.9%)** — accidentally imperative, order-free recoverable — vs **FAIL 18 (5.1%)**, the order-dependent tail; 3 unresolved (no facts captured) excluded.

**The tail decomposes** into self-feedback (read-modify-write inside one hook) + write+raise (partial-write escape order). **Conservative-bound caveat:** the self-feedback bucket includes `@api.depends` extractor artifacts, so the true order-dependent tail is ≤ the measured 5.1%. Context: onchange 15/17 resolved FAIL — cooperative loops are the genuinely order-dependent shape, as predicted. Cross-hook order is NOT counted here; recompute-DAG Kahn-orderability is re-asserted inside the probe.

**Method:** static order-signature from harvested facts — writes = inverted `emitted_by` (Odoo's declarative `compute=` target; the F17 ledger note "Python frontend leaves writes/calls empty" is exactly why the declarative target is used), reads = `reads_field`, raise = `raises`.

**What it means for F17:** the Odoo CONTROL leg is measured and behaves as a control should — 94.9% recoverable is consistent with "already declarative". D‑ACCIDENTAL‑IMPERATIVE stays **[H]** until the Rails TEST leg (`before_*`/`after_*` via `ruff_ruby_spo` writes/calls) runs — that is the remaining [H] gate.

**Cross-ref:** INTEGRATION-MAP F17 row (amended in place with the Odoo control-leg RUN annotation, same session), F15/F16 Odoo RUNs (recipe collapse / chaining collapse — the sibling probes on the same corpus).

---

Expand Down
2 changes: 1 addition & 1 deletion docs/INTEGRATION-MAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ R2 — not D.)
| F14 | **Wide-model render** | render `account.move` through `ClassView` with full presence (**>64 is the load-bearing bound; 109 declarations counted** in account_move.py, Odoo 17) | **gated: cannot RUN until Phase B** wires the field-enum into `RegistryClassView`; once runnable, fails by construction (FieldMask u64, L0b) until presence exceeds u64 — **Track X7 is the named path** |
| F15 | **AR-recipe collapse** (`PROBE-OGAR-AR-RECIPE-COLLAPSE`) | measure how much of a consumer's lifted behavioural arm folds to the shared ActiveRecord-lifecycle recipe + per-class override bitmask vs genuine per-class leftover. **Odoo upper-bound RUN** (`odoo-rs tests/recipe_redundancy_probe.rs`, default build, slice_2): guard arm 47→1 full-collapse, compute arm 101 distinct of 141 resolved, **45.7% collapse / 54.3% leftover**; clean run is Rails/OpenProject where `ruff_ruby_spo` captures `callbacks` as first-class `Model` data | D‑RECIPE‑BITMASK `[H]→[G]` when the Rails-AR clean run lands near the ~7% leftover target; the Odoo bound already refutes the strong "Odoo→7%" reading |
| F16 | **Constructor-chaining collapse** (`PROBE-OGAR-CHAINING-COLLAPSE`) | the inheritance axis: naive flatten (own + inherited copies) vs chained (stored once at the base `LazyLock<ClassView>` constant) over a consumer's `inherits_from` DAG. **Odoo RUN** (`odoo-rs tests/recipe_chaining_collapse.rs`, full manifest, 388 classes / 166 edges / 3328 methods): naive 4215 vs chained 3328 → **21.0% collapse / 22.7% behavioural**; top base `mail_activity_mixin` (324 copies). Chain-order correctness = F1; acyclic DAG | D‑RECIPE‑BITMASK‑CHAIN `[H]→[G]` (measured); confirms chaining resolves F15's "out-of-slice" upper bound — the real leftover sits below it; orthogonal to F15, stacks. Rails leg (concerns captured) should exceed Odoo's collapse |
| F17 | **Body-triage / accidentally-imperative ratio** (`PROBE-OGAR-BODY-TRIAGE`) | run the body pass over real hooks → `(target classid, verb-class, order-signature)` per hook → **round-trip-order-free** each coarse group (does the order-free `(verb,criteria)` reproduce the source output?). PASS-rate = the accidentally-imperative (recoverable) fraction; FAIL-rate = the order-dependent / essentially-foreign (preserve/escape) tail. Control = Odoo `_compute_*` (already declarative); test = Rails `before_*`/`after_*` | D‑ACCIDENTAL‑IMPERATIVE / D‑FUNCTION‑CATALOG `[H]→[G]`. ~~**Gated on a ruff extension:** capture writes/calls per function (today: reads/raises/traverses only) so "calls update on X" is extractable~~ **Prerequisite SHIPPED 2026-06-30** (AdaWorldAPI/ruff @ `claude/odoo-rs-transcode-lf8ya5`, commit `dd70588`): `ruff_spo_triplet::Function` gains `writes` (self.<field>= setters → `writes_field`, Authoritative) + `calls` (lifecycle-mutator dispatches as "receiver.method" → `calls`, Inferred); the `ruff_ruby_spo` body walker populates both from the Rails AST (closed `AR_MUTATORS` set). "calls update on X" is now extractable → **F17 is RUNNABLE** (probe still to author/run). Python frontend leaves them empty (Odoo write target already declarative via `Field::emitted_by`) |
| F17 | **Body-triage / accidentally-imperative ratio** (`PROBE-OGAR-BODY-TRIAGE`) | run the body pass over real hooks → `(target classid, verb-class, order-signature)` per hook → **round-trip-order-free** each coarse group (does the order-free `(verb,criteria)` reproduce the source output?). PASS-rate = the accidentally-imperative (recoverable) fraction; FAIL-rate = the order-dependent / essentially-foreign (preserve/escape) tail. Control = Odoo `_compute_*` (already declarative); test = Rails `before_*`/`after_*`. **Odoo control-leg RUN** (2026-07-06, `odoo-rs tests/body_triage_probe.rs`, default build, slice_2, run verified green, numbers pinned as drift-fuses in the probe): 393 lifecycle hooks; verb-classes guard-pure 44 / compute-pure 298 / self-feedback 30 / write+raise 2 / read-only 15 / no-facts 4; headline (behavioural arm = guards + computes: 357 hooks, 354 resolved): **PASS 336 (94.9%)** accidentally imperative, order-free recoverable / **FAIL 18 (5.1%)** order-dependent tail — decomposing into self-feedback (read-modify-write inside one hook; conservative, includes `@api.depends` extractor artifacts, so true tail ≤ measured) + write+raise (partial-write escape order); 3 unresolved (no facts captured) excluded; context: onchange 15/17 resolved FAIL — cooperative loops are the genuinely order-dependent shape, as predicted; cross-hook order NOT counted (recompute-DAG Kahn-orderability re-asserted inside the probe); method = static order-signature from harvested facts — writes = inverted `emitted_by` (Odoo's declarative `compute=` target; the ledger note below, "Python frontend leaves them empty", is exactly why the declarative target is used), reads = `reads_field`, raise = `raises` | D‑ACCIDENTAL‑IMPERATIVE / D‑FUNCTION‑CATALOG `[H]→[G]`. ~~**Gated on a ruff extension:** capture writes/calls per function (today: reads/raises/traverses only) so "calls update on X" is extractable~~ **Prerequisite SHIPPED 2026-06-30** (AdaWorldAPI/ruff @ `claude/odoo-rs-transcode-lf8ya5`, commit `dd70588`): `ruff_spo_triplet::Function` gains `writes` (self.<field>= setters → `writes_field`, Authoritative) + `calls` (lifecycle-mutator dispatches as "receiver.method" → `calls`, Inferred); the `ruff_ruby_spo` body walker populates both from the Rails AST (closed `AR_MUTATORS` set). "calls update on X" is now extractable → **F17 is RUNNABLE** (probe still to author/run). Python frontend leaves them empty (Odoo write target already declarative via `Field::emitted_by`). **Odoo CONTROL leg MEASURED 2026-07-06** (94.9% order-free recoverable — consistent with "already declarative", the control behaving as a control should); D‑ACCIDENTAL‑IMPERATIVE stays `[H]` until the Rails TEST leg (`before_*`/`after_*` via `ruff_ruby_spo` writes/calls) runs |

(F3 already carries the D‑QUANTGATE pre/post-quantization contrast.
F10–F13 restore the DISCOVERY-MAP §4.2 jc×hpc floor that v1.0 omitted —
Expand Down
Loading