vinta-ai-workflows 0.7.0-alpha8 → 0.7.0
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.
- package/CHANGELOG.md +472 -595
- package/README.md +33 -19
- package/package.json +4 -1
- package/schemas/README.md +11 -3
- package/schemas/ai-models.v1.schema.json +5 -0
- package/schemas/interview-answers.v1.schema.json +122 -0
- package/schemas/interview-round.v1.schema.json +346 -0
- package/schemas/plan-review.v1.schema.json +342 -0
- package/schemas/postmortem.v1.schema.json +848 -3
- package/schemas/prs-context-comments.v1.schema.json +1 -1
- package/schemas/prs-context-frontmatter.v1.schema.json +18 -7
- package/schemas/vinta-ai-workflows-config.v1.schema.json +677 -18
- package/schemas/workflow.v1.schema.json +751 -26
- package/skills/vinta-analyze-codebase/SKILL.md +5 -0
- package/skills/vinta-bootstrap-ai-tools/SKILL.md +154 -31
- package/skills/vinta-bootstrap-ai-tools/resources/stacks/README.md +1 -1
- package/skills/vinta-bootstrap-ai-tools/resources/stacks/django/notes.md +36 -1
- package/skills/vinta-bootstrap-ai-tools/resources/worktree-command/README.md +85 -0
- package/skills/vinta-bootstrap-ai-tools/resources/worktree-command/lib-template.sh +160 -0
- package/skills/vinta-bootstrap-ai-tools/resources/worktree-command/prepare-template.sh +250 -0
- package/skills/vinta-bootstrap-ai-tools/resources/worktree-command/teardown-template.sh +96 -0
- package/skills/vinta-derive-skills/SKILL.md +23 -15
- package/skills/vinta-derive-skills/resources/dependency-license-block.md +8 -9
- package/skills/vinta-derive-skills/resources/foundation-skills/add-one-off-script/SKILL.md +1 -1
- package/skills/vinta-derive-skills/resources/foundation-skills/create-qa-use-cases/SKILL.md +3 -3
- package/skills/vinta-derive-skills/resources/foundation-skills/create-spec/SKILL.md +21 -2
- package/skills/vinta-derive-skills/resources/foundation-skills/handoff/SKILL.md +3 -3
- package/skills/vinta-derive-skills/resources/foundation-skills/interview-ui/SKILL.md +121 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/interview-ui/resources/examples/docs/D4-concurrency.md +28 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/interview-ui/resources/examples/round-01.json +60 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/open-pr-from-context/SKILL.md +1 -1
- package/skills/vinta-derive-skills/resources/foundation-skills/open-pr-from-context/scripts/open-pr.sh +34 -7
- package/skills/vinta-derive-skills/resources/foundation-skills/plan-feature/SKILL.md +363 -142
- package/skills/vinta-derive-skills/resources/foundation-skills/plan-feature/resources/ai-models.yaml +19 -13
- package/skills/vinta-derive-skills/resources/foundation-skills/prepare-worktree/SKILL.md +39 -21
- package/skills/vinta-derive-skills/resources/foundation-skills/thermo-nuclear-code-quality-review/SKILL.md +8 -6
- package/skills/vinta-derive-skills/resources/foundation-skills/thermo-nuclear-review-loop/SKILL.md +181 -0
- package/skills/vinta-derive-skills/resources/plan-execution/README.md +40 -7
- package/skills/vinta-derive-skills/resources/plan-execution/partials/agent-models.md +14 -35
- package/skills/vinta-derive-skills/resources/plan-execution/partials/commit-strategy/stacked.md +21 -0
- package/skills/vinta-derive-skills/resources/plan-execution/partials/dispatched-agent.md +31 -0
- package/skills/vinta-derive-skills/resources/plan-execution/partials/implementer-prompt.md +67 -6
- package/skills/vinta-derive-skills/resources/plan-execution/partials/maestro-live-run.md +44 -0
- package/skills/vinta-derive-skills/resources/plan-execution/partials/model-pick.md +9 -3
- package/skills/vinta-derive-skills/resources/plan-execution/partials/parallel-lanes.md +95 -50
- package/skills/vinta-derive-skills/resources/plan-execution/partials/pr-context.md +4 -2
- package/skills/vinta-derive-skills/resources/plan-execution/partials/relay-questions.md +13 -0
- package/skills/vinta-derive-skills/resources/plan-execution/partials/review-loop.md +81 -0
- package/skills/vinta-derive-skills/resources/plan-execution/partials/worktree-seam.md +86 -17
- package/skills/vinta-derive-skills/resources/plan-execution/shell/amend-plan-template.md +35 -16
- package/skills/vinta-derive-skills/resources/plan-execution/shell/implement-phase-template.md +12 -1
- package/skills/vinta-derive-skills/resources/plan-execution/shell/implement-plan-template.md +49 -33
- package/skills/vinta-derive-skills/resources/plan-execution/shell/integrate-phase-template.md +2 -1
- package/skills/vinta-derive-skills/resources/plan-execution/shell/review-phase-template.md +19 -27
- package/skills/vinta-derive-skills/resources/prs-context-template.md +5 -4
- package/skills/vinta-derive-skills/resources/systematic-debugging-mcp-tools.md +1 -1
- package/skills/vinta-derive-skills/resources/systematic-debugging-template.md +8 -8
- package/skills/vinta-derive-skills/resources/write-unit-test-packs/stacks/django.md +4 -1
- package/skills/vinta-derive-skills/resources/write-unit-test-template.md +3 -0
- package/skills/vinta-derive-subagents/SKILL.md +25 -9
- package/skills/vinta-install-ai-tools-setup/SKILL.md +29 -2
- package/skills/vinta-migrate-plans-specs/SKILL.md +7 -7
- package/skills/vinta-sync-ai-tools/SKILL.md +19 -2
- package/skills/vinta-update-project-skills/SKILL.md +1 -0
- package/skills/vinta-write-agents-md/SKILL.md +10 -6
- package/skills/vinta-write-agents-md/resources/asking-the-human.md +56 -0
- package/skills/vinta-derive-skills/resources/plan-execution/partials/review-layers.md +0 -101
package/CHANGELOG.md
CHANGED
|
@@ -5,610 +5,489 @@ All notable changes to `vinta-ai-workflows` are documented in this file.
|
|
|
5
5
|
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/);
|
|
6
6
|
the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
## [0.7.0] —
|
|
8
|
+
## [0.7.0] — 2026-11-03
|
|
9
9
|
|
|
10
|
-
<!--
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
<!-- pre-release: 0.7.0-alpha4 on 2026-09-13 -->
|
|
15
|
-
<!-- pre-release: 0.7.0-alpha3 on 2026-09-12 -->
|
|
16
|
-
<!-- pre-release: 0.7.0-alpha2 on 2026-09-12 -->
|
|
17
|
-
<!-- pre-release: 0.7.0-alpha1 on 2026-09-11 -->
|
|
10
|
+
<!-- Graduates the 0.7.0-alpha1 … 0.7.0-alpha39 series (2026-09-11 to
|
|
11
|
+
2026-10-24). This section is the net change since 0.6.1. The
|
|
12
|
+
alpha-by-alpha record is in the GitHub pre-releases and in this file's
|
|
13
|
+
git history before the release commit. -->
|
|
18
14
|
|
|
19
15
|
### Added
|
|
20
16
|
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
A
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
- **
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
17
|
+
- **`vinta-ai-maestro`: a `plan-feature` plan runs itself, phases in parallel,
|
|
18
|
+
with you steering from a terminal or a browser.** A new workspace package,
|
|
19
|
+
`packages/vinta-ai-maestro/`, published as its own npm package under the same
|
|
20
|
+
version number as `vinta-ai-workflows` and run with `npx vinta-ai-maestro`
|
|
21
|
+
(Node ≥ 22). It is not part of the `vinta-ai-workflows` tarball: what reaches
|
|
22
|
+
the skills package is the generated schemas below and the skill changes that
|
|
23
|
+
produce and consume them. [SPEC.md](packages/vinta-ai-maestro/SPEC.md) is the
|
|
24
|
+
authority and the package README is the operator's manual.
|
|
25
|
+
- **A run.** `run <workflow.json>` starts the plan's `.workflow.json` as a
|
|
26
|
+
background job and returns; closing the terminal changes nothing
|
|
27
|
+
(`--foreground` keeps it in the process, for CI). The run works on a plan
|
|
28
|
+
branch, `plan/<workflow-id>/base`, cut from `base_branch`. Each phase gets a
|
|
29
|
+
crew member, a lane — a git worktree with its own copy of the dependency
|
|
30
|
+
dirs, forked `dev` / `test` databases, an isolated compose project, a
|
|
31
|
+
namespace in each shared service, the declared `env_files` and a
|
|
32
|
+
`setup_cmd` — and the `standard-phase` pipeline: implement, gates, review,
|
|
33
|
+
polish chores, verify, integrate (merge, gates on the merged tree, push,
|
|
34
|
+
PR), `after_pr` chores. A phase with one dependency branches from it, one
|
|
35
|
+
with several from an `integ-<id>` merge; each wave merges into
|
|
36
|
+
`plan/<id>/wave-<N>`, and the last wave opens the plan PR, the one PR that
|
|
37
|
+
lands the plan. `run --resume <run-id>` picks a paused, interrupted or
|
|
38
|
+
failed run back up with the policy it was started with. Policy flags:
|
|
39
|
+
`--on-failure retry|ask|stop` (default `retry`: one cold attempt, then a
|
|
40
|
+
question), `--retries`, `--retry-after <15m>` (an unanswered failure
|
|
41
|
+
question answers itself, backing off when attempts fail fast),
|
|
42
|
+
`--agent-answer-after` (how long an agent's own question waits before the
|
|
43
|
+
recommended options are taken), `--permission ask|auto|full|judged`
|
|
44
|
+
(default `auto`), `--harness-profile <name>` (a named binary and
|
|
45
|
+
environment — a second account, say — from
|
|
46
|
+
`~/.config/vinta-ai-maestro/profiles.yaml`), `--system-one <config.json>`,
|
|
47
|
+
`--no-coordinator` and `--coordinator-authority full`.
|
|
48
|
+
- **Harnesses.** claude-code, codex (`codex app-server`, codex-cli ≥ 0.147.0)
|
|
49
|
+
and opencode, behind one adapter contract: spawn, resume, inject a message
|
|
50
|
+
into a running turn, wait for background work, compact. A quota, rate-limit
|
|
51
|
+
or concurrency refusal parks the harness, not the phase, until the reset
|
|
52
|
+
time the vendor stated; `defaults.model_fallbacks` and
|
|
53
|
+
`defaults.harness_fallbacks` move the refused spawn to a fallback instead;
|
|
54
|
+
a provider outage re-runs the phase when the harness answers, charging
|
|
55
|
+
nothing to its attempts; a logged-out CLI asks you to log in. Sessions
|
|
56
|
+
start one at a time per harness, and the ceiling a run discovers is kept
|
|
57
|
+
for the next one.
|
|
58
|
+
- **The crew.** A plan staffs a team, the Crew table `plan-feature` writes:
|
|
59
|
+
one member per agent with a tier, a model and a harness, and every phase
|
|
60
|
+
assigned to one of them. A member keeps its worktree and its session across
|
|
61
|
+
the phases it takes, so what it learned in phase 1 is still there in
|
|
62
|
+
phase 4. A busy member is covered by the cheapest qualified free peer or by
|
|
63
|
+
a spare in its image (`defaults.max_spare_crew`, default 2); a phase is
|
|
64
|
+
never handed below its tier (`defaults.substitution`, default
|
|
65
|
+
`up_one_tier`); a phase its review keeps rejecting moves up a tier
|
|
66
|
+
(`defaults.escalate_after_rejections`, default 3); a merge conflict goes to
|
|
67
|
+
the most senior member who wrote one of its sides.
|
|
68
|
+
- **Gates.** A gate is a shell command, by type (`test`, `lint`, `typecheck`,
|
|
69
|
+
`e2e`, taking the project's `commands.*`) or by a project-wide id
|
|
70
|
+
(`maestro.gates.<id>`), or a judge question put to a System One classifier.
|
|
71
|
+
Phase gates run a `scoped_cmd` (`{changed_files}` / `{touches}`) until the
|
|
72
|
+
review approves; `verify` then runs the full `cmd` on the phase branch, and
|
|
73
|
+
the full suite runs on every merged base and wave (`verify_gates`,
|
|
74
|
+
`base_gates`, `wave_gates`, all full by default). Results are cached per
|
|
75
|
+
gate, command and tree. `fresh_cmd` and `fresh_when` run a gate from a
|
|
76
|
+
fresh test database when the tree moved under it; `cold_cmd` and
|
|
77
|
+
`scope_cache` cover a lane with no test cache; `timeout_s`,
|
|
78
|
+
`queue_timeout_s` and `tuning.allowed_flags` bound and retune a gate.
|
|
79
|
+
Resource pools (`resources`, `scope: run | host`) serialise the heavy ones
|
|
80
|
+
across lanes, and across every maestro run on the machine. Agents run a
|
|
81
|
+
gate with `vinta-ai-maestro gate <id>` and take a pool with
|
|
82
|
+
`vinta-ai-maestro with <resource> -- <cmd>`; on claude-code a `PreToolUse`
|
|
83
|
+
gate guard refuses the bare command, and `--permission judged` asks a
|
|
84
|
+
classifier about each shell call. `codegen` steps regenerate generated
|
|
85
|
+
files rather than merging them, `append_only` files merge as a union,
|
|
86
|
+
`post_merge` runs a formatter over what git merged, and `ci_only` records
|
|
87
|
+
the CI checks deliberately left to CI.
|
|
88
|
+
- **Review and chores.** Once a phase's gates are green, the implementer's
|
|
89
|
+
own session runs the `review` chore, `thermo-nuclear-review-loop`: one
|
|
90
|
+
reviewer sub-agent, each finding verified and fixed or rejected with
|
|
91
|
+
counter-evidence, until the reviewer explicitly approves. A phase's
|
|
92
|
+
decisions — answered questions, operator context, rejected findings — are
|
|
93
|
+
kept and carried into every later prompt, so nothing is asked twice.
|
|
94
|
+
`deslop` and the project's other `after_review` chores run before verify;
|
|
95
|
+
`after_pr` chores (a review canvas, say) run once the PR is open. A chore
|
|
96
|
+
reporting `Status: FAILURE` is recorded as failed. `max_fix_rounds` is
|
|
97
|
+
unset by default, which means no limit; set it to be asked.
|
|
98
|
+
- **Integration.** A conflict goes to a conflict fixer in the integration
|
|
99
|
+
worktree, with a time limit per round and its resolution gated by the union
|
|
100
|
+
of both phases' gates; what a round left is kept under
|
|
101
|
+
`refs/vinta-ai-maestro/` across attempts. A resolution that undoes a
|
|
102
|
+
phase's deletion is flagged. A merge git or a hook refuses goes to you.
|
|
103
|
+
Every phase and integration PR carries a **Landing** section pointing at
|
|
104
|
+
the plan PR; `land <run>` says how a finished run lands and closes the PRs
|
|
105
|
+
whose work is already in the base; `propagate <run> <phase>` carries a late
|
|
106
|
+
fix into every `integ-` and `wave-` branch; `sync-base <run>` brings a moved
|
|
107
|
+
`base_branch` into a live plan.
|
|
108
|
+
- **Steering.** `status`, `logs [-f]`, `logs --failures <gate-log>`, `pause`,
|
|
109
|
+
`stop`, `node context|redirect|pause|resume|abort|retry|fresh|answer`,
|
|
110
|
+
`node interrupt|reassign|step` (take a phase over at its step without
|
|
111
|
+
failing it), `switch-harness`, `fixer interrupt|reassign`, `workflow`,
|
|
112
|
+
`amend` (a live run takes an edited workflow, rebasing the done phases the
|
|
113
|
+
change reaches), `exec <run> <lane|integration> -- <cmd>` (a command with
|
|
114
|
+
the lane's environment, holding the integration worktree while it runs),
|
|
115
|
+
`gate-cache invalidate`, `purge [--lanes --branches]` (never the only copy
|
|
116
|
+
of work), `doctor` (every check a run depends on, from disk and servers to
|
|
117
|
+
env files, compose `-T`, gate scope and the CI jobs no gate covers),
|
|
118
|
+
`validate`, `simulate` and `judge calibrate`. Every acting request takes a
|
|
119
|
+
reason, journalled with what it explains.
|
|
120
|
+
- **The run coordinator.** One agent per run, woken when a phase fails, an
|
|
121
|
+
attempt errors, a phase waits on the integration worktree or a gate crosses
|
|
122
|
+
its cost threshold, at most 24 times a run. It reads the journal and the
|
|
123
|
+
repository and acts through the same API as you: steer, pause, retry,
|
|
124
|
+
answer the questions a timer could answer, amend the live run, run a
|
|
125
|
+
command. It may change how the run executes, never what it builds, and
|
|
126
|
+
never weakens a check. Everything decided without you — by it or by a
|
|
127
|
+
timer — is listed in `status`, the run view, the plan PR and the
|
|
128
|
+
post-mortem.
|
|
129
|
+
- **The browser UI.** `ui` serves every run in the project and hosts none,
|
|
130
|
+
so closing it interrupts nothing. A run view with the plan graph, the
|
|
131
|
+
roster, the integration worktree's record, resource pools, sessions and
|
|
132
|
+
cost, what was decided without you, a notifications inbox and the
|
|
133
|
+
coordinator as a sidebar; a phase view with the transcript rendered the way
|
|
134
|
+
the harnesses render it, the phase's running processes and gates, its
|
|
135
|
+
changes as a diff, its integration timeline, its PR, and steering as a chat
|
|
136
|
+
input; an analytics page while the run goes and the post-mortem as a report
|
|
137
|
+
after; a Logs view over the daemon's own log; a workflow editor that saves
|
|
138
|
+
only what you changed; Pause, Stop, Retry and Resume. Every page fits a
|
|
139
|
+
phone, in light and dark.
|
|
140
|
+
- **The record.** Everything lands under `.vinta-ai-maestro/` (gitignored):
|
|
141
|
+
the run's journal, each phase's transcript with the role that wrote each
|
|
142
|
+
line, gate logs, the daemon's own log (`logs/daemon.ndjson`, identifiers
|
|
143
|
+
only, enforced), and once the run ends a post-mortem (`postmortem.v1`):
|
|
144
|
+
dependencies declared but unused or discovered at gate time, conflicts,
|
|
145
|
+
the critical path, idle capacity, gate costs, failure causes, crew
|
|
146
|
+
substitutions, failed chores and unattended decisions. `plan-feature` reads
|
|
147
|
+
it before planning the next feature in the same repository.
|
|
148
|
+
- **Security.** The daemon binds loopback and every API request carries a
|
|
149
|
+
token. Agents hold a token of their own that reaches only their leases,
|
|
150
|
+
gates and hooks; the coordinator has one of its own; a run's job keeps its
|
|
151
|
+
token in a `0600` file that `ui` never prints. Nothing in the journal or
|
|
152
|
+
the log holds repository contents, and every token is redacted from both.
|
|
153
|
+
The only API key the package ever uses is the one a `--system-one`
|
|
154
|
+
classifier config names; the harnesses run on your logged-in CLIs.
|
|
155
|
+
- **Platforms.** macOS, Linux and Windows, each in CI.
|
|
156
|
+
|
|
157
|
+
- **`vinta-design-system` and `vinta-dag-editor`**, two more workspace
|
|
158
|
+
packages maestro's UI is built on: oklch tokens in three layers, six
|
|
159
|
+
run-status tones (waiting is amber and failure is red, never the same hue),
|
|
160
|
+
shadcn/ui components on Tailwind CSS v4 and a light/dark/system theme; and
|
|
161
|
+
the framework-agnostic Web Component that draws and edits plan DAGs —
|
|
162
|
+
arrowed edges, dependencies drawn by dragging, phase ids on the cards, a
|
|
163
|
+
details strip, keyboard zoom, full screen. They publish on their own cadence
|
|
164
|
+
as dependencies of `vinta-ai-maestro`; nothing in either reaches
|
|
165
|
+
`npx vinta-ai-workflows install`.
|
|
166
|
+
|
|
167
|
+
- **Plan review: a page for a plan before it runs, and a chat with the agent
|
|
168
|
+
that wrote it.** `vinta-ai-maestro review open <workflow.json>` serves the
|
|
169
|
+
plan's graph with every phase's real prompts, the plan's markdown, a phase ×
|
|
170
|
+
gate matrix, the projected schedule and what `validate` reports. You comment
|
|
171
|
+
on the plan, a phase, a prompt or a gate and send the batch; the agent answers
|
|
172
|
+
through `review wait` and `review reply`, edits the plan, and **Approve plan**
|
|
173
|
+
ends the loop. The review is committed beside the plan as
|
|
174
|
+
`ai-plans/<id>.review.json` (`plan-review.v1`, see
|
|
175
|
+
[packages/vinta-ai-maestro/SPEC.md § 19](packages/vinta-ai-maestro/SPEC.md)).
|
|
176
|
+
When maestro is installed, `plan-feature` runs `validate --json` on every
|
|
177
|
+
workflow it writes and asks whether to review on the page, in chat, or later.
|
|
178
|
+
|
|
179
|
+
- **The browser interview.** A decision-heavy interview — `create-spec`'s
|
|
180
|
+
Step 0 first — can run as a full-screen browser form instead of a chat
|
|
181
|
+
exchange: one decision per screen with the context the agent already knows,
|
|
182
|
+
Markdown, Mermaid or HTML explainers, option cards that state each option's
|
|
183
|
+
consequences with the recommended default marked, and a question panel for
|
|
184
|
+
asking the agent. Round-based and file-based, so it works the same under
|
|
185
|
+
every harness: the agent writes
|
|
186
|
+
`.vinta-ai-workflows/interviews/<slug>/rounds/round-NN.json`
|
|
187
|
+
(`interview-round.v1`), blocks on `vinta-ai-maestro interview wait`, and
|
|
188
|
+
resumes when the page submits `answers/round-NN.json`
|
|
189
|
+
(`interview-answers.v1`). The page is maestro's
|
|
190
|
+
(`interview start|wait|status|stop --dir <dir>`,
|
|
191
|
+
[SPEC.md § 20](packages/vinta-ai-maestro/SPEC.md)), rendered with the design
|
|
192
|
+
system; the server binds loopback, carries a token in the printed URL,
|
|
193
|
+
serves documents only from the interview's `docs/` and accepts a round's
|
|
194
|
+
answers once. Opt in with the new `interview-ui` foundation skill (bootstrap
|
|
195
|
+
**Optional foundation skills** question 7, `foundation_skills.interview-ui`
|
|
196
|
+
in the config schema); it ships `SKILL.md` and an example round, and needs
|
|
197
|
+
`vinta-ai-maestro` runnable from the project (`npx --no-install
|
|
198
|
+
vinta-ai-maestro` when it is a devDependency, `npx vinta-ai-maestro`
|
|
199
|
+
otherwise). `create-spec` asks once per interview whether to decide in the
|
|
200
|
+
browser or in chat; projects without the skill see no change.
|
|
201
|
+
|
|
202
|
+
- **`thermo-nuclear-review-loop` foundation skill.** A review-and-fix loop
|
|
203
|
+
over a change: the agent running it spawns one reviewer sub-agent, checks
|
|
204
|
+
each finding against the code, fixes the justified ones and answers the rest,
|
|
205
|
+
until the reviewer explicitly approves under a strict code-quality standard.
|
|
206
|
+
Questions only a person can settle — unreachable scenarios, requirement
|
|
207
|
+
ambiguity, destructive operations — go to them instead of being assumed.
|
|
208
|
+
Always shipped (`foundation_skills.thermo-nuclear-review-loop`), because
|
|
209
|
+
`review-phase` runs it and every maestro workflow names it in its `review`
|
|
210
|
+
chore; also invokable on its own.
|
|
211
|
+
|
|
212
|
+
- **`plan-feature` emits an executable workflow and staffs a crew.**
|
|
213
|
+
`ai-plans/YYYY-MM-DD-<feature-kebab>.workflow.json` lands beside every plan,
|
|
214
|
+
unconditionally — a project with no orchestrator carries a file nothing
|
|
215
|
+
reads, and one that adopts maestro later finds its plans already executable.
|
|
216
|
+
It is the same phase graph in the form a run loads: one node per phase,
|
|
217
|
+
`depends_on` from each phase's `**Depends on**:` line, its Touch List, gates,
|
|
218
|
+
pools and crew member, validated by `workflow.v1`. The plan opens **Phased
|
|
219
|
+
Rollout** with a **Crew** table and an **Execution graph** table, and every
|
|
220
|
+
phase carries `**Assigned to**:` and `**Depends on**:` lines; they replace
|
|
221
|
+
`**Suggested AI model**:`, which old plans may keep. The skill asks what a
|
|
222
|
+
phase lane needs its own copy of and writes the workflow's `project` block,
|
|
223
|
+
emits the codegen steps and append-only files it detects in the project,
|
|
224
|
+
writes the crew's model fallbacks, puts a contract test for any interface two
|
|
225
|
+
parallel phases share into the foundation phase, and reads the post-mortems
|
|
226
|
+
of earlier runs before drawing the next graph.
|
|
227
|
+
|
|
228
|
+
- **`implement-plan` runs independent phases in parallel** on the skills path
|
|
229
|
+
too, with no maestro. The plan carries a dependency graph and the conductor
|
|
230
|
+
schedules against it: a phase starts as soon as every phase it depends on is
|
|
231
|
+
green and a worktree lane is free. A chain-shaped plan behaves exactly as
|
|
232
|
+
before. Lanes are a pool of worktrees, branches base on their dependencies
|
|
233
|
+
(`integ-<id>` for several, `plan/<id>/wave-<N>` per wave), tracking is a
|
|
234
|
+
directory with one file per phase so wave merges never conflict on it, a
|
|
235
|
+
sibling-lane write guard covers the pool, and `modular-commits` keeps its
|
|
236
|
+
atomic units on lane branches. Two new config fields:
|
|
237
|
+
`run_options.implement-plan.parallel_phases` (default `true`) and
|
|
238
|
+
`max_parallel_lanes` (default `3`). The skill refuses rather than degrading
|
|
239
|
+
when parallel execution is asked for and worktrees are unavailable.
|
|
240
|
+
|
|
241
|
+
- **Provision worktrees with your own script instead of the `prepare-worktree`
|
|
242
|
+
skill.** Set `commands.worktree_prepare` (and optionally
|
|
243
|
+
`commands.worktree_teardown`) in `.vinta-ai-workflows.yaml`; `implement-plan`
|
|
244
|
+
and maestro run that command for every lane and the integration worktree,
|
|
245
|
+
with `VINTA_WORKTREE_NAME`, `_PATH`, `_BRANCH`, `_BASE_REF`, `_KIND`,
|
|
246
|
+
`VINTA_MAIN_CHECKOUT`, `VINTA_PLAN_PATH` and `VINTA_WORKTREE_SUMMARY` set,
|
|
247
|
+
and check the result with git rather than trusting the exit code. The
|
|
248
|
+
bootstrap offers existing worktree scripts `vinta-analyze-codebase` found,
|
|
249
|
+
and can write the scripts for you — `prepare.sh`, `teardown.sh` and `lib.sh`
|
|
250
|
+
under `scripts/worktree/`, from templates that carry the contract, dry runs,
|
|
251
|
+
rollback, compose isolation and a teardown that refuses a dirty worktree.
|
|
252
|
+
|
|
253
|
+
- **Agents stop for input with clickable questions instead of prose.** Every
|
|
254
|
+
skill and sub-agent asks through the harness's structured question tool
|
|
255
|
+
(Claude Code's `AskUserQuestion`, OpenCode's `question`, Codex's
|
|
256
|
+
`request_user_input`, Cursor's `AskQuestion`, Copilot's `askQuestions`,
|
|
257
|
+
Gemini CLI's `ask_user`): 2–4 options with descriptions, the recommended one
|
|
258
|
+
first. `AGENTS.md` gains an **Asking the human** section, copied verbatim
|
|
259
|
+
from
|
|
260
|
+
[`vinta-write-agents-md/resources/asking-the-human.md`](skills/vinta-write-agents-md/resources/asking-the-human.md).
|
|
261
|
+
Sub-agents, which cannot ask, return `status: NEEDS_INPUT` with the question
|
|
262
|
+
in the tool's shape, and the new `plan-execution/partials/relay-questions.md`
|
|
263
|
+
turns it into a question, records the answer and continues the same agent.
|
|
264
|
+
Every prose stop point across the plan-execution unit, the foundation skills
|
|
265
|
+
and the bootstrap skills became such a question. `vinta-sync-ai-tools` adds
|
|
266
|
+
a one-time migration for existing projects.
|
|
267
|
+
|
|
268
|
+
- **PR Review Canvas integration (`integrations.pr-review-canvas`).** The
|
|
269
|
+
bootstrap offers [PR Review Canvas](https://github.com/vintasoftware/pr-review-canvas)
|
|
270
|
+
as its first *integration*: an external tool that installs its own skill,
|
|
271
|
+
nothing of which is bundled here. A new optional top-level `integrations`
|
|
272
|
+
object in the config schema records the opt-in (interview group D.2, asked
|
|
273
|
+
when `code_host` is GitHub or GitLab and `pr_creation` is `agents-create`).
|
|
274
|
+
When enabled, `vinta-install-ai-tools-setup` runs `pr-review install-skill`
|
|
275
|
+
(the CLI is never auto-installed; the install command is printed), the
|
|
276
|
+
`integrate-phase` PR step runs `/pr-review-canvas <n>` after `open-pr.sh`
|
|
277
|
+
publishes, and `plan-feature` adds an `after_pr` `review-canvas` chore to the
|
|
278
|
+
workflow it writes. The analysis, derive and update skills treat an
|
|
279
|
+
integration-owned skill as the tool's and never edit it.
|
|
280
|
+
|
|
281
|
+
- **Model fallbacks for models that run out of quota.** `ai-models.yaml`
|
|
282
|
+
entries take `fallback:` (the shipped table sets
|
|
283
|
+
`claude-fable-5-1 → claude-opus-5-5` and `gpt-6-astra → gpt-5.6-sol`),
|
|
284
|
+
`ai-models.v1.schema.json` gains the optional field, the nightly
|
|
285
|
+
`check-ai-models` job checks fallback ids for staleness, `plan-feature`
|
|
286
|
+
writes the map into each workflow's `defaults.model_fallbacks`, and the
|
|
287
|
+
plan-execution skills follow the same rule when maestro is not running them.
|
|
288
|
+
|
|
289
|
+
- **Five generated JSON Schemas, and the schemas are checked.**
|
|
290
|
+
[`workflow.v1`](schemas/workflow.v1.schema.json) (the executable plan),
|
|
291
|
+
[`postmortem.v1`](schemas/postmortem.v1.schema.json),
|
|
292
|
+
[`plan-review.v1`](schemas/plan-review.v1.schema.json),
|
|
293
|
+
[`interview-round.v1`](schemas/interview-round.v1.schema.json) and
|
|
294
|
+
[`interview-answers.v1`](schemas/interview-answers.v1.schema.json) are
|
|
295
|
+
generated from zod sources in `vinta-ai-maestro` and byte-compared in its
|
|
296
|
+
tests; see [`schemas/README.md`](schemas/README.md). `npm run
|
|
297
|
+
validate-schemas` (part of `npm test`) compiles every schema under `schemas/`
|
|
298
|
+
with Ajv in strict Draft 2020-12 mode and checks the fixtures in
|
|
299
|
+
`tests/schema-fixtures/`: `valid/` must pass, `invalid/` must fail.
|
|
300
|
+
|
|
301
|
+
- **Config schema (`vinta-ai-workflows-config.v1`), all additive.** A `maestro`
|
|
302
|
+
section holding what every plan used to repeat — gates by type and by id,
|
|
303
|
+
resources (with `scope`), chores, `defaults` (gates, harness, pipeline,
|
|
304
|
+
`gate_scope`, `verify_gates`, `base_gates`, `wave_gates`,
|
|
305
|
+
`pull_requests: phase | plan`, `max_spare_crew`, `substitution`,
|
|
306
|
+
`escalate_after_rejections`, `model_fallbacks`, `harness_fallbacks`), the
|
|
307
|
+
`project` block (databases, services, `env_files`, `setup_cmd`,
|
|
308
|
+
`prepare_cmd`, `reset_cmd`, `recycle_keep`, `hooks`, `lane_seed`), `codegen`,
|
|
309
|
+
`append_only`, `ci_only` and `post_merge` — which maestro layers each plan
|
|
310
|
+
over (`commands.*`, then `maestro.*`, then the plan, then the run's own
|
|
311
|
+
amendments). Also `integrations`, `foundation_skills.interview-ui`,
|
|
312
|
+
`foundation_skills.thermo-nuclear-review-loop`, `commands.worktree_prepare`
|
|
313
|
+
/ `worktree_teardown`, `commands.worktree_candidates`, `commands.lint_scoped`
|
|
314
|
+
and `run_options.implement-plan.parallel_phases` / `max_parallel_lanes`. The
|
|
315
|
+
bootstrap interview asks for each (maestro defaults are group C.11, with
|
|
316
|
+
follow-ups on `env_files`, the test gate in lanes, a fresh-database form,
|
|
317
|
+
when the full suite runs, CI checks with no gate, and test-tool caches
|
|
318
|
+
missing from `.gitignore`), and `vinta-sync-ai-tools` offers them to
|
|
319
|
+
existing projects. `prs-context-frontmatter.v1` gains an optional `kind`
|
|
320
|
+
(`phase | integration | plan`).
|
|
321
|
+
|
|
322
|
+
### Changed
|
|
323
|
+
|
|
324
|
+
- **`plan-feature`: plans have fewer, longer phases.** The phase size ceiling
|
|
325
|
+
rises from 1500 to 4000 LoC, tests included, and the sub-phase trigger moves
|
|
326
|
+
to that same ceiling; the Step 0 **Phase granularity** default flips to
|
|
327
|
+
bundling closely-related use-cases into one phase, with one use-case per
|
|
328
|
+
phase as the opt-in answer. A phase of a few hundred lines has to justify
|
|
329
|
+
standing alone. A plan drawn before the change is still valid as written.
|
|
330
|
+
The skill also tells the author to read the CI config and give every locally
|
|
331
|
+
runnable CI job a gate (and to record the rest under `ci_only`), treats two
|
|
332
|
+
parallel phases adding migrations to the same app as file overlap, treats a
|
|
333
|
+
rename of a shared symbol as an interface change, names the enum for
|
|
334
|
+
same-named choice fields two phases expose, lists the usual append-only
|
|
335
|
+
registries, tells authors to declare the gitignored files a lane needs under
|
|
336
|
+
`project.env_files`, and states that `gates: []` means *none*. Its AI model
|
|
337
|
+
tiers cite the latest OpenAI, Anthropic and Google releases
|
|
338
|
+
(`claude-sonnet-5-5`, `gpt-6.1-sol`, `gemini-3.1-pro-preview`); tier
|
|
339
|
+
placement is unchanged. Re-derive the skill to pick these up.
|
|
340
|
+
|
|
341
|
+
- **`implement-plan` and its sub-skills follow what maestro learned from real
|
|
342
|
+
runs.** Implementers commit when a gate stays red and report `FAILURE`
|
|
343
|
+
naming the gate; an uncommitted file does not exist as far as the run is
|
|
344
|
+
concerned. They run every command in the foreground, never hand-edit a
|
|
345
|
+
generated file, and list every gate they ran and its result; the conductor
|
|
346
|
+
reviews only a `SUCCESS` report whose gates are all green. Every spawn of a
|
|
347
|
+
phase carries the decisions already made in it, and a resumed implementer
|
|
348
|
+
checks the branch for committed work first. Every merged tree runs the full
|
|
349
|
+
gate, whatever the `full_test_suite` answer is, and the Quick test scope
|
|
350
|
+
means scoped tests until the review approves and the full suite once before
|
|
351
|
+
integration. The merge fixer keeps what a side deleted, stages by name,
|
|
352
|
+
verifies narrowly, and confirms a resolution by scanning the files for
|
|
353
|
+
markers, never by asking git; a merge refused by a hook or by git goes to
|
|
354
|
+
the human. A member moved to its next phase is told first that its objective
|
|
355
|
+
changed; a continuation that fails is retried cold with the full brief; an
|
|
356
|
+
outage or an expired login asks `Wait and retry` / `Switch model` / `Stop
|
|
357
|
+
the run` rather than escalating the tier. Lanes are recycled fully between
|
|
358
|
+
phases, leftovers saved to a `refs/wip/` ref first. A dispatched phase agent
|
|
359
|
+
does the work itself: every composed implementer prompt and a guard at the
|
|
360
|
+
top of each conductor refuse to hand a phase to a sub-agent. The plan PR is
|
|
361
|
+
the one PR that lands the plan, and every phase and integration PR says so.
|
|
362
|
+
Re-derive the skills to pick this up; plans and tracking directories written
|
|
363
|
+
before the change still work.
|
|
364
|
+
|
|
365
|
+
- **`review-phase` runs the thermo-nuclear review loop.** Each phase is
|
|
366
|
+
reviewed by `thermo-nuclear-review-loop`, hosted by the conductor because a
|
|
367
|
+
sub-agent cannot spawn sub-agents of its own: one reviewer one tier above the
|
|
368
|
+
phase's implementer (a Tier 4 phase is reviewed at Tier 4), each round of
|
|
369
|
+
findings handed to the phase's own implementer, which verifies, fixes or
|
|
370
|
+
rejects with counter-evidence and commits the round. A reviewer pass with no
|
|
371
|
+
verdict is continued once and never counts as approval; a finding re-raised
|
|
372
|
+
without new evidence is rejected on the spot; after 3 rejecting passes a
|
|
373
|
+
fresh implementer one tier up takes over; after 20 passes that still return
|
|
374
|
+
blockers the conductor asks whether to continue, stop the phase unapproved,
|
|
375
|
+
**Accept as is** (integrated with its open blockers recorded) or amend the
|
|
376
|
+
plan. After approval the implementer runs `deslop-comments` over the
|
|
377
|
+
comments the phase added.
|
|
378
|
+
|
|
379
|
+
- **`amend-plan` cascades along the dependency graph, and amends a live
|
|
380
|
+
maestro run.** A rewrite touches the amended phase's dependent closure
|
|
381
|
+
instead of "every phase with a higher number", rebases in topological order,
|
|
382
|
+
rebuilds `integ-` bases first, refuses to run while a phase is in flight, and
|
|
383
|
+
gains a `dependency-change` amendment kind. When a maestro run of the plan is
|
|
384
|
+
running, paused, interrupted or failed, the skill asks whether to amend it,
|
|
385
|
+
edits the plan and the run's own workflow copy, commits both on the plan
|
|
386
|
+
branch and applies them with `vinta-ai-maestro amend`; it also carries the
|
|
387
|
+
operator recipes for a live run (`switch-harness`, `node reassign`, `node
|
|
388
|
+
interrupt`, `--harness-profile`, `propagate`, `sync-base`).
|
|
389
|
+
|
|
390
|
+
- **`prepare-worktree`: worktrees get their own copy of the dependency dirs,
|
|
391
|
+
never a symlink.** A symlinked `node_modules` / `vendor/` / `venv/` sent
|
|
392
|
+
writes back into the main checkout and made parallel worktrees race on one
|
|
393
|
+
tree. The skill copies every dependency dir with a copy-on-write clone
|
|
394
|
+
(`cp -ac` on macOS, `cp -a --reflink=auto` on Linux) and reinstalls
|
|
395
|
+
virtualenvs and yarn PnP; `skills.prepare-worktree.deps_strategy` now
|
|
396
|
+
defaults to `copy`. The skill also documents provisioning a pool of lanes for
|
|
397
|
+
one plan with a `reset_cmd` per forked database, and its summary's `|`
|
|
398
|
+
alternatives are closed sets read by machine. **Consumers:** re-sync to pick
|
|
399
|
+
up the new body; worktrees that already exist keep their links until they
|
|
400
|
+
are re-provisioned.
|
|
401
|
+
|
|
402
|
+
- **`create-spec` offers a browser surface for its Step 0 interview** when
|
|
403
|
+
`ai-tools/skills/interview-ui/` exists (see **The browser interview** above).
|
|
404
|
+
The question bank, clarity loop, read-back and exit conditions are
|
|
405
|
+
unchanged.
|
|
406
|
+
|
|
407
|
+
- **`write-unit-test`: time-independent tests and deterministic generated
|
|
408
|
+
output.** Rule 8 requires a frozen clock and an explicit timezone on any test
|
|
409
|
+
touching dates, and host-independent schema or client generation. The Django
|
|
410
|
+
pack and stack notes spell out `freezegun` / `time-machine` with
|
|
411
|
+
`override_settings(TIME_ZONE=...)` and `tzdata`-sourced timezone choices.
|
|
412
|
+
|
|
413
|
+
- **Django stack notes** cover database reuse and testmon in lanes, keeping
|
|
414
|
+
the virtual environment out of a bind-mounted worktree, registries every
|
|
415
|
+
phase appends to, drf-spectacular `ENUM_NAME_OVERRIDES` for new choice
|
|
416
|
+
fields, and the CI-mirroring checks a plan's gates should carry
|
|
417
|
+
(`manage.py check --deploy --fail-level WARNING`, `makemigrations --check`,
|
|
418
|
+
a regenerate-and-diff gate for a schema or client).
|
|
419
|
+
|
|
420
|
+
- **The bootstrap and sync skills.** `vinta-bootstrap-ai-tools` asks the new
|
|
421
|
+
questions listed under **Config schema** above, no longer offers `symlink`
|
|
422
|
+
for dependency dirs, and no longer asks for a reviewer tier; the **Optional
|
|
423
|
+
foundation skills** group grows to eight questions (`interview-ui` is 7,
|
|
424
|
+
`handoff-to-client` moves to 8). `vinta-analyze-codebase` records existing
|
|
425
|
+
worktree scripts and integration-owned skills. `vinta-sync-ai-tools` carries
|
|
426
|
+
the asking-the-human migration, offers the PR Review Canvas integration to
|
|
427
|
+
existing projects as an `opt-in-offer`, and re-renders the plan-execution
|
|
428
|
+
skills together. Every generated skill now carries
|
|
429
|
+
`disable-model-invocation: true`.
|
|
430
|
+
|
|
431
|
+
- **`agent_models.fixer` now sets only the merge-conflict fixer's tier.** The
|
|
432
|
+
phase's own implementer fixes review findings at its own tier, so a project
|
|
215
433
|
that set `fixer` cheap to save money is saving it on fewer rounds.
|
|
216
434
|
|
|
217
|
-
|
|
218
|
-
12. An orchestrator that reuses one agent session across a phase's implement
|
|
219
|
-
and fix turns needs a ceiling on how long that session may grow before the next
|
|
220
|
-
turn starts cold; without one a long phase eventually dies on a context-window
|
|
221
|
-
error that reads as a broken harness. `plan-feature` omits the field — it is a
|
|
222
|
-
safety limit, not something a plan tunes — and its field table says so.
|
|
223
|
-
|
|
224
|
-
- **`plan-feature` asks about the project's databases and emits the workflow's
|
|
225
|
-
`project` block.** The block records what a phase lane must **fork** to be a
|
|
226
|
-
working checkout — the `dev` and `test` databases, and the project's own
|
|
227
|
-
migrate command, which runs once per template database rather than once per
|
|
228
|
-
lane. Without it every lane got a git worktree and nothing else, so two phases
|
|
229
|
-
running concurrently pointed their test gate at the same rows. Asked at
|
|
230
|
-
emission time with one `AskUserQuestion` call ("what does a phase lane need its
|
|
231
|
-
own copy of", "how is that database delivered"); the rest — the migrate
|
|
232
|
-
command, the database names, the env var names — is read out of the project's
|
|
233
|
-
settings and task runner rather than asked.
|
|
234
|
-
|
|
235
|
-
Two rules the skill is explicit about, because both are easy to get wrong:
|
|
236
|
-
**sharing is the absence of a declaration** (there is no `share` value, and a
|
|
237
|
-
lane that reads the main checkout's database has nothing to describe), and
|
|
238
|
-
**each role names its own database** (a lane's fork is named from `name` and
|
|
239
|
-
the lane, not the role, so `dev` and `test` sharing one `name` collapse to one
|
|
240
|
-
forked database). Everything `prepare-worktree` discovers per worktree —
|
|
241
|
-
`reset_cmd`, compose project names, volume forks, seed commands, env-file
|
|
242
|
-
strategy — stays out of the block by design.
|
|
243
|
-
|
|
244
|
-
- **New schema
|
|
245
|
-
[`postmortem.v1.schema.json`](schemas/postmortem.v1.schema.json)** — the
|
|
246
|
-
structured plan post-mortem an orchestrator writes at
|
|
247
|
-
`.vinta-ai-maestro/runs/<run-id>/postmortem.json` once a run has ended: dependencies
|
|
248
|
-
that were declared but never used, dependencies discovered at gate time,
|
|
249
|
-
same-wave phases that actually conflicted, and phases whose real duration
|
|
250
|
-
diverged from their wave placement. `plan-feature` reads it before drawing the
|
|
251
|
-
next feature's Execution graph, which is what stops a plan from repeating a
|
|
252
|
-
defect the last run already paid for. Like
|
|
253
|
-
[`workflow.v1.schema.json`](schemas/workflow.v1.schema.json) it is
|
|
254
|
-
**generated** from a zod source rather than hand-written — see
|
|
255
|
-
[`schemas/README.md`](schemas/README.md).
|
|
435
|
+
### Deprecated
|
|
256
436
|
|
|
257
|
-
|
|
437
|
+
- **`agent_models.reviewer` is ignored.** The review runs one tier above the
|
|
438
|
+
phase's implementer, so no configured tier is read. The key stays in the v1
|
|
439
|
+
config schema so existing configs still validate; drop it at your next edit.
|
|
440
|
+
|
|
441
|
+
- **`skills.prepare-worktree.deps_strategy: symlink`** stays in the schema
|
|
442
|
+
enum so existing configs validate, but is deprecated and read as `copy`.
|
|
443
|
+
Change it to `copy` (or `reinstall`) in `.vinta-ai-workflows.yaml` to stop
|
|
444
|
+
the interview default from being re-emitted.
|
|
258
445
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
"everything finished so far" — a sibling lane's work is not in the phase's base
|
|
274
|
-
branch, and describing it as done made the implementer code against files it could
|
|
275
|
-
not see.
|
|
276
|
-
- **The stray-write guard covers sibling lanes.** The sandbox denies the whole
|
|
277
|
-
worktree pool root and allows back only the running lane; the review-phase backstop
|
|
278
|
-
checks the main checkout and every sibling workroot after each implementer and
|
|
279
|
-
fixer. A write into a lane that is mid-implementation is worse than a stray
|
|
280
|
-
main-checkout write.
|
|
281
|
-
- **`amend-plan` cascades along the dependency graph.** A rewrite touches the
|
|
282
|
-
amended phase's dependent closure instead of "every phase with a higher number",
|
|
283
|
-
rebases in topological order, rebuilds `integ-` bases before rebasing a
|
|
284
|
-
multi-dependency phase onto them, and refuses to run while any phase is still in
|
|
285
|
-
flight. It gained a `dependency-change` amendment kind for edits to a
|
|
286
|
-
`**Depends on**:` line.
|
|
287
|
-
- **`implement-plan` refuses rather than degrading** when parallel execution is asked
|
|
288
|
-
for but worktrees are unavailable — several agents cannot share one working tree,
|
|
289
|
-
and silently falling back to sequential would discard the schedule the user
|
|
290
|
-
approved.
|
|
291
|
-
- **`modular-commits` supports parallel runs**: lanes commit their atomic units on
|
|
292
|
-
`plan/{plan-id}/lane-{phase-id}` branches, merged `--no-ff` into the single plan
|
|
293
|
-
branch at each wave boundary, so the unit commits survive.
|
|
446
|
+
### Removed
|
|
447
|
+
|
|
448
|
+
- **The three-layer phase review.** `review-phase` no longer runs the
|
|
449
|
+
mechanical checks (including the review-time secret scan, dependency-license
|
|
450
|
+
check and co-author trailer check), the plan-compliance walkthrough
|
|
451
|
+
(including the comment-hygiene check), the crew reviewer, or a separate
|
|
452
|
+
fixer per finding; the thermo-nuclear review loop replaces them. The
|
|
453
|
+
implementer's own install-time license check and co-author rules are
|
|
454
|
+
unchanged.
|
|
455
|
+
|
|
456
|
+
- **Reviewers on the plan.** `plan-feature`'s Crew table has no `Role` column
|
|
457
|
+
and no reviewer rows, and phases have no `**Review models**:` line.
|
|
458
|
+
**Migration:** plans written with them still run; `implement-plan` ignores
|
|
459
|
+
them.
|
|
294
460
|
|
|
295
461
|
### Fixed
|
|
296
462
|
|
|
297
|
-
- **`
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
`
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
`
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
operations; the following parts require approval". §11 keeps repository
|
|
326
|
-
*contents* out of the record; a refusal's own explanation is not contents, and
|
|
327
|
-
the `tool_use` row above it already carries the path and the command verbatim.
|
|
328
|
-
Withholding it protected nothing and hid the one fact worth having.
|
|
329
|
-
|
|
330
|
-
- **`serve` opens a run that has already finished.** The API resolved a run from
|
|
331
|
-
the in-memory registry *and* the journal and required both, so a daemon
|
|
332
|
-
started with nothing running listed the operator's history — the list reads
|
|
333
|
-
the journal — and then answered 404 for every run in it, under a message
|
|
334
|
-
saying the daemon was not running. Reads now need only the journal, which is
|
|
335
|
-
where a run's whole record lives and which outlives the daemon by design
|
|
336
|
-
(§5.3). Steering a finished run is still refused, with `409` rather than
|
|
337
|
-
`404`: the run exists, and saying it does not sends the operator hunting for a
|
|
338
|
-
typo instead of reading the status in front of them.
|
|
339
|
-
|
|
340
|
-
- **Four places the UI asked the operator to work around it.** The transcript
|
|
341
|
-
opened at the *oldest* row it held, so a live agent's newest line — the one
|
|
342
|
-
the panel was opened to read — sat below the fold and every arriving entry
|
|
343
|
-
pushed it further down; it now opens at the newest and stays there, but only
|
|
344
|
-
while the operator is already at the bottom, because scrolling up is reading.
|
|
345
|
-
The `git diff` command overflowed its panel, uncopyable without selecting
|
|
346
|
-
blind, and now wraps. The shell's bounded column went from 1280px to 1600px:
|
|
347
|
-
1280 is a reading measure, and the Nodes table's columns are ids, lane names
|
|
348
|
-
and branch names, none of which can be abbreviated without losing what
|
|
349
|
-
identifies them. And the notification interval said "Remind every 5 min"
|
|
350
|
-
without ever saying what it would remind anyone about — it repeats the
|
|
351
|
-
notification for a phase that stopped to ask the operator something, until
|
|
352
|
-
they answer, which is what the options say now.
|
|
353
|
-
|
|
354
|
-
- **A killed terminal releases its directory on Windows.** Two PTY tests failed
|
|
355
|
-
teardown with `EBUSY: rmdir`: killing a process there is not synchronous with
|
|
356
|
-
releasing what it held, so the conpty and its background child are gone as far
|
|
357
|
-
as the test is concerned while the OS still has the working directory open.
|
|
358
|
-
|
|
359
|
-
- **A failed phase can be retried instead of ending the run.** `run` takes
|
|
360
|
-
`--on-failure <stop|ask>`. `stop` is the default and is what every run has
|
|
361
|
-
always done — the phase fails, its dependents block, the run finishes. `ask`
|
|
362
|
-
parks the node on a question instead: retry, retry with another member of the
|
|
363
|
-
crew, or stop.
|
|
364
|
-
|
|
365
|
-
It exists because the failures worth retrying are overwhelmingly
|
|
366
|
-
environmental — a permission wall, a grant nobody made, a gate whose service
|
|
367
|
-
was not up — and the only recovery was to start the whole plan again, running
|
|
368
|
-
every phase that had already succeeded a second time. Only pass `ask` when
|
|
369
|
-
somebody is watching: the run waits, which is exactly why it is not the
|
|
370
|
-
default.
|
|
371
|
-
|
|
372
|
-
The alternatives offered are **members of the crew, not models**. A staffed
|
|
373
|
-
run has no free-floating models in it — a phase is taken by a member, and the
|
|
374
|
-
tier floor that decides who may take it is the assigned member's own — so a
|
|
375
|
-
model is something the plan cannot express and nobody could be found to hold.
|
|
376
|
-
A member below the phase's tier is never offered: an operator answering a
|
|
377
|
-
question is not a reason to hand a phase to somebody the plan judged too
|
|
378
|
-
junior for it.
|
|
379
|
-
|
|
380
|
-
The retry starts **cold**, and everything the node held goes back before it
|
|
381
|
-
waits (§6.1) — an operator at lunch must not be holding a lane another phase
|
|
382
|
-
could use.
|
|
383
|
-
|
|
384
|
-
- **A refusal nobody was asked about is now said out loud.** The adapter knew
|
|
385
|
-
about `permission_request`, a question waiting for an answer, and nothing
|
|
386
|
-
else. The refusal an operator actually hits is not a question: a read outside
|
|
387
|
-
the working directory is decided by the CLI and announced as
|
|
388
|
-
`permission_denied`, with no request to reply to. That frame was dropped at
|
|
389
|
-
the first `switch` — no event, no journal row, no transcript line. The new
|
|
390
|
-
`permission_denied` event carries the decision token (`workingDir`, `mode`)
|
|
391
|
-
and never the vendor's prose, which names the file being read (§11).
|
|
392
|
-
|
|
393
|
-
- **A turn that ended blocked is no longer a turn that succeeded.** The CLI
|
|
394
|
-
says `status_category: "blocked"` one frame before reporting
|
|
395
|
-
`is_error: false`, and both are true from its side: it was asked for
|
|
396
|
-
something it could not do and said so. Taking the second at its word is how a
|
|
397
|
-
phase passed having written no code and then failed two steps later under
|
|
398
|
-
another name. A session that reported an error no longer ends `ok` — which
|
|
399
|
-
also makes a reviewer fail closed, since its verdict is read back out of a
|
|
400
|
-
transcript whose session did not end cleanly.
|
|
401
|
-
|
|
402
|
-
- **An agent still could not write in its own lane.** The entry below passed
|
|
403
|
-
claude-code `--permission-mode auto`, which matched our own vocabulary for
|
|
404
|
-
"works unattended" and is not what the vendor means by the word: `auto` still
|
|
405
|
-
routes a write to a permission prompt, and in `-p` there is nobody to answer
|
|
406
|
-
one. Run against the CLI, a `Write` to the agent's *own working directory*
|
|
407
|
-
comes back denied with no reason attached — the same dead end, wearing the
|
|
408
|
-
word that made it look closed. `acceptEdits` is the mode under which that
|
|
409
|
-
write succeeds, and is what `auto` now maps to. The test covering this
|
|
410
|
-
asserted the word rather than the behaviour, so it pinned the bug in place.
|
|
411
|
-
|
|
412
|
-
- **A phase can read the operator's checkout.** A lane is a worktree cut from a
|
|
413
|
-
branch, so anything uncommitted — a plan written this morning, a spec that
|
|
414
|
-
never leaves the operator's machine — is present where they are and absent
|
|
415
|
-
from every lane. Reaching for it was refused before the model saw a byte, with
|
|
416
|
-
a message that reads like a prompt awaiting an answer ("Claude requested
|
|
417
|
-
permissions to read from …, but you haven't granted it yet") when in fact
|
|
418
|
-
nothing is asking: the CLI denies it outright, emits no permission request,
|
|
419
|
-
and the session then ends *successfully*, having written nothing.
|
|
420
|
-
|
|
421
|
-
The repository root is now granted to every claude-code agent for **reading**.
|
|
422
|
-
Granting a directory also grants writing in it, and the lane sits inside the
|
|
423
|
-
directory being granted, so the grant is paired with a deny list that keeps
|
|
424
|
-
the lane the only writable place under it — the operator's source and every
|
|
425
|
-
sibling lane stay refused. That list names the *siblings* at each level down
|
|
426
|
-
to the lane rather than the root itself, because the vendor resolves deny
|
|
427
|
-
before allow with no carve-out: `deny: <repo>/**` plus `allow: <lane>/**`
|
|
428
|
-
refuses the lane too. Each of those facts was established by running the CLI.
|
|
429
|
-
|
|
430
|
-
**This covers the file-editing tools and not `Bash`.** A shell redirection was
|
|
431
|
-
never confined to the working directory and is not confined now; that boundary
|
|
432
|
-
is the OS's, and the vendor's sandbox that enforces it also switches off the
|
|
433
|
-
network a phase needs to install anything.
|
|
434
|
-
|
|
435
|
-
codex needed nothing: under `--approve-for-me` it already reads anywhere on
|
|
436
|
-
disk, which was confirmed the same way.
|
|
437
|
-
|
|
438
|
-
- **An agent can write in its own lane.** Every adapter declared
|
|
439
|
-
`permissionControl: true` and passed no policy at all: claude-code was spawned
|
|
440
|
-
as `-p --output-format stream-json …` with no `--permission-mode`, and codex as
|
|
441
|
-
`exec --json` with no sandbox and no approval flag, under a comment saying it
|
|
442
|
-
took both on the command line. So a headless run asked before its first write,
|
|
443
|
-
emitted a `permission_request`, rendered it in the transcript — and nothing
|
|
444
|
-
anywhere answered. The phase failed reporting a permission system it could not
|
|
445
|
-
see, having written nothing.
|
|
446
|
-
|
|
447
|
-
`run` and `serve` now take `--permission <ask|auto|full>`, defaulting to
|
|
448
|
-
`auto`. **The operator sets it, never the workflow document**: the document is
|
|
449
|
-
committed and shared, and a file in a repository should not be able to tell
|
|
450
|
-
someone else's machine to run agents without approvals.
|
|
451
|
-
|
|
452
|
-
Both CLIs refuse combinations that looked reasonable, and both were found by
|
|
453
|
-
running them rather than reading them: codex rejects `--sandbox` alongside
|
|
454
|
-
`--approve-for-me`, and `codex exec resume` accepts neither — passing the
|
|
455
|
-
fresh-spawn policy there turned a `stale_session` refusal, which the scheduler
|
|
456
|
-
retries cold, into a `fatal` one that fails the node.
|
|
457
|
-
|
|
458
|
-
This reverses a documented decision. The README said the daemon passed no
|
|
459
|
-
permission flags and that a committed `.claude/settings.json` was what made a
|
|
460
|
-
run able to write; that is now the narrowing layer on top of a mode, not the
|
|
461
|
-
only thing standing between an agent and a blocked lane.
|
|
462
|
-
- **`purge --lanes --branches` clears what a failed run leaves behind.** A run's
|
|
463
|
-
lane worktrees are not under `runs/`, so no purge ever reached them: three
|
|
464
|
-
failed attempts at one plan left twelve worktrees, twelve summaries, and a set
|
|
465
|
-
of `plan/<id>/phase-*` branches still checked out — which is what makes the
|
|
466
|
-
*next* run of that plan impossible, since git refuses to check out a branch a
|
|
467
|
-
second worktree holds.
|
|
468
|
-
|
|
469
|
-
One rule decides both: **never delete the only copy of work.** A phase can
|
|
470
|
-
leave work committed on its branch or uncommitted in its worktree, and both
|
|
471
|
-
count — so a branch carrying commits no other branch has is kept, a lane with
|
|
472
|
-
a dirty tree is kept, and each is listed with the command to remove it by
|
|
473
|
-
hand. Untracked files count as work: a phase that wrote three new modules and
|
|
474
|
-
never committed them is exactly the case worth protecting.
|
|
475
|
-
|
|
476
|
-
Emptiness is measured as "carries no commit another branch does not already
|
|
477
|
-
have", not as "merged into HEAD". The latter is relative to wherever the
|
|
478
|
-
operator is standing, so on a feature branch — the checkout this is most often
|
|
479
|
-
run from — every empty phase branch looked unmerged and nothing was ever
|
|
480
|
-
cleaned up.
|
|
481
|
-
|
|
482
|
-
`--dry-run` and `--yes` work as they already did, and a worktree that will not
|
|
483
|
-
go is named rather than counted.
|
|
484
|
-
|
|
485
|
-
- **`doctor` now catches, before a lane exists, the failures that used to take a
|
|
486
|
-
run each.** Four consecutive runs of one plan failed four different ways, and
|
|
487
|
-
every one of them was knowable at minute zero from the workflow and the repo.
|
|
488
|
-
- **Every `prompt_ref` and `plan_context_ref` is resolved against
|
|
489
|
-
`base_branch`**, with `git cat-file -e`, which reads the branch's tree and
|
|
490
|
-
so cannot be satisfied by a working-tree copy — the working tree being
|
|
491
|
-
exactly what a lane will not have. It distinguishes the three cases, because
|
|
492
|
-
they have three different fixes: never committed, **staged but never
|
|
493
|
-
committed** (`git add` alone does not put a file in a branch), and committed
|
|
494
|
-
on a different branch. The last offers both routes out — merge it, or point
|
|
495
|
-
`base_branch` at the branch that has it — since only the operator knows
|
|
496
|
-
which they want.
|
|
497
|
-
- **Phase branches held by another worktree** are reported with the directory
|
|
498
|
-
to remove. Lane directories are named per run and phase branches per
|
|
499
|
-
workflow, so a failed run leaves worktrees holding the branch names the next
|
|
500
|
-
run will try to cut, and git refuses to check out a branch twice. Nothing
|
|
501
|
-
cleans those up: `purge` deletes run state under `.vinta-ai-maestro/runs/`,
|
|
502
|
-
and lane worktrees are not there. `doctor` does not delete them either — a
|
|
503
|
-
failed lane's worktree is the only place its state survives — but it now
|
|
504
|
-
names each one and the exact command.
|
|
505
|
-
|
|
506
|
-
- **A failed node records why.** `node_status` carried `{"status":"failed"}` and
|
|
507
|
-
nothing else, so two runs failing for two unrelated reasons produced identical
|
|
508
|
-
journal rows and the cause survived only in the operator's terminal. The
|
|
509
|
-
reason is now persisted — **sanitized**, not raw: errors the package builds
|
|
510
|
-
itself are identifiers by construction and are kept verbatim, and anything
|
|
511
|
-
else is reduced to its kind, the rule `recycleStage` already followed. The
|
|
512
|
-
journal is durable and API-served, and an exception message from a dependency
|
|
513
|
-
is exactly how repository content gets into one. Blocked dependents record
|
|
514
|
-
which node blocked them.
|
|
515
|
-
|
|
516
|
-
- **Two diagnostics that named the symptom and hid the cause.** Both came out of
|
|
517
|
-
one real run, and neither was a wrong answer — just an unusable one.
|
|
518
|
-
- **A phase whose plan is not committed** failed with `prompt_ref "…" names no
|
|
519
|
-
readable file`, against a path that was spelled correctly. A lane is a fresh
|
|
520
|
-
worktree of the base branch, so a plan sitting untracked in the operator's
|
|
521
|
-
checkout is in the one place the run cannot look. The message now names the
|
|
522
|
-
directory it resolved against and says why a plan is often not in it.
|
|
523
|
-
- **A lane summary the daemon could not accept** reported `summary unreadable`
|
|
524
|
-
and advised deleting the lane — which takes its forked databases with it,
|
|
525
|
-
over what turned out to be two wrong fields. `doctor` now names the fields
|
|
526
|
-
and what was expected, and offers repair before deletion. A file that does
|
|
527
|
-
not parse at all still reports as unreadable, because there is no field to
|
|
528
|
-
name. Neither message carries the offending *value*: a summary holds
|
|
529
|
-
database names and connection variables, and the value that failed
|
|
530
|
-
validation is the likeliest thing in it to be one.
|
|
531
|
-
|
|
532
|
-
`prepare-worktree` gained the rule that would have prevented the summary in
|
|
533
|
-
the first place — its `|` alternatives are closed sets read by machine, `null`
|
|
534
|
-
is how you say "none", and a strategy outside the set should be the closest
|
|
535
|
-
one plus a `note:` rather than a fourth word.
|
|
536
|
-
|
|
537
|
-
- **`npx vinta-ai-maestro` now runs.** The published package pointed its `bin` at
|
|
538
|
-
`src/cli/bin.ts` and relied on Node stripping the types at startup — which Node
|
|
539
|
-
refuses to do anywhere under `node_modules`, unconditionally and with no flag to
|
|
540
|
-
override. So the CLI worked from a checkout and died on first run once installed,
|
|
541
|
-
with `ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING`.
|
|
542
|
-
|
|
543
|
-
`packages/vinta-ai-maestro` now builds: `tsc` emits `dist/` with
|
|
544
|
-
`rewriteRelativeImportExtensions` (the source imports `.ts` specifiers, which
|
|
545
|
-
emitted JS cannot keep), vite writes the daemon's UI into `dist/ui`, and the
|
|
546
|
-
shebang is rewritten from the source's `--experimental-transform-types` form to
|
|
547
|
-
a plain `#!/usr/bin/env node` — a compiled entry point has no types left to
|
|
548
|
-
transform, and should not ask Node for a flag it is free to retire. `prepack`
|
|
549
|
-
runs the build, so a tarball can never be cut from a stale `dist/`.
|
|
550
|
-
|
|
551
|
-
Three packaging faults surfaced with it, each of which broke an install on its
|
|
552
|
-
own:
|
|
553
|
-
- **The UI was never in the tarball.** `serve` resolves its static root as
|
|
554
|
-
`dist/ui` and refuses to read outside it, so it would have booted and answered
|
|
555
|
-
every page with "build the UI first". The build now asserts `dist/ui/index.html`
|
|
556
|
-
exists rather than trusting a vite config that writes outside its own root.
|
|
557
|
-
- **`tailwindcss` and `tw-animate-css` were imported but never declared.** They
|
|
558
|
-
resolved only through pnpm's `.bin` shim setting `NODE_PATH`; building by any
|
|
559
|
-
other path failed to resolve them. Both are now devDependencies.
|
|
560
|
-
- **Everything the UI imports was a runtime dependency.** React, xterm,
|
|
561
|
-
lucide-react and the three workspace packages are bundled into `dist/ui` by
|
|
562
|
-
vite and cannot be loaded at runtime — yet a consumer installed all of them,
|
|
563
|
-
and two carried `workspace:*` specifiers that no registry understands. Moved to
|
|
564
|
-
devDependencies; the published package now declares six runtime dependencies
|
|
565
|
-
instead of fourteen.
|
|
566
|
-
|
|
567
|
-
CI packs the tarball, installs it into a throwaway project and runs the binary
|
|
568
|
-
from `node_modules`. Every previous check ran from a checkout, which is the one
|
|
569
|
-
place this class of bug cannot appear.
|
|
570
|
-
|
|
571
|
-
- **Lane provisioning serializes `git worktree add`, not only the database
|
|
572
|
-
template.** `prepare-worktree` previously named one serialization point; there
|
|
573
|
-
are two. Git rewrites `.git/worktrees/` metadata on every add, and concurrent
|
|
574
|
-
adds against one repository clobber each other's entries — a reproducible
|
|
575
|
-
corruption, not a theoretical race. Worktrees are added one at a time; the
|
|
576
|
-
expensive per-lane work (dependency linking, database cloning, summary
|
|
577
|
-
writing) still overlaps around it.
|
|
578
|
-
|
|
579
|
-
- **The conflict-fixer round budget is an integration-level setting, not a
|
|
580
|
-
phase's `max_fix_rounds`.** `parallel-lanes.md` now says so, and defaults it to
|
|
581
|
-
two. A merge conflict belongs to a *pair* of phases, so deriving the budget
|
|
582
|
-
from one of them made the answer depend on which phase happened to merge
|
|
583
|
-
second.
|
|
584
|
-
|
|
585
|
-
- **A resolved merge conflict is confirmed by scanning the files, never by asking
|
|
586
|
-
git.** `git add` clears a path's unmerged flag whether or not `<<<<<<<` is
|
|
587
|
-
still sitting in it, so git's index cannot answer "did the fixer actually fix
|
|
588
|
-
it". `parallel-lanes.md` now requires scanning the conflicted paths for
|
|
589
|
-
conflict markers before the merge is committed. Without it, a fixer that did
|
|
590
|
-
nothing produces a merge commit full of markers that passes into the wave
|
|
591
|
-
branch unnoticed.
|
|
592
|
-
|
|
593
|
-
> The repository also gained `packages/vinta-ai-maestro/`, the workspace package
|
|
594
|
-
> that executes these workflows. It is published as its own npm package,
|
|
595
|
-
> `vinta-ai-maestro`, carrying the same version as `vinta-ai-workflows`, and is
|
|
596
|
-
> run with `npx vinta-ai-maestro`. It is not part of the `vinta-ai-workflows`
|
|
597
|
-
> tarball — the root `files` whitelist excludes `packages/`, so nothing in it is
|
|
598
|
-
> installed by `npx vinta-ai-workflows install`. What ships from that work into
|
|
599
|
-
> the skills package is the two generated schemas above and the skill changes
|
|
600
|
-
> that produce and consume them.
|
|
601
|
-
>
|
|
602
|
-
> Its browser UI is now built on `packages/design-system/` (`vinta-design-system`),
|
|
603
|
-
> a second workspace package: oklch tokens in three layers mirroring
|
|
604
|
-
> `vinta-schedule-design-system`, six run-status **tones** (`idle`, `active`,
|
|
605
|
-
> `wait`, `attention`, `ok`, `error` — waiting is amber and failure is red, never
|
|
606
|
-
> the same hue), shadcn/ui components on Tailwind CSS v4, a small layout kit, and
|
|
607
|
-
> a light/dark/system theme. The run graph and the pipeline editor are re-skinned
|
|
608
|
-
> through their own custom properties, so the canvas and the badges beside it
|
|
609
|
-
> share one palette. It and `vinta-dag-editor` publish on their own cadence
|
|
610
|
-
> (`0.1.0`) as dependencies of `vinta-ai-maestro`; nothing in either reaches
|
|
611
|
-
> `npx vinta-ai-workflows install`.
|
|
463
|
+
- **`open-pr.sh` posts inline comments on macOS and reports why a comment
|
|
464
|
+
failed.** Four bugs in the `open-pr-from-context` script, all seen while
|
|
465
|
+
publishing a stacked plan from a Mac: a GNU-only `sed` idiom that BSD `sed`
|
|
466
|
+
rejected, so trailing blank lines were never trimmed; a lowercase
|
|
467
|
+
`side: right` that GitHub answered with "422 Validation Failed", now
|
|
468
|
+
upper-cased; `gh api` and `glab api` stderr thrown away, so a failed comment
|
|
469
|
+
gave no reason; and a multi-line `awk -v` that BSD `awk` rejected when
|
|
470
|
+
adding to a `## Publish log` section. Projects that patched their own copy
|
|
471
|
+
can re-sync with `vinta-sync-ai-tools`.
|
|
472
|
+
|
|
473
|
+
- **`check-ai-models` no longer mistakes sibling models for snapshots of a
|
|
474
|
+
cited id.** The matcher used substrings, so `claude-sonnet-5` matched
|
|
475
|
+
`claude-sonnet-5-5` and hid the newer release, and `gemini-3-pro` matched
|
|
476
|
+
`gemini-3-pro-image` so a retired model still looked available. It accepts
|
|
477
|
+
only exact ids, dated or `-vN` snapshot suffixes, and provider prefixes.
|
|
478
|
+
|
|
479
|
+
- **`implement-plan`'s final report no longer suggests `docker compose down -v`
|
|
480
|
+
to tear down a lane.** `down -v` also deletes the compose volumes a worktree
|
|
481
|
+
deliberately shares with the main checkout. The report prints the sequence
|
|
482
|
+
`prepare-worktree` documents: `docker compose -p <project> down`, then
|
|
483
|
+
`docker volume rm` for each forked volume, then removal of the generated
|
|
484
|
+
compose override.
|
|
485
|
+
|
|
486
|
+
- **`prepare-worktree` serialises `git worktree add`, not only the database
|
|
487
|
+
template.** Git rewrites `.git/worktrees/` metadata on every add, and
|
|
488
|
+
concurrent adds against one repository clobber each other's entries.
|
|
489
|
+
Worktrees are added one at a time; the per-lane work around them still
|
|
490
|
+
overlaps.
|
|
612
491
|
|
|
613
492
|
## [0.6.1] — 2026-08-17
|
|
614
493
|
|
|
@@ -971,7 +850,6 @@ the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
971
850
|
**Consumers**: re-sync to pick up the opt-in questions. E2E-disabled projects
|
|
972
851
|
are unaffected (the e2e regions strip out as before).
|
|
973
852
|
|
|
974
|
-
|
|
975
853
|
<!-- pre-release: 0.2.0-alpha6 on 2026-07-13 -->
|
|
976
854
|
|
|
977
855
|
### Changed
|
|
@@ -1008,7 +886,6 @@ the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
1008
886
|
|
|
1009
887
|
### Added
|
|
1010
888
|
|
|
1011
|
-
|
|
1012
889
|
- **`handoff` foundation skill — session-continuation handoff docs between
|
|
1013
890
|
agents.** Write mode captures the current task (goal, verified-vs-unverified
|
|
1014
891
|
state, decisions + rejected alternatives, landmines, single concrete next
|