vinta-ai-workflows 0.7.0-alpha25 → 0.7.0-alpha27

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 (44) hide show
  1. package/CHANGELOG.md +391 -0
  2. package/README.md +15 -17
  3. package/package.json +1 -1
  4. package/schemas/README.md +5 -2
  5. package/schemas/ai-models.v1.schema.json +5 -0
  6. package/schemas/interview-answers.v1.schema.json +51 -0
  7. package/schemas/interview-round.v1.schema.json +165 -0
  8. package/schemas/plan-review.v1.schema.json +342 -0
  9. package/schemas/vinta-ai-workflows-config.v1.schema.json +357 -15
  10. package/schemas/workflow.v1.schema.json +76 -38
  11. package/skills/vinta-analyze-codebase/SKILL.md +4 -0
  12. package/skills/vinta-bootstrap-ai-tools/SKILL.md +94 -21
  13. package/skills/vinta-bootstrap-ai-tools/resources/worktree-command/README.md +85 -0
  14. package/skills/vinta-bootstrap-ai-tools/resources/worktree-command/lib-template.sh +160 -0
  15. package/skills/vinta-bootstrap-ai-tools/resources/worktree-command/prepare-template.sh +250 -0
  16. package/skills/vinta-bootstrap-ai-tools/resources/worktree-command/teardown-template.sh +96 -0
  17. package/skills/vinta-derive-skills/SKILL.md +13 -12
  18. package/skills/vinta-derive-skills/resources/dependency-license-block.md +1 -1
  19. package/skills/vinta-derive-skills/resources/foundation-skills/create-spec/SKILL.md +16 -0
  20. package/skills/vinta-derive-skills/resources/foundation-skills/interview-ui/SKILL.md +117 -0
  21. package/skills/vinta-derive-skills/resources/foundation-skills/interview-ui/resources/examples/docs/D4-concurrency.md +28 -0
  22. package/skills/vinta-derive-skills/resources/foundation-skills/interview-ui/resources/examples/round-01.json +60 -0
  23. package/skills/vinta-derive-skills/resources/foundation-skills/interview-ui/resources/index.html +523 -0
  24. package/skills/vinta-derive-skills/resources/foundation-skills/interview-ui/scripts/interview-ui.mjs +416 -0
  25. package/skills/vinta-derive-skills/resources/foundation-skills/plan-feature/SKILL.md +216 -85
  26. package/skills/vinta-derive-skills/resources/foundation-skills/plan-feature/resources/ai-models.yaml +7 -0
  27. package/skills/vinta-derive-skills/resources/foundation-skills/prepare-worktree/SKILL.md +1 -0
  28. package/skills/vinta-derive-skills/resources/foundation-skills/thermo-nuclear-code-quality-review/SKILL.md +8 -6
  29. package/skills/vinta-derive-skills/resources/foundation-skills/thermo-nuclear-review-loop/SKILL.md +181 -0
  30. package/skills/vinta-derive-skills/resources/plan-execution/README.md +5 -3
  31. package/skills/vinta-derive-skills/resources/plan-execution/partials/agent-models.md +14 -35
  32. package/skills/vinta-derive-skills/resources/plan-execution/partials/implementer-prompt.md +1 -1
  33. package/skills/vinta-derive-skills/resources/plan-execution/partials/model-pick.md +2 -0
  34. package/skills/vinta-derive-skills/resources/plan-execution/partials/parallel-lanes.md +14 -20
  35. package/skills/vinta-derive-skills/resources/plan-execution/partials/relay-questions.md +1 -1
  36. package/skills/vinta-derive-skills/resources/plan-execution/partials/review-loop.md +72 -0
  37. package/skills/vinta-derive-skills/resources/plan-execution/partials/worktree-seam.md +86 -17
  38. package/skills/vinta-derive-skills/resources/plan-execution/shell/amend-plan-template.md +7 -7
  39. package/skills/vinta-derive-skills/resources/plan-execution/shell/implement-phase-template.md +6 -0
  40. package/skills/vinta-derive-skills/resources/plan-execution/shell/implement-plan-template.md +17 -17
  41. package/skills/vinta-derive-skills/resources/plan-execution/shell/review-phase-template.md +14 -27
  42. package/skills/vinta-derive-skills/resources/systematic-debugging-template.md +3 -3
  43. package/skills/vinta-derive-subagents/SKILL.md +7 -5
  44. package/skills/vinta-derive-skills/resources/plan-execution/partials/review-layers.md +0 -112
package/CHANGELOG.md CHANGED
@@ -30,6 +30,207 @@ the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
30
30
 
31
31
  ### Added
32
32
 
33
+ - **New optional foundation skill: `interview-ui`** — run decision-heavy
34
+ interviews as a full-screen browser form instead of a chat exchange. One
35
+ decision per screen with the context the agent already knows, Markdown +
36
+ Mermaid (or HTML) explainers, option cards that state each option's
37
+ consequences, the recommended default marked, and an in-page question panel
38
+ for asking the agent (questions, not decisions — the agent replies in the
39
+ next round). Round-based and file-based, so it works the same under Claude
40
+ Code, Codex, Cursor, and Copilot: the agent writes
41
+ `.vinta-ai-workflows/interviews/<slug>/rounds/round-NN.json`, blocks on
42
+ `interview-ui.mjs wait`, and resumes when the browser submits
43
+ `answers/round-NN.json`. Source:
44
+ [skills/vinta-derive-skills/resources/foundation-skills/interview-ui/](skills/vinta-derive-skills/resources/foundation-skills/interview-ui/)
45
+ — `SKILL.md`, the zero-dependency Node ≥ 18 localhost server + CLI
46
+ [scripts/interview-ui.mjs](skills/vinta-derive-skills/resources/foundation-skills/interview-ui/scripts/interview-ui.mjs)
47
+ (`start` / `wait` / `stop` / `status` / `serve`; binds `127.0.0.1` only,
48
+ serves files only from the interview's `docs/`), the shell
49
+ [resources/index.html](skills/vinta-derive-skills/resources/foundation-skills/interview-ui/resources/index.html),
50
+ and a sample round under `resources/examples/`. Copied verbatim as a whole
51
+ directory (bucket A), opt-in via the bootstrap's **Optional foundation
52
+ skills** question 7.
53
+ - **Two new JSON Schemas**:
54
+ [`schemas/interview-round.v1.schema.json`](schemas/interview-round.v1.schema.json)
55
+ (agent → browser: groups, decisions, options with `consequences` /
56
+ `recommended` / `tags`, inline or file explainers, `replies[]`, `readback`
57
+ rounds) and
58
+ [`schemas/interview-answers.v1.schema.json`](schemas/interview-answers.v1.schema.json)
59
+ (browser → agent: per-decision `answered` / `waived` / `skipped` with
60
+ values, free text and notes, plus `questions[]` for the agent). Inventory
61
+ rows added to `schemas/README.md`.
62
+ - **Config schema field `foundation_skills.interview-ui`** (`enabled` /
63
+ `disabled`). Additive — no schema major bump. Emitted by the bootstrap
64
+ Step 0.5 YAML; existing projects can add it by hand or on the next sync.
65
+ - **Plan review: a page for a plan before it runs, and a chat with the agent
66
+ that wrote it.** Maestro's UI gains a **Plans** section. `vinta-ai-maestro
67
+ review open <workflow.json>` serves it and prints a link straight to the
68
+ plan. The page shows:
69
+ - **Graph.** The phase DAG, coloured by review state. Below it, the selected
70
+ phase's brief, its staffing and pipeline, the implementer and fixer
71
+ prompts, and its chores' prompts (the review loop's among them). These are
72
+ the real cold prompts a run would send, composed by the scheduler's own
73
+ function.
74
+ - **Plan.** The markdown, section by section, with an outline.
75
+ - **Gates.** A phase × gate matrix of the commands a run would execute.
76
+ - **Schedule.** A projected timeline with the critical path marked.
77
+ - **Issues.** What `validate` reports.
78
+
79
+ The reviewer can comment on the plan, a section, a phase, a prompt or a
80
+ gate, or select text and comment on the quote. Comments stay drafts until
81
+ sent to the agent as one batch. The sidebar chat shows whether the agent is
82
+ listening, working or away. The agent answers from its own session through
83
+ two new commands:
84
+ - `review wait` blocks, then prints what the person sent as JSON.
85
+ - `review reply` answers in the chat or on a thread, with `--resolve`.
86
+
87
+ Edits the agent makes to the plan show on the page within seconds.
88
+ **Approve plan** ends the loop. The review is committed beside the plan as
89
+ `ai-plans/<id>.review.json`. A new generated schema,
90
+ `schemas/plan-review.v1.schema.json`, validates it. Maestro's SPEC gains
91
+ §19 to describe it.
92
+ - **`vinta-ai-maestro validate <workflow.json> [--json]`.** It checks a
93
+ workflow the way a run loads it, layered over `.vinta-ai-workflows.yaml`.
94
+ It also checks two things only a run used to find: the filename matches
95
+ the id, and every `plan_ref`, `prompt_ref` and `plan_context_refs` anchor
96
+ names a heading the plan has. Exit `0` means valid and `1` means not.
97
+ `--json` gives an agent one object with each issue's source, path and
98
+ message.
99
+ - **`plan-feature` validates its workflow and runs the review.** When
100
+ `vinta-ai-maestro` is installed (on `PATH`, in `node_modules/.bin`, or
101
+ already cached for `npx --no-install`), the skill runs `validate --json` on
102
+ every workflow it writes. It fixes each issue and runs the check again, and
103
+ runs it again after every edit made during review. It never installs maestro
104
+ itself.
105
+
106
+ Once the files are written, the skill asks how to review: on the review
107
+ page, in chat, or later. On the page it serves the review, posts an
108
+ opening message, and loops on `review wait`. It edits the plan and then the
109
+ workflow for each comment, and answers every thread. The loop ends when the
110
+ plan is approved.
111
+
112
+ - **Model fallbacks for models that run out of quota.** A frontier model sold
113
+ as a small credit allowance used to stall a whole run when its credits ran
114
+ out: the `quota` refusal parked the harness, and every model on it waited
115
+ for a reset that might never come. Now a model can name a fallback, and the
116
+ run switches to it instead of waiting.
117
+ - **`ai-models.yaml` entries take `fallback:`.** The shipped table sets
118
+ `claude-fable-5-1 → claude-opus-5-5` and `gpt-6-astra → gpt-5.6-sol`
119
+ (tier 4). `ai-models.v1.schema.json` gains the optional field, and the
120
+ nightly `check-ai-models` job checks fallback ids for staleness too.
121
+ - **Maestro: `defaults.model_fallbacks`** (model id → fallback id), in a
122
+ plan's workflow or in `.vinta-ai-workflows.yaml` under
123
+ `maestro.defaults`. A `quota` refusal on a listed model retries the
124
+ spawn on its fallback right away and leaves the harness unparked. Later
125
+ spawns of that model on the same harness go straight to the fallback,
126
+ until the reset time the vendor gave, or for the rest of the run if it
127
+ gave none. This also covers a turn cut off mid-way and the monitor and
128
+ conflict-fixer spawns. Chains are followed. If the fallback is refused
129
+ for quota too, the whole account is out: the harness parks as it did
130
+ before. Each substituted spawn is journaled as `node_model_fallback`.
131
+ - **`plan-feature` writes the map** into each plan's workflow from the
132
+ crew's `fallback:` entries. The plan-execution skills (`implement-phase`,
133
+ `review-phase`) follow the same rule when maestro isn't running them.
134
+ - **`thermo-nuclear-review-loop` foundation skill.** A review-and-fix loop
135
+ over a change: the agent running it spawns one reviewer sub-agent, checks
136
+ each finding against the code, fixes the justified ones and answers the
137
+ rest, until the reviewer explicitly approves under a strict code-quality
138
+ standard. Questions only the human can settle (unreachable scenarios,
139
+ requirement ambiguity, destructive operations) go to them instead of being
140
+ assumed. Always shipped and copied verbatim (new
141
+ `foundation_skills.thermo-nuclear-review-loop`), because `review-phase`
142
+ runs it and every maestro workflow `plan-feature` writes names it in its
143
+ `review` chore. Also
144
+ invokable on its own. **Consumers**: re-sync to pick it up.
145
+ - **Project defaults for maestro in `.vinta-ai-workflows.yaml`.** A new
146
+ `maestro:` section holds what every plan's `.workflow.json` used to repeat:
147
+ per-type gate defaults, resource pools, chores, run defaults and the
148
+ `project` block. Maestro layers each plan over it. The project's
149
+ `commands.*` come first, then `maestro.*`, then the plan, then the run's own
150
+ amendments. A plan now states only what is different, and editing the
151
+ project file reaches every plan that did not override it.
152
+ - **Gate types.** A gate with `"type": "test" | "lint" | "typecheck" |
153
+ "e2e"` takes its command from `maestro.gates.<type>`, else from
154
+ `commands.test_unit` / `lint` / `build` / `e2e`. A `maestro.gates.<type>.cmd`
155
+ gives maestro its own line, and `implement-plan` keeps running
156
+ `commands.*`. Every type the project has a command for is available under
157
+ the type's name, so a node can list `["typecheck", "test"]` with no gate
158
+ table.
159
+ - **`defaults.gates`**, the gates every phase runs unless it names its own.
160
+ `defaults.harness` and `defaults.pipeline` now default to `claude-code`
161
+ and `standard-phase`, and `base_branch` defaults to
162
+ `project.default_branch`.
163
+ - **The bootstrap asks for these** (interview item C.11) and writes the
164
+ section. `plan-feature` reads it and emits only plan-specific values.
165
+ - **Scoped and full gates.** A gate can carry a `scoped_cmd` with
166
+ `{changed_files}` / `{touches}`. Phase gates run it, and the full `cmd` runs
167
+ once on each wave's merged tree. A failure there is a regression between
168
+ phases, and it fails the merge (`defaults.gate_scope: scoped`, the default;
169
+ `full` runs `cmd` everywhere). `commands.test_unit_scoped` and the new
170
+ `commands.lint_scoped` are inherited as scoped commands when they contain a
171
+ placeholder. `implement-plan`'s scoped suite fills the same placeholders.
172
+ - **Every maestro run works on a plan branch, `plan/<workflow-id>/base`.**
173
+ It is cut from `base_branch` at start, and phases and waves build on it.
174
+ Pull requests still target `base_branch`. Commit a change to
175
+ `.vinta-ai-workflows.yaml` or the plan's `.workflow.json` on that branch,
176
+ and the running plan picks it up as a `config` amendment that names the
177
+ commit. A config change never undoes a change an operator or the monitor
178
+ made in the run, never rewrites a phase that has started, and ships with
179
+ the plan's PR. `run` warns when the checkout's config file differs from
180
+ what is committed on the plan branch.
181
+ - **The gate guard.** On claude-code, every maestro agent gets a
182
+ `PreToolUse` hook, in every permission mode, through the per-lane settings
183
+ file only. It refuses two things: a gate's full command typed by hand
184
+ (answer: `vinta-ai-maestro gate <id>`), and a command matching a pool's new
185
+ `match` patterns when run without the lease (answer:
186
+ `vinta-ai-maestro with <pool> --`). Refusals are journalled as
187
+ `bare_gate_blocked`. The hook fails open and never auto-approves anything.
188
+ On codex and opencode a matching command is recorded after the fact as
189
+ `bare_gate_detected`. `doctor` reports which you get as
190
+ `gate-guard:<harness>`.
191
+
192
+ - **Provision worktrees with your own script instead of the `prepare-worktree`
193
+ skill.** Set `commands.worktree_prepare` in `.vinta-ai-workflows.yaml` (and
194
+ optionally `commands.worktree_teardown`), and `implement-plan` runs that
195
+ command for the shared worktree, every lane and the integration worktree.
196
+ No LLM step and no `agent_models.worktree_prep` delegate are involved.
197
+ Worktrees, and therefore parallel phases, are now available when the skill
198
+ is enabled **or** the command is set. When both are set the command wins,
199
+ and the skill is offered as a fallback if the command fails.
200
+ - **The contract.** The command runs from the repo root with
201
+ `VINTA_WORKTREE_NAME`, `_PATH`, `_BRANCH`, `_BASE_REF`, `_KIND`
202
+ (`single` | `lane` | `integration`), `VINTA_MAIN_CHECKOUT`,
203
+ `VINTA_PLAN_PATH` and `VINTA_WORKTREE_SUMMARY` set. It must create a
204
+ runnable worktree at that path, on that new branch, and exit non-zero on
205
+ failure. The conductor then checks the result with git rather than
206
+ trusting the exit code: the right branch, the worktree registered, and
207
+ the main checkout's status unchanged. Writing the summary YAML is
208
+ optional. A summary carrying `reset_cmd`s lets a lane be reused across a
209
+ migration boundary. Without one the lane is re-provisioned (teardown,
210
+ then prepare again) instead. Lanes are provisioned one at a time, because
211
+ the command runs `git worktree add` itself.
212
+ - **Sandbox tier.** The conductor probes the tier itself. With the skill
213
+ disabled, its `sandbox-run.sh` is not installed, so the tier is `none` and
214
+ the review-phase stray-write check is the guard.
215
+ - **Bootstrap.** The `prepare-worktree` question gains a
216
+ `Yes — we provision with our own script/command` option.
217
+ `vinta-analyze-codebase` now records existing worktree scripts in
218
+ `commands.worktree_candidates`, and the interview offers them as the
219
+ command. Existing configs need no change.
220
+ - **The bootstrap can write the script for you.** A fourth answer,
221
+ `Yes — generate a provisioning script for this project`, adds an optional
222
+ step after `vinta-derive-skills`. It writes `prepare.sh`, `teardown.sh`
223
+ and a shared `lib.sh` (default `scripts/worktree/`) from bundled
224
+ templates, and points `commands.worktree_prepare` / `_teardown` at them.
225
+ The templates carry the contract: `--dry-run`, sanity checks, rollback of
226
+ a half-made worktree, generic compose isolation, the full summary YAML,
227
+ and a teardown that refuses a dirty worktree, drops only `*_wt_<name>`
228
+ databases and never runs `down -v`. They also refuse to fork or drop a
229
+ database on a non-local host. The bootstrap fills only the project's
230
+ dependency, env, database and service steps from the inventory, then
231
+ verifies with `bash -n`, a dry run, and an optional real smoke test. The
232
+ scripts are the project's to commit and edit; humans can run
233
+ `prepare.sh <name>` / `teardown.sh <name>` directly too.
33
234
  - **Agents stop for input with clickable questions instead of prose.** When a
34
235
  skill or a sub-agent needs a decision from you, it now asks through your
35
236
  harness's structured question tool, so you get the options as buttons plus
@@ -294,6 +495,61 @@ the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
294
495
 
295
496
  ### Changed
296
497
 
498
+ - **`create-spec` offers a browser surface for its Step 0 interview.** When
499
+ `ai-tools/skills/interview-ui/` exists, the skill asks once whether to make
500
+ decisions in the browser or in chat. In browser mode the question bank,
501
+ clarity loop, read-back, and exit conditions are unchanged; each question
502
+ becomes a decision with `why`, quoted-back `context`, options with
503
+ consequences, and explainer docs, written one round at a time (A–C first,
504
+ later groups once the journeys are known). Projects without `interview-ui`
505
+ see no change.
506
+ - **Bootstrap `Optional foundation skills` group grows to eight questions**
507
+ (`interview-ui` is question 7; `handoff-to-client` moves to 8).
508
+ - **`review-phase` runs the thermo-nuclear review loop.** On the skills path
509
+ (`implement-plan`, `amend-plan`, `systematic-debugging`), each phase is now
510
+ reviewed by `thermo-nuclear-review-loop`, the loop maestro's `review` chore
511
+ runs. The conductor hosts it, because a sub-agent cannot spawn sub-agents of
512
+ its own. It spawns one reviewer sub-agent one tier above the tier the
513
+ phase's implementer ran at (a Tier 4 phase is reviewed at Tier 4), and hands
514
+ each round of findings to the phase's own implementer. The implementer
515
+ verifies each finding, fixes the justified ones, rejects the rest with
516
+ counter-evidence, and commits the round. Questions only a person can settle
517
+ come to you as structured questions. The phase passes only when the
518
+ reviewer explicitly approves. After 20 passes that still return blockers,
519
+ the conductor asks whether to continue for 20 more, stop the phase
520
+ unapproved, or amend the plan. **Consumers**: re-sync to re-render the
521
+ plan-execution skills.
522
+ - **Maestro: a phase's review is now the `review` chore.** Once the phase's
523
+ gates are green, the implementer's own session runs
524
+ `thermo-nuclear-review-loop`: it spawns one reviewer sub-agent and fixes or
525
+ answers its findings until the reviewer approves. Then `deslop` runs, and
526
+ the gates run once more on the final tree. A red gate still goes to the
527
+ fixer. A review turn that ends unapproved asks the operator to continue or
528
+ stop. `plan-feature` now emits the `review`
529
+ chore and `defaults.chores: ["review", "deslop"]`, and transcribes the
530
+ Crew table's implementers into `crew`.
531
+ - **Maestro: chore `when` is now `review`, `after_review` (the default) or
532
+ `after_pr`.** `review` chores must end with `VERDICT: pass` or
533
+ `VERDICT: fail`, and the phase continues only on pass. `after_review`
534
+ replaces `before_gate`.
535
+ - **Maestro: `max_fix_rounds` has no default, and unset means no limit.** The
536
+ fixer works on a red gate until it is green, and the review loop runs until
537
+ the reviewer approves, without asking. Set `max_fix_rounds` on a node to get
538
+ the old behaviour back: after that many fix rounds or unsuccessful review
539
+ passes, the phase asks whether to continue or stop. **Migration:** a plan
540
+ that relied on the default of 4 now runs unbounded; add
541
+ `"max_fix_rounds": 4` to keep it.
542
+ - **Maestro: every `workflow_amended` row carries `targets`.** Operator and
543
+ config amendments get them too, computed from the snapshot and the
544
+ proposal. Before, only monitor amendments had them.
545
+ - **Maestro: a gate command can be amended after a phase that uses it is
546
+ done.** Changing a gate table no longer counts as rewriting a finished
547
+ phase. Before, such an amendment was refused as `body_changed_after_done`.
548
+ - **Maestro: the editor saves only what you changed.** It shows the workflow
549
+ resolved over the project config, and on save it writes back only the
550
+ edited values. A first save no longer copies every default, or the
551
+ project's values, into the plan file.
552
+
297
553
  - **Maestro: the node view's right-hand column stays short.** Gate logs open
298
554
  in a dialog instead of an inline accordion. The dialog opens at the end of
299
555
  the log, keeps up with a running gate's output, numbers the lines, and has
@@ -391,8 +647,143 @@ the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
391
647
  and never selects text. The host box follows the window's height instead of
392
648
  being fixed at 380px.
393
649
 
650
+ ### Deprecated
651
+
652
+ - **`agent_models.reviewer` is ignored.** The review runs one tier above the
653
+ phase's implementer, so no configured tier is read. The key stays in the v1
654
+ config schema so existing configs still validate; drop it at your next
655
+ edit. Bootstrap no longer asks for it. `agent_models.fixer` now sets only
656
+ the merge-conflict fixer's tier, since the phase's implementer fixes review
657
+ findings at its own tier.
658
+
659
+ ### Removed
660
+
661
+ - **The three-layer phase review.** `review-phase` no longer runs the
662
+ mechanical checks (including the review-time secret scan, dependency-license
663
+ check and co-author trailer check), the plan-compliance walkthrough
664
+ (including the comment-hygiene check), the crew reviewer, or a separate
665
+ fixer per finding. The implementer's own install-time license check and
666
+ co-author rules are unchanged.
667
+ - **Reviewers on the plan.** `plan-feature`'s Crew table loses its `Role`
668
+ column and its reviewer rows, and phases lose the optional
669
+ `**Review models**:` line. **Migration:** plans written with reviewer rows,
670
+ a `Role` column or `**Review models**:` lines still run; `implement-plan`
671
+ ignores them.
672
+ - **Maestro: the reviewer role and its review loop.** Crew members are
673
+ implementers only, and the crew `role` field is gone. Also gone:
674
+ `defaults.reviewer_model` (in the workflow file and in the
675
+ `.vinta-ai-workflows.yaml` `maestro.defaults`), the consult step and the
676
+ review ledger. **Migration:** a `.workflow.json` with a crew `role`, a
677
+ reviewer crew member, a `before_gate` chore or `reviewer_model` no longer
678
+ parses. Re-emit it with `plan-feature`, or edit it by hand: drop the
679
+ reviewer members and every `role`, rename `before_gate` to `after_review`,
680
+ delete `reviewer_model`, and add the `review` chore.
681
+
394
682
  ### Fixed
395
683
 
684
+ - **Maestro: a merge commit git refuses no longer leaves the integration
685
+ worktree mid-merge.** A pre-commit hook failing in the integration worktree
686
+ left `MERGE_HEAD` behind, and every phase whose base was built there then
687
+ failed in its own setup on `git checkout exited 1` — four phases, up to
688
+ twenty-three attempts each, in one run. The integrator now keeps the
689
+ resolution as a commit under `refs/vinta-ai-maestro/resolutions/<node>`,
690
+ abandons the merge, and asks the phase whose merge it is: `commit`,
691
+ `commit --no-verify`, or `abort merge` (the unattended answer under
692
+ `--retry-after`). A retry reuses the kept resolution. Before any checkout,
693
+ the integrator refuses a worktree that is mid-merge, mid-rebase or
694
+ mid-cherry-pick *by name* (`integration worktree is mid-merge: a merge of
695
+ plan/x/phase-b into plan/x/integ-c …`). A conflict fixer that could not run
696
+ abandons the merge it was handed.
697
+ - **Maestro: `GitCommandError` carries git's stderr.** The redacted, bounded
698
+ tail of what git said is in the error, in `node.attempt_failed`, in the
699
+ journal's `node_error` and so in the UI — `git commit exited 1: …No module
700
+ named 'settings.local'` instead of `git commit exited 1`. The integrator's
701
+ own errors (`UnresolvedConflictError` among them) keep their messages too
702
+ instead of being reported as their class name.
703
+ - **Maestro: a setup failure that repeats is not retried unattended.** A phase
704
+ that fails before any agent ran, twice in a row on the same line, is parked
705
+ on its question without `--retry-after`'s self-answer, and the question
706
+ says why.
707
+ - **Maestro: `project.env_files` reaches adopted lanes.** A resume gives each
708
+ lane the declared files it lacks and never overwrites one it has, so
709
+ amending the list reaches lanes that already exist. `doctor` fails a
710
+ declared file missing from the checkout and warns, by name, when a
711
+ gitignored file has a tracked example (`.env.example`,
712
+ `settings/local.py.example`) and nothing declares it.
713
+ - **Maestro: a phase with no gates is no longer a silent pass.** `validate`
714
+ refuses a node that resolves to an empty `gates` list and `doctor` warns
715
+ naming the phases, unless the plan sets `defaults.allow_ungated_phases:
716
+ true` (new, additive). Twelve phases had finished without a check because
717
+ every node carried `gates: []` where its author meant "the project's".
718
+ - **Maestro: a refused conflict-fixer spawn is backpressure.** A plan limit or
719
+ quota refusal while spawning the fixer parks the phase on the harness's
720
+ wait (`waiting_on_capacity`) instead of failing it and retrying on a timer.
721
+ - **Maestro: `createdb` / `dropdb` reach the server `server_url` names.** The
722
+ template and lane commands pass `-h`, `-p` and `-U` from the URL; they used
723
+ the local socket, which is not a Docker-published server. The password stays
724
+ off the command line (`PGPASSWORD` or `~/.pgpass`).
725
+ - **Maestro: `vinta-ai-maestro` resolves from inside every lane.** The daemon
726
+ writes a launcher for itself into `.vinta-ai-maestro/bin/` and puts it first
727
+ on the agents' `PATH`, so `with` and `gate` work when maestro is a project
728
+ devDependency reached through `node_modules/.bin` or `npx`.
729
+ - **Maestro: agents are told a compose-delivered database is unreachable from
730
+ the host.** The implementer prompt names the connection variables that
731
+ resolve only inside the lane's compose network and says to run the suite
732
+ through the project's commands or the gate verb.
733
+ - **Maestro: an editor save writes a patch even when the stored file does not
734
+ validate.** A cross-reference error in the committed file (a chore the
735
+ project no longer declares) made the save write the whole resolved document
736
+ — a hundred-line diff for a one-field edit. The shape is now enough to diff
737
+ against.
738
+ - **Maestro: `purge <run-id>` forgets the run in `flow.db` too.** The UI went
739
+ on listing, and offering to resume, a run whose directory was gone.
740
+ - **Maestro: the monitor thinks with the model the run declares now.** It was
741
+ built once at job start; an amendment to the crew's models reached it only
742
+ after a pause and resume.
743
+ - **Maestro: `run` says where the run's state lives.** The store is the
744
+ checkout's, so a `ui` started in another checkout of the same repository
745
+ (the main one, while the run is in a worktree) lists other runs; the output
746
+ now names the store and the `--repo` to pass.
747
+ - **plan-feature: `project.env_files` and the gate/chore inheritance rules.**
748
+ The skill told authors env-file copying did not belong in the `project`
749
+ block, which left every lane without `.env`; it now tells them to find the
750
+ gitignored files the project's hooks, gates and settings need (`*.example`
751
+ siblings, compose `env_file:` lines, the settings module) and to declare
752
+ them — once, in `.vinta-ai-workflows.yaml` under `maestro.project.env_files`,
753
+ or in the workflow. It also states plainly that `gates: []` and
754
+ `defaults.chores: []` mean *none* rather than "the project's", that an
755
+ override of a project gate must carry `type`, and that `vinta-ai-maestro
756
+ validate` must exit 0 before the plan is handed over. `vinta-bootstrap-ai-tools`
757
+ asks about `env_files` when it writes the `maestro:` section.
758
+ - **Maestro: wave merges again use the membership the executor counted.**
759
+ `RecordingIntegrator.mergeWave` dropped it, so in production a merge fell
760
+ back to the integrator's own reading of the wave. That reading could differ
761
+ from the count if an amendment landed in between.
762
+ - **Maestro: the gate run on a conflict resolution uses the amended gate
763
+ commands.** It used the workflow from the start of the run.
764
+ - **Maestro: the API serves a run's definition as amended.** It cached the
765
+ snapshot forever, so a monitor retune made in the run's own process never
766
+ reached the UI.
767
+ - **Maestro: an editor save from `ui` now reaches the run's job.** `ui`
768
+ is a separate process from the job hosting a run. A save to a running
769
+ plan's workflow used to replace the run's frozen snapshot from `ui` with no
770
+ runner: nothing adopted the change, and an amendment that needed a rebase
771
+ was refused. The job kept running the old definition until a resume. The
772
+ save is now sent to the job (`POST /api/runs/<id>/amend`), which applies it
773
+ under the usual amend rules, and `ui` writes the plan file only once the
774
+ job has accepted it. If the job does not answer, the save is refused
775
+ (`run_host_unreachable`) and nothing is written.
776
+ - **Maestro: saving in the editor during a run no longer reports a failure.**
777
+ The amendment response failed the client's schema check even though the
778
+ save had gone through.
779
+
780
+ - **`implement-plan`'s final report no longer suggests `docker compose down -v`
781
+ to tear down a lane.** `down -v` also deletes the compose volumes a worktree
782
+ deliberately shares with the main checkout (`shared_volumes`, such as a
783
+ dependency cache). The report now prints the same sequence the
784
+ `prepare-worktree` skill documents: `docker compose -p <project> down`, then
785
+ `docker volume rm` for each volume the worktree forked, then removal of the
786
+ generated compose override.
396
787
  - **`open-pr.sh` posts inline comments on macOS and reports why a comment
397
788
  failed.** Four bugs in the `open-pr-from-context` script, all seen while
398
789
  publishing a stacked plan from a Mac:
package/README.md CHANGED
@@ -80,7 +80,7 @@ The bootstrap skills are **one-shot**. They scaffold the project once and are re
80
80
  - **Goals + Non-goals** — what's in / out of scope.
81
81
  - **Guiding Decisions** — feature flag (key, scope, default, flip-on criterion if any), storage shape, tenant scoping, API contract, schema rules. Load-bearing — every phase reaches back here.
82
82
  - **Data Model Changes** — migrations + rollout order.
83
- - **Phased Rollout** — opens with a **Crew** table (the agents this plan is staffed with, each with a role — `implementer` or `reviewer` — and a tier; every implementer keeps one worktree and one session for the whole run, while reviewers read the lane they are reviewing before it is committed), then each phase declares: `id`, `title`, `goal`, `Assigned to` (which crew member takes it — implement-plan resolves their tier to the cheapest available model), `reusable_skills` (other project skills the implementer should invoke), `Changes`, `Tests`, `Acceptance`, plus flags for `is_cross_repo` and `is_flag_removal` (both deferred).
83
+ - **Phased Rollout** — opens with a **Crew** table (the implementers this plan is staffed with, each with a tier; every implementer keeps one worktree and one session for the whole run, and the `.workflow.json` transcribes the same roster). Reviews are not staffed: both `implement-plan` and `vinta-ai-maestro` review each phase with `thermo-nuclear-review-loop`, which spawns its own reviewer. Then each phase declares: `id`, `title`, `goal`, `Assigned to` (which crew member takes it — implement-plan resolves their tier to the cheapest available model), `reusable_skills` (other project skills the implementer should invoke), `Changes`, `Tests`, `Acceptance`, plus flags for `is_cross_repo` and `is_flag_removal` (both deferred).
84
84
  - **Risk & Rollout Notes**, **Open Questions**, **Touch List**.
85
85
 
86
86
  Phases are sized so the slowest path (e.g. cross-repo producer wiring, external integration approval) starts in Phase 1 and fast in-repo work fills in behind. Large mutation phases get split (`4a / 4b / 4c`) rather than monolithic.
@@ -99,11 +99,8 @@ Phases are sized so the slowest path (e.g. cross-repo producer wiring, external
99
99
  2. **Pick the model from the plan's per-phase suggestion.** Filter to what the runtime can actually run, choose the cheapest survivor. Capability gap on retry → escalate one tier; after Tier 4, stop and surface to the user.
100
100
  3. **Spawn the right agent type.** `implementer` by default; switch to a stack-specialist (`migration-author`, `deploy-author`, etc.) when that role's risk dominates the phase.
101
101
  4. **Implementer runs inner + outer loop.** Inner: lint → scoped tests → typecheck on touched files; iterate until green. Outer (only after inner is green): full build + full test suite + e2e where applicable. Never commits, pushes, or proceeds with a red gate.
102
- 5. **Three-layer review** before merging the phase branch:
103
- - **Layer 1 — mechanical**: read every diff, confirm outer gate ran green, scope-creep + secrets scan.
104
- - **Layer 2 — plan compliance**: walk every "Changes" item, every "Tests" entry, the Acceptance line, AGENTS.md conventions, any reusable-skill compliance, feature-flag wiring, cross-phase consistency.
105
- - **Layer 3 — independent reviewer**: spawn a fresh `reviewer` agent with no implementation context. Findings triaged BLOCKER / SHOULD-FIX / NIT.
106
- 6. **Fix loop**: each finding → spawn a `fixer` agent (separate session) that re-runs inner + outer loops; orchestrator never edits directly. Repeat until all three layers are clean.
102
+ 5. **Review loop** before integrating the phase. `review-phase` runs the `thermo-nuclear-review-loop` skill with the orchestrator as the loop's host. One reviewer sub-agent, with no implementation context and one tier above the tier the implementer ran at, reviews the phase diff against the phase body and the plan's **Goals** and **Guiding Decisions**. Its findings go back to the phase's own implementer, which verifies each one, fixes the justified ones, rejects the rest with counter-evidence, re-runs the gates and commits the round. A question only a person can settle (an unreachable scenario, a scope call, a destructive step) comes to you as a structured question. The orchestrator never edits code.
103
+ 6. **Loop until the reviewer approves.** The reviewer re-reads the whole diff on every pass, and the phase passes only on its explicit approval. After 20 passes that still return blockers, the orchestrator pauses and asks whether to continue for 20 more, stop the phase unapproved, or amend the plan.
107
104
 
108
105
  **Branch model — one branch per phase, based on that phase's dependencies:**
109
106
 
@@ -139,7 +136,7 @@ Each phase's PR (or branch, depending on the project's PR policy captured at boo
139
136
  - **Cross-repo phases** (`is_cross_repo: true`) — work in another repository. Marked deferred in tracking; orchestrator continues to the next in-repo phase. Don't block on cross-repo work.
140
137
  - **Flag-removal phase** (always the last phase when a feature flag exists). Gated on real-world soak signal — handled by a dedicated flag-removal skill, not `implement-plan`. Marked deferred; orchestrator ends the run with a hand-off note.
141
138
 
142
- **Failure handling:** if a phase fails Layer 1 / 2 / 3 + fixer escalation, orchestrator stops, posts the agent's report, and asks how to proceed. It does not silently rerun, skip, or escalate models without the user.
139
+ **Failure handling:** if a phase's gates stay red after escalation, or its review stops unapproved, orchestrator stops, posts the agent's report, and asks how to proceed. It does not silently rerun, skip, or escalate models without the user.
143
140
 
144
141
  #### PR creation: single flow via `prs-context` + `open-pr.sh`
145
142
 
@@ -200,7 +197,7 @@ The script bails early with `missing dependency: <name>` if any are absent. If a
200
197
 
201
198
  # Day 3+ — execution
202
199
  /implement-plan # orchestrator runs phase 1 → phase 2 → ... → phase N-1
203
- # each phase: implementer + reviewer + fixer agents,
200
+ # each phase: implementer + a review loop until approval,
204
201
  # one stacked branch + PR per phase
205
202
  # merge phase branches sequentially as approvals land
206
203
  # soak phase 1 in prod → soak phase 2 → ...
@@ -223,12 +220,12 @@ Quick inventory of what `vinta-bootstrap-ai-tools` writes into your repo's `ai-t
223
220
  The 0.2.0 alpha line adds five foundation skills and restructures plan execution. Two ship in every bootstrapped project, three are opt-in:
224
221
 
225
222
  - **`handoff` (always)** — writes a session-continuation doc to `.vinta-ai-workflows/handoffs/` so a fresh session, a different agent, or a teammate can resume in-flight work without re-deriving context. Write mode gathers the goal, what's verified vs. still assumed, decisions and the alternatives rejected, landmines, and the single concrete next step **from the repo, never from memory**. Resume mode reads a handoff and re-checks its claims against the repo before trusting them.
226
- - **`deslop-comments` (always)** — rewrites the comments and doc blocks a task touched into Simple English, stripping AI-slop vocabulary and negative framing. Comment-only: no renames, no behavior change. It's wired into the review flow — `review-phase` Layer 2 gained a comment-hygiene check and dispatches a `fixer` to run this skill on any comment-slop finding — and is also invokable standalone ("deslop these comments").
223
+ - **`deslop-comments` (always)** — rewrites the comments and doc blocks a task touched into Simple English, stripping AI-slop vocabulary and negative framing. Comment-only: no renames, no behavior change. `integrate-phase` / `amend-plan` run it over the PR-context prose they write, `vinta-ai-maestro` runs it as each phase's `deslop` chore, and it is also invokable standalone ("deslop these comments").
227
224
  - **`prepare-worktree` (opt-in)** — provisions a fully-runnable git worktree for parallel plan work so a long-running plan can build, test, migrate, and hit databases without disturbing the main checkout. It reads the plan plus `.gitignore` / manifests / env / docker config and gives every worktree its own copy of the dependency dirs (never a symlink) and decides per remaining ignored path whether to copy, fork, or share (dev DB, env files, compose project name). It also ships an OS-level write-guard — `sandbox-run.sh` (`sandbox-exec` / `bwrap`) for subprocess runtimes and a `PreToolUse` hook for Claude Code's in-process subagents — so a stray write back to the main checkout fails at the kernel layer instead of relying on a cooperative "stay in the worktree" instruction. `implement-plan` Step 0 question (c) opts a run into it, and parallel phase execution requires it — one lane per concurrent phase.
228
- - **`thermo-nuclear-code-quality-review` (opt-in)** — a deliberately harsh, on-demand structural-maintainability audit of a diff (abstraction quality, giant files, spaghetti-condition growth) that hunts for "code-judo" reframes collapsing whole branches / helpers / modes / layers rather than polishing them. Read-only — it reports findings and hands each fix to a `fixer`. `review-phase` Layer 3 now applies a condensed version of this lens on every phase and escalates to the full audit only when a phase touches core architecture, crosses ~1,000 lines, or surfaces a structural smell too big to fix inline.
225
+ - **`thermo-nuclear-code-quality-review` (opt-in)** — a deliberately harsh, on-demand structural-maintainability audit of a diff (abstraction quality, giant files, spaghetti-condition growth) that hunts for "code-judo" reframes collapsing whole branches / helpers / modes / layers rather than polishing them. Read-only — it reports findings and hands each fix to a `fixer`. The per-phase review loop already applies a structural-simplification lens on every phase; this is the deliberate deep audit for when a change touches core architecture, crosses ~1,000 lines, or carries a structural smell worth a dedicated pass.
229
226
  - **`handoff-to-client` (opt-in, API-only repos)** — generates a self-contained markdown document for the client teams consuming the repo's API: every endpoint / operation added, changed, deprecated, or removed on the current branch vs. the default branch, with request/response shapes derived from the code, auth + error changes, breaking-change flags judged from the strictest plausible client, one realistic example per operation, and per-platform migration notes. Template-rendered from `skills.handoff-to-client.*` config (required `client_platforms`, plus `api_style` / `api_spec_path` / `output_dir`).
230
227
 
231
- Alongside the new skills, **`implement-plan` was decomposed into a modular plan-execution unit** — a thin conductor plus three co-shipped single-purpose sub-skills (`implement-phase`, `review-phase`, `integrate-phase`). `review-phase` is now the one review implementation shared by `implement-plan`, `amend-plan`, and `systematic-debugging`. The behavior is unchanged; the split is for reviewability and determinism. Two more knobs land in `.vinta-ai-workflows.yaml`: **`agent_models`** (set a tier per `reviewer` / `fixer` / `worktree_prep` / `integrate` so the review sub-agents and mechanical steps aren't stuck on the runtime default), and **E2E tests are now opt-in** in both `plan-feature` and `implement-plan` (they make runs materially slower; default off, re-enable per-run or per-project).
228
+ Alongside the new skills, **`implement-plan` was decomposed into a modular plan-execution unit** — a thin conductor plus three co-shipped single-purpose sub-skills (`implement-phase`, `review-phase`, `integrate-phase`). `review-phase` is now the one review implementation shared by `implement-plan`, `amend-plan`, and `systematic-debugging`. The behavior is unchanged; the split is for reviewability and determinism. Two more knobs land in `.vinta-ai-workflows.yaml`: **`agent_models`** (set a tier per `fixer` / `worktree_prep` / `integrate` so the merge-conflict fixer and mechanical steps aren't stuck on the runtime default; `reviewer` is deprecated and ignored since 0.7.0, because the review runs one tier above the implementer), and **E2E tests are now opt-in** in both `plan-feature` and `implement-plan` (they make runs materially slower; default off, re-enable per-run or per-project).
232
229
 
233
230
  ### Foundation skills (project-agnostic)
234
231
 
@@ -242,18 +239,19 @@ Land at `ai-tools/skills/<name>/SKILL.md`. Always-on unless flagged optional.
242
239
  | [`open-pr-from-context`](skills/vinta-derive-skills/resources/foundation-skills/open-pr-from-context/SKILL.md) | always | Publish a `.vinta-ai-workflows/prs-context/<feature>/<phase>.md` file as a real PR + inline comments via `gh` / `glab`. Bundles [`open-pr.sh`](skills/vinta-derive-skills/resources/foundation-skills/open-pr-from-context/scripts/open-pr.sh). |
243
240
  | `implement-plan` | always (generated) | Phase-by-phase plan execution. Thin **conductor**: parses the plan, resolves one `WORKROOT`, and runs a fixed pipeline per phase (`implement-phase` → `review-phase` → `integrate-phase`), tracking + reporting. Generated from a template with project commands + branch / PR / co-author policy. |
244
241
  | `implement-phase` | always (unit) | Plan-execution sub-skill co-shipped with `implement-plan`: compose the implementer prompt, pick the model, spawn one implementer subagent for a single phase. |
245
- | `review-phase` | always (unit) | Plan-execution sub-skill: the three-layer review (mechanical / plan-compliance / independent reviewer) + fix loop. Shared by `implement-plan`, `amend-plan`, and `systematic-debugging`. |
242
+ | `review-phase` | always (unit) | Plan-execution sub-skill: runs the `thermo-nuclear-review-loop` over one phase with the conductor as host — one reviewer sub-agent one tier above the implementer, the phase's own implementer fixing, questions to the human, until the reviewer explicitly approves. Shared by `implement-plan`, `amend-plan`, and `systematic-debugging`. |
246
243
  | `integrate-phase` | always (unit) | Plan-execution sub-skill: push the reviewed phase along the project's commit strategy + open the PR via context file. Under `commit_strategy = ask`, ships as `integrate-phase-stacked` + `integrate-phase-modular`. |
247
244
  | `amend-plan` | always (generated) | History-rewriting companion to `implement-plan` — revises in-flight plans, amends prior-phase commits, force-pushes, rebases stacked downstream branches. Reuses `review-phase` + `implement-phase`'s shared prompt loop. |
248
245
  | [`handoff`](skills/vinta-derive-skills/resources/foundation-skills/handoff/SKILL.md) | always | Session-continuation handoff doc → `.vinta-ai-workflows/handoffs/`. **Write** captures goal, verified-vs-unverified state, decisions + rejected alternatives, landmines, and the single next step — gathered from the repo, never memory. **Resume** verifies a handoff's claims against the repo before continuing from its next step. |
249
- | [`deslop-comments`](skills/vinta-derive-skills/resources/foundation-skills/deslop-comments/SKILL.md) | always | Rewrite comments + doc blocks touched during a task into Simple English, and delete the ones that shouldn't exist at all — where-used lists, another module's internals, restatements of the code, deferred-work notes, paths not taken (comment-only; no renames, no behavior change). `review-phase` Layer 2 depends on it, `integrate-phase` / `amend-plan` run it over the PR-context file, and it's invokable standalone. |
246
+ | [`deslop-comments`](skills/vinta-derive-skills/resources/foundation-skills/deslop-comments/SKILL.md) | always | Rewrite comments + doc blocks touched during a task into Simple English, and delete the ones that shouldn't exist at all — where-used lists, another module's internals, restatements of the code, deferred-work notes, paths not taken (comment-only; no renames, no behavior change). `integrate-phase` / `amend-plan` run it over the PR-context file, `vinta-ai-maestro` runs it as each phase's `deslop` chore, and it's invokable standalone. |
247
+ | [`thermo-nuclear-review-loop`](skills/vinta-derive-skills/resources/foundation-skills/thermo-nuclear-review-loop/SKILL.md) | always | Review-and-fix loop over a change: the running agent spawns one reviewer sub-agent, verifies its findings, fixes the justified ones and answers the rest, until the reviewer explicitly approves under a strict code-quality standard. Scope questions go to the human instead of being assumed. It is the per-phase review on both execution paths: `review-phase` runs it with the conductor as host, and `vinta-ai-maestro` runs it as each phase's `review` chore once the gates are green. Also invokable standalone. |
250
248
  | `write-unit-test` | default-on (generated) | Write durable unit tests for a unit of behavior, enforcing six framework-agnostic rules + this project's captured test conventions, with runner- and stack-specific best-practice packs. Ships automatically whenever a unit-test framework is detected (set `disabled` to opt out). Generated from a template; config under `skills.write-unit-test.*`. See below. |
251
249
  | `systematic-debugging` | **opt-in** | Root-cause-first debugging with project-specific repro commands + MCP evidence-gathering (error tracking, traces, logs, metrics, alerts). Renders from a catalogue of observability MCP servers the user declares. |
252
250
  | `add-e2e-test` | **opt-in** | Add an e2e test. Body covers e2e framework, page-object pattern, auth/storage-state, seed helpers, tenant scoping, screenshot conventions. |
253
251
  | `add-env-var` | **opt-in** | Propagate a new env var through every layer (`.env.example`, build tool envPrefix, build cache hash, app config, AGENTS.md, CI, deploy injection). |
254
252
  | [`add-one-off-script`](skills/vinta-derive-skills/resources/foundation-skills/add-one-off-script/SKILL.md) | **opt-in** | Author one-off operational scripts (backfills, cleanups, ad-hoc fixes). Ships a `BaseOneOffScript` class (Python + TS) enforcing dry-run default, idempotency, batched DB ops, segmented CSV backups, signal-safe interruption, multi-sink logging. |
255
253
  | [`prepare-worktree`](skills/vinta-derive-skills/resources/foundation-skills/prepare-worktree/SKILL.md) | **opt-in** | Provision a fully-runnable git worktree for parallel plan work — reads the plan + `.gitignore` + manifests + env / docker config and gives each worktree its **own dependency copy** (never a symlink) and decides per remaining ignored path whether to **copy / fork / share** (dev DB, env files, compose project name). Ships an OS-level write-guard (`sandbox-run.sh` + a Claude Code `PreToolUse` hook) so stray writes to the main checkout fail at the kernel layer. `implement-plan` Step 0 question (c) opts a run into it, and parallel phase execution requires it — one lane per concurrent phase. |
256
- | [`thermo-nuclear-code-quality-review`](skills/vinta-derive-skills/resources/foundation-skills/thermo-nuclear-code-quality-review/SKILL.md) | **opt-in** | Deliberately harsh structural-maintainability audit of a diff — abstraction quality, giant files, spaghetti-condition growth — hunting "code-judo" reframes that collapse whole branches / helpers / modes / layers. Read-only; hands each fix to `fixer`. `review-phase` Layer 3 runs a condensed lens every phase and escalates to this full audit on core-architecture / ~1000-line / structurally-smelly phases. |
254
+ | [`thermo-nuclear-code-quality-review`](skills/vinta-derive-skills/resources/foundation-skills/thermo-nuclear-code-quality-review/SKILL.md) | **opt-in** | Deliberately harsh structural-maintainability audit of a diff — abstraction quality, giant files, spaghetti-condition growth — hunting "code-judo" reframes that collapse whole branches / helpers / modes / layers. Read-only; hands each fix to `fixer`. The per-phase review loop carries a condensed structural lens; this is the deliberate deep audit on top of it. |
257
255
  | `handoff-to-client` | **opt-in** | (API-only repos) Generate a self-contained API-change handoff doc for the client teams consuming the repo's API — every endpoint / operation added / changed / deprecated / removed vs the default branch, with request/response shapes, auth + error changes, breaking-change flags, one example per operation, and per-platform migration notes. Template-rendered from `skills.handoff-to-client.*` config (client platforms, API style, spec path). |
258
256
 
259
257
  #### `write-unit-test` in depth
@@ -287,8 +285,8 @@ Land at `ai-tools/agents/<name>.yaml` (canonical YAML; `setup-ai-tools.mjs` emit
287
285
  | Agent | Access | Role |
288
286
  |---|---|---|
289
287
  | `implementer` | read-write | Default coder for one plan phase. Reads AGENTS.md + plan + phase body, runs inner + outer test gates, reports back. Never branches, pushes, opens PRs, or adds AI co-author trailers. |
290
- | `reviewer` | read-only | Adversarial reviewer. Reads phase + diff + AGENTS.md, outputs `BLOCKER` / `SHOULD-FIX` / `NIT` findings with `file:line`. Does not edit. |
291
- | `fixer` | read-write | Applies one reviewer finding (or one named test failure). Smallest correct change, re-runs gates, reports. |
288
+ | `reviewer` | read-only | Adversarial reviewer for reviews the team asks for. Reads phase + diff + AGENTS.md, outputs `BLOCKER` / `SHOULD-FIX` / `NIT` findings with `file:line`. Does not edit. `review-phase` does not use it: its loop spawns a general-purpose reviewer, so one standard applies. |
289
+ | `fixer` | read-write | Resolves one merge conflict between phases, applies one review finding handed over cold, or fixes one named test failure. Smallest correct change, re-runs gates, reports. |
292
290
 
293
291
  Stack templates may add specialists like `migration-author` (Django) or `deploy-author` (Medplum) — see disclaimer above.
294
292
 
@@ -594,7 +592,7 @@ vinta-ai-workflows/
594
592
 
595
593
  `vinta-bootstrap-ai-tools` is the entry point — walks a fresh repo, runs the others in order. The rest can also be invoked individually to refresh a single artifact.
596
594
 
597
- The repository is also a pnpm workspace. `packages/` holds **private, unpublished** packages that are not part of what `install` puts in your project — the `files` whitelist excludes the directory. The one worth knowing about is [`packages/vinta-ai-maestro`](packages/vinta-ai-maestro/README.md): an opt-in daemon that executes the `ai-plans/<feature>.workflow.json` files `plan-feature` emits, scheduling independent phases across worktree lanes. Nothing requires it; the skills path runs the same plans with no daemon installed.
595
+ The repository is also a pnpm workspace. `packages/` holds **private, unpublished** packages that are not part of what `install` puts in your project — the `files` whitelist excludes the directory. The one worth knowing about is [`packages/vinta-ai-maestro`](packages/vinta-ai-maestro/README.md): an opt-in daemon that executes the `ai-plans/<feature>.workflow.json` files `plan-feature` emits, scheduling independent phases across worktree lanes. Each phase there is implemented, gated, then reviewed by its own implementer through the `thermo-nuclear-review-loop` skill until the loop's reviewer approves, comment-cleaned by `deslop-comments`, and gated once more before it integrates. Nothing requires it; the skills path runs the same plans with no daemon installed.
598
596
 
599
597
  ### Why the `vinta-` prefix?
600
598
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vinta-ai-workflows",
3
- "version": "0.7.0-alpha25",
3
+ "version": "0.7.0-alpha27",
4
4
  "description": "Bootstrap AI tooling (AGENTS.md, skills, sub-agents) across Claude Code, Codex, Cursor, and VS Code + GitHub Copilot.",
5
5
  "type": "module",
6
6
  "bin": {
package/schemas/README.md CHANGED
@@ -6,17 +6,20 @@ JSON Schema (Draft 2020-12) contracts for every YAML or JSON payload the vinta-a
6
6
 
7
7
  | Artifact | YAML location in target project | Schema file | Authored by | Read by |
8
8
  |---|---|---|---|---|
9
- | Project config | `.vinta-ai-workflows.yaml` (repo root) | [`vinta-ai-workflows-config.v1.schema.json`](vinta-ai-workflows-config.v1.schema.json) | `vinta-bootstrap-ai-tools` (initial) → `vinta-sync-ai-tools` (updates) | every builder skill, every template render, every meta-skill |
9
+ | Project config | `.vinta-ai-workflows.yaml` (repo root) | [`vinta-ai-workflows-config.v1.schema.json`](vinta-ai-workflows-config.v1.schema.json) | `vinta-bootstrap-ai-tools` (initial) → `vinta-sync-ai-tools` (updates) | every builder skill, every template render, every meta-skill ; `vinta-ai-maestro` reads `commands` + `maestro` and layers every workflow over them |
10
10
  | Sub-agent definition | `ai-tools/agents/<name>.yaml` | [`sub-agent.v1.schema.json`](sub-agent.v1.schema.json) | `vinta-derive-subagents` | `setup-ai-tools.mjs` (emits per-vendor copies) |
11
11
  | PR-context frontmatter | top-of-file YAML in `.vinta-ai-workflows/prs-context/{feature-kebab}/phase-{phase.id}.md` | [`prs-context-frontmatter.v1.schema.json`](prs-context-frontmatter.v1.schema.json) | `implement-plan` / `amend-plan` | `open-pr.sh` |
12
12
  | PR-context inline comments | YAML inside the ` ```yaml ... ``` ` fence under `# Comments` of the same file | [`prs-context-comments.v1.schema.json`](prs-context-comments.v1.schema.json) | `implement-plan` / `amend-plan` | `open-pr.sh` |
13
13
  | MCP preflight cache | `.vinta-ai-workflows/cache.yaml` (gitignored — per-developer-machine state) | [`mcp-preflight-cache.v1.schema.json`](mcp-preflight-cache.v1.schema.json) | rendered `systematic-debugging` SKILL.md (writes during Phase 0) | rendered `systematic-debugging` SKILL.md (reads at Phase 0 start) |
14
+ | Interview round | `.vinta-ai-workflows/interviews/<slug>/rounds/round-NN.json` (gitignored working trail; JSON, not YAML) | [`interview-round.v1.schema.json`](interview-round.v1.schema.json) | the skill running the interview (`create-spec` Step 0 via `interview-ui`) | `interview-ui` server + shell (`ai-tools/skills/interview-ui/`) |
15
+ | Interview answers | `.vinta-ai-workflows/interviews/<slug>/answers/round-NN.json` (gitignored; JSON) | [`interview-answers.v1.schema.json`](interview-answers.v1.schema.json) | `interview-ui` server, on browser submit | the skill running the interview (reads answers, writes the next round) |
14
16
  | AI model tier table | `ai-tools/skills/plan-feature/resources/ai-models.yaml` (shipped verbatim with the `plan-feature` foundation skill; source: `skills/vinta-derive-skills/resources/foundation-skills/plan-feature/resources/ai-models.yaml`) | [`ai-models.v1.schema.json`](ai-models.v1.schema.json) | nightly `check-ai-models` job ([`scripts/check-ai-models.mjs`](../scripts/check-ai-models.mjs)) → auto-PR | `plan-feature` (per-phase model suggestion) |
15
17
  | Workflow (executable plan) | `ai-plans/YYYY-MM-DD-<feature-kebab>.workflow.json` — **JSON, not YAML** | [`workflow.v1.schema.json`](workflow.v1.schema.json) | `plan-feature` (emitted alongside the human-readable plan) | `vinta-ai-maestro` (the orchestrator daemon) |
16
18
  | Plan post-mortem | `.vinta-ai-maestro/runs/<run-id>/postmortem.json` — **JSON, not YAML**; per-run state beside the frozen workflow, copied to `ai-plans/<feature-kebab>.postmortem.json` when a team wants it committed | [`postmortem.v1.schema.json`](postmortem.v1.schema.json) | `vinta-ai-maestro` (once a run has ended) | `plan-feature` (when planning the next feature in the same repo) |
19
+ | Plan review | `ai-plans/YYYY-MM-DD-<feature-kebab>.review.json` — **JSON, not YAML**; beside the plan and its workflow, committed with them | [`plan-review.v1.schema.json`](plan-review.v1.schema.json) | the `vinta-ai-maestro` review page (a person's comments, messages, approval) and `vinta-ai-maestro review reply` (the agent's answers) | `plan-feature`, through `vinta-ai-maestro review wait` |
17
20
  | Monitor intervention | not a file the user writes — the document the run's monitor answers with when a watchdog wakes it, recorded per attempt at `.vinta-ai-maestro/runs/<run-id>/interventions.jsonl` | [`intervention.v1.schema.json`](intervention.v1.schema.json) | the run monitor (`vinta-ai-maestro`, when a phase or a gate crosses a threshold) | `vinta-ai-maestro` (validates it, then applies it through §9's amend path) |
18
21
 
19
- > **Three of these are generated, not hand-written**: `workflow.v1`, `postmortem.v1` and `intervention.v1`. The workflow's source of truth is `packages/vinta-ai-maestro/src/types.ts`; regenerate with `pnpm --filter vinta-ai-maestro schema:gen` and verify with `schema:check`. The post-mortem's is `src/postmortem/postmortem.ts` and the intervention's is `src/intervention/intervention.ts`; regenerate either with `pnpm --filter vinta-ai-maestro <postmortem|intervention>:schema:gen`, verify with `:schema:check` — `tests/postmortem.test.ts` and `tests/intervention.test.ts` run those byte comparisons too. Edit the zod schemas, never the JSON.
22
+ > **Four of these are generated, not hand-written**: `workflow.v1`, `postmortem.v1`, `intervention.v1` and `plan-review.v1`. The workflow's source of truth is `packages/vinta-ai-maestro/src/types.ts`; regenerate with `pnpm --filter vinta-ai-maestro schema:gen` and verify with `schema:check`. The post-mortem's is `src/postmortem/postmortem.ts`, the intervention's is `src/intervention/intervention.ts` and the plan review's is `src/review/document.ts`; regenerate any of them with `pnpm --filter vinta-ai-maestro <postmortem|intervention|review>:schema:gen`, verify with `:schema:check` — `tests/postmortem.test.ts`, `tests/intervention.test.ts` and `tests/review.test.ts` run those byte comparisons too. Edit the zod schemas, never the JSON.
20
23
  >
21
24
  > The intervention schema is the odd one: it validates a document a *model* writes rather than one a skill or a person does, and it is the boundary that decides what an unattended run may change about itself. Its verbs are deliberately few and deliberately cannot express a change to what a phase builds — see [`docs/monitor-intervention.md`](../packages/vinta-ai-maestro/docs/monitor-intervention.md).
22
25
 
@@ -75,6 +75,11 @@
75
75
  "note": {
76
76
  "type": "string",
77
77
  "description": "Optional caveat (fallback, variant, when-to-step-up)."
78
+ },
79
+ "fallback": {
80
+ "type": "string",
81
+ "minLength": 1,
82
+ "description": "Model id, same vendor, to run instead once this model is out of quota or credits. Transcribed into a plan's workflow as `defaults.model_fallbacks`; the plan-execution skills apply it when a spawn on this model is refused for quota. A budget decision, not a tier placement: it may point outside this tier."
78
83
  }
79
84
  }
80
85
  }