vinta-ai-workflows 0.7.0-alpha26 → 0.7.0-alpha28

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 (39) hide show
  1. package/CHANGELOG.md +407 -0
  2. package/README.md +15 -17
  3. package/package.json +1 -1
  4. package/schemas/README.md +4 -3
  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/postmortem.v1.schema.json +337 -2
  10. package/schemas/vinta-ai-workflows-config.v1.schema.json +49 -12
  11. package/schemas/workflow.v1.schema.json +71 -25
  12. package/skills/vinta-bootstrap-ai-tools/SKILL.md +26 -13
  13. package/skills/vinta-derive-skills/SKILL.md +10 -9
  14. package/skills/vinta-derive-skills/resources/dependency-license-block.md +1 -1
  15. package/skills/vinta-derive-skills/resources/foundation-skills/create-spec/SKILL.md +16 -0
  16. package/skills/vinta-derive-skills/resources/foundation-skills/interview-ui/SKILL.md +117 -0
  17. package/skills/vinta-derive-skills/resources/foundation-skills/interview-ui/resources/examples/docs/D4-concurrency.md +28 -0
  18. package/skills/vinta-derive-skills/resources/foundation-skills/interview-ui/resources/examples/round-01.json +60 -0
  19. package/skills/vinta-derive-skills/resources/foundation-skills/interview-ui/resources/index.html +523 -0
  20. package/skills/vinta-derive-skills/resources/foundation-skills/interview-ui/scripts/interview-ui.mjs +416 -0
  21. package/skills/vinta-derive-skills/resources/foundation-skills/plan-feature/SKILL.md +218 -91
  22. package/skills/vinta-derive-skills/resources/foundation-skills/plan-feature/resources/ai-models.yaml +7 -0
  23. package/skills/vinta-derive-skills/resources/foundation-skills/thermo-nuclear-code-quality-review/SKILL.md +8 -6
  24. package/skills/vinta-derive-skills/resources/foundation-skills/thermo-nuclear-review-loop/SKILL.md +181 -0
  25. package/skills/vinta-derive-skills/resources/plan-execution/README.md +2 -2
  26. package/skills/vinta-derive-skills/resources/plan-execution/partials/agent-models.md +13 -34
  27. package/skills/vinta-derive-skills/resources/plan-execution/partials/model-pick.md +2 -0
  28. package/skills/vinta-derive-skills/resources/plan-execution/partials/parallel-lanes.md +7 -15
  29. package/skills/vinta-derive-skills/resources/plan-execution/partials/relay-questions.md +1 -1
  30. package/skills/vinta-derive-skills/resources/plan-execution/partials/review-loop.md +72 -0
  31. package/skills/vinta-derive-skills/resources/plan-execution/partials/worktree-seam.md +3 -3
  32. package/skills/vinta-derive-skills/resources/plan-execution/shell/amend-plan-template.md +7 -7
  33. package/skills/vinta-derive-skills/resources/plan-execution/shell/implement-phase-template.md +6 -0
  34. package/skills/vinta-derive-skills/resources/plan-execution/shell/implement-plan-template.md +11 -11
  35. package/skills/vinta-derive-skills/resources/plan-execution/shell/review-phase-template.md +14 -27
  36. package/skills/vinta-derive-skills/resources/systematic-debugging-template.md +3 -3
  37. package/skills/vinta-derive-subagents/SKILL.md +7 -5
  38. package/schemas/intervention.v1.schema.json +0 -170
  39. package/skills/vinta-derive-skills/resources/plan-execution/partials/review-layers.md +0 -112
package/CHANGELOG.md CHANGED
@@ -30,6 +30,134 @@ the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
30
30
 
31
31
  ### Added
32
32
 
33
+ - **`vinta-ai-maestro`: `createdb_cmd` / `dropdb_cmd` on a Postgres
34
+ `external` database** (`workflow.v1.schema.json`, optional, defaults
35
+ `createdb` / `dropdb`). They replace only the binary name — in the template
36
+ setup, the per-lane clone and the reset — so a project whose Postgres is a
37
+ container with a password the host cannot supply can set
38
+ `docker compose exec -T db createdb`. `-h/-p/-U` from `server_url` still
39
+ follow. Existing workflows are unchanged.
40
+
41
+ - **`vinta-ai-maestro`: a database password prompt no longer hangs `run`.**
42
+ Template, clone and reset commands now run with stdin closed, no controlling
43
+ terminal and a two-minute timeout that ends the whole process tree; a prompt
44
+ becomes a failed run carrying the command's stderr instead of a job stuck at
45
+ `starting`. `doctor` now runs the effective `dropdb_cmd --if-exists` against
46
+ a name that cannot exist and `FAIL`s, naming the missing password, when it
47
+ cannot authenticate — a server that merely answers used to pass.
48
+
49
+ - **New optional foundation skill: `interview-ui`** — run decision-heavy
50
+ interviews as a full-screen browser form instead of a chat exchange. One
51
+ decision per screen with the context the agent already knows, Markdown +
52
+ Mermaid (or HTML) explainers, option cards that state each option's
53
+ consequences, the recommended default marked, and an in-page question panel
54
+ for asking the agent (questions, not decisions — the agent replies in the
55
+ next round). Round-based and file-based, so it works the same under Claude
56
+ Code, Codex, Cursor, and Copilot: the agent writes
57
+ `.vinta-ai-workflows/interviews/<slug>/rounds/round-NN.json`, blocks on
58
+ `interview-ui.mjs wait`, and resumes when the browser submits
59
+ `answers/round-NN.json`. Source:
60
+ [skills/vinta-derive-skills/resources/foundation-skills/interview-ui/](skills/vinta-derive-skills/resources/foundation-skills/interview-ui/)
61
+ — `SKILL.md`, the zero-dependency Node ≥ 18 localhost server + CLI
62
+ [scripts/interview-ui.mjs](skills/vinta-derive-skills/resources/foundation-skills/interview-ui/scripts/interview-ui.mjs)
63
+ (`start` / `wait` / `stop` / `status` / `serve`; binds `127.0.0.1` only,
64
+ serves files only from the interview's `docs/`), the shell
65
+ [resources/index.html](skills/vinta-derive-skills/resources/foundation-skills/interview-ui/resources/index.html),
66
+ and a sample round under `resources/examples/`. Copied verbatim as a whole
67
+ directory (bucket A), opt-in via the bootstrap's **Optional foundation
68
+ skills** question 7.
69
+ - **Two new JSON Schemas**:
70
+ [`schemas/interview-round.v1.schema.json`](schemas/interview-round.v1.schema.json)
71
+ (agent → browser: groups, decisions, options with `consequences` /
72
+ `recommended` / `tags`, inline or file explainers, `replies[]`, `readback`
73
+ rounds) and
74
+ [`schemas/interview-answers.v1.schema.json`](schemas/interview-answers.v1.schema.json)
75
+ (browser → agent: per-decision `answered` / `waived` / `skipped` with
76
+ values, free text and notes, plus `questions[]` for the agent). Inventory
77
+ rows added to `schemas/README.md`.
78
+ - **Config schema field `foundation_skills.interview-ui`** (`enabled` /
79
+ `disabled`). Additive — no schema major bump. Emitted by the bootstrap
80
+ Step 0.5 YAML; existing projects can add it by hand or on the next sync.
81
+ - **Plan review: a page for a plan before it runs, and a chat with the agent
82
+ that wrote it.** Maestro's UI gains a **Plans** section. `vinta-ai-maestro
83
+ review open <workflow.json>` serves it and prints a link straight to the
84
+ plan. The page shows:
85
+ - **Graph.** The phase DAG, coloured by review state. Below it, the selected
86
+ phase's brief, its staffing and pipeline, the implementer and fixer
87
+ prompts, and its chores' prompts (the review loop's among them). These are
88
+ the real cold prompts a run would send, composed by the scheduler's own
89
+ function.
90
+ - **Plan.** The markdown, section by section, with an outline.
91
+ - **Gates.** A phase × gate matrix of the commands a run would execute.
92
+ - **Schedule.** A projected timeline with the critical path marked.
93
+ - **Issues.** What `validate` reports.
94
+
95
+ The reviewer can comment on the plan, a section, a phase, a prompt or a
96
+ gate, or select text and comment on the quote. Comments stay drafts until
97
+ sent to the agent as one batch. The sidebar chat shows whether the agent is
98
+ listening, working or away. The agent answers from its own session through
99
+ two new commands:
100
+ - `review wait` blocks, then prints what the person sent as JSON.
101
+ - `review reply` answers in the chat or on a thread, with `--resolve`.
102
+
103
+ Edits the agent makes to the plan show on the page within seconds.
104
+ **Approve plan** ends the loop. The review is committed beside the plan as
105
+ `ai-plans/<id>.review.json`. A new generated schema,
106
+ `schemas/plan-review.v1.schema.json`, validates it. Maestro's SPEC gains
107
+ §19 to describe it.
108
+ - **`vinta-ai-maestro validate <workflow.json> [--json]`.** It checks a
109
+ workflow the way a run loads it, layered over `.vinta-ai-workflows.yaml`.
110
+ It also checks two things only a run used to find: the filename matches
111
+ the id, and every `plan_ref`, `prompt_ref` and `plan_context_refs` anchor
112
+ names a heading the plan has. Exit `0` means valid and `1` means not.
113
+ `--json` gives an agent one object with each issue's source, path and
114
+ message.
115
+ - **`plan-feature` validates its workflow and runs the review.** When
116
+ `vinta-ai-maestro` is installed (on `PATH`, in `node_modules/.bin`, or
117
+ already cached for `npx --no-install`), the skill runs `validate --json` on
118
+ every workflow it writes. It fixes each issue and runs the check again, and
119
+ runs it again after every edit made during review. It never installs maestro
120
+ itself.
121
+
122
+ Once the files are written, the skill asks how to review: on the review
123
+ page, in chat, or later. On the page it serves the review, posts an
124
+ opening message, and loops on `review wait`. It edits the plan and then the
125
+ workflow for each comment, and answers every thread. The loop ends when the
126
+ plan is approved.
127
+
128
+ - **Model fallbacks for models that run out of quota.** A frontier model sold
129
+ as a small credit allowance used to stall a whole run when its credits ran
130
+ out: the `quota` refusal parked the harness, and every model on it waited
131
+ for a reset that might never come. Now a model can name a fallback, and the
132
+ run switches to it instead of waiting.
133
+ - **`ai-models.yaml` entries take `fallback:`.** The shipped table sets
134
+ `claude-fable-5-1 → claude-opus-5-5` and `gpt-6-astra → gpt-5.6-sol`
135
+ (tier 4). `ai-models.v1.schema.json` gains the optional field, and the
136
+ nightly `check-ai-models` job checks fallback ids for staleness too.
137
+ - **Maestro: `defaults.model_fallbacks`** (model id → fallback id), in a
138
+ plan's workflow or in `.vinta-ai-workflows.yaml` under
139
+ `maestro.defaults`. A `quota` refusal on a listed model retries the
140
+ spawn on its fallback right away and leaves the harness unparked. Later
141
+ spawns of that model on the same harness go straight to the fallback,
142
+ until the reset time the vendor gave, or for the rest of the run if it
143
+ gave none. This also covers a turn cut off mid-way and the monitor and
144
+ conflict-fixer spawns. Chains are followed. If the fallback is refused
145
+ for quota too, the whole account is out: the harness parks as it did
146
+ before. Each substituted spawn is journaled as `node_model_fallback`.
147
+ - **`plan-feature` writes the map** into each plan's workflow from the
148
+ crew's `fallback:` entries. The plan-execution skills (`implement-phase`,
149
+ `review-phase`) follow the same rule when maestro isn't running them.
150
+ - **`thermo-nuclear-review-loop` foundation skill.** A review-and-fix loop
151
+ over a change: the agent running it spawns one reviewer sub-agent, checks
152
+ each finding against the code, fixes the justified ones and answers the
153
+ rest, until the reviewer explicitly approves under a strict code-quality
154
+ standard. Questions only the human can settle (unreachable scenarios,
155
+ requirement ambiguity, destructive operations) go to them instead of being
156
+ assumed. Always shipped and copied verbatim (new
157
+ `foundation_skills.thermo-nuclear-review-loop`), because `review-phase`
158
+ runs it and every maestro workflow `plan-feature` writes names it in its
159
+ `review` chore. Also
160
+ invokable on its own. **Consumers**: re-sync to pick it up.
33
161
  - **Project defaults for maestro in `.vinta-ai-workflows.yaml`.** A new
34
162
  `maestro:` section holds what every plan's `.workflow.json` used to repeat:
35
163
  per-type gate defaults, resource pools, chores, run defaults and the
@@ -383,6 +511,50 @@ the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
383
511
 
384
512
  ### Changed
385
513
 
514
+ - **`create-spec` offers a browser surface for its Step 0 interview.** When
515
+ `ai-tools/skills/interview-ui/` exists, the skill asks once whether to make
516
+ decisions in the browser or in chat. In browser mode the question bank,
517
+ clarity loop, read-back, and exit conditions are unchanged; each question
518
+ becomes a decision with `why`, quoted-back `context`, options with
519
+ consequences, and explainer docs, written one round at a time (A–C first,
520
+ later groups once the journeys are known). Projects without `interview-ui`
521
+ see no change.
522
+ - **Bootstrap `Optional foundation skills` group grows to eight questions**
523
+ (`interview-ui` is question 7; `handoff-to-client` moves to 8).
524
+ - **`review-phase` runs the thermo-nuclear review loop.** On the skills path
525
+ (`implement-plan`, `amend-plan`, `systematic-debugging`), each phase is now
526
+ reviewed by `thermo-nuclear-review-loop`, the loop maestro's `review` chore
527
+ runs. The conductor hosts it, because a sub-agent cannot spawn sub-agents of
528
+ its own. It spawns one reviewer sub-agent one tier above the tier the
529
+ phase's implementer ran at (a Tier 4 phase is reviewed at Tier 4), and hands
530
+ each round of findings to the phase's own implementer. The implementer
531
+ verifies each finding, fixes the justified ones, rejects the rest with
532
+ counter-evidence, and commits the round. Questions only a person can settle
533
+ come to you as structured questions. The phase passes only when the
534
+ reviewer explicitly approves. After 20 passes that still return blockers,
535
+ the conductor asks whether to continue for 20 more, stop the phase
536
+ unapproved, or amend the plan. **Consumers**: re-sync to re-render the
537
+ plan-execution skills.
538
+ - **Maestro: a phase's review is now the `review` chore.** Once the phase's
539
+ gates are green, the implementer's own session runs
540
+ `thermo-nuclear-review-loop`: it spawns one reviewer sub-agent and fixes or
541
+ answers its findings until the reviewer approves. Then `deslop` runs, and
542
+ the gates run once more on the final tree. A red gate still goes to the
543
+ fixer. A review turn that ends unapproved asks the operator to continue or
544
+ stop. `plan-feature` now emits the `review`
545
+ chore and `defaults.chores: ["review", "deslop"]`, and transcribes the
546
+ Crew table's implementers into `crew`.
547
+ - **Maestro: chore `when` is now `review`, `after_review` (the default) or
548
+ `after_pr`.** `review` chores must end with `VERDICT: pass` or
549
+ `VERDICT: fail`, and the phase continues only on pass. `after_review`
550
+ replaces `before_gate`.
551
+ - **Maestro: `max_fix_rounds` has no default, and unset means no limit.** The
552
+ fixer works on a red gate until it is green, and the review loop runs until
553
+ the reviewer approves, without asking. Set `max_fix_rounds` on a node to get
554
+ the old behaviour back: after that many fix rounds or unsuccessful review
555
+ passes, the phase asks whether to continue or stop. **Migration:** a plan
556
+ that relied on the default of 4 now runs unbounded; add
557
+ `"max_fix_rounds": 4` to keep it.
386
558
  - **Maestro: every `workflow_amended` row carries `targets`.** Operator and
387
559
  config amendments get them too, computed from the snapshot and the
388
560
  proposal. Before, only monitor amendments had them.
@@ -491,8 +663,230 @@ the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
491
663
  and never selects text. The host box follows the window's height instead of
492
664
  being fixed at 380px.
493
665
 
666
+ ### Deprecated
667
+
668
+ - **`agent_models.reviewer` is ignored.** The review runs one tier above the
669
+ phase's implementer, so no configured tier is read. The key stays in the v1
670
+ config schema so existing configs still validate; drop it at your next
671
+ edit. Bootstrap no longer asks for it. `agent_models.fixer` now sets only
672
+ the merge-conflict fixer's tier, since the phase's implementer fixes review
673
+ findings at its own tier.
674
+
675
+ ### Removed
676
+
677
+ - **Maestro: the monitor's intervention documents.** The watchdog no longer
678
+ asks the monitor for a JSON proposal of four verbs; the coordinator acts
679
+ through the run's API under the same "how, never what" rule, enforced on
680
+ every amendment it makes. `schemas/intervention.v1.schema.json`, the
681
+ `intervention:schema:*` scripts and `runs/<id>/interventions.jsonl` are
682
+ gone; the post-mortem's `interventions` now point at the coordinator's
683
+ conversation.
684
+ - **The three-layer phase review.** `review-phase` no longer runs the
685
+ mechanical checks (including the review-time secret scan, dependency-license
686
+ check and co-author trailer check), the plan-compliance walkthrough
687
+ (including the comment-hygiene check), the crew reviewer, or a separate
688
+ fixer per finding. The implementer's own install-time license check and
689
+ co-author rules are unchanged.
690
+ - **Reviewers on the plan.** `plan-feature`'s Crew table loses its `Role`
691
+ column and its reviewer rows, and phases lose the optional
692
+ `**Review models**:` line. **Migration:** plans written with reviewer rows,
693
+ a `Role` column or `**Review models**:` lines still run; `implement-plan`
694
+ ignores them.
695
+ - **Maestro: the reviewer role and its review loop.** Crew members are
696
+ implementers only, and the crew `role` field is gone. Also gone:
697
+ `defaults.reviewer_model` (in the workflow file and in the
698
+ `.vinta-ai-workflows.yaml` `maestro.defaults`), the consult step and the
699
+ review ledger. **Migration:** a `.workflow.json` with a crew `role`, a
700
+ reviewer crew member, a `before_gate` chore or `reviewer_model` no longer
701
+ parses. Re-emit it with `plan-feature`, or edit it by hand: drop the
702
+ reviewer members and every `role`, rename `before_gate` to `after_review`,
703
+ delete `reviewer_model`, and add the `review` chore.
704
+
705
+ ### Added
706
+
707
+ - **Maestro: `land` and `propagate`.** `land <run-id>` says how a finished
708
+ run lands — the plan PR, with a merge commit, and nothing else — lists every
709
+ phase and integration PR with its state, and marks the ones whose work is
710
+ already in the base (every commit they add is a merge of commits the base
711
+ has, such as a GitHub "Update branch"); `--close` closes those with a
712
+ comment. `propagate <run-id> <phase>` carries a fix made on a phase branch
713
+ after the run into every `integ-*` and `wave-*` branch that contains it,
714
+ keeping the wave chain, and stops at a conflict with the branch untouched.
715
+ - **Maestro: `defaults.substitution`** (`same_tier` | `up_one_tier` | `any`,
716
+ additive, default `up_one_tier`). A busy member's phase may go at most to
717
+ the next tier the roster has, and a warm session no longer moves a phase up
718
+ a tier unless `any`. **Behavior change:** runs that relied on warm-session
719
+ promotion to a higher tier now stay at the planned tier; set `any` to keep
720
+ it. Substitutions above plan are shown in `status`, the run view and the
721
+ post-mortem.
722
+ - **Maestro: post-mortem findings** `failure_causes`, `crew_substitutions`,
723
+ `operations` and `cross_phase_failures`, and `wave_conflicts[].where`
724
+ (additive). `plan-feature` reads them.
725
+ - **Maestro: the run coordinator.** The run's monitor becomes its
726
+ coordinator: one agent per run that is woken when a phase fails, an attempt
727
+ errors, maestro logs an error about itself, a phase waits 20 minutes for
728
+ the integration worktree, or a phase or gate crosses its cost threshold, and
729
+ that can act: steer, redirect, pause, abort or retry a phase, answer a
730
+ question a `--retry-after` timer could answer, amend the live run, and run
731
+ commands in a lane or the integration worktree. It reaches the run with a
732
+ token of its own, everything it does is journalled as its own, and the run
733
+ refuses what it may not do: change what the plan builds, weaken a check
734
+ (drop a gate or chore, rewrite a gate command beyond its
735
+ `tuning.allowed_flags`, edit a judge gate, change `hooks`, lower
736
+ `wave_gates`), answer a question the operator holds, or halt the run. Woken
737
+ at most 24 times per run; `--no-coordinator` turns the wakes off
738
+ (`--no-intervene` still works).
739
+ - **Maestro: `node`, `workflow`, `amend` and `exec` commands.** Steer one
740
+ phase (`context`, `redirect`, `pause`, `abort`, `retry`, `answer`), print or
741
+ amend a live run's workflow, and run a command in a lane or the integration
742
+ worktree with that worktree's environment — its database, compose project
743
+ and ports — from a terminal. `exec … integration` holds the integration
744
+ worktree while the command runs, so no merge or unattended retry checks a
745
+ branch out underneath a manual repair.
746
+ - **Maestro: `defaults.wave_gates`** (`off` | `final` | `every`, additive,
747
+ default `final`). The phases' gates now run in full on the merged tree:
748
+ every gate of the plan on the last wave before the plan PR opens, and a
749
+ wave's gates on any wave whose merge needed a conflict resolution; `every`
750
+ checks every wave. Merged waves were never tested under `gate_scope: full`,
751
+ and two parallel phases that each passed their gates disagreed on a signal's
752
+ keyword arguments, failing 22 tests that only showed up after the plan PR.
753
+ `plan-feature` now puts a contract test for any interface two parallel
754
+ phases share into the foundation phase.
755
+ - **Maestro: pausing a phase parked on a question holds it.** Under
756
+ `--retry-after` the unattended timer no longer answers a question the
757
+ operator paused; a person's answer releases it, and `status` and the node
758
+ view say "paused by operator". The pause used to be recorded as `ignored`
759
+ while the timer fired anyway. Node operations now answer with the delivery
760
+ they recorded, so `POST …/pause` on a node with nothing to pause reports
761
+ `"delivery": "ignored"` instead of a bare `ok`.
762
+ - **Maestro: `nodes[].deferred`** (additive). A phase carrying it — the
763
+ soak-gated flag removal `plan-feature` now emits it on — is not dispatched
764
+ when its dependencies merge; it parks on a question naming the reason, and
765
+ the operator answers `start` or `stop`. The scheduler used to run such a
766
+ phase immediately.
767
+ - **Maestro: `node_wait` and the "waiting for the integration worktree"
768
+ state.** A phase queued behind the integration worktree journals who holds
769
+ it; `status` and the node view show it. It used to read `running` with no
770
+ agent process, which looked like a frozen run.
771
+ - **Maestro: `interrupted` run status.** A signal to the job now kills every
772
+ live agent turn and gate, the fix round in progress and any merge standing
773
+ in the integration worktree, and ends the run `interrupted` (resumable)
774
+ instead of `failed` with orphaned agents still editing the worktree. The
775
+ daemon's close is bounded so an open browser socket cannot hang shutdown.
776
+ - **Maestro: `doctor` warns about `docker compose run`/`exec` without `-T`**
777
+ in gates and the `project` block, and `plan-feature` says so.
778
+
494
779
  ### Fixed
495
780
 
781
+ - **Maestro: PRs say how the plan lands.** Every phase and integration PR is
782
+ marked as a review unit that lands through the plan PR, and the plan PR says
783
+ to merge it alone; it used to offer two landing paths, and a 36-PR landing
784
+ resolved the same conflicts several times by hand. A phase PR also names the
785
+ sibling phases its base leaves out, so a CI failure in their area is not
786
+ read as its own.
787
+ - **Maestro: the post-mortem reports what happened.** Conflicts are read from
788
+ the journal, base merges included, so a run that restarted no longer
789
+ reports none; amendments and operator operations, failure causes, crew
790
+ substitutions and cross-phase failures on merged waves are recorded.
791
+ - **Maestro: a finished run stops its compose stacks** (volumes kept) and
792
+ prints how to remove its lanes and volumes; `status` and `doctor` list what
793
+ runs that are over left running or on disk. One run left twenty containers,
794
+ five worktrees and a job process up a day and a half after it was done.
795
+ - **Maestro: wave branches are built across a restart.** Wave completion was
796
+ counted in memory, so a run that restarted with some phases of a wave merged
797
+ before and the rest after never built that wave, and the next wave failed on
798
+ `git checkout` (exit 128) on every retry. A phase the journal calls `done`
799
+ now counts as arrived; a wave the run never built is built before the wave
800
+ on top of it, and a wave that completes before the one under it waits for
801
+ it (`wave_deferred`) instead of failing. A missing wave is named
802
+ ("wave 5 was never built") rather than left to git. New `wave_built` event.
803
+ - **Maestro: a phase that moved lanes can check out its branch.** The branch
804
+ is released from the sibling worktree that still had it (detached at its
805
+ commit, tree untouched) before the new lane takes it. Git's "already used
806
+ by worktree" refusal failed one phase 39 attempts in a row.
807
+ - **Maestro: a conflict-fixer round has a time limit** (20 minutes by
808
+ default) and is told to verify only the files it touched; one round spent
809
+ hours re-running a suite that could not reach its database while three
810
+ phases queued behind it.
811
+ - **Maestro: recreated lanes read the amended `env_files`.** The pool takes
812
+ the amended `project` block, so a single-use lane re-provisioned mid-run no
813
+ longer loses files declared after the run started. A compose-delivered
814
+ database whose service is in `compose.publish` also gets
815
+ `<connection_url_var>_HOST`, the same URL on the published host port.
816
+ - **Maestro: a merge commit git refuses no longer leaves the integration
817
+ worktree mid-merge.** A pre-commit hook failing in the integration worktree
818
+ left `MERGE_HEAD` behind, and every phase whose base was built there then
819
+ failed in its own setup on `git checkout exited 1` — four phases, up to
820
+ twenty-three attempts each, in one run. The integrator now keeps the
821
+ resolution as a commit under `refs/vinta-ai-maestro/resolutions/<node>`,
822
+ abandons the merge, and asks the phase whose merge it is: `commit`,
823
+ `commit --no-verify`, or `abort merge` (the unattended answer under
824
+ `--retry-after`). A retry reuses the kept resolution. Before any checkout,
825
+ the integrator refuses a worktree that is mid-merge, mid-rebase or
826
+ mid-cherry-pick *by name* (`integration worktree is mid-merge: a merge of
827
+ plan/x/phase-b into plan/x/integ-c …`). A conflict fixer that could not run
828
+ abandons the merge it was handed.
829
+ - **Maestro: `GitCommandError` carries git's stderr.** The redacted, bounded
830
+ tail of what git said is in the error, in `node.attempt_failed`, in the
831
+ journal's `node_error` and so in the UI — `git commit exited 1: …No module
832
+ named 'settings.local'` instead of `git commit exited 1`. The integrator's
833
+ own errors (`UnresolvedConflictError` among them) keep their messages too
834
+ instead of being reported as their class name.
835
+ - **Maestro: a setup failure that repeats is not retried unattended.** A phase
836
+ that fails before any agent ran, twice in a row on the same line, is parked
837
+ on its question without `--retry-after`'s self-answer, and the question
838
+ says why.
839
+ - **Maestro: `project.env_files` reaches adopted lanes.** A resume gives each
840
+ lane the declared files it lacks and never overwrites one it has, so
841
+ amending the list reaches lanes that already exist. `doctor` fails a
842
+ declared file missing from the checkout and warns, by name, when a
843
+ gitignored file has a tracked example (`.env.example`,
844
+ `settings/local.py.example`) and nothing declares it.
845
+ - **Maestro: a phase with no gates is no longer a silent pass.** `validate`
846
+ refuses a node that resolves to an empty `gates` list and `doctor` warns
847
+ naming the phases, unless the plan sets `defaults.allow_ungated_phases:
848
+ true` (new, additive). Twelve phases had finished without a check because
849
+ every node carried `gates: []` where its author meant "the project's".
850
+ - **Maestro: a refused conflict-fixer spawn is backpressure.** A plan limit or
851
+ quota refusal while spawning the fixer parks the phase on the harness's
852
+ wait (`waiting_on_capacity`) instead of failing it and retrying on a timer.
853
+ - **Maestro: `createdb` / `dropdb` reach the server `server_url` names.** The
854
+ template and lane commands pass `-h`, `-p` and `-U` from the URL; they used
855
+ the local socket, which is not a Docker-published server. The password stays
856
+ off the command line (`PGPASSWORD` or `~/.pgpass`).
857
+ - **Maestro: `vinta-ai-maestro` resolves from inside every lane.** The daemon
858
+ writes a launcher for itself into `.vinta-ai-maestro/bin/` and puts it first
859
+ on the agents' `PATH`, so `with` and `gate` work when maestro is a project
860
+ devDependency reached through `node_modules/.bin` or `npx`.
861
+ - **Maestro: agents are told a compose-delivered database is unreachable from
862
+ the host.** The implementer prompt names the connection variables that
863
+ resolve only inside the lane's compose network and says to run the suite
864
+ through the project's commands or the gate verb.
865
+ - **Maestro: an editor save writes a patch even when the stored file does not
866
+ validate.** A cross-reference error in the committed file (a chore the
867
+ project no longer declares) made the save write the whole resolved document
868
+ — a hundred-line diff for a one-field edit. The shape is now enough to diff
869
+ against.
870
+ - **Maestro: `purge <run-id>` forgets the run in `flow.db` too.** The UI went
871
+ on listing, and offering to resume, a run whose directory was gone.
872
+ - **Maestro: the monitor thinks with the model the run declares now.** It was
873
+ built once at job start; an amendment to the crew's models reached it only
874
+ after a pause and resume.
875
+ - **Maestro: `run` says where the run's state lives.** The store is the
876
+ checkout's, so a `ui` started in another checkout of the same repository
877
+ (the main one, while the run is in a worktree) lists other runs; the output
878
+ now names the store and the `--repo` to pass.
879
+ - **plan-feature: `project.env_files` and the gate/chore inheritance rules.**
880
+ The skill told authors env-file copying did not belong in the `project`
881
+ block, which left every lane without `.env`; it now tells them to find the
882
+ gitignored files the project's hooks, gates and settings need (`*.example`
883
+ siblings, compose `env_file:` lines, the settings module) and to declare
884
+ them — once, in `.vinta-ai-workflows.yaml` under `maestro.project.env_files`,
885
+ or in the workflow. It also states plainly that `gates: []` and
886
+ `defaults.chores: []` mean *none* rather than "the project's", that an
887
+ override of a project gate must carry `type`, and that `vinta-ai-maestro
888
+ validate` must exit 0 before the plan is handed over. `vinta-bootstrap-ai-tools`
889
+ asks about `env_files` when it writes the `maestro:` section.
496
890
  - **Maestro: wave merges again use the membership the executor counted.**
497
891
  `RecordingIntegrator.mergeWave` dropped it, so in production a merge fell
498
892
  back to the integrator's own reading of the wave. That reading could differ
@@ -2312,6 +2706,19 @@ the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
2312
2706
  nothing produces a merge commit full of markers that passes into the wave
2313
2707
  branch unnoticed.
2314
2708
 
2709
+ ### Security
2710
+
2711
+ - **Maestro: lane agents hold a token of their own.** A run's agents used to
2712
+ reach its API with the operator's token (`VINTA_AI_MAESTRO_TOKEN`), so an
2713
+ agent could steer, abort, amend, `exec` in, pause or stop its own run, or
2714
+ save a workflow from the editor, as the operator. They now get an agent
2715
+ token that reaches only their own leases (`with`), `gate`, and the
2716
+ permission-judge and gate-guard hooks; every other route answers
2717
+ `403 agent_forbidden`. It does not open the WebSocket (and so no PTY
2718
+ takeover), `ui` never forwards it to a run's job, and it is redacted from
2719
+ the logs like the other tokens. Nothing to migrate: lanes are handed the new
2720
+ token when a run starts or resumes.
2721
+
2315
2722
  > The repository also gained `packages/vinta-ai-maestro/`, the workspace package
2316
2723
  > that executes these workflows. It is published as its own npm package,
2317
2724
  > `vinta-ai-maestro`, carrying the same version as `vinta-ai-workflows`, and is
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-alpha26",
3
+ "version": "0.7.0-alpha28",
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
@@ -11,14 +11,15 @@ JSON Schema (Draft 2020-12) contracts for every YAML or JSON payload the vinta-a
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) |
17
- | 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) |
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` |
18
20
 
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.
21
+ > **Three of these are generated, not hand-written**: `workflow.v1`, `postmortem.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` and the plan review's is `src/review/document.ts`; regenerate either with `pnpm --filter vinta-ai-maestro <postmortem|review>:schema:gen`, verify with `:schema:check` — `tests/postmortem.test.ts` and `tests/review.test.ts` run those byte comparisons too. Edit the zod schemas, never the JSON.
20
22
  >
21
- > 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
23
 
23
24
  ## Versioning rules
24
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
  }