vinta-ai-workflows 0.2.0-alpha2 → 0.2.0-alpha4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/CHANGELOG.md +199 -0
  2. package/README.md +5 -2
  3. package/package.json +7 -1
  4. package/schemas/README.md +1 -0
  5. package/schemas/ai-models.v1.schema.json +87 -0
  6. package/schemas/vinta-ai-workflows-config.v1.schema.json +20 -1
  7. package/skills/vinta-analyze-codebase/SKILL.md +1 -1
  8. package/skills/vinta-bootstrap-ai-tools/SKILL.md +19 -9
  9. package/skills/vinta-derive-skills/SKILL.md +98 -47
  10. package/skills/vinta-derive-skills/resources/foundation-skills/deslop-comments/SKILL.md +148 -0
  11. package/skills/vinta-derive-skills/resources/foundation-skills/plan-feature/SKILL.md +24 -27
  12. package/skills/vinta-derive-skills/resources/foundation-skills/plan-feature/resources/ai-models.yaml +98 -0
  13. package/skills/vinta-derive-skills/resources/foundation-skills/prepare-worktree/SKILL.md +89 -0
  14. package/skills/vinta-derive-skills/resources/foundation-skills/prepare-worktree/scripts/claude-worktree-write-guard.py +118 -0
  15. package/skills/vinta-derive-skills/resources/foundation-skills/prepare-worktree/scripts/gen-claude-sandbox-settings.sh +167 -0
  16. package/skills/vinta-derive-skills/resources/foundation-skills/prepare-worktree/scripts/sandbox-run.sh +106 -0
  17. package/skills/vinta-derive-skills/resources/foundation-skills/thermo-nuclear-code-quality-review/SKILL.md +129 -0
  18. package/skills/vinta-derive-skills/resources/plan-execution/README.md +42 -0
  19. package/skills/vinta-derive-skills/resources/{implement-plan-template-modular-substitutions.md → plan-execution/partials/commit-strategy/modular.md} +38 -70
  20. package/skills/vinta-derive-skills/resources/plan-execution/partials/commit-strategy/stacked.md +46 -0
  21. package/skills/vinta-derive-skills/resources/plan-execution/partials/implementer-prompt.md +78 -0
  22. package/skills/vinta-derive-skills/resources/plan-execution/partials/model-pick.md +19 -0
  23. package/skills/vinta-derive-skills/resources/plan-execution/partials/pr-context.md +61 -0
  24. package/skills/vinta-derive-skills/resources/plan-execution/partials/review-layers.md +50 -0
  25. package/skills/vinta-derive-skills/resources/plan-execution/partials/worktree-seam.md +68 -0
  26. package/skills/vinta-derive-skills/resources/{amend-plan-template.md → plan-execution/shell/amend-plan-template.md} +48 -42
  27. package/skills/vinta-derive-skills/resources/plan-execution/shell/implement-phase-template.md +47 -0
  28. package/skills/vinta-derive-skills/resources/plan-execution/shell/implement-plan-template.md +186 -0
  29. package/skills/vinta-derive-skills/resources/plan-execution/shell/integrate-phase-template.md +30 -0
  30. package/skills/vinta-derive-skills/resources/plan-execution/shell/review-phase-template.md +25 -0
  31. package/skills/vinta-derive-skills/resources/systematic-debugging-template.md +7 -3
  32. package/skills/vinta-update-project-skills/SKILL.md +1 -1
  33. package/skills/vinta-derive-skills/resources/implement-plan-template.md +0 -416
@@ -0,0 +1,68 @@
1
+ <!-- Partial: worktree-seam — the WORKROOT abstraction. Collapses the former scattered `if use_worktree` conditionals into one resolution (conductor) + two local, data-driven checks (implement-phase spawn wrap, review-phase stray-write). Blocks: WORKROOT_RESOLUTION (conductors), WORKROOT_TOPOLOGY_RULE (conductors + integrate-phase), SANDBOX_WRAP (implement-phase), STRAY_WRITE_CHECK (review-phase). -->
2
+
3
+ <!-- block-begin: WORKROOT_RESOLUTION -->
4
+ ## Step 0.5 — Resolve `WORKROOT`
5
+
6
+ Resolve three values **once**, before any phase runs, and record them in tracking. Every later step uses them as data — no step re-derives worktree state.
7
+
8
+ | Value | `run_options.use_worktree = false` | `run_options.use_worktree = true` |
9
+ |---|---|---|
10
+ | `WORKROOT` | the main checkout root (the repo the skill was invoked from) | `<worktree_path>` returned by prepare-worktree |
11
+ | `BASE_BRANCH` | `{{DEFAULT_BRANCH}}` | `<worktree_branch>` prepare-worktree created |
12
+ | `SANDBOX_TIER` | `none` | `enforced` or `none` (probed by prepare-worktree) |
13
+
14
+ **When `use_worktree = false`:** set `WORKROOT` = main checkout, `BASE_BRANCH = {{DEFAULT_BRANCH}}`, `SANDBOX_TIER = none`. Make `BASE_BRANCH` current + up to date: `git -C <WORKROOT> checkout {{DEFAULT_BRANCH}} && git -C <WORKROOT> pull --ff-only`. Jump to Step 1.
15
+
16
+ **When `use_worktree = true`:** invoke [prepare-worktree](../prepare-worktree/SKILL.md) **once**:
17
+
18
+ 1. **Inputs.** Plan path (so prepare-worktree can read it for deps / migrations / env / compose churn — see prepare-worktree's **Plan inspection** step), suggested worktree name = `plan-{plan-id-kebab}`, plan-driven mode.
19
+ 2. **Pre-run sanity.** Confirm no existing worktree at the target path (`git worktree list | grep <name>` — refuse if collision). Confirm `git -C <main_checkout> status` of the main checkout (warn if dirty; defer to prepare-worktree's **Sanity checks** step for the call).
20
+ 3. **Run prepare-worktree.** Pass the plan file + worktree name. It returns:
21
+ - `worktree_path` → `WORKROOT`.
22
+ - `worktree_branch` → `BASE_BRANCH` (prepare-worktree based it on `origin/{{DEFAULT_BRANCH}}`, so it is already current).
23
+ - `worktree_summary` — `.vinta-ai-workflows/worktrees/<name>.yaml` (read by teardown).
24
+ - `sandbox_tier` → `SANDBOX_TIER`: `enforced` (the [Filesystem sandbox](../prepare-worktree/SKILL.md#step-55--filesystem-sandbox-os-level-write-guard) step found `sandbox-exec` / `bwrap` and will OS-block main-checkout writes) or `none` (no sandbox tool — prevention degrades to the review-phase stray-write backstop).
25
+ 4. **Persist to tracking.** Write `run_options.worktree_path`, `run_options.worktree_branch`, `run_options.worktree_summary`, `run_options.sandbox_tier` into `{{PLAN_DIR}}/TRACKING_{plan-id}.md`. All later phases read them — never re-provision mid-plan.
26
+ 5. **Report to user.** Quote the prepare-worktree summary back: which dirs symlinked vs copied vs forked; which DB(s) forked + their names; compose project name; teardown command. Hold here until the user confirms (`AskUserQuestion`: `Looks good — start phase 1`, `Stop — let me adjust`).
27
+
28
+ Failure modes:
29
+ - **prepare-worktree returns an error** (disk full, branch exists, DB clone failed) → surface to the user; do NOT fall back to "just run in the main checkout" silently — that defeats the opt-in. Ask: `Retry`, `Run in main checkout instead (flip use_worktree to false)`, `Stop`.
30
+ - **User cancels at the confirmation gate** → tear the worktree down (run the teardown command from prepare-worktree's report) before exiting, so the next run starts clean.
31
+ <!-- block-end: WORKROOT_RESOLUTION -->
32
+
33
+ <!-- block-begin: WORKROOT_TOPOLOGY_RULE -->
34
+ **`WORKROOT` topology rule.** Every phase branches off the previous phase (first executed phase off `<BASE_BRANCH>`), and **every** `git` / lint / test / build / migrate call runs with `git -C <WORKROOT>` (or after `cd <WORKROOT>`). When `use_worktree = false`, `WORKROOT` is the main checkout and this is exactly today's in-place behavior; when `true`, `WORKROOT` is the worktree and branches / commits stack inside it, never touching the main checkout's working tree. One uniform path — no per-step worktree branching.
35
+ <!-- block-end: WORKROOT_TOPOLOGY_RULE -->
36
+
37
+ <!-- block-begin: SANDBOX_WRAP -->
38
+ **Sandbox the spawn — only when `SANDBOX_TIER = enforced`.** The prompt tells the subagent to stay in `WORKROOT`, but that's cooperative — a smaller model can resolve a path back to the main checkout and silently write there (the review-phase stray-write check catches this reactively). When `SANDBOX_TIER = enforced` **and** the runtime spawns subagents as **subprocesses** (it shells out to an agent CLI — e.g. `codex exec …`, a `claude -p …` child, a custom runner), wrap that launch command in the worktree's bundled guard so the OS blocks main-checkout writes regardless of harness:
39
+
40
+ ```bash
41
+ ai-tools/skills/prepare-worktree/scripts/sandbox-run.sh \
42
+ --deny <main_checkout> \
43
+ --allow <WORKROOT> \
44
+ --allow <main_checkout>/.vinta-ai-workflows \
45
+ --allow <main_checkout>/.git \
46
+ -- <the agent spawn command>
47
+ ```
48
+
49
+ `<main_checkout>` is the repo root the skill was invoked from (never `WORKROOT` when a worktree is in use). A stray write then fails with `Operation not permitted` / `EROFS`; the subagent retries against the worktree. `<main_checkout>/.git` must be allowed because git worktrees write commits into the main repo's `.git` (shared objects/refs, `.git/worktrees/<name>/index.lock`); omitting it makes the subagent's own `git commit` fail.
50
+
51
+ - **In-process subagent runtimes** (orchestrator and subagent share one OS process — e.g. claude-code's Task tool) can't wrap a single spawn. Two options: (a) install a runtime pre-write guard hook scoped to `WORKROOT` (prepare-worktree ships `scripts/claude-worktree-write-guard.py` + `scripts/gen-claude-sandbox-settings.sh` for claude-code); or (b) run the **entire** invocation under `sandbox-run.sh` with the same `--deny` / `--allow` set. Pick whichever the runtime supports.
52
+ - **`SANDBOX_TIER = none`** (no sandbox tool, or `use_worktree = false`) → skip wrapping; prevention falls back entirely to the review-phase stray-write check. Surface this once to the user when a worktree run is unsandboxed so the weaker guarantee is explicit.
53
+ <!-- block-end: SANDBOX_WRAP -->
54
+
55
+ <!-- block-begin: STRAY_WRITE_CHECK -->
56
+ **Stray main-checkout writes — only when `WORKROOT != <main_checkout>` (i.e. a worktree run).** A subagent told to work inside the worktree can resolve an absolute path back to the **main checkout** and silently edit files there; because worktrees have independent working trees, those edits never reach the phase commit — they sit as uncommitted thrash in the main checkout and read as a silent implementer/fixer failure. **When `SANDBOX_TIER = enforced`, the OS sandbox already blocks these writes and this becomes a cheap backstop (a clean `git status` is the expected result). When `SANDBOX_TIER = none`, it is the *only* defense — run it religiously.** After **every** implementer **and** fixer subagent returns, run:
57
+
58
+ ```bash
59
+ git -C <main_checkout> status --short | grep -vE '^\?\?' # tracked modifications only
60
+ ```
61
+
62
+ Any output is a BLOCKER for this phase:
63
+ - Diff the stray files (`git -C <main_checkout> diff -- <path>`) to recover intent.
64
+ - If the edit belongs in the worktree, re-dispatch the fixer/implementer with an explicit instruction to write to `WORKROOT` (the change is missing from the phase commit until it does).
65
+ - Once recovered (or confirmed superseded by the correctly-committed worktree version), discard the stray edits with `git -C <main_checkout> restore -- <path>` so the main checkout returns clean. Never leave the main checkout dirty between phases — a later phase can't tell new thrash from old.
66
+
67
+ `<main_checkout>` is the repo root the skill was invoked from (NOT `WORKROOT`). When `WORKROOT == <main_checkout>` (`use_worktree = false`), skip this check entirely — your work legitimately lives in that tree.
68
+ <!-- block-end: STRAY_WRITE_CHECK -->
@@ -5,7 +5,7 @@ description: Adjust an existing implementation plan in `{{PLAN_DIR}}/` after imp
5
5
 
6
6
  # Amend Plan
7
7
 
8
- Revise a plan in [`{{PLAN_DIR}}/`]({{PLAN_DIR}}/) after work has begun. Companion to [implement-plan](../implement-plan/SKILL.md): same agents, same review gates, same PR-context flow — but the orchestrator's job here is **history rewriting** instead of forward execution.
8
+ Revise a plan in [`{{PLAN_DIR}}/`]({{PLAN_DIR}}/) after work has begun. Companion conductor to [implement-plan](../implement-plan/SKILL.md): it reuses the same sub-skills ([implement-phase](../implement-phase/SKILL.md) for the body change, [review-phase](../review-phase/SKILL.md) for the gates) — but the orchestrator's job here is **history rewriting** instead of forward execution.
9
9
 
10
10
  The flow is destructive (force-push). Every modification is gated on user confirmation. Default disposition for any ambiguous case is "stop and ask" — never force-push without an explicit per-branch `Confirm` from the user.{{COMMIT_STRATEGY_REFUSAL_BLOCK}}
11
11
 
@@ -22,6 +22,7 @@ The flow is destructive (force-push). Every modification is gated on user confir
22
22
  - {{COAUTHOR_POLICY_BLOCK}}
23
23
  - Default branch: `{{DEFAULT_BRANCH}}`.
24
24
  - Branch naming convention (set by [implement-plan](../implement-plan/SKILL.md)): `plan/{plan-id-kebab}/phase-{phase.id}`.
25
+ - **`WORKROOT`.** Resolve once, same as the [implement-plan Resolve WORKROOT step](../implement-plan/SKILL.md#step-05--resolve-workroot): the main checkout by default, or the plan's worktree when `run_options.use_worktree = true` in the tracking file. Every `git` call below runs with `git -C <WORKROOT>`; when no worktree is in play, `WORKROOT` is the main checkout and the commands read exactly as in-place git.
25
26
 
26
27
  ## When to use
27
28
 
@@ -48,7 +49,7 @@ The flow is destructive (force-push). Every modification is gated on user confir
48
49
 
49
50
  3. **Parse the plan.** Same structured fields as [implement-plan's "Extract structured fields" step](../implement-plan/SKILL.md#step-0--locate--parse-plan): plan id, **Goals + Non-goals** / **Guiding Decisions** / **Data Model Changes** / phase records from **Phased Rollout** / **Risk & Rollout Notes** through **Touch List**.
50
51
 
51
- 4. **Read the tracking file** `{{PLAN_DIR}}/TRACKING_{plan-id}.md` if present. Its `Completed Phases` section tells you which phase branches were pushed and which model + base were used. If absent → `git branch -a | grep plan/{plan-id-kebab}` to enumerate pushed phase branches.
52
+ 4. **Read the tracking file** `{{PLAN_DIR}}/TRACKING_{plan-id}.md` if present. Its `Completed Phases` section tells you which phase branches were pushed, which model + base were used, and the `run_options` (including worktree state → `WORKROOT`). If absent → `git -C <WORKROOT> branch -a | grep plan/{plan-id-kebab}` to enumerate pushed phase branches.
52
53
 
53
54
  5. **Build a per-phase state map.** For every phase in the plan, record:
54
55
 
@@ -57,9 +58,9 @@ The flow is destructive (force-push). Every modification is gated on user confir
57
58
  | `phase.id`, `phase.title` | plan's **Phased Rollout** section |
58
59
  | `state` | one of `not-started` / `in-progress` / `implemented-not-merged` / `merged-to-default` |
59
60
  | `branch` | tracking file or git, pattern `plan/{plan-id-kebab}/phase-{id}` |
60
- | `base` | tracking file or `git merge-base origin/<branch> <prev-branch>`; root phase bases on `{{DEFAULT_BRANCH}}` |
61
+ | `base` | tracking file or `git -C <WORKROOT> merge-base origin/<branch> <prev-branch>`; root phase bases on `{{DEFAULT_BRANCH}}` |
61
62
  | `pr_status` | `.vinta-ai-workflows/prs-context/{feature-kebab}/phase-{id}.md` frontmatter (`pending` / `published`) when the file exists |
62
- | `merged_to_default` | `git branch --merged origin/{{DEFAULT_BRANCH}} | grep` against the branch |
63
+ | `merged_to_default` | `git -C <WORKROOT> branch --merged origin/{{DEFAULT_BRANCH}} | grep` against the branch |
63
64
 
64
65
  `merged-to-default = true` blocks any commit rewrite for that phase — see [Step 3 — Refuse force-pushes that can't work](#step-3--refuse-force-pushes-that-cant-work) below.
65
66
 
@@ -78,7 +79,7 @@ The flow is destructive (force-push). Every modification is gated on user confir
78
79
  | `guiding-decisions-change` cascading into | ≥ 50% of implemented phases |
79
80
  | Phases in `merged-to-default` (immutable, must be `append-new`) | ≥ 2, AND remaining work also rewrites earlier phases |
80
81
  | New body materially changes the data-model contract from **Data Model Changes** | rewrite of >2 phases hinges on it |
81
- | Estimated touched LoC across rewrites | ≥ 70% of original implementation diff size (rough estimate via `git diff --stat <base>..<branch>` summed across affected branches) |
82
+ | Estimated touched LoC across rewrites | ≥ 70% of original implementation diff size (rough estimate via `git -C <WORKROOT> diff --stat <base>..<branch>` summed across affected branches) |
82
83
  | Multi-author phase branches in the rewrite queue | ≥ 1 (force-push erases collaborator local state) |
83
84
  | Approved PRs in the rewrite queue | ≥ 2 (re-review burden becomes non-trivial) |
84
85
 
@@ -141,13 +142,13 @@ Always the first write. Plan file is durable; commits get rewritten next.
141
142
 
142
143
  ## Step 2 — Build the rewrite queue
143
144
 
144
- For each phase classified as needing commit rewrites (`body-rewrite` for already-implemented phases, downstream phases for `insert-new` / `body-rewrite` / `section-2-decision-change`), build a queue ordered by branch stack depth: parent first, children after.
145
+ For each phase classified as needing commit rewrites (`body-rewrite` for already-implemented phases, downstream phases for `insert-new` / `body-rewrite` / `guiding-decisions-change`), build a queue ordered by branch stack depth: parent first, children after.
145
146
 
146
147
  For each entry record:
147
148
 
148
149
  - `branch`, `base` (parent in the stack — may be `{{DEFAULT_BRANCH}}` or another phase branch).
149
150
  - `change_kind`: `amend-existing` (modify the phase body's effect on the diff) or `rebase-only` (parent moved, no body change for this phase).
150
- - `commits_to_amend`: list of SHAs the orchestrator may rewrite (look at `git log <base>..<branch>`).
151
+ - `commits_to_amend`: list of SHAs the orchestrator may rewrite (look at `git -C <WORKROOT> log <base>..<branch>`).
151
152
 
152
153
  Phases in `not-started` state are deferred to [implement-plan](../implement-plan/SKILL.md) — not rewritten here.
153
154
 
@@ -163,7 +164,7 @@ Before any write to remote, **block on these conditions**:
163
164
 
164
165
  3. **Branch protection rules block force-push.** `gh api repos/{owner}/{repo}/branches/{branch}/protection` (or `glab` equivalent). If the branch is protected, force-push will fail noisily — surface the rule, stop.
165
166
 
166
- 4. **Multiple authors on the branch.** `git log --pretty=format:%ae <base>..<branch> | sort -u | wc -l` > 1 → other developers committed too. Force-push erases their local state. Surface, require explicit `Yes, I've coordinated with <names>` confirmation.
167
+ 4. **Multiple authors on the branch.** `git -C <WORKROOT> log --pretty=format:%ae <base>..<branch> | sort -u | wc -l` > 1 → other developers committed too. Force-push erases their local state. Surface, require explicit `Yes, I've coordinated with <names>` confirmation.
167
168
 
168
169
  If any block triggers and the user can't dismiss it: stop. Don't proceed further. Tell the user the rewrite path is unavailable; suggest an `append-new` phase as the fallback.
169
170
 
@@ -174,14 +175,14 @@ For each entry in the rewrite queue, in stack order:
174
175
  ### 4a. Check out the branch
175
176
 
176
177
  ```bash
177
- git fetch origin
178
- git checkout {branch}
179
- git reset --hard origin/{branch}
178
+ git -C <WORKROOT> fetch origin
179
+ git -C <WORKROOT> checkout {branch}
180
+ git -C <WORKROOT> reset --hard origin/{branch}
180
181
  ```
181
182
 
182
183
  ### 4b. For `change_kind = amend-existing` only — apply the body change
183
184
 
184
- Spawn an implementer subagent. Prompt shape (token-efficient, mirrors the [implement-plan "Prepare agent prompt" step](../implement-plan/SKILL.md#1a-prepare-agent-prompt-token-efficient)):
185
+ Spawn an implementer subagent. The prompt mirrors [implement-phase](../implement-phase/SKILL.md#1-compose-the-agent-prompt-token-efficient) but records the change differently (new commit on top by default, never a push). Compose:
185
186
 
186
187
  ```
187
188
  You are amending {phase.id}: {phase.title} of plan {plan.id}.
@@ -189,10 +190,13 @@ You are amending {phase.id}: {phase.title} of plan {plan.id}.
189
190
  ## Repo
190
191
  {{PROJECT_NAME}} ({{STACK_SUMMARY}}).
191
192
 
193
+ ## Working location
194
+ Work inside `<WORKROOT>`. `cd` into it before any command.
195
+
192
196
  ## Read first
193
197
  1. AGENTS.md — repo conventions.
194
198
  2. {{PLAN_DIR}}/{plan-filename}, the **Goals + Non-goals**, **Guiding Decisions**, and **Data Model Changes** sections, plus the rewritten phase body inside **Phased Rollout**.
195
- 3. The current diff: `git diff {base}...HEAD` — what's already on this branch.
199
+ 3. The current diff: `git -C <WORKROOT> diff {base}...HEAD` — what's already on this branch.
196
200
 
197
201
  ## What changed in the plan (verbatim)
198
202
  {Diff between old phase body and new — produce via `diff <(old-body) <(new-body)`. Or, if the plan was rewritten in place, the new body verbatim with a note "this replaces what was here before".}
@@ -212,17 +216,19 @@ Use `git commit --amend` ONLY when:
212
216
  - The user explicitly authorized amend in Step 0.
213
217
 
214
218
  {{DEPENDENCY_LICENSE_BLOCK}}
219
+ ```
220
+
221
+ Then splice in the shared inner/outer verification loop verbatim:
215
222
 
216
- ## Working instructions (same loops as implement-plan)
217
- 1. Read existing code paths your changes touch.
218
- 2. Edit. Match existing patterns.
219
- 3. Inner loop: `{{LINT_CMD}}` → {{NEW_TEST_CMD_PATTERN}} → scoped suite ({{SCOPED_TEST_PATTERN}}).
220
- 4. Iterate 2–3 until green.
221
- 5. Outer gate: `{{BUILD_CMD}}` AND `{{TEST_CMD}}`{{E2E_OUTER_GATE_LINE}}.
222
- 6. Stage explicitly: `git add {{STAGE_PATTERN}}`.
223
- 7. Commit. {{COMMIT_STYLE_LINE}}.
224
- 8. {{COAUTHOR_INSTRUCTION_LINE}}
225
- 9. **Do NOT push. Do NOT force-push.** Orchestrator owns the remote.
223
+ <!-- include: partials/implementer-prompt.md#INNER_OUTER_LOOP -->
224
+
225
+ …and close the prompt with the amend-specific staging tail:
226
+
227
+ ```
228
+ 7. Stage explicitly: `git add {{STAGE_PATTERN}}`.
229
+ 8. Commit. {{COMMIT_STYLE_LINE}}.
230
+ 9. {{COAUTHOR_INSTRUCTION_LINE}}
231
+ 10. **Do NOT push. Do NOT force-push.** The orchestrator owns the remote.
226
232
 
227
233
  ## Required output
228
234
  - Status: SUCCESS or FAILURE.
@@ -233,26 +239,26 @@ Use `git commit --amend` ONLY when:
233
239
 
234
240
  For `change_kind = rebase-only` (downstream phase whose parent moved): skip the agent. The work is purely git topology.
235
241
 
236
- ### 4c. Run the three-layer review (same as implement-plan)
242
+ ### 4c. Run the three-layer review
237
243
 
238
- Same Layer 1 / 2 / 3 / fix-loop as the [implement-plan "Thorough review" step](../implement-plan/SKILL.md#1d-thorough-review). The reviewer agent gets the **new** phase body to walk against. Layer 2 walks: every "Changes" item in the new body, every "Tests" entry, the new acceptance line.
244
+ Invoke [review-phase](../review-phase/SKILL.md) against the rewritten branch, passing the **new** phase body to walk against and `WORKROOT`. Layer 2 walks: every "Changes" item in the new body, every "Tests" entry, the new acceptance line.
239
245
 
240
- Skip Layer 3 only when `change_kind = rebase-only` (no body change → no compliance walk). Layers 1 + 2 still apply (verify the rebase didn't lose unrelated work).
246
+ Skip this step only when `change_kind = rebase-only` (no body change → no compliance walk). Even then, spot-run review-phase's Layer 1 mechanical checks to verify the rebase didn't lose unrelated work.
241
247
 
242
248
  ### 4d. Rebase onto the (possibly-rewritten) parent
243
249
 
244
250
  ```bash
245
251
  # parent's tip may have moved if it was rewritten earlier in the queue.
246
- git fetch origin
247
- PARENT_TIP=$(git rev-parse origin/{base})
248
- git rebase $PARENT_TIP
252
+ git -C <WORKROOT> fetch origin
253
+ PARENT_TIP=$(git -C <WORKROOT> rev-parse origin/{base})
254
+ git -C <WORKROOT> rebase $PARENT_TIP
249
255
  ```
250
256
 
251
257
  Conflicts:
252
258
 
253
- 1. **Spawn a fixer subagent** with the conflict body + new phase body + parent's tip diff. Same agent type as the [implement-plan "Fix loop" subsection](../implement-plan/SKILL.md#fix-loop).
254
- 2. Fixer resolves, runs inner + outer gate.
255
- 3. Orchestrator continues the rebase: `git rebase --continue`.
259
+ 1. **Spawn a fixer subagent** with the conflict body + new phase body + parent's tip diff. Same fixer agent type as [review-phase](../review-phase/SKILL.md#fix-loop).
260
+ 2. Fixer resolves, runs inner + outer gate (in `<WORKROOT>`).
261
+ 3. Orchestrator continues the rebase: `git -C <WORKROOT> rebase --continue`.
256
262
 
257
263
  Repeat until the rebase finishes clean. If the fixer can't resolve after one retry → stop. Surface to user; do not push a half-rebased branch.
258
264
 
@@ -266,7 +272,7 @@ Repeat until the rebase finishes clean. If the fixer can't resolve after one ret
266
272
  On confirm:
267
273
 
268
274
  ```bash
269
- git push --force-with-lease origin {branch}
275
+ git -C <WORKROOT> push --force-with-lease origin {branch}
270
276
  ```
271
277
 
272
278
  **Use `--force-with-lease`, not `--force`.** It refuses to overwrite if the remote moved since the last fetch — protects against another developer's pushes the orchestrator didn't see.
@@ -278,12 +284,12 @@ If `--force-with-lease` rejects: another developer pushed. Stop. Re-fetch, re-ap
278
284
  For the rewritten branch, look for `.vinta-ai-workflows/prs-context/{feature-kebab}/phase-{phase.id}.md`:
279
285
 
280
286
  - **File missing** — skip; nothing to refresh.
281
- - **File `status: pending`** — rewrite the file to reflect new title / description / comments per the [prs-context-template](prs-context-template.md). Status stays `pending`. The user will publish later via [open-pr-from-context](../foundation-skills/open-pr-from-context/SKILL.md).
287
+ - **File `status: pending`** — rewrite the file to reflect new title / description / comments per the [prs-context-template](../../prs-context-template.md). Status stays `pending`. The user will publish later via [open-pr-from-context](../open-pr-from-context/SKILL.md).
282
288
  - **File `status: published`** — the existing PR is auto-updated by the force-push (GitHub/GitLab pick up the new tip). But:
283
289
  - Inline comments may now reference SHAs that no longer exist. They'll appear as "outdated" in the PR UI.
284
- - If the new diff has materially different comment-worthy spots, regenerate the `# Comments` block, set `status: pending`, and re-run [open-pr.sh](../foundation-skills/open-pr-from-context/scripts/open-pr.sh) on the file. The script reuses the existing PR, posts new comments. Old "outdated" comments stay visible in the PR for audit; that's the platform's behavior.
290
+ - If the new diff has materially different comment-worthy spots, regenerate the `# Comments` block, set `status: pending`, and re-run [open-pr.sh](../open-pr-from-context/scripts/open-pr.sh) on the file. The script reuses the existing PR, posts new comments. Old "outdated" comments stay visible in the PR for audit; that's the platform's behavior.
285
291
 
286
- When rewriting the `# Description` body, **honor `project.pr_template_paths`** from `.vinta-ai-workflows.yaml` — same rule as step 2 of the [implement-plan "Open PR via context file" step](../implement-plan/SKILL.md#1f-open-pr-via-context-file): follow the project's PR template structure, fill new sections with phase-specific content from the rewritten body, leave un-fillable placeholders untouched. If the prior file used a different template than the project now declares (template was added or swapped between the original `implement-plan` run and this amend), prefer the current `pr_template_paths` choice — surface the change to the user when the body shape shifts visibly.
292
+ When rewriting the `# Description` body, **honor `project.pr_template_paths`** from `.vinta-ai-workflows.yaml` — same rule as [integrate-phase]({{INTEGRATE_PHASE_LINK}})'s **Open PR via context file** step: follow the project's PR template structure, fill new sections with phase-specific content from the rewritten body, leave un-fillable placeholders untouched. If the prior file used a different template than the project now declares, prefer the current `pr_template_paths` choice — surface the change to the user when the body shape shifts visibly.
287
293
 
288
294
  Always include in the publish-log block at the bottom of the file:
289
295
 
@@ -319,29 +325,29 @@ After every queue entry processes:
319
325
  - **Never `--force`. Always `--force-with-lease`.** Protects against silent overwrites.
320
326
  - **Plan file edit is the first write.** Commit the new plan body before any branch rewrite. The plan is the contract; the branches are the artifact.
321
327
  - **Recommend restart when blast radius is high.** The blast-radius step inside Step 0 evaluates signals; ≥2 tripping signals → surface a restart option to the user before any force-push plan is shown. Don't quietly amend a half-rewrite of the whole plan.
322
- - **Never use `§N` shorthand to point at sections** — neither in this skill body, the rewritten plan body, the amendment log entry, nor any prs-context refresh. Always use the section's full name (and link when possible). `§N` references are hard for humans to follow and shift when section numbering moves.
328
+ - **Never use `§N` shorthand to point at sections** — neither in this skill body, the rewritten plan body, the amendment log entry, nor any prs-context refresh. Always use the section's full name (and link when possible).
323
329
  - **Phases merged to `{{DEFAULT_BRANCH}}` are immutable.** Convert to `append-new` phases. Refuse to attempt rewrites.
324
330
  - **Confirm every force-push individually.** No batch "confirm all".
325
- - **Use `--force-with-lease`** (already stated; worth restating).
326
- - **Three-layer review on every rewritten branch.** Same standard as [implement-plan](../implement-plan/SKILL.md). The amendment isn't done until Layer 3 passes.
331
+ - **`WORKROOT` is resolved once, used everywhere.** Every `git` call takes `git -C <WORKROOT>`; no per-step worktree branching.
332
+ - **Three-layer review on every rewritten branch.** Same standard as [implement-plan](../implement-plan/SKILL.md) — via [review-phase](../review-phase/SKILL.md). The amendment isn't done until Layer 3 passes.
327
333
  - **PR-context file is a derived artifact.** Refresh it after the rewrite; never edit the file as a substitute for fixing the diff.
328
334
  - **Subagents commit but never push.** Orchestrator owns force-push. {{PR_RULE_TAIL}}.
329
335
  {{COAUTHOR_RULE_LINE}}
330
336
  {{DEPENDENCY_LICENSE_RULE_LINE}}
331
- - **Stop on Tier-4 failure** (model escalation, same rules as the [implement-plan "Pick model" step](../implement-plan/SKILL.md#1b-pick-model-from-plans-per-phase-suggestion)).
337
+ - **Stop on Tier-4 failure** (model escalation, same rules as [implement-phase](../implement-phase/SKILL.md#pick-the-model-from-the-plans-per-phase-suggestion)).
332
338
  - **Stop on rebase failure** the fixer can't resolve in one retry. Don't ship half-rebased branches.
333
339
 
334
340
  ## Quick checklist (orchestrator, per amendment run)
335
341
 
336
342
  - [ ] User-requested change captured verbatim; classification determined (`body-rewrite` / `insert-new` / `append-new` / `guiding-decisions-change`).
337
- - [ ] Plan parsed; per-phase state map built (state, branch, base, pr_status, merged_to_default).
343
+ - [ ] Plan parsed; per-phase state map built (state, branch, base, pr_status, merged_to_default); `WORKROOT` resolved from tracking `run_options`.
338
344
  - [ ] Blast-radius signals computed; `low` → straight to confirmation, `high-blast-radius` / `restart-recommended` → user offered `Restart` / `Amend in place` / `Stop` before the force-push plan is shown.
339
345
  - [ ] On `Restart` choice: new plan drafted (or hand-off to [plan-feature](../plan-feature/SKILL.md)); old plan annotated `Superseded`; tracking marked; this skill exits.
340
346
  - [ ] Step 3 refusals surfaced; force-push plan confirmed by user.
341
347
  - [ ] Plan file edited; amendment log entry appended; committed on `{{DEFAULT_BRANCH}}`.
342
348
  - [ ] Rewrite queue ordered by stack depth (parent first).
343
349
  - [ ] For each entry: body change applied (when `amend-existing`); inner + outer gate green.
344
- - [ ] Three-layer review on each rewritten branch; BLOCKERs fixed; SHOULD-FIX noted.
350
+ - [ ] [review-phase](../review-phase/SKILL.md) run on each rewritten branch; BLOCKERs fixed; SHOULD-FIX noted.
345
351
  - [ ] Rebase onto rewritten parent; conflicts resolved via fixer; tests re-run.
346
352
  - [ ] `--force-with-lease` push confirmed and executed per branch.
347
353
  - [ ] PR-context file refreshed (pending or republished).
@@ -0,0 +1,47 @@
1
+ ---
2
+ name: implement-phase
3
+ description: Internal execution step of [implement-plan] / [amend-plan] — NOT a standalone entry point. Given one already-classified plan phase plus the resolved `WORKROOT` / `BASE_BRANCH` / `SANDBOX_TIER`, it composes a token-efficient implementer prompt, picks the model from the phase's own suggestion, and spawns exactly one implementer subagent, returning that agent's report. Do not invoke directly for ad-hoc edits or in response to a user's raw feature request; the conductor invokes it once per executable phase in {{PROJECT_NAME}}.
4
+ ---
5
+
6
+ # Implement one phase
7
+
8
+ Execution unit invoked by [implement-plan](../implement-plan/SKILL.md) (and by [amend-plan](../amend-plan/SKILL.md) for `amend-existing` rewrites). One phase in → one implementer report out. This skill does **not** review, branch, push, or open PRs — those are [review-phase](../review-phase/SKILL.md) and [integrate-phase](../integrate-phase/SKILL.md). It also does **not** decide whether a phase runs — the conductor already filtered cross-repo / flag-removal phases.
9
+
10
+ ## Inputs (passed by the conductor as data — this skill re-derives none of them)
11
+
12
+ - `phase` record: `{ id, title, goal, body, spec_use_case, suggested_model_tier, reusable_skills, has_e2e, acceptance }`.
13
+ - Plan-level decisions: **Goals + Non-goals**, **Guiding Decisions**, the relevant **Data Model Changes** subsection.
14
+ - Prior-phase summaries (the tracking file's "Completed Phases" section).
15
+ - `WORKROOT`, `BASE_BRANCH`, `SANDBOX_TIER` — resolved once by the conductor ([Resolve WORKROOT step](../implement-plan/SKILL.md#step-05--resolve-workroot)).
16
+ - `run_options.full_test_suite` — resolves the outer gate's test scope in the composed prompt's `{If run_options.full_test_suite = true:}` marker (false = scoped suite only; true = full repo suite).
17
+
18
+ ## 1. Compose the agent prompt (token-efficient)
19
+
20
+ Compose with **only what the agent needs**:
21
+
22
+ <!-- include: partials/implementer-prompt.md#FULL -->
23
+
24
+ <!-- include: partials/model-pick.md#MODEL_PICK -->
25
+
26
+ ## 3. Spawn the subagent
27
+
28
+ Use whatever agent-spawning primitive the runtime exposes. Pass:
29
+
30
+ - A descriptive label (e.g. `"{plan.id} {phase.id}: {phase.title}"`).
31
+ - The model from the [Pick the model](#pick-the-model-from-the-plans-per-phase-suggestion) step, translated to the runner's form.
32
+ - The phase prompt from the [Compose the agent prompt](#1-compose-the-agent-prompt-token-efficient) step.
33
+ - The right **agent type** (below).
34
+
35
+ <!-- include: partials/worktree-seam.md#SANDBOX_WRAP -->
36
+
37
+ **Agent type per phase.** Project agents in [`ai-tools/agents/`](ai-tools/agents/) (exposed to claude-code via `.claude/agents` symlink):
38
+
39
+ {{AGENT_DISPATCH_TABLE}}
40
+
41
+ A phase that combines shapes → the agent type stays `implementer`, and the prompt lists every relevant SKILL.md. The agent type changes only when a stack-specialist's risk is the primary one.
42
+
43
+ **Avoid bouncing the same phase between multiple agents.** Wanting to "hand off" mid-phase → the plan should have split into sub-phases instead.
44
+
45
+ ## Output
46
+
47
+ Return the implementer's single final report verbatim to the conductor (status, files, summary, deviations, blockers). The conductor — not this skill — writes tracking from the git diff + the report.
@@ -0,0 +1,186 @@
1
+ ---
2
+ name: implement-plan
3
+ description: Execute a phased implementation plan from `{{PLAN_DIR}}/` in {{PROJECT_NAME}} by orchestrating one subagent per phase (using whatever model the plan suggests and the runtime supports), pushing one stacked branch per phase to {{CODE_HOST}}, and tracking progress. Use when the user says "implement the plan", "execute plan X", "start implementation", "run phase N of plan Y", "implement {feature} plan", or asks to drive a `*_IMPLEMENTATION_PLAN.md` file phase-by-phase. NOT for one-off changes, single-file edits, or work that doesn't have an existing plan. {{PR_POLICY_DESCRIPTION}}
4
+ ---
5
+
6
+ # Implement Plan
7
+
8
+ Drive a phased plan in [`{{PLAN_DIR}}/`]({{PLAN_DIR}}/) to completion. This skill is a **thin conductor**: it parses the plan once, resolves one `WORKROOT`, then runs a fixed three-step pipeline per phase, delegating the real work to focused sub-skills:
9
+
10
+ 1. [implement-phase](../implement-phase/SKILL.md) — compose prompt, pick model, spawn the implementer.
11
+ 2. [review-phase](../review-phase/SKILL.md) — three-layer review + fix loop.
12
+ 3. {{INTEGRATE_PHASE_DISPATCH}} — push the branch + open the PR via context file.
13
+
14
+ The conductor itself owns only: plan parsing, phase classification, `WORKROOT` resolution, the loop, the progress-tracking file, the pause gate, and the final report. Harness-agnostic — claude-code, OpenAI Codex, Google's runtime, or any framework with a "spawn subagent with model + prompt" primitive.
15
+
16
+ Execution counterpart to [plan-feature](../plan-feature/SKILL.md). Plan = contract; this skill = build pipeline.
17
+
18
+ ## Working assumptions
19
+
20
+ - Repo: {{PROJECT_NAME}} ({{STACK_SUMMARY}}). Conventions: [AGENTS.md](AGENTS.md).
21
+ - Plan files: [`{{PLAN_DIR}}/YYYY-MM-DD-FEATURE_NAME_IMPLEMENTATION_PLAN.md`]({{PLAN_DIR}}/).
22
+ - Lint: `{{LINT_CMD}}`. Format: `{{FORMAT_CMD}}`.
23
+ - Type / build gate: `{{BUILD_CMD}}`{{TYPECHECK_NOTE}}.
24
+ - Unit / integration tests: `{{TEST_CMD}}` (everything){{SCOPED_TEST_NOTE}}.
25
+ {{E2E_BLOCK}}
26
+ {{STACK_SPECIFIC_DEPLOY_BLOCK}}
27
+ - Code host: **{{CODE_HOST}}**. {{PR_POLICY_BLOCK}}
28
+ - {{COAUTHOR_POLICY_BLOCK}}
29
+
30
+ ## Step 0 — Locate + parse plan
31
+
32
+ Parse once, reuse for every phase:
33
+
34
+ 1. **Identify plan file.** Ask user which plan (path or feature name). Feature name: `ls {{PLAN_DIR}}/` + grep; confirm before proceeding.
35
+ 2. **Extract structured fields**, in order:
36
+ - **Feature name** + **plan id** — derived from filename's `FEATURE_NAME` portion only: strip `YYYY-MM-DD-` prefix + `_IMPLEMENTATION_PLAN.md` suffix. Kebab variant for branch names.
37
+ - **Goals + Non-goals** section — verbatim, used in every phase prompt.
38
+ - **Guiding Decisions** section — verbatim. Pay attention to: feature flag (key, scope, default, flip-on criterion), storage shape, tenant scoping, API contract decisions.
39
+ - **Data Model Changes** section — keep full body; later phases reference earlier subsections.
40
+ - **Phased Rollout** section — parse into phase records: `{ id, title, goal, body, spec_use_case, suggested_model_tier, reusable_skills, has_e2e, acceptance, is_cross_repo, is_flag_removal }`.
41
+ - **Risk & Rollout Notes**, **Open Questions**, **Touch List** sections — keep available; include in phase prompts only when relevant.
42
+ 3. **Classify each phase**: `is_cross_repo`, `is_flag_removal` — the conductor does NOT auto-execute these (see [Cross-repo phases](#cross-repo-phases) + [Flag-removal phase](#flag-removal-phase-always-out-of-scope)).
43
+ 4. **Ask the user three opt-in questions** via `AskUserQuestion`. Defaults are project-specific (see below); record every answer in tracking under `run_options`:
44
+
45
+ a. **Pause between phases?** *"Do you want me to pause and wait for confirmation after each phase, before starting the next one? Lets you review the diff / branch / PR / tracking summary before moving on."* Options: `Auto-flow (default) — keep going phase to phase`, `Pause between phases — wait for go after each one`.
46
+
47
+ b. **Draft inline review comments per phase?** *"On top of the standard PR description, do you want me to scan each phase's diff and add 3–10 inline comments calling out non-obvious decisions (subtle invariants, feature-flag short-circuits, cross-phase coupling, upstream-contract naming)? Off by default — say yes when reviewers will appreciate annotated diffs."* Options: `Yes — include inline comments`, `No — PR description only`.
48
+
49
+ c. **Run phases in a worktree?** *"Do you want every phase's subagent to work inside an isolated git worktree (its own runnable copy of the app with its own dev + test DB, env files, docker-compose project name) instead of sharing your main checkout? Lets you keep using `{{DEFAULT_BRANCH}}` for unrelated work while this plan runs; survives parallel plans on the same repo without DB / port / docker collisions. Costs one extra checkout's worth of disk + the time it takes [prepare-worktree](../prepare-worktree/SKILL.md) to provision it."* Options: `No — run in current checkout`, `Yes — provision one shared worktree for the whole plan`. Default = value of `run_options.implement-plan.use_worktree` in `.vinta-ai-workflows.yaml` (`No` when unset).
50
+
51
+ When `Yes`: **the same worktree is used for every executable phase** — all phase branches stack inside it. The skill never provisions a second worktree mid-plan. If the user wants per-phase worktrees, that's a different workflow (split the plan into independent plans).
52
+
53
+ Skip this question entirely when `foundation_skills.prepare-worktree` is `disabled` in `.vinta-ai-workflows.yaml`: record `run_options.use_worktree = false`; surface a one-line note that worktree isolation is available if the team opts in via [vinta-sync-ai-tools](../../skills/vinta-sync-ai-tools/SKILL.md).
54
+
55
+ d. **Full test suite each phase?** *"Each phase's outer gate always runs the repo-wide type/build gate. For tests, do you want the quick path (run only the scoped suite covering the apps/files that phase touched — faster phases) or the full repo test suite every phase (slower, but guards against regressions in untouched code)? New tests still pass individually in the inner loop either way."* Options: `Quick — scoped tests only each phase (default)`, `Full — run the whole test suite each phase`. Default = value of `run_options.implement-plan.full_test_suite` in `.vinta-ai-workflows.yaml` (`Quick`/false when unset). Records `run_options.full_test_suite` (`true` only for the `Full` answer).
56
+
57
+ PR opening itself is **not** asked here — it's governed by the project's PR creation policy captured at bootstrap (see `{{PR_POLICY_BLOCK}}` above). When that policy = "agents create PRs", the {{INTEGRATE_PHASE_DISPATCH}} step always opens the PR via [open-pr.sh](../open-pr-from-context/scripts/open-pr.sh) regardless of the comment opt-in.{{COMMIT_STRATEGY_STEP0_QUESTION}}
58
+
59
+ 5. **Confirm with user before starting.** Show plan path, phase list (id + title + tier + cross-repo/flag-removal flags + e2e flag), phases this skill will execute vs defer, {{BRANCH_NAMING_PATTERN_SUMMARY}}, captured `run_options.pause_between_phases` + `run_options.generate_inline_comments` + `run_options.use_worktree` + `run_options.full_test_suite`{{COMMIT_STRATEGY_CONFIRM_NOTE}}{{PR_REMINDER_LINE}}.
60
+
61
+ Wait for "go". After that, the per-phase pause behavior follows `run_options.pause_between_phases`. Inline-comment drafting follows `run_options.generate_inline_comments`. Worktree isolation follows `run_options.use_worktree`. Outer-gate test scope follows `run_options.full_test_suite`.{{COMMIT_STRATEGY_STEP0_TRAILER}}
62
+
63
+ <!-- include: partials/worktree-seam.md#WORKROOT_RESOLUTION -->
64
+
65
+ <!-- include: partials/worktree-seam.md#WORKROOT_TOPOLOGY_RULE -->
66
+
67
+ ## Step 1 — Per-phase loop
68
+
69
+ For each phase that's `not is_cross_repo and not is_flag_removal`, in plan order, run the pipeline:
70
+
71
+ ### 1a. Implement
72
+
73
+ Invoke [implement-phase](../implement-phase/SKILL.md), passing the phase record, the plan-level decisions (**Goals + Non-goals**, **Guiding Decisions**, the relevant **Data Model Changes** subsection), the prior-phase tracking summaries, `run_options.full_test_suite`, and `WORKROOT` / `BASE_BRANCH` / `SANDBOX_TIER`. It returns the implementer's report.
74
+
75
+ **Model escalation.** implement-phase escalates one tier + retries once on a clear capability gap. After Tier 4 fails, it stops and hands back the failure — update tracking with `❌`, post the report to the user, ask how to proceed. Don't silently re-derive tier.
76
+
77
+ ### 1b. Review
78
+
79
+ Invoke [review-phase](../review-phase/SKILL.md) against the phase diff, passing the phase body to walk, `WORKROOT`, `main_checkout`, `run_options.full_test_suite`, and the `reviewer` / `fixer` agent types. It loops its three layers + fix loop until clean, then returns `PASS` (or the surfaced findings). Do not proceed to integrate while any layer is red.
80
+
81
+ ### 1c. Integrate
82
+
83
+ Invoke {{INTEGRATE_PHASE_DISPATCH}}, passing `WORKROOT` / `BASE_BRANCH`, the `{{PR_POLICY_BLOCK}}` policy, and `run_options.generate_inline_comments`. It pushes the branch and routes the PR through the context file, returning the branch + PR-context path + status.
84
+
85
+ ### 1d. Update tracking file
86
+
87
+ Tracking lives at `{{PLAN_DIR}}/TRACKING_{plan-id}.md`. Commit on the **current** phase's branch — deletion in [Step 2](#step-2--final-report).
88
+
89
+ Schema: feature-name, plan path, started/last-updated dates, optional feature-flag info, **run options** (`pause_between_phases`, `generate_inline_comments`, `full_test_suite`, `use_worktree`, `worktree_path`, `worktree_branch`, `worktree_summary`, `sandbox_tier` — last four only when `use_worktree = true`), {{TRACKING_BRANCH_FIELD}}, completed-phases (with status, model{{TRACKING_PHASE_BRANCH_FIELD}}, e2e+screenshots if any, 5–15 line summary), current phase, remaining phases, deferred phases.
90
+
91
+ The conductor writes this from the git diff + the agent's summary — not from the agent's narration.
92
+
93
+ ### 1e. Send brief update to user
94
+
95
+ One short paragraph: phase N done, branch pushed{{PR_LINK_NOTE}}, what got built, and — when the [Integrate](#1c-integrate) step ran — the PR-context file path with its `status` (`published` + URL when `open-pr.sh` opened the PR; `pending` when the script wasn't run because PR policy = branches only or deps were missing). When `status: pending`, mention how to publish later (`bash ai-tools/skills/open-pr-from-context/scripts/open-pr.sh <path>`). Moving to phase N+1. No long retrospective — the tracking file is the durable record.
96
+
97
+ ### 1f. Per-phase pause gate (opt-in)
98
+
99
+ `run_options.pause_between_phases = false` (default) → **immediately start the next phase**. Do not wait.
100
+
101
+ `run_options.pause_between_phases = true` → ask the user via `AskUserQuestion`:
102
+
103
+ - `Continue — start phase N+1`
104
+ - `Pause — stop here, I'll resume later by re-invoking the skill` (conductor exits cleanly; tracking file already records progress so the next invocation resumes mid-plan per [Re-running mid-plan](#re-running-mid-plan)).
105
+ - `Stop — abort the plan run` (conductor stops; user decides next steps manually).
106
+
107
+ Wait for the answer. Don't spawn anything in the meantime. The pause is the user's review window — they may inspect the diff, the branch, the PR-context file, or the tracking file before agreeing to continue.
108
+
109
+ ## Cross-repo phases
110
+
111
+ Phase in another repo:
112
+ 1. **Do not implement.**
113
+ 2. Mark in tracking under "Deferred Phases".
114
+ 3. Continue to the next in-repo phase. Don't block on cross-repo work.
115
+
116
+ ## Flag-removal phase (always out of scope)
117
+
118
+ Plan declared a flag → last phase is `Phase N — Remove the {flag-key} feature flag`. This skill **never** executes that phase. Flag removal is gated on real-world soak signal + is the exclusive responsibility of a dedicated flag-removal skill (separate skill).
119
+
120
+ What this skill does instead:
121
+ 1. Identify the phase during Step 0; always exclude.
122
+ 2. Mark in tracking as deferred.
123
+ 3. End the run with a `/schedule` offer pointing at the dedicated flag-removal skill.
124
+ 4. Refuse + redirect if the user asks this skill to remove the flag.
125
+
126
+ ## Re-running mid-plan
127
+
128
+ User invokes the skill against a partially-done plan:
129
+
130
+ 1. Read `{{PLAN_DIR}}/TRACKING_{plan-id}.md` if present. Extract `run_options.*` — including `worktree_path` / `worktree_branch` / `worktree_summary` when set. Never re-prompt the Step 0 opt-in questions on resume; the original answers stick.
131
+ 2. **Worktree resume.** When `run_options.use_worktree = true`:
132
+ - Confirm the worktree still exists (`git worktree list | grep <worktree_path>`). Missing → ask user: `Reprovision (run prepare-worktree again with the same name)`, `Switch to main checkout (flip use_worktree to false for the rest of the run)`, `Stop`.
133
+ - Confirm the worktree summary file still parses; if not, regenerate from the existing worktree state.
134
+ - **Re-probe `SANDBOX_TIER`** (`command -v sandbox-exec || command -v bwrap`) — a resume may run on a different machine than the original provisioning. Update `run_options.sandbox_tier` in tracking before spawning; the implement-phase spawn wrapping follows the re-probed value.
135
+ - All resumed phases use the existing worktree — do not provision a second one.
136
+ 3. `git -C <WORKROOT> branch -a | grep plan/{plan-id-kebab}` to detect already-pushed phase branches.
137
+ 4. Cross-reference with the plan's phase list.
138
+ 5. Confirm the resumption point with the user.
139
+
140
+ ## Step 2 — Final report
141
+
142
+ After all executable phases complete:
143
+
144
+ 1. **Delete `TRACKING_{plan-id}.md`** on the last phase's branch. Commit. The plan file stays.
145
+ 2. Send the user a final summary: {{FINAL_REPORT_BRANCH_SUMMARY}}; for UI-flow phases — list of `pr-screenshots/` files (if applicable); deferred phases (cross-repo + flag-removal); next steps for the human. When `run_options.use_worktree = true`: include the worktree path + branch + summary file path + the teardown command (`git worktree remove <path>` + the per-engine drop-db / `docker compose -p <project> down -v` lines from `<worktree_summary>`). Do NOT auto-run teardown — the user may still want the worktree to debug review feedback or land follow-ups.
146
+ {{FINAL_REPORT_PR_NOTE}}
147
+ 3. Flag-removal phase deferred → end with `/schedule` offer for the dedicated flag-removal skill.
148
+
149
+ ## Important rules
150
+
151
+ - **Read AGENTS.md** in every phase prompt.
152
+ - **Stage explicitly.** No `git add -A`.
153
+ - **Subagents work in fresh sessions.** Each phase = a new subagent. Tracking + plan files = the context handoff.
154
+ - **Conductor owns git topology.** Subagents commit but never branch, push, {{PR_RULE_TAIL}}.
155
+ {{COAUTHOR_RULE_LINE}}
156
+ - **Trust the plan's per-phase model suggestion.** Model selection lives in [implement-phase](../implement-phase/SKILL.md); the conductor never re-derives tiers.
157
+ - **Don't re-implement what a project skill encodes.**
158
+ {{UI_E2E_RULE_LINE}}
159
+ - **Two-tier verification, in order, every phase.** Inner scoped, then the outer gate — enforced inside [implement-phase](../implement-phase/SKILL.md). The outer gate always runs the repo-wide type/build gate; its test scope follows `run_options.full_test_suite` (scoped suite by default, full repo suite when opted in).
160
+ - **Three-layer review, every phase, no exceptions** — [review-phase](../review-phase/SKILL.md) is not optional and not inlined here.
161
+ - **Orchestrator never edits code.**
162
+ - **Feature flags = gates, not toggles for tests.**
163
+ - **Never remove a feature flag from this skill.**
164
+ - **Stop on Tier-4 failure.**
165
+ - **Honor opt-in flags.** `run_options.pause_between_phases` controls the [Per-phase pause gate](#1f-per-phase-pause-gate-opt-in); `run_options.generate_inline_comments` controls whether {{INTEGRATE_PHASE_DISPATCH}} drafts inline comments (always writes the file when that step runs at all — empty comments when off); `run_options.use_worktree` controls whether the [Resolve WORKROOT step](#step-05--resolve-workroot) provisions a worktree and thus what `WORKROOT` / `BASE_BRANCH` / `SANDBOX_TIER` resolve to; `run_options.full_test_suite` controls the outer-gate test scope ([Implement](#1a-implement) + [Review](#1b-review) Layer 1) — scoped suite by default, full repo suite when `true`.
166
+ - **One worktree per plan run.** When `use_worktree = true`, provision once in the [Resolve WORKROOT step](#step-05--resolve-workroot) and reuse for every phase. Never spawn a second worktree mid-plan; never silently fall back to the main checkout on prepare-worktree failure (ask the user).
167
+ - **Don't auto-tear-down the worktree.** Step 2 surfaces the teardown command; the user runs it when ready.
168
+ - **`WORKROOT` is resolved once, used everywhere.** Every sub-skill takes `WORKROOT` / `BASE_BRANCH` / `SANDBOX_TIER` as data — no step re-derives worktree state. OS-level prevention (sandbox wrap in implement-phase when `SANDBOX_TIER = enforced`) plus the review-phase stray-write backstop keep main-checkout writes out; see [worktree-seam](../implement-phase/SKILL.md#3-spawn-the-subagent).
169
+ - **PR-context file + `open-pr.sh` is the only PR-creation path.** No raw `gh pr create` / `glab mr create` calls outside the bundled script.
170
+ {{DEPENDENCY_LICENSE_RULE_LINE}}
171
+ - **Never use `§N` shorthand to point at sections** — neither in this skill body nor in any rendered file (tracking, prs-context, branch description). Always use the section's full name with a markdown link when possible.
172
+
173
+ ## Quick checklist (conductor, per phase)
174
+
175
+ - [ ] Plan parsed; structured fields cached.
176
+ - [ ] Cross-repo + flag-removal phases identified + deferred.
177
+ - [ ] `WORKROOT` / `BASE_BRANCH` / `SANDBOX_TIER` resolved once ([Resolve WORKROOT step](#step-05--resolve-workroot)); worktree provisioned + summary captured + user confirmed when `use_worktree = true`.
178
+ - [ ] [implement-phase](../implement-phase/SKILL.md) run: prompt composed with **Goals + Non-goals** + **Guiding Decisions** + relevant **Data Model Changes** subsection + tracking summaries + this phase's body; model picked from `**Suggested AI model**:` (cheapest available); implementer report received.
179
+ - [ ] [review-phase](../review-phase/SKILL.md) run: Layers 1–3 clean; BLOCKERs fixed; SHOULD-FIX fixed or noted; outer gate re-run after any fix; when a worktree is in use, `git -C <main_checkout> status --short` clean after the implementer and after every fixer.
180
+ - [ ] {{INTEGRATE_PHASE_DISPATCH}} run: {{BRANCH_CHECKLIST_LINE}}{{PR_CHECKLIST_NOTE}}
181
+ {{COMMIT_STRATEGY_CHECKLIST_BLOCK}}
182
+ - [ ] **Open PR via context file** decision applied per matrix (PR policy + `generate_inline_comments`): file written when at least one of policy=create / comments=true holds; `open-pr.sh` run when policy=create AND deps available (PR URL captured); per-comment failures (exit 1) and hard failures (exit 2) surfaced.
183
+ - [ ] `TRACKING_{plan-id}.md` updated.
184
+ - [ ] One-paragraph user update sent (PR URL or pending-file path included).
185
+ - [ ] If `run_options.pause_between_phases = true`: prompted user (`Continue` / `Pause` / `Stop`); honored answer. Else: next phase started immediately.
186
+ - [ ] On final phase: tracking file deleted; final summary lists branches{{FINAL_CHECKLIST_PR_NOTE}}; any `status: pending` PR-context files listed with publish command; `/schedule` offer for flag-removal if applicable.
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: {{INTEGRATE_PHASE_NAME}}
3
+ description: Internal integration step of [implement-plan] — NOT a standalone entry point. Pushes one reviewed phase along {{PROJECT_NAME}}'s commit strategy and opens (or updates) its PR through the prs-context file + bundled open-pr.sh — the only PR-creation path. The conductor passes the resolved `WORKROOT` / `BASE_BRANCH` and the PR / inline-comment policy; do not invoke directly to push arbitrary work.
4
+ ---
5
+
6
+ # Integrate one phase
7
+
8
+ Invoked by [implement-plan](../implement-plan/SKILL.md) after [review-phase](../review-phase/SKILL.md) returns clean. Pushes the phase and routes its PR through the context file. Subagents never push or open PRs — this orchestrator step does.
9
+
10
+ <!-- derive-skills note: for projects with `policies.commit_strategy` = stacked-branches or modular-commits this template renders once to `ai-tools/skills/integrate-phase/`. For `ask`, it renders TWICE — to `integrate-phase-stacked` and `integrate-phase-modular` — each with `<RESOLVED>` bound to its strategy and `{{INTEGRATE_PHASE_NAME}}` set to match its dir; the conductor dispatches to one by name on `run_options.commit_strategy_resolved`. -->
11
+
12
+ ## Inputs (passed by the conductor)
13
+
14
+ - `WORKROOT`, `BASE_BRANCH` — resolved once by the conductor.
15
+ - `{{PR_POLICY_BLOCK}}` policy + `run_options.generate_inline_comments`.
16
+ - The phase record + plan-level decisions (for the PR body).
17
+
18
+ <!-- include: partials/worktree-seam.md#WORKROOT_TOPOLOGY_RULE -->
19
+
20
+ ## {{BRANCH_PUSH_HEADING}}
21
+
22
+ <!-- include: partials/commit-strategy/<RESOLVED>.md#BRANCH_NAMING -->
23
+
24
+ ## Open PR via context file
25
+
26
+ <!-- include: partials/pr-context.md#PR_CONTEXT -->
27
+
28
+ ## Output
29
+
30
+ Return to the conductor: the branch pushed, and the PR-context file path with its `status` (`published` + `pr_url` when `open-pr.sh` ran; `pending` otherwise) plus the publish command when `pending`.
@@ -0,0 +1,25 @@
1
+ ---
2
+ name: review-phase
3
+ description: Internal review gate of [implement-plan] / [amend-plan] / [systematic-debugging] — NOT a standalone entry point. Runs the mandatory three-layer review (mechanical checks, plan-compliance walkthrough, independent reviewer subagent) plus the fix loop against one phase's diff in {{PROJECT_NAME}}, spawning reviewer + fixer subagents and looping until all three layers are clean. The invoking conductor passes the diff, the phase body to walk against, and the resolved `WORKROOT`; do not invoke directly to "review my code" — use the project's standard code-review path for that.
4
+ ---
5
+
6
+ # Review one phase
7
+
8
+ The single review implementation shared by every plan-execution conductor: [implement-plan](../implement-plan/SKILL.md) (after an implementer runs), [amend-plan](../amend-plan/SKILL.md) (after a rewrite), and [systematic-debugging](../systematic-debugging/SKILL.md) (against the fix diff). Read-only orchestration: this skill **never edits code** — every issue becomes a fix-up subagent task.
9
+
10
+ ## Inputs (passed by the conductor)
11
+
12
+ - The phase diff (on the current branch inside `WORKROOT`).
13
+ - The phase body to walk against (the **new** body when invoked by amend-plan).
14
+ - `WORKROOT`, `SANDBOX_TIER` — resolved once by the conductor.
15
+ - `main_checkout` — the repo root the run was invoked from (equals `WORKROOT` when no worktree).
16
+ - `run_options.full_test_suite` — resolves which outer gate Layer 1 item 3 verifies ran (false = scoped suite; true = full repo suite).
17
+ - The project's `reviewer` + `fixer` agent types.
18
+
19
+ ## Review
20
+
21
+ <!-- include: partials/review-layers.md#LAYERS -->
22
+
23
+ ## Output
24
+
25
+ Return to the conductor: `PASS` (all three layers clean) with a one-line note, or the list of BLOCKER / SHOULD-FIX findings and what the fix loop applied. The conductor owns branch / push / PR — this skill hands back a clean (or annotated) working tree in `WORKROOT`.