Skip to content

Commit 180e591

Browse files
committed
handover: recipe integration Phase 2 plan + session kickoff prompt
Self-contained handover for a fresh session to execute Phase 2 (wire recipe_concept_from_surface into the ogar-from-ruff lift): mandatory reads, the architecture in one screen, the verified gap ledger, the Phase 2 work order (additive Option<RecipeConceptId> on the lift facets), the C5 A/B measurement gate, the operator branch-consumability decision, the Scope/Concern mint-on-emit triggers, the session's hard lessons, and a copy-paste kickoff prompt (§9). Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SqGtdddWRV8BHwhrtuaWLN
1 parent 34fa06c commit 180e591

1 file changed

Lines changed: 166 additions & 0 deletions

File tree

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
# Recipe integration — Phase 2 handover + integration plan (2026-07-05)
2+
3+
> **What this is.** A self-contained handover so a fresh session can execute
4+
> Phase 2 of the recipe-integration arc without re-deriving context. Phase 1
5+
> (the recipe-concept codebook + the lift-time resolver) is **shipped** on
6+
> branch `claude/openproject-nexgen-ogar-review-mkjtpq`. The copy-paste
7+
> **session kickoff prompt** is §9 at the bottom.
8+
9+
---
10+
11+
## 0. Mandatory reads (in this order — do NOT skip)
12+
13+
1. **OGAR `CLAUDE.md`** + `docs/DISCOVERY-MAP.md` + `docs/INTEGRATION-MAP.md` (session preamble).
14+
2. **This arc's canon**`.claude/board/EPIPHANIES.md`, newest first:
15+
- `E-RECIPE-FAMILIES-MINT-ON-EMIT` — Scope/Concern reserved, mint-on-emit.
16+
- `E-RECIPE-CODEBOOK-MINTED-P1` — what Phase 1 shipped.
17+
- `E-GRAMMAR-IS-THE-RECIPE-SHAPE` — the `<port>::<path>(<shape>)` = SPO-triple unification (the WHY of the whole codebook).
18+
- `E-F17-PREREQ-VERIFIED` — the gap ledger, verified in code.
19+
- `E-RECIPE-REUNION-ORDER` — the operator ORDER (the reunion; ORM-for-schema+actions-only; keep AR; Redmine ancestry; ERB→askama).
20+
- `E-ROUTE-KIND-VERB-STRATA`**SUPERSEDED**; read only as the cautionary record of a mis-framed council.
21+
3. **The two docs a shallow read skipped this session (READ BEFORE ANY recipe/route/fieldmask work):**
22+
- `docs/CLASSVIEW-FIELDVIEW-ASKAMA-BITMASK.md` — route dedup IS SoC; `FIELD_MASK_CAP = MAX_SIBLINGS_PER_TIER` (one cap).
23+
- op-nexgen `.claude/knowledge/RAILS-COVERAGE-KIT.md` §5 — the four recipe families + `RecipeConceptId` + `LabelDto` spec (what Phase 1 implements).
24+
4. **`docs/OGAR-AS-IR.md`** — MANDATORY before adding a field to `Class` / a variant to `ActionDef` (Phase 2 does exactly this).
25+
26+
---
27+
28+
## 1. Where we are — Phase 1 SHIPPED
29+
30+
`crates/ogar-vocab/src/recipe.rs` (new `pub mod recipe`):
31+
32+
- `RecipeConceptId(u16)` — a **typed newtype** (not bare `u16` like `class_ids`): a recipe id `0x0101` and class id `0x0101` (`project`) are numerically equal but different address spaces; the newtype makes mixing them a compile error.
33+
- `RecipeFamily``Lifecycle 0x01` / `Guard 0x02` / `Relation 0x03` / `Action 0x04` (+ `0x05`/`0x06` **reserved** for Scope/Concern, unminted — §7).
34+
- 27 promoted concepts in `recipe_ids::*` (RESERVE-DON'T-RECLAIM), `RECIPE_CODEBOOK`, `recipe_concept_id` / `recipe_concept_name` (forward/reverse, exact siblings of `canonical_concept_id`/`_name`), `recipes_in_family`.
35+
- **`recipe_concept_from_surface(surface, lang) -> Option<RecipeConceptId>`** — the lift-time predicate resolver. Ruby + Odoo relation surfaces seeded; the verb-side convergence pin (`belongs_to``Many2one``REL_MANY_TO_ONE`) is machine-checked.
36+
- 13 unit tests + 3 doctests green (106 lib total, zero regressions), clippy + fmt clean.
37+
38+
---
39+
40+
## 2. The architecture in one screen (so you don't re-derive it)
41+
42+
`E-GRAMMAR-IS-THE-RECIPE-SHAPE`: a recipe **is** a canonicalized SPO triple, and the invocation grammar `<port>::<path>(<shape>)` is that triple.
43+
44+
| grammar | SPO leg | canonicalized by | status |
45+
|---|---|---|---|
46+
| `<path>` = `part_of::is_a` | **subject** — class facet → classid | `ruff_spo_address::mint` (noun codebook, `class_ids`) | shipped |
47+
| `<shape>`'s **verb** | **predicate** — the recipe | `RecipeConceptId` (`ogar_vocab::recipe`) | **codebook shipped; not yet wired** |
48+
| `<shape>` `input[type]` | **object** — typed payload | schema/association stratum | shipped |
49+
50+
The "zoo" = the surface predicate string (`Triple.p` is a `String`). `recipe_concept_from_surface` is the canonicalizer. Phase 2 makes the lift call it.
51+
52+
---
53+
54+
## 3. Gap ledger — verified in code (do NOT restate stale doc claims)
55+
56+
- **(a) writes/calls capture — CLOSED.** `Function::{writes, calls}` shipped in `ruff_spo_triplet` (`ir.rs:264-284`), populated by the Ruby walker, emitted as `writes_field`/`calls` triples.
57+
- **(b) `routes.rb` stratum — OPEN.** HTTP verb / member-collection / return-shape — the Action-kind fact source. Upstream ruff work; not required for Phase 2 (Action surfaces are seeded from `HandlerKind` names today).
58+
- **(c) recipe-concept codebook — HALF-CLOSED.** Codebook + resolver shipped (Phase 1). Phase 2 closes it by wiring.
59+
60+
---
61+
62+
## 4. Phase 2 — the work (the critical path)
63+
64+
**Goal:** the harvested recipe predicates carry their `RecipeConceptId`, so the codebook stops being a parked resolver and the reunion's behaviour arm is canonicalized end-to-end.
65+
66+
**The one design decision (gated by `OGAR-AS-IR.md`): where the id attaches.** Recommended (smallest reviewable, zero-break): an **additive `Option<RecipeConceptId>`** on the lift facets — `None` for unresolved — leaving `Triple.p` as the label skin. Do NOT re-encode the triple predicate itself in this pass.
67+
68+
**Concrete steps:**
69+
70+
1. **`ogar-vocab`** — add `Option<RecipeConceptId>` fields:
71+
- on the DO-arm `ActionDef` (the Action-kind of a controller method);
72+
- on the `Class` recipe facets that already exist — `Association`, `Validation`/guard, `Callback` (the Relation / Guard / Lifecycle kinds).
73+
- All types are `#[non_exhaustive]` already, so this is additive. Default `None`.
74+
2. **`ogar-from-ruff`** (`src/lib.rs``lift_actions`, `lift_association`, and the validation/callback lifts) — resolve the surface via `recipe_concept_from_surface(surface, RecipeLang::Ruby)` and populate the `Option`:
75+
- callbacks: the phase token before the `:` in `"<phase>:<target>"``LIFECYCLE_*`.
76+
- validations: the kind string → `GUARD_*`.
77+
- associations: the assoc kind → `REL_*`.
78+
- actions (controller methods from `extract_tree_with`): the `HandlerKind` name → `ACTION_*`.
79+
3. **Tests** (`-p ogar-vocab -p ogar-from-ruff`): a fixture `Model` → lift → assert the ids stamped; **re-assert the convergence pin at the lift level** — OP `belongs_to` and Redmine `belongs_to` both stamp `REL_MANY_TO_ONE`.
80+
4. **Board hygiene:** prepend `E-RECIPE-CODEBOOK-WIRED` (gap (c) → CLOSED), update the gap ledger; mirror a one-line note in op-nexgen's board.
81+
82+
**Scope discipline:** `cargo test -p ogar-vocab -p ogar-from-ruff`; `cargo clippy -p …`; **NEVER `--all` / `--all-targets` from OGAR** (path-deps would drag siblings — the tesseract-rs iron rule applies to any path-dep workspace).
83+
84+
---
85+
86+
## 5. After Phase 2 — the measurement gate (the C5 A/B)
87+
88+
The pre-registered **OP⇄Redmine verb A/B** (`E-RECIPE-REUNION-ORDER`, redmine-op plan C5): classify both ports' route/recipe surfaces and measure the shared-`RecipeConceptId` collapse rate. **Pre-register the KILL threshold (collapse-rate %) BEFORE running** — the noun side (26/26) is *asserted*, not measured, so the verb side may not borrow it as a measured precedent. This is distinct from the noun-side convergence and does not stand in for it.
89+
90+
---
91+
92+
## 6. ⚠ The operator decision that blocks consumer adoption — CONSUMABILITY
93+
94+
All recipe work is on `claude/openproject-nexgen-ogar-review-mkjtpq`, but **op-nexgen (and every consumer) deps OGAR via `branch = "claude/odoo-rs-transcode-lf8ya5"`** (the convergence branch). So `ogar_vocab::recipe` is **NOT reachable by any consumer** until it lands on the convergence branch OR the consumer dep is repointed. That is a branch/merge-strategy decision for the **operator** — do not unilaterally repoint or retarget. Phase 2 itself is fully doable OGAR-side without resolving this; consumer adoption (op-nexgen's `OpHandlerKind``RecipeConceptId`, retiring the per-consumer enum) is what's gated.
95+
96+
---
97+
98+
## 7. Scope / Concern — reserved, mint ON EMIT (do NOT pre-mint)
99+
100+
`E-RECIPE-FAMILIES-MINT-ON-EMIT` (operator rule). Bytes reserved, no variant/concept until the emit seam exists:
101+
102+
- **`0x05` Scope** — mint when the ruff **DTO-AST route-dedup** path emits a named filtered view (Rails `scope`/`default_scope`, or a `ClassView` fieldmask standing in for N routes).
103+
- **`0x06` Concern** — mint when the **god-object split** emits it (the `ruff_spo_address::soc` `Conflation` verdict → sub-ClassViews; Rails `concerns`/mixins).
104+
105+
Phase 2's controller-action lift may be where Scope first wants to emit (a scoped index handler). If so, mint it then — not before.
106+
107+
---
108+
109+
## 8. Hard lessons from this session — do NOT repeat
110+
111+
1. **Do NOT run the 5+3 council against a standing operator ruling.** This session convened a council that *rejected* the route-dedup↔SoC unification as "mere rhyme" — but the operator had canonized it a week earlier; the council was mis-framed (never pointed at the rulings). Read the plans; execute canon; only council genuinely-new claims.
112+
2. **Verify gap-ledger claims in CODE before restating them.** A stale "ruff captures reads not writes" claim propagated into a board entry; the code had shipped `writes` months earlier. Grep the symbol, read the source.
113+
3. **Read `CLASSVIEW-FIELDVIEW-ASKAMA-BITMASK.md` + `RAILS-COVERAGE-KIT.md` §5 before ANY recipe/route/fieldmask work.** The whole mis-framing traced to not reading them.
114+
4. **Scope cargo to `-p <crate>`; never `--all` from OGAR.**
115+
5. **Board is append-only:** regrade `**Status:**` in place, prepend corrections; never edit an entry body.
116+
117+
---
118+
119+
## 9. SESSION KICKOFF PROMPT (copy-paste to start the next session)
120+
121+
```
122+
You are continuing the OGAR recipe-integration arc. Phase 1 (the recipe-concept
123+
codebook `ogar_vocab::recipe` + the lift-time resolver `recipe_concept_from_surface`)
124+
is SHIPPED on branch `claude/openproject-nexgen-ogar-review-mkjtpq`. Your task is
125+
Phase 2: wire the resolver into the `ogar-from-ruff` lift so harvested recipe
126+
predicates carry their canonical `RecipeConceptId`.
127+
128+
FIRST, read (mandatory, in order):
129+
- OGAR CLAUDE.md, docs/DISCOVERY-MAP.md, docs/INTEGRATION-MAP.md
130+
- .claude/handovers/2026-07-05-recipe-integration-phase-2-handover.md (full context + the Phase 2 spec — §4 is your work order)
131+
- .claude/board/EPIPHANIES.md — the top 6 entries (the recipe arc)
132+
- docs/CLASSVIEW-FIELDVIEW-ASKAMA-BITMASK.md
133+
- docs/OGAR-AS-IR.md
134+
- openproject-nexgen-rs/.claude/knowledge/RAILS-COVERAGE-KIT.md §5
135+
136+
Those entries carry OPERATOR RULINGS. They are canon — execute them, do NOT
137+
re-litigate. In particular: do NOT run the 5+3 council to "test" the
138+
route-dedup↔SoC unification or the AR-shape reunion; a council did that this
139+
session and wrongly rejected settled canon (see E-ROUTE-KIND-VERB-STRATA,
140+
SUPERSEDED). Verify any gap-ledger claim in code before restating it.
141+
142+
THEN execute handover §4:
143+
- ogar-vocab: additive `Option<RecipeConceptId>` on `ActionDef` + the `Class`
144+
recipe facets (Association/Validation/Callback), default None.
145+
- ogar-from-ruff: populate them via `recipe_concept_from_surface(surface,
146+
RecipeLang::Ruby)` at lift (callback phase→LIFECYCLE_*, validation
147+
kind→GUARD_*, assoc kind→REL_*, controller HandlerKind→ACTION_*).
148+
- Tests incl. the OP⇄Redmine convergence pin at the lift level.
149+
- Board: prepend E-RECIPE-CODEBOOK-WIRED, regrade gap (c) → CLOSED; mirror in
150+
op-nexgen's board.
151+
152+
Scope: `cargo test/clippy -p ogar-vocab -p ogar-from-ruff`. NEVER `--all` from
153+
OGAR (path-deps drag siblings). Commit small + push to the same branch. Do NOT
154+
open a PR unless asked.
155+
156+
FLAG, don't resolve: consumers dep OGAR via `claude/odoo-rs-transcode-lf8ya5`,
157+
so this work isn't consumable until the operator decides the branch/merge
158+
strategy (handover §6). Phase 2 is fully doable OGAR-side regardless.
159+
```
160+
161+
---
162+
163+
## Appendix — arc commit trail (branch `claude/openproject-nexgen-ogar-review-mkjtpq`)
164+
165+
OGAR (6): `b792002` route-kind-verb-strata → `8503948` reunion-order correction → `5dd2be1` F17-verified → `e02608b` grammar-is-recipe-shape → `f76698c` recipe codebook Phase 1 → `34fa06c` Scope/Concern reserved.
166+
op-nexgen (5): `22c6826` park dto-check → `f942c77` reunion-order → `379580d` F17-verified → `603610b` grammar mirror → `83426d7` codebook-P1 mirror.

0 commit comments

Comments
 (0)