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,129 @@
1
+ ---
2
+ name: thermo-nuclear-code-quality-review
3
+ description: Run an extremely strict maintainability review of a diff — abstraction quality, giant files, and spaghetti-condition growth. This is a deep, on-demand structural audit, harsher than the normal per-phase review: it hunts for "code judo" reframes that make whole branches, helpers, modes, or layers disappear rather than polishing what's there. Use when the user asks for a "thermo-nuclear code quality review", "thermonuclear review", "deep code quality audit", or "harsh maintainability review", or when the standard review flow escalates a structural concern. Opt-in only — do not auto-run it on every diff; it is meant to be invoked deliberately. Read-only: it reports findings and hands each fix to a fixer, it does not edit code itself.
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # Thermo-nuclear code quality review
8
+
9
+ An intentionally severe maintainability audit. The normal review checks that a change is correct, tested, and in-convention. This review asks a harder question: **is the change structured as well as it could be, or did it grow complexity that a better framing would have avoided?**
10
+
11
+ The mindset is **ambitious structural simplification**, not incremental cleanup. Look for reframes that make whole branches, helpers, modes, conditionals, or layers disappear entirely — a "code judo" move that preserves behavior while collapsing the structure. Do not approve a change merely because it works.
12
+
13
+ This is a heavy, deliberate pass. It is **not** part of the automatic per-phase review — run it when asked, or when the standard `review-phase` review escalates a structural concern it can't fully resolve. (See "Relationship to the standard review flow" below.)
14
+
15
+ ## When to use / when to skip
16
+
17
+ Use it when:
18
+ - The user explicitly asks for a thermo-nuclear / deep / harsh maintainability review.
19
+ - A phase touched core architecture, added a large file, or introduced branching that "smells" — and the standard reviewer flagged it for a deeper look.
20
+ - Before merging something large or long-lived where structure matters more than speed.
21
+
22
+ Skip it when:
23
+ - The diff is a small, self-contained fix, a docs/comment change, or generated output. Running a thermo-nuclear pass on a two-line change wastes effort and produces noise.
24
+ - Correctness is the open question, not structure — use the standard review or the `systematic-debugging` skill for that.
25
+
26
+ ## Scope
27
+
28
+ Default scope is the current change set: find it with `git diff --stat` / `git status --short` against the base the work started from (or the phase diff, when a review conductor passes one). If the user names a PR, a directory, or specific files, use that scope instead.
29
+
30
+ Read the **full diff** of every file in scope, plus enough of each touched file's surroundings to judge structure — a diff line looks innocent until you see the 1,200-line file it lands in.
31
+
32
+ ## The standards (all non-negotiable)
33
+
34
+ 0. **Ambitious structural simplification.** Look for opportunities to reframe the change so that whole branches, helpers, modes, conditionals, or layers disappear entirely. This is the primary lens; the rest are specific ways it shows up.
35
+ 1. **File-size boundary.** Do not let a change push a file from under ~1,000 lines to over ~1,000 lines without a very strong reason, especially when the added code is extractable.
36
+ 2. **Spaghetti growth.** Be highly suspicious of new ad-hoc conditionals, scattered special cases, or one-off branches inserted into unrelated flows.
37
+ 3. **Design-first bias.** If behavior can stay the same while the structure becomes meaningfully cleaner, push for the cleaner version.
38
+ 4. **Direct code preference.** Treat brittle, ad-hoc, or "magic" behavior as a code-quality problem, not a clever solution.
39
+ 5. **Type and boundary cleanliness.** Question unnecessary optionality, `unknown`, `any`, or cast-heavy code when a clearer type boundary could exist. (Apply the equivalent in the project's language — loose typing, stringly-typed data, escape hatches.)
40
+ 6. **Canonical layer logic.** Call out feature logic leaking into shared paths, or implementation details leaking through an API boundary. Reuse existing canonical utilities instead of bespoke duplicates.
41
+ 7. **Sequential orchestration.** If independent work is serialized for no good reason, ask whether the flow should run in parallel, and whether partial-update logic leaves state less atomic than it should be.
42
+
43
+ ## Primary review questions
44
+
45
+ Apply these systematically to the diff:
46
+
47
+ 1. Is there a "code judo" move that would make this dramatically simpler?
48
+ 2. Can this change be reframed so fewer concepts, branches, or helper layers are needed?
49
+ 3. Does this improve or worsen the local architecture?
50
+ 4. Did the diff add branching complexity where a better abstraction should exist?
51
+ 5. Did a previously cohesive module become more coupled, more stateful, or harder to scan?
52
+ 6. Is this logic living in the right file and layer?
53
+ 7. Did this change enlarge a file or component past a healthy size boundary?
54
+ 8. Are there repeated conditionals that signal a missing model or missing helper?
55
+ 9. Is the implementation direct and legible, or does it rely on special cases and incidental control flow?
56
+ 10. Is this abstraction actually earning its keep, or is it just a wrapper?
57
+ 11. Did the diff introduce casts, optionality, or ad-hoc object shapes that obscure the real invariant?
58
+ 12. Is this logic in the canonical layer, or did the diff leak details across a boundary?
59
+ 13. Is this orchestration more sequential or less atomic than it needs to be?
60
+
61
+ ## Flag aggressively
62
+
63
+ - A complicated implementation where a cleaner reframe could eliminate whole categories of complexity.
64
+ - Refactors that move code without reducing conceptual overhead for readers.
65
+ - Files crossing ~1,000 lines because of this change, especially when the added code is extractable.
66
+ - New conditionals bolted onto unrelated code paths.
67
+ - One-off booleans, nullable modes, or flags complicating existing control flow.
68
+ - Feature-specific logic leaking into general-purpose modules.
69
+ - Generic "magic" handling that obscures a simple structure.
70
+ - Thin wrappers or identity abstractions adding indirection without clarity.
71
+ - Unnecessary casts, `any` / `unknown`, or optional params muddying contracts.
72
+ - Copy-pasted logic instead of an extracted helper.
73
+ - Narrow edge-case handling wedged into the middle of already-busy functions.
74
+ - Refactors that technically pass tests but reduce modularity or readability.
75
+ - "Temporary" branching that is likely to become permanent debt.
76
+ - Bespoke helpers duplicating existing canonical utilities.
77
+ - Logic placed in the wrong layer/package when more central ownership exists.
78
+ - Sequential async flow where independent work could run in parallel.
79
+ - Partial-update logic that leaves state less atomic than necessary.
80
+
81
+ ## Approval bar
82
+
83
+ Treat these as blockers unless there is a strong, stated justification:
84
+
85
+ - Plausible code-judo moves exist but were left unexplored.
86
+ - A file crosses ~1,000 lines because of this change without a compelling reason.
87
+ - Ad-hoc branching tangles an existing flow.
88
+ - Feature checks scatter across shared code to solve a local problem.
89
+ - Unnecessary abstractions, wrappers, or cast-heavy contracts increase indirection.
90
+ - Existing helpers are duplicated, or logic lands in the wrong canonical layer.
91
+
92
+ Do not approve merely because behavior seems correct.
93
+
94
+ ## Output format
95
+
96
+ Report findings prioritized in this order:
97
+
98
+ 1. Structural code-quality regressions.
99
+ 2. Missed opportunities for dramatic simplification / code-judo restructuring.
100
+ 3. Spaghetti / branching complexity increases.
101
+ 4. File-size and layering violations.
102
+ 5. Type / boundary and duplication issues.
103
+
104
+ For each finding: name the file and lines, state the concrete regression, and — this is the point of the review — describe the reframe that removes it, not just "this is complex." Do not flood the review with low-value nits when larger structural issues exist; a page of naming quibbles buries the one restructuring that matters.
105
+
106
+ Triage each finding like the standard review does:
107
+ - **BLOCKER** — must fix before merge (matches the approval-bar list above).
108
+ - **SHOULD-FIX** — fix now if cheap, otherwise a tracked follow-up.
109
+ - **NIT** — mention only if trivially cheap.
110
+
111
+ ## Relationship to the standard review flow
112
+
113
+ This skill is read-only, like the project's normal review. It does not edit code. When a finding warrants a change, hand it to the project's `fixer` agent ([ai-tools/agents/fixer.md](ai-tools/agents/fixer.md)) with the finding quoted verbatim, exactly as the standard fix loop does.
114
+
115
+ The per-phase review (the `reviewer` agent, [ai-tools/agents/reviewer.md](ai-tools/agents/reviewer.md)) applies a condensed version of standard 0 on every phase — "is there an obvious code-judo reframe?" When that lens surfaces something structural that deserves a full audit, the reviewer escalates by invoking this skill against the phase diff. Reserve the full pass for when it earns its cost; the condensed lens is enough for routine phases.
116
+
117
+ ## Pitfalls
118
+
119
+ - **Nit flooding.** The failure mode of a harsh review is a wall of trivial comments that hides the one finding that matters. Lead with structure; drop the nits.
120
+ - **"Cleaner" that is not.** A reframe that trades one form of complexity for another, or that hurts readability to save lines, is not a win. Only push a change when it genuinely reduces conceptual overhead.
121
+ - **Rewriting for taste.** Behavior must be preserved. This is a review, not a redesign mandate — propose reframes, quote them as findings, and let the fixer and conductor decide.
122
+ - **Running it everywhere.** It is opt-in for a reason. Auto-running it on every small diff produces noise and slows the flow.
123
+
124
+ ## Verification
125
+
126
+ - Every finding names a concrete file/line and a specific reframe, not a vague "too complex."
127
+ - Findings are ordered by the priority list above, BLOCKER first.
128
+ - The pass edited no code directly — any change went through a fixer.
129
+ - If nothing structural was found on a large, multi-file diff, you looked again before saying so.
@@ -0,0 +1,42 @@
1
+ # `plan-execution/` — shell templates + shared partials
2
+
3
+ Source-of-truth fragments for the **plan-execution skill family** that
4
+ `vinta-derive-skills` renders into a target project's `ai-tools/skills/`:
5
+
6
+ - `implement-plan` (conductor) — parse → classify → resolve `WORKROOT` → per-phase loop → track → report.
7
+ - `implement-phase` — compose prompt + pick model + spawn implementer (one phase).
8
+ - `review-phase` — three-layer review + fix loop (shared by all three conductors).
9
+ - `integrate-phase` — push + open PR via context file (commit-strategy-resolved).
10
+ - `amend-plan` (conductor) — history-rewriting topology; reuses `review-phase` + the implementer-prompt partial.
11
+
12
+ ## Layout
13
+
14
+ ```
15
+ plan-execution/
16
+ ├─ shell/ one *-template.md per rendered SKILL.md (thin; mostly includes)
17
+ └─ partials/ shared bodies authored once, included by multiple shells
18
+ ```
19
+
20
+ ## Assembly mechanism (executed by the `vinta-derive-skills` agent)
21
+
22
+ Each shell carries include directives. The derive-skills agent, per skill:
23
+
24
+ 1. **Expand includes.**
25
+ - `<!-- include: partials/<file>.md -->` — splice the whole partial body in place of the marker.
26
+ - `<!-- include: partials/<file>.md#BLOCK -->` — splice only the block between `<!-- block-begin: BLOCK -->` and `<!-- block-end: BLOCK -->` inside that partial (markers themselves excluded).
27
+ 2. **Substitute `{{PLACEHOLDER}}`** using the inventory + Step 0 interview answers (same substitution table as every other Bucket B template — see [../../SKILL.md](../../SKILL.md)).
28
+ 3. **Write** the assembled, fully-substituted body to `ai-tools/skills/<name>/SKILL.md`.
29
+
30
+ Partials and shells are **not** `SKILL.md` files, so they legitimately keep `{{...}}` and `<!-- include -->` markers; `validate-skill-md` never walks them. The **shipped** SKILL.md must have every include expanded and every placeholder substituted — validate that before saving.
31
+
32
+ ## The `WORKROOT` seam (why worktree branching is gone)
33
+
34
+ The conductor resolves three values **once** (see `partials/worktree-seam.md#WORKROOT_RESOLUTION`) and passes them to every sub-skill as data:
35
+
36
+ | Value | `use_worktree = false` | `use_worktree = true` |
37
+ |---|---|---|
38
+ | `WORKROOT` | `<main_checkout>` | `<worktree_path>` |
39
+ | `BASE_BRANCH` | `{{DEFAULT_BRANCH}}` | `<worktree_branch>` |
40
+ | `SANDBOX_TIER` | `none` | `enforced` \| `none` (probed by prepare-worktree) |
41
+
42
+ Every `git` / lint / test / build call in every sub-skill uses `git -C <WORKROOT>` **uniformly** — no `if use_worktree` inside them. Only two genuine conditionals remain, each local and data-driven: the `SANDBOX_TIER`-gated spawn wrap in `implement-phase`, and the `WORKROOT != main_checkout`-gated stray-write check in `review-phase`.
@@ -1,36 +1,29 @@
1
- # Modular-commits substitutions for `implement-plan-template.md`
1
+ <!-- Partial: commit-strategy / modular-commits. Folds in the former implement-plan-template-modular-substitutions.md. Blocks consumed by implement-phase (PER_PHASE_COMMIT) + integrate-phase (BRANCH_NAMING, PR_OPEN_TIMING) + conductor (CHECKLIST). All git calls use `git -C <WORKROOT>`; the first executed phase branches off `<BASE_BRANCH>` — both resolved once by the conductor (see worktree-seam.md#WORKROOT_RESOLUTION). The rendering-guidance appendix at the bottom is read by derive-skills to resolve the {{MODULAR_*}} placeholders; it is NOT part of any shipped block. -->
2
2
 
3
- This file holds the substitution bodies for the `{{COMMIT_STRATEGY_*}}` placeholder family when `policies.commit_strategy = modular-commits`. The `stacked-branches` substitutions are inline in the parent placeholder table in [SKILL.md](../SKILL.md). The `ask` variant emits **both** the stacked and the modular bodies gated by inline runtime markers — see [Phase 4 ask-mode substitutions](#ask-mode-substitutions) at the bottom.
4
-
5
- Each section below is delimited by `<!-- substitution: {{PLACEHOLDER}} -->` markers so derive-skills can extract the block by name. The block's content is everything between the open and close markers, **excluding** the markers themselves.
6
-
7
- ## `{{BRANCH_NAMING_BLOCK}}` (modular)
8
-
9
- <!-- substitution-begin: BRANCH_NAMING_BLOCK -->
3
+ <!-- block-begin: BRANCH_NAMING -->
10
4
  Branch naming: `plan/{plan-id-kebab}` (one branch for the whole plan — no per-phase suffix).
11
5
 
12
- **First executed phase** (branches from `{{DEFAULT_BRANCH}}`):
6
+ **First executed phase** (branches from `<BASE_BRANCH>`, already made current by the conductor):
7
+
13
8
  ```bash
14
- git checkout {{DEFAULT_BRANCH}}
15
- git pull --ff-only
16
- git checkout -b plan/{plan-id-kebab}
9
+ git -C <WORKROOT> checkout <BASE_BRANCH>
10
+ git -C <WORKROOT> checkout -b plan/{plan-id-kebab}
17
11
  # subagent's atomic unit commits land on this branch
18
- git push -u origin plan/{plan-id-kebab}
12
+ git -C <WORKROOT> push -u origin plan/{plan-id-kebab}
19
13
  ```
20
14
 
21
15
  **Subsequent phases** (stay on the same plan branch — no new branch):
16
+
22
17
  ```bash
23
- git checkout plan/{plan-id-kebab}
18
+ git -C <WORKROOT> checkout plan/{plan-id-kebab}
24
19
  # subagent's atomic unit commits land on this branch
25
- git push origin plan/{plan-id-kebab}
20
+ git -C <WORKROOT> push origin plan/{plan-id-kebab}
26
21
  ```
27
22
 
28
23
  The branch carries every phase's commits in plan order. Reviewers read the commit log top-to-bottom as a table of contents of the implementation.
29
- <!-- substitution-end: BRANCH_NAMING_BLOCK -->
24
+ <!-- block-end: BRANCH_NAMING -->
30
25
 
31
- ## `{{PER_PHASE_COMMIT_BLOCK}}` (modular)
32
-
33
- <!-- substitution-begin: PER_PHASE_COMMIT_BLOCK -->
26
+ <!-- block-begin: PER_PHASE_COMMIT -->
34
27
  7. **Plan commit units before staging.** List the logical units this phase produces (e.g. `3 services + 1 use case update + 1 init export`). Each unit = **one** commit. Tests for that unit travel **in the same commit** as the code they test — never a separate commit.
35
28
  8. For each unit, in order:
36
29
  a. Stage exactly that unit's files: `git add <explicit paths>` (NEVER `git add -A` — {{ANTI_GIT_ADD_ALL_REASON}}). Tests for the unit go in the same `git add`.
@@ -76,11 +69,35 @@ Tests for a unit belong **in the same commit** as that unit. Never commit tests
76
69
  | "The user can squash later" | Squashing destroys the logical history this discipline exists to preserve. |
77
70
  | "It's faster to do one commit" | Planning units takes 2 minutes; reviewing a 2000-line blob takes much longer. |
78
71
  | "The changes are all related" | Related ≠ same unit. Services that depend on each other still get separate commits. |
79
- <!-- substitution-end: PER_PHASE_COMMIT_BLOCK -->
72
+ <!-- block-end: PER_PHASE_COMMIT -->
73
+
74
+ <!-- block-begin: PR_OPEN_TIMING -->
75
+ **PR opens once — after Phase 1 passes review.** Subsequent phases push their atomic unit commits to the same plan branch (`plan/{plan-id-kebab}`); the orchestrator re-runs [open-pr.sh](../open-pr-from-context/scripts/open-pr.sh) against the same plan-level prs-context file at `.vinta-ai-workflows/prs-context/{feature-kebab}/plan.md`. The script is idempotent for already-open PRs — it updates the body, appends new inline comments, and posts a `Phase {N} complete — pushed M commits` PR comment.
76
+ <!-- block-end: PR_OPEN_TIMING -->
77
+
78
+ <!-- block-begin: CHECKLIST -->
79
+ - [ ] Commit units listed upfront before any staging.
80
+ - [ ] Each commit covers exactly one logical unit (no "and" in commit messages).
81
+ - [ ] Tests landed in the same commit as the code they cover (never a separate test-only commit).
82
+ - [ ] All unit commits pushed to `plan/{plan-id-kebab}` at end of phase.
83
+ <!-- block-end: CHECKLIST -->
84
+
85
+ <!-- Single-line values (derive-skills substitutes these into the shells directly):
86
+ BRANCH_PUSH_HEADING = Push to plan branch
87
+ BRANCH_NAMING_PATTERN_SUMMARY = plan branch (one branch for whole plan: `plan/{plan-id-kebab}`)
88
+ PRS_CONTEXT_FILE_PATH = a single `.vinta-ai-workflows/prs-context/{feature-kebab}/plan.md` file (one PR per plan, not per phase)
89
+ TRACKING_BRANCH_FIELD = top-level `plan_branch:` field
90
+ TRACKING_PHASE_BRANCH_FIELD = (empty — no per-phase branch under modular)
91
+ FINAL_REPORT_BRANCH_SUMMARY = single plan branch `plan/{plan-id-kebab}` with commit log organized by phase
92
+ BRANCH_CHECKLIST_LINE = Plan branch updated with phase commits; pushed. -->
93
+
94
+ <!-- ===================================================================== -->
95
+ <!-- rendering-guidance (read by derive-skills; NOT shipped in any block) -->
96
+ <!-- ===================================================================== -->
80
97
 
81
98
  ### Conditional example messages (driven by `policies.commit_style`)
82
99
 
83
- derive-skills resolves the six `{{MODULAR_EXAMPLE_*}}` placeholders + the `{{MODULAR_COMMIT_MESSAGE_FORMAT_BLOCK}}` from this table when rendering `{{PER_PHASE_COMMIT_BLOCK}}`:
100
+ derive-skills resolves the six `{{MODULAR_EXAMPLE_*}}` placeholders + the `{{MODULAR_COMMIT_MESSAGE_FORMAT_BLOCK}}` from this table when rendering the `PER_PHASE_COMMIT` block above:
84
101
 
85
102
  | Placeholder | `commit_style = conventional` | `commit_style = imperative` | `commit_style = other` |
86
103
  |---|---|---|---|
@@ -147,52 +164,3 @@ WIP
147
164
  add stuff
148
165
  Implement full record copy feature ← too broad, should be split
149
166
  ```
150
-
151
- ## `{{PR_OPEN_TIMING_BLOCK}}` (modular)
152
-
153
- <!-- substitution-begin: PR_OPEN_TIMING_BLOCK -->
154
- **PR opens once — after Phase 1 passes review.** Subsequent phases push their atomic unit commits to the same plan branch (`plan/{plan-id-kebab}`); the orchestrator re-runs [open-pr.sh](../foundation-skills/open-pr-from-context/scripts/open-pr.sh) against the same plan-level prs-context file at `.vinta-ai-workflows/prs-context/{feature-kebab}/plan.md`. The script is idempotent for already-open PRs — it updates the body, appends new inline comments, and posts an `Phase {N} complete — pushed M commits` PR comment.
155
-
156
- <!-- substitution-end: PR_OPEN_TIMING_BLOCK -->
157
-
158
- ## `{{COMMIT_STRATEGY_CHECKLIST_BLOCK}}` (modular)
159
-
160
- <!-- substitution-begin: COMMIT_STRATEGY_CHECKLIST_BLOCK -->
161
- - [ ] Commit units listed upfront before any staging.
162
- - [ ] Each commit covers exactly one logical unit (no "and" in commit messages).
163
- - [ ] Tests landed in the same commit as the code they cover (never a separate test-only commit).
164
- - [ ] All unit commits pushed to `plan/{plan-id-kebab}` at end of phase.
165
- <!-- substitution-end: COMMIT_STRATEGY_CHECKLIST_BLOCK -->
166
-
167
- ## Other modular substitutions (single-line — listed for completeness)
168
-
169
- | Placeholder | Modular substitution |
170
- |---|---|
171
- | `{{BRANCH_PUSH_HEADING}}` | `Push to plan branch` |
172
- | `{{BRANCH_NAMING_PATTERN_SUMMARY}}` | ``plan branch (one branch for whole plan: `plan/{plan-id-kebab}`)`` |
173
- | `{{PRS_CONTEXT_FILE_PATH_DESCRIPTION}}` | `` a single `.vinta-ai-workflows/prs-context/{feature-kebab}/plan.md` file (one PR per plan, not per phase) `` |
174
- | `{{TRACKING_BRANCH_FIELD}}` | `top-level \`plan_branch:\` field` |
175
- | `{{TRACKING_PHASE_BRANCH_FIELD}}` | empty string (no per-phase branch under modular) |
176
- | `{{FINAL_REPORT_BRANCH_SUMMARY}}` | ``single plan branch `plan/{plan-id-kebab}` with commit log organized by phase`` |
177
- | `{{BRANCH_CHECKLIST_LINE}}` | `Plan branch updated with phase commits; pushed.` |
178
- | `{{COMMIT_STRATEGY_STEP0_QUESTION}}` | empty string (modular is set as the project default; nothing to ask) |
179
- | `{{COMMIT_STRATEGY_STEP0_TRAILER}}` | empty string |
180
- | `{{COMMIT_STRATEGY_CONFIRM_NOTE}}` | empty string |
181
-
182
- ## Ask-mode substitutions
183
-
184
- When `policies.commit_strategy = ask`, derive-skills renders **both** the stacked-branches and the modular-commits bodies for each multi-line placeholder, gated by inline runtime markers the agent reads at execution time:
185
-
186
- ```markdown
187
- **If `run_options.commit_strategy_resolved = "modular-commits"`:**
188
-
189
- <modular substitution body here>
190
-
191
- **Else (`run_options.commit_strategy_resolved = "stacked-branches"`):**
192
-
193
- <stacked substitution body here>
194
- ```
195
-
196
- Single-line placeholders under ask use the same gating pattern but inline (`If modular: <a> · Else (stacked): <b>`).
197
-
198
- For the Step 0 question itself (`{{COMMIT_STRATEGY_STEP0_QUESTION}}`), the ask substitution is the AskUserQuestion block documented in the parent placeholder table in [SKILL.md](../SKILL.md) — same content used to populate the resolved value.
@@ -0,0 +1,46 @@
1
+ <!-- Partial: commit-strategy / stacked-branches. Blocks consumed by implement-phase (PER_PHASE_COMMIT) + integrate-phase (BRANCH_NAMING, PR_OPEN_TIMING) + conductor (CHECKLIST). All git calls use `git -C <WORKROOT>`; the first executed phase branches off `<BASE_BRANCH>` — both resolved once by the conductor (see worktree-seam.md#WORKROOT_RESOLUTION). -->
2
+
3
+ <!-- block-begin: BRANCH_NAMING -->
4
+ Branch naming: `plan/{plan-id-kebab}/phase-{phase.id}` (one branch + one PR per phase, stacked).
5
+
6
+ **First executed phase** (branches from `<BASE_BRANCH>`, already made current by the conductor):
7
+
8
+ ```bash
9
+ git -C <WORKROOT> checkout <BASE_BRANCH>
10
+ git -C <WORKROOT> checkout -b plan/{plan-id-kebab}/phase-{phase.id}
11
+ # subagent's commits land on this branch
12
+ git -C <WORKROOT> push -u origin plan/{plan-id-kebab}/phase-{phase.id}
13
+ ```
14
+
15
+ **Subsequent phases** (stacked on the previous phase's branch):
16
+
17
+ ```bash
18
+ git -C <WORKROOT> checkout plan/{plan-id-kebab}/phase-{prev.id}
19
+ git -C <WORKROOT> checkout -b plan/{plan-id-kebab}/phase-{phase.id}
20
+ git -C <WORKROOT> push -u origin plan/{plan-id-kebab}/phase-{phase.id}
21
+ ```
22
+ <!-- block-end: BRANCH_NAMING -->
23
+
24
+ <!-- block-begin: PER_PHASE_COMMIT -->
25
+ 7. Stage the right files (NEVER `git add -A` — {{ANTI_GIT_ADD_ALL_REASON}}). Stage explicitly: `git add {{STAGE_PATTERN}}`.
26
+ 8. Commit with the repo's style — look at `git log -10 --oneline` first. {{COMMIT_STYLE_LINE}}.
27
+ 9. {{COAUTHOR_INSTRUCTION_LINE}}
28
+ 10. {{PUSH_INSTRUCTION_LINE}}
29
+ <!-- block-end: PER_PHASE_COMMIT -->
30
+
31
+ <!-- block-begin: PR_OPEN_TIMING -->
32
+ One PR per phase — the [Open PR via context file](#open-pr-via-context-file) step runs after this phase passes review, writing `.vinta-ai-workflows/prs-context/{feature-kebab}/phase-{phase.id}.md`.
33
+ <!-- block-end: PR_OPEN_TIMING -->
34
+
35
+ <!-- block-begin: CHECKLIST -->
36
+ <!-- stacked adds no extra commit-discipline checklist items beyond the branch line -->
37
+ <!-- block-end: CHECKLIST -->
38
+
39
+ <!-- Single-line values (derive-skills substitutes these into the shells directly):
40
+ BRANCH_PUSH_HEADING = Push stacked branch
41
+ BRANCH_NAMING_PATTERN_SUMMARY = branch naming pattern (default: `plan/{plan-id-kebab}/phase-{phase-id}`)
42
+ PRS_CONTEXT_FILE_PATH = `.vinta-ai-workflows/prs-context/{feature-kebab}/phase-{phase.id}.md`
43
+ TRACKING_BRANCH_FIELD = (empty — per-phase branch lives inline under TRACKING_PHASE_BRANCH_FIELD)
44
+ TRACKING_PHASE_BRANCH_FIELD = , branch, base
45
+ FINAL_REPORT_BRANCH_SUMMARY = branches pushed (with bases, in stack order)
46
+ BRANCH_CHECKLIST_LINE = Stacked branch created; pushed. -->
@@ -0,0 +1,78 @@
1
+ <!-- Partial: implementer-prompt — the token-efficient per-phase prompt. FULL = the forward-implementation prompt used by implement-phase. INNER_OUTER_LOOP = the read→edit→inner→outer verification steps (1–6), reused verbatim by amend-plan's 4b (which appends its own amend-specific commit / no-push tail instead of the commit-strategy block). The {If run_options.use_worktree = true:} markers are runtime gates the agent reads at execution time; derive-skills strips them entirely when foundation_skills.prepare-worktree is disabled (use_worktree can only ever be false). -->
2
+
3
+ <!-- block-begin: FULL -->
4
+ ```
5
+ You are implementing {phase.id}: {phase.title} of plan {plan.id}.
6
+
7
+ ## Repo
8
+ {{PROJECT_NAME}} ({{STACK_SUMMARY}}).
9
+
10
+ ## Working location
11
+ Work entirely inside `<WORKROOT>`. `cd` into it before any command. Every `git`,
12
+ every lint / test / build / migrate call runs there.
13
+ {If run_options.use_worktree = true:}
14
+ `<WORKROOT>` is an isolated git worktree — do NOT touch the main checkout; its DB,
15
+ env, and compose stack are intentionally separated. See `<WORKROOT>/WORKTREE.md` for
16
+ what's forked vs shared (deps, dev DB, test DB, compose project name, env file).
17
+ {If run_options.sandbox_tier = enforced:} Writes to the main checkout are OS-blocked —
18
+ if you see `Operation not permitted` / `EROFS` on a write, you used a main-checkout
19
+ path by mistake; redo it against this worktree path.
20
+ Branch base for this phase: `<phase-specific base>` — the orchestrator already created
21
+ your phase branch there; commit straight to it.
22
+
23
+ ## Read first
24
+ 1. AGENTS.md — repo conventions.
25
+ 2. {{PLAN_DIR}}/{plan-filename}, the **Goals + Non-goals**, **Guiding Decisions**, **Data Model Changes** sections and YOUR phase body inside **Phased Rollout**.
26
+ {If run_options.use_worktree = true:} 3. `WORKTREE.md` at the worktree root — fork map (which dirs symlink to main vs are independent copies).
27
+
28
+ ## Plan-level decisions (from Goals + Non-goals + Guiding Decisions)
29
+ {Goals + Non-goals verbatim}
30
+ {Guiding Decisions table verbatim}
31
+ {If feature flag declared:}
32
+ Feature flag: `{flag-key}` — scope `{per-tenant|per-request}`, default `{false|true}`.
33
+ Wire reads + writes per the plan's **Guiding Decisions** entry. Off-flag path = byte-for-byte pre-feature behavior.
34
+
35
+ ## What was already implemented in prior phases
36
+ {Tracking file "Completed Phases" section. First executed phase: "Nothing yet — this is the first phase."}
37
+
38
+ ## Your tasks (Phase {id} only)
39
+ {phase.body verbatim, including Goal / Spec use-case / Feature flag / Changes / Tests / Acceptance lines}
40
+
41
+ ## Reusable skills you SHOULD invoke
42
+ {phase.reusable_skills — for each, instruct the agent to first read ai-tools/skills/{name}/SKILL.md, then follow that pattern.}
43
+
44
+ Project skills available: {{PROJECT_SKILLS_LIST}}
45
+
46
+ {{DEPENDENCY_LICENSE_BLOCK}}
47
+
48
+ <!-- include: partials/implementer-prompt.md#INNER_OUTER_LOOP -->
49
+ {{PER_PHASE_COMMIT_BLOCK}}
50
+
51
+ ## Required output (single final report)
52
+ - Status: SUCCESS or FAILURE (and why).
53
+ - Files created/modified (paths only).
54
+ - 5–15 line summary of what you implemented and key decisions.
55
+ {{E2E_REPORT_FIELD}}
56
+ - Deviations from the plan body and reasoning.
57
+ - Anything you couldn't do (with explanation).
58
+ ```
59
+
60
+ **Don't** dump the full plan into every prompt. Tracking summaries replace prior phases as context. Always include the **Goals + Non-goals** and **Guiding Decisions** sections plus the relevant **Data Model Changes** subsection — load-bearing decisions; phases reach back frequently.
61
+ <!-- block-end: FULL -->
62
+
63
+ <!-- block-begin: INNER_OUTER_LOOP -->
64
+ ## Working instructions
65
+ 1. Read existing code paths your changes touch — do not write before reading.
66
+ 2. Implement using Read/Edit/Write. Match existing patterns.
67
+ 3. **Inner loop — fast iteration.** Scoped to files/apps you touched:
68
+ a. `{{LINT_CMD}}` until clean.
69
+ b. {{NEW_TEST_CMD_PATTERN}} for new tests individually.
70
+ c. Scoped suite: {{SCOPED_TEST_PATTERN}}.
71
+ 4. Iterate 2–3 until **new tests pass individually** and the scoped suite is green. Do **not** advance to step 5 with red scoped tests.
72
+ 5. **Outer gate — local verification, only after step 4 is green.** All MUST pass before staging:
73
+ a. **Type / build:** `{{BUILD_CMD}}` — repo-wide, always.
74
+ b. **Tests:** by default run only the **scoped suite** `{{SCOPED_TEST_PATTERN}}` for the apps/files you touched — the new tests already passed individually in step 4b, so this re-confirms the touched surface without paying for the whole repo.
75
+ {If run_options.full_test_suite = true:} run the **full test suite** `{{TEST_CMD}}` instead of the scoped suite — this phase guards against regressions in untouched code too.
76
+ {{E2E_OUTER_GATE_LINE}}
77
+ 6. Outer gate fails → return step 2 (fix regression), re-run inner loop, then 5a/5b/5c. **Never** commit, push, or proceed while any gate is red.
78
+ <!-- block-end: INNER_OUTER_LOOP -->
@@ -0,0 +1,19 @@
1
+ <!-- Partial: model-pick — the plan-owns-model-selection rules. Included by implement-phase; referenced (linked, not included) by amend-plan's Tier-4 rule. -->
2
+ <!-- block-begin: MODEL_PICK -->
3
+ ## Pick the model from the plan's per-phase suggestion
4
+
5
+ **The plan owns model selection — this skill does not re-derive tiers and doesn't assume a vendor.** Each phase carries a `**Suggested AI model**:` line listing one model per vendor.
6
+
7
+ Pick:
8
+
9
+ 1. Read the line, parse out **all** vendor suggestions.
10
+ 2. **Filter to what's actually available in the runtime.** Different harnesses expose different sets.
11
+ 3. From the surviving suggestions, **pick the cheapest / fastest** the runner can use.
12
+ 4. Translate the chosen model to whatever form the runner's spawning tool expects.
13
+ 5. Phase suggestion straddles tiers → pick the higher-tier suggestion.
14
+ 6. Line missing / malformed → **ask the user**. Don't silently re-derive tier.
15
+
16
+ **Retry escalation (no user prompt):** the picked model fails on a clear capability gap → step **one tier up** and retry once. After Tier 4 fails, STOP. Update tracking with `❌`, post the agent's report to the user, ask how to proceed.
17
+
18
+ Record the **model actually used** + the **plan's suggested tier** in tracking.
19
+ <!-- block-end: MODEL_PICK -->
@@ -0,0 +1,61 @@
1
+ <!-- Partial: pr-context — the "Open PR via context file" body (former 1f), decoupled from commit-strategy. Included by integrate-phase. The commit-strategy-specific PR-open timing + prs-context file path come from commit-strategy/<resolved>.md (PR_OPEN_TIMING block + PRS_CONTEXT_FILE_PATH value). generate_inline_comments is a runtime flag whose only effect is localized here (whether the `# Comments` block is populated). -->
2
+
3
+ <!-- block-begin: PR_CONTEXT -->
4
+ This is the **only** PR-creation path. PRs always go through {{PRS_CONTEXT_FILE_PATH}} + the bundled [open-pr.sh](../open-pr-from-context/scripts/open-pr.sh) script — even when inline comments are not requested. The file is the durable record; the script is the publisher. Subagents never open PRs themselves; the orchestrator does, after review passes.
5
+
6
+ {{PR_OPEN_TIMING_BLOCK}}
7
+
8
+ Two project-level signals decide the actual behavior:
9
+
10
+ | `{{PR_POLICY_BLOCK}}` policy | `run_options.generate_inline_comments` | What this step does |
11
+ |---|---|---|
12
+ | agents create PRs | false | Write minimal context file (`# Title`, `# Description`, empty `# Comments`). Run `open-pr.sh` → PR opened, no inline comments. |
13
+ | agents create PRs | true | Write full context file (title + description + 3–10 inline comments). Run `open-pr.sh` → PR opened, all comments posted. |
14
+ | branches only | false | **Skip this step entirely.** Human will open the PR manually from the pushed branch. |
15
+ | branches only | true | Write full context file (durable record). **Don't run `open-pr.sh`.** Human can publish later from a CLI-equipped session via [open-pr-from-context](../open-pr-from-context/SKILL.md). Surface this in the user update. |
16
+
17
+ ### Steps
18
+
19
+ 1. **Skip if neither column applies** (policy = branches only AND `generate_inline_comments = false`). Return to the conductor's tracking step.
20
+
21
+ 2. **Honor existing PR / MR templates.** Read `project.pr_template_paths` from `.vinta-ai-workflows.yaml`. For each entry:
22
+ - **One template** → load it; the prs-context `# Description` body must follow that template's section structure verbatim. Fill each section with phase-specific content drawn from the plan's **Goals + Non-goals**, **Guiding Decisions**, and the phase body. Preserve any `<!-- HTML comments -->` placeholders; do not strip the template's checklists. Sections you can't fill from phase data → leave the template's placeholder/prompt untouched (don't fabricate).
23
+ - **Multiple templates** (`PULL_REQUEST_TEMPLATE/` directory) → ask once via `AskUserQuestion`: list each template + its filename, ask which to use for this run. Cache the choice in tracking under `run_options.pr_template_used` so subsequent phases of the same plan use the same one without re-asking.
24
+ - **Empty array** → free-form description. Default sections: `## Summary` (1–3 sentences), `## Plan reference` (link / phase id), `## Test plan` (commands the reviewer can run).
25
+
26
+ When the project's PR template includes a checkbox checklist (e.g. `- [ ] Tests added`, `- [ ] Docs updated`), tick the boxes the phase's diff actually satisfies and leave unsatisfied ones unticked — never auto-tick everything.
27
+
28
+ GitHub also honors `?template=<name>` in the PR-create URL when the project has a multi-template directory. `gh pr create --body-file` writes the body directly so the URL trick isn't needed; the body must match the chosen template's structure regardless.
29
+
30
+ 3. **Pick comment targets** (only when `generate_inline_comments = true`). Read the phase diff via `git -C <WORKROOT> diff <BASE_BRANCH>...HEAD` (or the previous phase branch for stacked phases). Select 3–10 spots that benefit from a one-paragraph context note — typically:
31
+ - A subtle invariant the diff relies on (cite the plan's **Goals + Non-goals** / **Guiding Decisions** entries — by name, never use `§` shorthand).
32
+ - A workaround for a known framework / library limitation.
33
+ - A naming choice driven by an upstream contract.
34
+ - The off-flag short-circuit when a feature flag is in **Guiding Decisions**.
35
+ - Why a seemingly-cleaner refactor wasn't made (out of scope per **Goals + Non-goals**).
36
+ - Cross-phase coupling (this hook is consumed by phase N+k).
37
+
38
+ Skip lint/format churn, boilerplate matching nearby files, standard patterns from AGENTS.md, and self-explanatory test names. **A clean phase produces few comments — that's fine. Don't pad.**
39
+
40
+ When `generate_inline_comments = false`: skip this step. The file's `# Comments` block stays empty.
41
+
42
+ 4. **Write the prs-context file** at {{PRS_CONTEXT_FILE_PATH}}, following [resources/prs-context-template.md](../../prs-context-template.md). Frontmatter: `plan_id`, `feature_name`, `phase_id`, `phase_title`, `branch`, `base`, `created_at`, `status: pending`, empty `pr_url`. Body sections: `# Title` (single-line PR title), `# Description` (Markdown body — uses the project's PR template structure from step 2 when one exists), `# Comments` (YAML list of `{file, start_line, end_line?, side, body}` — empty list when comments are off).
43
+
44
+ 5. **Confirm `.vinta-ai-workflows/prs-context/` is in `.gitignore`.** [vinta-install-ai-tools-setup](../../../vinta-install-ai-tools-setup/SKILL.md) runs the multi-vendor setup script which appends `.vinta-ai-workflows/prs-context/` on its first invocation. If an older bootstrap missed it, append it now.
45
+
46
+ 6. **Run `open-pr.sh`** (only when policy = agents create PRs). Detect a usable CLI (`gh` for GitHub, `glab` for GitLab) plus the script's other deps (`yq`, `jq`):
47
+
48
+ ```bash
49
+ bash ai-tools/skills/open-pr-from-context/scripts/open-pr.sh {{PRS_CONTEXT_FILE_PATH}}
50
+ ```
51
+
52
+ The script opens the PR (or detects an existing one), posts each inline comment, rewrites the file's frontmatter to `status: published` + populated `pr_url`, appends a publish log. Exit codes:
53
+
54
+ - `0` — PR up, all comments (if any) posted. Capture `pr_url` for the user update.
55
+ - `1` — PR up, ≥1 comment failed. Surface the failed `(file:line)` list to the user; continue to the tracking step.
56
+ - `2` — Hard failure (deps missing, branch not pushed, CLI unauthed, file invalid). Surface the script's stderr; treat the phase as having no PR. The file stays `status: pending` so the user can re-run after fixing the gap.
57
+
58
+ When policy = "branches only": **don't run the script.** File stays `status: pending`.
59
+
60
+ 7. **Skill wrapper** — [open-pr-from-context](../open-pr-from-context/SKILL.md) is available for ad-hoc invocation (after the run, on a different machine, etc.). The orchestrator can call the script directly here; the skill is for humans.
61
+ <!-- block-end: PR_CONTEXT -->
@@ -0,0 +1,50 @@
1
+ <!-- Partial: review-layers — the three-layer review + fix loop. Included by review-phase. amend-plan and systematic-debugging reuse it by INVOKING review-phase (not by including this partial). The orchestrator running review-phase never edits code itself — every issue surfaces as a fix-up subagent task. -->
2
+
3
+ <!-- block-begin: LAYERS -->
4
+ Three layers, all required, in order. The reviewing orchestrator never edits — every issue surfaces as a fix-up subagent task.
5
+
6
+ ## Layer 1 — Mechanical checks
7
+
8
+ 1. `git -C <WORKROOT> status` + `git -C <WORKROOT> diff --stat`: confirm the file list matches the agent's report.
9
+ 2. **Read the full diff** for every changed file using `git -C <WORKROOT> diff`. Spot-checking is not enough.
10
+ 3. **Verify the outer gate** ran + green. By default that is `{{BUILD_CMD}}` (repo-wide) AND the scoped suite `{{SCOPED_TEST_PATTERN}}` covering the touched apps. {If run_options.full_test_suite = true:} the outer gate runs `{{BUILD_CMD}}` AND the full `{{TEST_CMD}}` instead — verify that. Look in the report for explicit confirmation the applicable gate was executed + passed{{E2E_LAYER1_NOTE}}. Vague confirmation → **re-run yourself** (in `<WORKROOT>`).
11
+ 4. **Scope creep**: file touched outside the expected surface area? Unrelated formatting churn? Surface it.
12
+ 5. **No-secrets scan**: `git -C <WORKROOT> diff` for `password|secret|token|api_key|AKIA|BEGIN [A-Z]+ KEY`.
13
+ 6. <!-- include: partials/worktree-seam.md#STRAY_WRITE_CHECK -->
14
+ {{DEPENDENCY_LICENSE_LAYER1_CHECK}}
15
+ {{COAUTHOR_LAYER1_CHECK}}
16
+
17
+ ## Layer 2 — Plan compliance walkthrough
18
+
19
+ Open the phase body alongside the diff and walk:
20
+
21
+ 1. **Every numbered "Changes" item implemented.**
22
+ 2. **Every "Tests" entry materialized**, with assertions actually exercising the called-out behavior.
23
+ 3. **Acceptance line satisfiable** by the diff.
24
+ 4. **Repo conventions** from AGENTS.md.
25
+ 5. **Reusable-skill compliance.**
26
+ {{E2E_LAYER2_CHECK}}
27
+ 6. **Feature-flag wiring** if the plan's **Guiding Decisions** declared a flag — flag-OFF is byte-for-byte pre-feature behavior, ≥1 test asserts it.
28
+ 7. **Cross-phase consistency** with prior tracking summaries.
29
+ 8. **Comment hygiene** — new or changed comments and doc blocks in the diff read as Simple English, one idea per sentence, no AI-slop vocabulary or negative framing, per the `deslop-comments` skill ([ai-tools/skills/deslop-comments/SKILL.md](ai-tools/skills/deslop-comments/SKILL.md)). Flag any that need rewriting; the fix loop dispatches a fixer to run `deslop-comments` on the phase's touched files.
30
+
31
+ ## Layer 3 — Independent reviewer subagent
32
+
33
+ After Layers 1–2 pass, spawn a **separate** subagent (different session, no implementation context) using the project's `reviewer` agent type ([ai-tools/agents/reviewer.md](ai-tools/agents/reviewer.md)). Read-only by design.
34
+
35
+ Reviewer prompt template — see the reviewer agent's body for the standard form. Triage findings:
36
+ - **BLOCKER**: must fix before the phase is pushed (the conductor's integrate step).
37
+ - **SHOULD-FIX**: fix in-phase if cheap; else follow-up issue + tracking note.
38
+ - **NIT**: ignore unless trivially cheap.
39
+
40
+ The reviewer also applies a condensed **structural-simplification lens** — one question: is there an obvious "code-judo" reframe that would make whole branches, helpers, modes, or layers disappear, rather than polishing what's there? Routine phases stop at that one question. When the phase touched core architecture, pushed a file past ~1,000 lines, or the lens surfaces a structural smell too big to resolve inline, escalate to the full [thermo-nuclear-code-quality-review](ai-tools/skills/thermo-nuclear-code-quality-review/SKILL.md) skill against the phase diff — an opt-in deep audit, run deliberately, never on every phase.
41
+
42
+ The reviewer finds nothing on a >300-LoC multi-file phase → suspicious. Read once more.
43
+
44
+ ## Fix loop
45
+
46
+ 1. Spawn a **new** subagent — the project's `fixer` agent type ([ai-tools/agents/fixer.md](ai-tools/agents/fixer.md)). The fix prompt quotes the finding verbatim. For comment-hygiene findings (Layer 2 item 8), the fix prompt tells the fixer to run the `deslop-comments` skill ([ai-tools/skills/deslop-comments/SKILL.md](ai-tools/skills/deslop-comments/SKILL.md)) scoped to the phase's touched files — comment-only edits, no behavior change.
47
+ 2. The `fixer`'s system prompt mandates re-running the inner loop + outer gate (in `<WORKROOT>`).
48
+ 3. After the fixer returns, redo Layer 1 in full + the affected portion of Layer 2.
49
+ 4. Loop until Layers 1, 2, 3 are all clean.
50
+ <!-- block-end: LAYERS -->