|
1 | 1 | # Apply-engine direction — diff-shape recipes + agent-in-the-loop substrate |
2 | 2 |
|
3 | | -> **Status:** open · substrate growth (Steps 5–7 partial) lives in [`substrate-extraction.md`](./substrate-extraction.md) (tiers 1–6 shipped). This plan owns the **apply-engine / diff-shape recipe** half of the richer-index synthesis. |
| 3 | +> **Status:** closing — Steps 2–4, 6–12 shipped (`feat/apply-engine-slices`). Substrate Steps 5–7 live in [`substrate-extraction.md`](./substrate-extraction.md) (tiers 1–6 shipped). This plan owns the **apply-engine / diff-shape recipe** half of the richer-index synthesis. |
4 | 4 | > |
5 | 5 | > **Motivator:** extend `codemap apply` from recipe-driven single-file hunks toward agent-in-the-loop row contracts (`apply --rows -`, diff-input, fixpoint loops) without crossing [Moat A](../roadmap.md#moats-load-bearing) (SQL/recipe API) or [Moat B](../roadmap.md#moats-load-bearing) (no re-extraction in apply). |
6 | 6 | > |
|
20 | 20 |
|
21 | 21 | ## Open steps (implementation sequence) |
22 | 22 |
|
23 | | -### Step 2 — Three diff-shape recipes (S × 3) |
| 23 | +_All steps below shipped on branch `feat/apply-engine-slices` (single PR). Wave-2 recipes (`organize-imports`, `missing-exports`, …) remain backlog per synthesis § 4.3._ |
24 | 24 |
|
25 | | -Ship `replace-marker-kind`, `migrate-import-source`, `add-jsdoc-deprecated` — pure SQL + frontmatter; no engine/schema change. |
| 25 | +### Step 2 — Three diff-shape recipes (S × 3) — ✓ Shipped |
26 | 26 |
|
27 | | -Open: sequential PRs per [tracer-bullets](../../.agents/rules/tracer-bullets.md); hold `organize-imports` / `missing-exports` for wave 2. |
| 27 | +`replace-marker-kind`, `migrate-import-source`, `add-jsdoc-deprecated` — bundled SQL + frontmatter + golden scenarios. |
28 | 28 |
|
29 | | -### Step 3 — Per-row `actions[].command` template (S) |
| 29 | +### Step 3 — Per-row `actions[].command` template (S) — ✓ Shipped |
30 | 30 |
|
31 | | -Extend `recipes-loader.ts` / `query-recipes.ts` so `actions[]` carries a rendered `command` template (reuse `recipe-params.ts`; block-list shape only). |
| 31 | +`RecipeAction.command` + `renderRecipeActionCommands` / `getQueryRecipeActionsRendered`. |
32 | 32 |
|
33 | | -### Step 4 — `auto_fixable` gating (S) |
| 33 | +### Step 4 — `auto_fixable` gating (S) — ✓ Shipped |
34 | 34 |
|
35 | | -Enforce `actions[].auto_fixable: true` (or `--force`) before write. `--force` bypasses gate only, not phase-1 conflict detection. |
| 35 | +`assertApplyAutoFixable` + CLI/MCP `--force`. |
36 | 36 |
|
37 | | -### Step 6 — App-wide rename recipe (S; depends Step 5 substrate ✓) |
| 37 | +### Step 6 — App-wide rename recipe (S) — ✓ Shipped |
38 | 38 |
|
39 | | -Extend `rename-preview.sql` with `call_rows` CTE. Bias: extend existing recipe id, not a second rename recipe. Preserve honest v1 gap list (re-exports, JSX, default-import binds). |
| 39 | +`rename-preview.sql` `call_rows` CTE; golden updated with `call_site` rows. |
40 | 40 |
|
41 | | -### Step 7 (recipe) — `rename-preview` `re_export_rows` CTE (S) |
| 41 | +### Step 7 (recipe) — `rename-preview` `re_export_rows` CTE (S) — ✓ Shipped |
42 | 42 |
|
43 | | -Substrate shipped; **recipe extension open**. Single-hop alias chains in v1; recursive CTE if gap appears. |
| 43 | +Single-hop `re_export_rows` CTE; gated by `include_re_exports`. |
44 | 44 |
|
45 | | -### Step 8 — `apply --rows -` + `apply_rows` MCP/HTTP tool (M) |
| 45 | +### Step 8 — `apply --rows -` + `apply_rows` MCP/HTTP tool (M) — ✓ Shipped |
46 | 46 |
|
47 | | -JSON array of `{file_path, line_start, before_pattern, after_pattern}` from stdin/args; existing phase-1/2 validation. Separate MCP tool (not polymorphic with recipe id). |
| 47 | +CLI `--rows`; MCP/HTTP `apply_rows` tool. |
48 | 48 |
|
49 | | -### Step 9 — `apply --diff-input <file>` (S) |
| 49 | +### Step 9 — `apply --diff-input <file>` (S) — ✓ Shipped |
50 | 50 |
|
51 | | -Unified diff → row contract → same engine. Hand-roll parser; per-file atomicity; cross-file rollback deferred. |
| 51 | +`parseUnifiedDiffToRows` + CLI `--diff-input`. |
52 | 52 |
|
53 | | -### Step 10 — `apply --commit "<msg>"` (S) |
| 53 | +### Step 10 — `apply --commit "<msg>"` (S) — ✓ Shipped |
54 | 54 |
|
55 | | -`git add` only files apply touched, then commit. Message templating deferred. |
| 55 | +`gitCommitAppliedFiles` + CLI `--commit`. |
56 | 56 |
|
57 | | -### Step 11 — `--until-empty` + `--max-passes N` (S) |
| 57 | +### Step 11 — `--until-empty` + `--max-passes N` (S) — ✓ Shipped |
58 | 58 |
|
59 | | -Apply → reindex → re-run recipe loop. Abort whole loop on phase-1 conflicts. Extend result envelope with `passes` + `terminated_by`. |
| 59 | +`runApplyUntilEmpty` + envelope `passes` / `terminated_by` (CLI only). |
60 | 60 |
|
61 | | -### Step 12 — `apply.autoApplyRecipes` allowlist (S) |
| 61 | +### Step 12 — `apply.autoApplyRecipes` allowlist (S) — ✓ Shipped |
62 | 62 |
|
63 | | -Config list of recipe ids allowed with `--yes` without interactive confirm. `--force` bypasses allowlist. |
| 63 | +`codemapUserConfigSchema.apply.autoApplyRecipes` + `assertApplyAllowlist`. |
64 | 64 |
|
65 | 65 | --- |
66 | 66 |
|
|
0 commit comments