vinta-ai-workflows 0.6.1 → 0.7.0-alpha2
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 +288 -0
- package/README.md +21 -13
- package/package.json +2 -1
- package/schemas/README.md +5 -1
- package/schemas/postmortem.v1.schema.json +339 -0
- package/schemas/vinta-ai-workflows-config.v1.schema.json +13 -1
- package/schemas/workflow.v1.schema.json +833 -0
- package/skills/vinta-bootstrap-ai-tools/SKILL.md +9 -1
- package/skills/vinta-derive-skills/SKILL.md +6 -2
- package/skills/vinta-derive-skills/resources/foundation-skills/plan-feature/SKILL.md +622 -32
- package/skills/vinta-derive-skills/resources/foundation-skills/prepare-worktree/SKILL.md +24 -2
- package/skills/vinta-derive-skills/resources/plan-execution/README.md +21 -4
- package/skills/vinta-derive-skills/resources/plan-execution/partials/agent-models.md +30 -3
- package/skills/vinta-derive-skills/resources/plan-execution/partials/commit-strategy/modular.md +27 -14
- package/skills/vinta-derive-skills/resources/plan-execution/partials/commit-strategy/stacked.md +12 -18
- package/skills/vinta-derive-skills/resources/plan-execution/partials/implementer-prompt.md +19 -9
- package/skills/vinta-derive-skills/resources/plan-execution/partials/model-pick.md +25 -9
- package/skills/vinta-derive-skills/resources/plan-execution/partials/parallel-lanes.md +240 -0
- package/skills/vinta-derive-skills/resources/plan-execution/partials/review-layers.md +56 -5
- package/skills/vinta-derive-skills/resources/plan-execution/partials/worktree-seam.md +13 -6
- package/skills/vinta-derive-skills/resources/plan-execution/shell/amend-plan-template.md +17 -12
- package/skills/vinta-derive-skills/resources/plan-execution/shell/implement-phase-template.md +5 -3
- package/skills/vinta-derive-skills/resources/plan-execution/shell/implement-plan-template.md +94 -57
- 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 +16 -5
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,294 @@ 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] — YYYY-MM-DD
|
|
9
|
+
|
|
10
|
+
<!-- pre-release: 0.7.0-alpha2 on 2026-09-12 -->
|
|
11
|
+
<!-- pre-release: 0.7.0-alpha1 on 2026-09-11 -->
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **A plan staffs a team, instead of picking a model per phase.** Choosing a tier
|
|
16
|
+
phase by phase answers "what runs this one" ten times and never adds it up, so the
|
|
17
|
+
two questions that decide what a feature costs go unasked: how many agents does
|
|
18
|
+
this need at once, and is any of them too junior for what it was handed.
|
|
19
|
+
- `plan-feature` opens **Phased Rollout** with a **Crew** table — one row per
|
|
20
|
+
agent, carrying its tier and the phases it takes — and every phase carries an
|
|
21
|
+
**`**Assigned to**:`** line naming one of them. It replaces
|
|
22
|
+
`**Suggested AI model**:`; a plan that still has the old line keeps working, and
|
|
23
|
+
the executor reads the tier straight off it.
|
|
24
|
+
- The **Execution graph** table gains an **Agent** column and an **Idle** note.
|
|
25
|
+
Reading across a row says who is working that wave; reading down a column says
|
|
26
|
+
who is not. A wave that will serialize because the roster cannot staff it is now
|
|
27
|
+
stated in the plan rather than discovered as a slow run.
|
|
28
|
+
- **Every member has to earn their place**, by concurrency (a wave genuinely needs
|
|
29
|
+
that many hands *at or above* those phases' tiers) or by cheapness (they take
|
|
30
|
+
work a dearer member would otherwise do). The roster is therefore **not** capped
|
|
31
|
+
at the widest wave — a junior who runs the migration and the flag deletion is
|
|
32
|
+
worth having in a graph that never runs two phases at once — but the lane pool
|
|
33
|
+
still is, because lanes are bought with concurrency and crew are not.
|
|
34
|
+
- **Reviewers are a role on the crew, and implementers and reviewers are
|
|
35
|
+
disjoint.** A member has `role: implementer` or `role: reviewer`; a phase cannot
|
|
36
|
+
be assigned to a reviewer and a reviewer never writes code, so an agent reading
|
|
37
|
+
its own diff is not something a plan can express. A phase is read by the
|
|
38
|
+
cheapest reviewer at or above its tier. A roster with no reviewer still runs and
|
|
39
|
+
falls back to `agent_models.reviewer`, cold, one session per phase.
|
|
40
|
+
- **A reviewer reads the lane it is reviewing**, with the phase's changes still
|
|
41
|
+
uncommitted in it, and has no worktree of its own. That is what puts review
|
|
42
|
+
before the commit: a finding is fixed in the working tree rather than
|
|
43
|
+
recorded as a mistake on the branch plus a correction after it. The cost is
|
|
44
|
+
that a reviewer's directory follows the work, so its session carries only
|
|
45
|
+
between reviews that land in the same lane.
|
|
46
|
+
- **A crew member is an agent that lives for the whole run.** Each one keeps its
|
|
47
|
+
own worktree and its own session across every phase it takes, so the agent that
|
|
48
|
+
takes Phase 4 still knows what it learned about the codebase in Phase 1 —
|
|
49
|
+
which is most of what a cold agent's first turn of a phase is spent
|
|
50
|
+
rediscovering.
|
|
51
|
+
- This works because the *directory* stops moving. Lanes used to be anonymous
|
|
52
|
+
slots handed out by a free list, so a member landed somewhere different each
|
|
53
|
+
phase and its context described paths it was not standing in. Pinning each
|
|
54
|
+
member to one worktree leaves a far smaller question — which files changed —
|
|
55
|
+
and `git diff --name-only` answers it exactly.
|
|
56
|
+
- A cross-phase continuation therefore gets the new phase's **full brief** (it
|
|
57
|
+
is new work, not a delta) behind a re-orientation: same agent, same directory,
|
|
58
|
+
everything you learned still holds; the tree is on a different branch; these
|
|
59
|
+
files differ; and — the sentence that matters most — whether the previous
|
|
60
|
+
phase's own work is in this tree at all.
|
|
61
|
+
- A delta that cannot be computed is reported as **unknown**, never as empty.
|
|
62
|
+
"Nothing changed" is the one wording that would stop an agent re-reading.
|
|
63
|
+
- Two things still start cold: a member whose previous phase **failed**, because
|
|
64
|
+
its session is the context that failed with it, and the final fix round.
|
|
65
|
+
- The cost, stated plainly: **one worktree and one set of forked databases per
|
|
66
|
+
implementer**, so `resources.lane.capacity` is now the implementer count
|
|
67
|
+
rather than the widest wave, and adding a cheaper implementer is a trade of
|
|
68
|
+
disk against money rather than free.
|
|
69
|
+
- The workflow document gained a top-level **`crew`** block and **`nodes[].crew`**.
|
|
70
|
+
A staffed node carries no `model` — the member has one — and a document that is
|
|
71
|
+
half-staffed, names a member nobody declared, assigns a phase to a reviewer,
|
|
72
|
+
declares an implementer nobody is assigned to, or staffs a reviewer below every
|
|
73
|
+
phase on the plan is refused before the run starts.
|
|
74
|
+
- `vinta-ai-maestro` claims an agent **before** the lane, prefers the member the plan
|
|
75
|
+
named, covers with the **cheapest** qualified free peer when they are busy, and
|
|
76
|
+
**waits rather than handing a phase below its tier** — even with a lane free. A
|
|
77
|
+
lane is disk; a phase run by too junior an agent does not fail cleanly, it fails
|
|
78
|
+
review two rounds later with nothing pointing back at the staffing. A reviewer is
|
|
79
|
+
claimed per review turn rather than per phase — it has one session ledger and
|
|
80
|
+
two concurrent reviews would collide over it — so one reviewer on a three-lane
|
|
81
|
+
plan is a queue at the review step and not a serialised run.
|
|
82
|
+
- The run view reports who actually worked against who the plan said would.
|
|
83
|
+
`substituted` is the figure to read beside a cost that overran: every
|
|
84
|
+
substitution ran at or above the budgeted tier, so a run can be entirely green
|
|
85
|
+
and still have been staffed dearer than planned.
|
|
86
|
+
|
|
87
|
+
- **`implement-plan` runs independent phases in parallel.** The plan now carries a
|
|
88
|
+
dependency graph and the conductor schedules against it: a phase starts as soon as
|
|
89
|
+
every phase it depends on is green and a worktree lane is free, instead of waiting
|
|
90
|
+
for its turn in plan order. A chain-shaped plan behaves exactly as before —
|
|
91
|
+
sequential execution is the one-lane case of the same scheduler.
|
|
92
|
+
- `plan-feature` gives every phase a **`**Depends on**:`** line naming the artifact
|
|
93
|
+
it needs from each upstream phase, and opens **Phased Rollout** with an
|
|
94
|
+
**Execution graph** table derived from those lines. It also checks same-wave
|
|
95
|
+
phases against the **Touch List** for file overlap and tells you to add an edge
|
|
96
|
+
when two phases would fight over the same file.
|
|
97
|
+
- New shared partial `plan-execution/partials/parallel-lanes.md` carries the graph
|
|
98
|
+
parse, the worktree lane pool, the dependency-derived branch topology, the
|
|
99
|
+
dispatch loop, the tracking-directory schema, and the sibling-lane write guard.
|
|
100
|
+
- `prepare-worktree` documents provisioning a **pool** of lanes for one plan and
|
|
101
|
+
records a `reset_cmd` per forked DB so a lane can be reused across phases without
|
|
102
|
+
carrying the previous phase's migrations into the next one's test run.
|
|
103
|
+
- Two new config fields: `run_options.implement-plan.parallel_phases` (default
|
|
104
|
+
`true`) and `run_options.implement-plan.max_parallel_lanes` (default `3`), asked
|
|
105
|
+
at bootstrap alongside the existing `prepare-worktree` follow-ups.
|
|
106
|
+
|
|
107
|
+
- **`plan-feature` emits an executable `ai-plans/<feature-kebab>.workflow.json`
|
|
108
|
+
beside every plan.** The markdown stays the document humans review; the JSON is
|
|
109
|
+
the same phase graph in the form an orchestrator runs — one node per phase, one
|
|
110
|
+
`depends_on` entry per `**Depends on**:` clause carrying both the upstream phase
|
|
111
|
+
and the artifact it provides, plus the phase's Touch List, gates, capacity pools
|
|
112
|
+
and model tier. Validated by
|
|
113
|
+
[`schemas/workflow.v1.schema.json`](schemas/workflow.v1.schema.json), which the
|
|
114
|
+
emitted file references from its `$schema` key so editors validate it as it is
|
|
115
|
+
written. **Unconditional** — no config field, no bootstrap question, no opt-in:
|
|
116
|
+
a project with no orchestrator carries a file nothing reads, and a project that
|
|
117
|
+
adopts one later finds its plans already executable.
|
|
118
|
+
|
|
119
|
+
- **Review findings go back to the phase's own implementer, not to a fresh fixer.**
|
|
120
|
+
The agent that wrote the code still holds the phase brief, the plan's bounds, the
|
|
121
|
+
dependency context and its own reasoning; a fresh fixer held a quoted finding and
|
|
122
|
+
had to rediscover the rest — slower, dearer, and likelier to "fix" a symptom by
|
|
123
|
+
undoing something the phase chose deliberately. The fix message is now a delta —
|
|
124
|
+
the findings, nothing else — because re-sending the brief invites a
|
|
125
|
+
re-implementation rather than a fix.
|
|
126
|
+
|
|
127
|
+
Three rules keep that from costing what it buys. **The reviewer is never the
|
|
128
|
+
implementer**: continuing the reviewer across rounds is fine, but the review must
|
|
129
|
+
come from an agent that did not write the code. **The last round before giving up
|
|
130
|
+
goes to a fresh fixer, always** — reuse means the agent that wrote the bug is
|
|
131
|
+
fixing it, which is usually the point and occasionally exactly wrong, because that
|
|
132
|
+
assumption *was* the bug. And where a runtime cannot continue a finished
|
|
133
|
+
sub-agent, the old cold hand-off still happens and is recorded as one, so a slow
|
|
134
|
+
phase can be read later without guessing.
|
|
135
|
+
|
|
136
|
+
One consequence worth knowing: a continued implementer fixes at its own crew
|
|
137
|
+
member's tier, so `agent_models.fixer` now governs only the cold cases. A project
|
|
138
|
+
that set `fixer` cheap to save money is saving it on fewer rounds.
|
|
139
|
+
|
|
140
|
+
- **The workflow schema gained `defaults.max_session_turns`.** Optional, default
|
|
141
|
+
12. An orchestrator that reuses one agent session across a phase's implement
|
|
142
|
+
and fix turns needs a ceiling on how long that session may grow before the next
|
|
143
|
+
turn starts cold; without one a long phase eventually dies on a context-window
|
|
144
|
+
error that reads as a broken harness. `plan-feature` omits the field — it is a
|
|
145
|
+
safety limit, not something a plan tunes — and its field table says so.
|
|
146
|
+
|
|
147
|
+
- **`plan-feature` asks about the project's databases and emits the workflow's
|
|
148
|
+
`project` block.** The block records what a phase lane must **fork** to be a
|
|
149
|
+
working checkout — the `dev` and `test` databases, and the project's own
|
|
150
|
+
migrate command, which runs once per template database rather than once per
|
|
151
|
+
lane. Without it every lane got a git worktree and nothing else, so two phases
|
|
152
|
+
running concurrently pointed their test gate at the same rows. Asked at
|
|
153
|
+
emission time with one `AskUserQuestion` call ("what does a phase lane need its
|
|
154
|
+
own copy of", "how is that database delivered"); the rest — the migrate
|
|
155
|
+
command, the database names, the env var names — is read out of the project's
|
|
156
|
+
settings and task runner rather than asked.
|
|
157
|
+
|
|
158
|
+
Two rules the skill is explicit about, because both are easy to get wrong:
|
|
159
|
+
**sharing is the absence of a declaration** (there is no `share` value, and a
|
|
160
|
+
lane that reads the main checkout's database has nothing to describe), and
|
|
161
|
+
**each role names its own database** (a lane's fork is named from `name` and
|
|
162
|
+
the lane, not the role, so `dev` and `test` sharing one `name` collapse to one
|
|
163
|
+
forked database). Everything `prepare-worktree` discovers per worktree —
|
|
164
|
+
`reset_cmd`, compose project names, volume forks, seed commands, env-file
|
|
165
|
+
strategy — stays out of the block by design.
|
|
166
|
+
|
|
167
|
+
- **New schema
|
|
168
|
+
[`postmortem.v1.schema.json`](schemas/postmortem.v1.schema.json)** — the
|
|
169
|
+
structured plan post-mortem an orchestrator writes at
|
|
170
|
+
`.vinta-ai-maestro/runs/<run-id>/postmortem.json` once a run has ended: dependencies
|
|
171
|
+
that were declared but never used, dependencies discovered at gate time,
|
|
172
|
+
same-wave phases that actually conflicted, and phases whose real duration
|
|
173
|
+
diverged from their wave placement. `plan-feature` reads it before drawing the
|
|
174
|
+
next feature's Execution graph, which is what stops a plan from repeating a
|
|
175
|
+
defect the last run already paid for. Like
|
|
176
|
+
[`workflow.v1.schema.json`](schemas/workflow.v1.schema.json) it is
|
|
177
|
+
**generated** from a zod source rather than hand-written — see
|
|
178
|
+
[`schemas/README.md`](schemas/README.md).
|
|
179
|
+
|
|
180
|
+
### Changed
|
|
181
|
+
|
|
182
|
+
- **Phase branches base on their dependencies, not on the previous phase.** A phase
|
|
183
|
+
with no dependencies cuts from the default branch; one with a single dependency
|
|
184
|
+
cuts from that phase's branch; one with several cuts from a
|
|
185
|
+
`plan/{plan-id}/integ-{phase-id}` branch that merges them. Each wave is then merged
|
|
186
|
+
into a `plan/{plan-id}/wave-{N}` integration branch, which is what a resume anchors
|
|
187
|
+
on and what the final report points at. The PR `base` follows the same value —
|
|
188
|
+
a stacked plan produces exactly the stack it did before.
|
|
189
|
+
- **Tracking is a directory, not a file.** `{{PLAN_DIR}}/TRACKING_{plan-id}/` holds
|
|
190
|
+
`run.md` (conductor-owned), one `phase-{id}.md` per phase (written only by the lane
|
|
191
|
+
that ran it, committed on that phase's own branch), and `waves/wave-{N}.md`. No two
|
|
192
|
+
branches write the same path, so wave merges no longer conflict on tracking. A run
|
|
193
|
+
started under the old single-file layout is migrated on resume.
|
|
194
|
+
- **An implementer is told about its dependencies only.** Prior-phase context passed
|
|
195
|
+
into a phase prompt is now that phase's transitive dependency closure rather than
|
|
196
|
+
"everything finished so far" — a sibling lane's work is not in the phase's base
|
|
197
|
+
branch, and describing it as done made the implementer code against files it could
|
|
198
|
+
not see.
|
|
199
|
+
- **The stray-write guard covers sibling lanes.** The sandbox denies the whole
|
|
200
|
+
worktree pool root and allows back only the running lane; the review-phase backstop
|
|
201
|
+
checks the main checkout and every sibling workroot after each implementer and
|
|
202
|
+
fixer. A write into a lane that is mid-implementation is worse than a stray
|
|
203
|
+
main-checkout write.
|
|
204
|
+
- **`amend-plan` cascades along the dependency graph.** A rewrite touches the
|
|
205
|
+
amended phase's dependent closure instead of "every phase with a higher number",
|
|
206
|
+
rebases in topological order, rebuilds `integ-` bases before rebasing a
|
|
207
|
+
multi-dependency phase onto them, and refuses to run while any phase is still in
|
|
208
|
+
flight. It gained a `dependency-change` amendment kind for edits to a
|
|
209
|
+
`**Depends on**:` line.
|
|
210
|
+
- **`implement-plan` refuses rather than degrading** when parallel execution is asked
|
|
211
|
+
for but worktrees are unavailable — several agents cannot share one working tree,
|
|
212
|
+
and silently falling back to sequential would discard the schedule the user
|
|
213
|
+
approved.
|
|
214
|
+
- **`modular-commits` supports parallel runs**: lanes commit their atomic units on
|
|
215
|
+
`plan/{plan-id}/lane-{phase-id}` branches, merged `--no-ff` into the single plan
|
|
216
|
+
branch at each wave boundary, so the unit commits survive.
|
|
217
|
+
|
|
218
|
+
### Fixed
|
|
219
|
+
|
|
220
|
+
- **`npx vinta-ai-maestro` now runs.** The published package pointed its `bin` at
|
|
221
|
+
`src/cli/bin.ts` and relied on Node stripping the types at startup — which Node
|
|
222
|
+
refuses to do anywhere under `node_modules`, unconditionally and with no flag to
|
|
223
|
+
override. So the CLI worked from a checkout and died on first run once installed,
|
|
224
|
+
with `ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING`.
|
|
225
|
+
|
|
226
|
+
`packages/vinta-ai-maestro` now builds: `tsc` emits `dist/` with
|
|
227
|
+
`rewriteRelativeImportExtensions` (the source imports `.ts` specifiers, which
|
|
228
|
+
emitted JS cannot keep), vite writes the daemon's UI into `dist/ui`, and the
|
|
229
|
+
shebang is rewritten from the source's `--experimental-transform-types` form to
|
|
230
|
+
a plain `#!/usr/bin/env node` — a compiled entry point has no types left to
|
|
231
|
+
transform, and should not ask Node for a flag it is free to retire. `prepack`
|
|
232
|
+
runs the build, so a tarball can never be cut from a stale `dist/`.
|
|
233
|
+
|
|
234
|
+
Three packaging faults surfaced with it, each of which broke an install on its
|
|
235
|
+
own:
|
|
236
|
+
- **The UI was never in the tarball.** `serve` resolves its static root as
|
|
237
|
+
`dist/ui` and refuses to read outside it, so it would have booted and answered
|
|
238
|
+
every page with "build the UI first". The build now asserts `dist/ui/index.html`
|
|
239
|
+
exists rather than trusting a vite config that writes outside its own root.
|
|
240
|
+
- **`tailwindcss` and `tw-animate-css` were imported but never declared.** They
|
|
241
|
+
resolved only through pnpm's `.bin` shim setting `NODE_PATH`; building by any
|
|
242
|
+
other path failed to resolve them. Both are now devDependencies.
|
|
243
|
+
- **Everything the UI imports was a runtime dependency.** React, xterm,
|
|
244
|
+
lucide-react and the three workspace packages are bundled into `dist/ui` by
|
|
245
|
+
vite and cannot be loaded at runtime — yet a consumer installed all of them,
|
|
246
|
+
and two carried `workspace:*` specifiers that no registry understands. Moved to
|
|
247
|
+
devDependencies; the published package now declares six runtime dependencies
|
|
248
|
+
instead of fourteen.
|
|
249
|
+
|
|
250
|
+
CI packs the tarball, installs it into a throwaway project and runs the binary
|
|
251
|
+
from `node_modules`. Every previous check ran from a checkout, which is the one
|
|
252
|
+
place this class of bug cannot appear.
|
|
253
|
+
|
|
254
|
+
- **Lane provisioning serializes `git worktree add`, not only the database
|
|
255
|
+
template.** `prepare-worktree` previously named one serialization point; there
|
|
256
|
+
are two. Git rewrites `.git/worktrees/` metadata on every add, and concurrent
|
|
257
|
+
adds against one repository clobber each other's entries — a reproducible
|
|
258
|
+
corruption, not a theoretical race. Worktrees are added one at a time; the
|
|
259
|
+
expensive per-lane work (dependency linking, database cloning, summary
|
|
260
|
+
writing) still overlaps around it.
|
|
261
|
+
|
|
262
|
+
- **The conflict-fixer round budget is an integration-level setting, not a
|
|
263
|
+
phase's `max_fix_rounds`.** `parallel-lanes.md` now says so, and defaults it to
|
|
264
|
+
two. A merge conflict belongs to a *pair* of phases, so deriving the budget
|
|
265
|
+
from one of them made the answer depend on which phase happened to merge
|
|
266
|
+
second.
|
|
267
|
+
|
|
268
|
+
- **A resolved merge conflict is confirmed by scanning the files, never by asking
|
|
269
|
+
git.** `git add` clears a path's unmerged flag whether or not `<<<<<<<` is
|
|
270
|
+
still sitting in it, so git's index cannot answer "did the fixer actually fix
|
|
271
|
+
it". `parallel-lanes.md` now requires scanning the conflicted paths for
|
|
272
|
+
conflict markers before the merge is committed. Without it, a fixer that did
|
|
273
|
+
nothing produces a merge commit full of markers that passes into the wave
|
|
274
|
+
branch unnoticed.
|
|
275
|
+
|
|
276
|
+
> The repository also gained `packages/vinta-ai-maestro/`, the workspace package
|
|
277
|
+
> that executes these workflows. It is published as its own npm package,
|
|
278
|
+
> `vinta-ai-maestro`, carrying the same version as `vinta-ai-workflows`, and is
|
|
279
|
+
> run with `npx vinta-ai-maestro`. It is not part of the `vinta-ai-workflows`
|
|
280
|
+
> tarball — the root `files` whitelist excludes `packages/`, so nothing in it is
|
|
281
|
+
> installed by `npx vinta-ai-workflows install`. What ships from that work into
|
|
282
|
+
> the skills package is the two generated schemas above and the skill changes
|
|
283
|
+
> that produce and consume them.
|
|
284
|
+
>
|
|
285
|
+
> Its browser UI is now built on `packages/design-system/` (`vinta-design-system`),
|
|
286
|
+
> a second workspace package: oklch tokens in three layers mirroring
|
|
287
|
+
> `vinta-schedule-design-system`, six run-status **tones** (`idle`, `active`,
|
|
288
|
+
> `wait`, `attention`, `ok`, `error` — waiting is amber and failure is red, never
|
|
289
|
+
> the same hue), shadcn/ui components on Tailwind CSS v4, a small layout kit, and
|
|
290
|
+
> a light/dark/system theme. The run graph and the pipeline editor are re-skinned
|
|
291
|
+
> through their own custom properties, so the canvas and the badges beside it
|
|
292
|
+
> share one palette. It and `vinta-dag-editor` publish on their own cadence
|
|
293
|
+
> (`0.1.0`) as dependencies of `vinta-ai-maestro`; nothing in either reaches
|
|
294
|
+
> `npx vinta-ai-workflows install`.
|
|
295
|
+
|
|
8
296
|
## [0.6.1] — 2026-08-17
|
|
9
297
|
|
|
10
298
|
### Fixed
|
package/README.md
CHANGED
|
@@ -48,9 +48,9 @@ After bootstrap, the project ships with **three foundation skills** that take a
|
|
|
48
48
|
└─────────────────┘ Phased Rollout, Touch List, Risks)
|
|
49
49
|
│
|
|
50
50
|
▼
|
|
51
|
-
┌─────────────────┐ one
|
|
52
|
-
│ implement-plan │───►
|
|
53
|
-
└─────────────────┘
|
|
51
|
+
┌─────────────────┐ one branch per phase (independent phases run in
|
|
52
|
+
│ implement-plan │───► parallel lanes) + a tracking dir
|
|
53
|
+
└─────────────────┘ plan/<feature>/phase-1, phase-2, wave-1, ...
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
You also get: an `AGENTS.md` tuned to the codebase — a regular file at the repo root, with per-vendor aliases (`CLAUDE.md`, `.github/copilot-instructions.md`) symlinked to it — project-specific sub-agents and skills derived from the actual stack, and per-vendor wiring so Claude Code / Codex / Cursor / Copilot all see the same artifacts.
|
|
@@ -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** — each phase declares: `id`, `title`, `goal`, `
|
|
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).
|
|
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.
|
|
@@ -105,28 +105,34 @@ Phases are sized so the slowest path (e.g. cross-repo producer wiring, external
|
|
|
105
105
|
- **Layer 3 — independent reviewer**: spawn a fresh `reviewer` agent with no implementation context. Findings triaged BLOCKER / SHOULD-FIX / NIT.
|
|
106
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.
|
|
107
107
|
|
|
108
|
-
**Branch model — one branch per phase,
|
|
108
|
+
**Branch model — one branch per phase, based on that phase's dependencies:**
|
|
109
|
+
|
|
110
|
+
Every phase in the plan declares what it needs (`**Depends on**: Phase 1 (the `BookmarkFolder` model), …`). That line — not the phase's number — decides both when it runs and what it branches from.
|
|
109
111
|
|
|
110
112
|
```bash
|
|
111
|
-
#
|
|
113
|
+
# A phase with no dependencies — branches from the default branch.
|
|
112
114
|
git checkout main && git pull --ff-only
|
|
113
115
|
git checkout -b plan/<feature-kebab>/phase-1
|
|
114
|
-
# implementer's commits land here
|
|
115
116
|
git push -u origin plan/<feature-kebab>/phase-1
|
|
116
117
|
|
|
117
|
-
#
|
|
118
|
+
# A phase depending on exactly one phase — branches from it.
|
|
118
119
|
git checkout plan/<feature-kebab>/phase-1
|
|
119
120
|
git checkout -b plan/<feature-kebab>/phase-2
|
|
120
121
|
git push -u origin plan/<feature-kebab>/phase-2
|
|
121
122
|
|
|
122
|
-
#
|
|
123
|
+
# A phase depending on several — branches from a merge of them.
|
|
124
|
+
git checkout -B plan/<feature-kebab>/integ-4 plan/<feature-kebab>/phase-2
|
|
125
|
+
git merge --no-ff plan/<feature-kebab>/phase-3
|
|
126
|
+
git checkout -b plan/<feature-kebab>/phase-4
|
|
123
127
|
```
|
|
124
128
|
|
|
125
|
-
Each phase's PR (or branch, depending on the project's PR policy captured at bootstrap) targets
|
|
129
|
+
Each phase's PR (or branch, depending on the project's PR policy captured at bootstrap) targets its own base, not `main`. This keeps the diff per PR scoped to a single phase, makes review manageable, and lets the team merge as approvals land. A plan whose phases form a chain produces exactly the classic stack; a plan with independent phases produces several short stacks, reunited by per-wave integration branches (`plan/<feature-kebab>/wave-<N>`).
|
|
130
|
+
|
|
131
|
+
**Parallel phases.** Because the plan carries a dependency graph, `implement-plan` implements independent phases **at the same time** — one worktree lane per phase in flight, each with its own dev + test database and compose stack, so concurrent test runs don't collide. A phase starts the moment every phase it depends on is green and a lane frees up; a failed phase blocks only its dependents while the rest of the plan keeps going. On by default (`run_options.implement-plan.parallel_phases`, capped by `max_parallel_lanes`, default 3), it requires `prepare-worktree` and refuses to run rather than silently falling back to sequential when worktrees aren't available. A chain-shaped plan runs one phase at a time — same scheduler, one lane.
|
|
126
132
|
|
|
127
133
|
**Alternative: modular commits.** Teams that prefer one branch + one PR per plan can set `policies.commit_strategy: modular-commits` in `.vinta-ai-workflows.yaml`. Under that mode, every phase pushes its **atomic unit commits** (one per service, use-case wire-up, init export, serializer field, refactor, or bug fix — tests in the same commit as code) to a single `plan/<feature-kebab>` branch; the PR opens once after Phase 1 review and gets updated as later phases push. The third option, `commit_strategy: ask`, prompts `implement-plan` at Step 0 (alongside the existing `pause_between_phases` / `generate_inline_comments` opt-ins) and caches the answer in the tracking file. Default is `stacked-branches` — the model documented above. See [`schemas/vinta-ai-workflows-config.v1.schema.json`](schemas/vinta-ai-workflows-config.v1.schema.json) for the field definition.
|
|
128
134
|
|
|
129
|
-
**Tracking
|
|
135
|
+
**Tracking directory** — `ai-plans/TRACKING_<feature-kebab>/`. The orchestrator writes it from `git diff` + the agent's report (not the agent's narration): `run.md` for run options, the resolved dependency graph, and the lane pool; one `phase-<id>.md` per phase (status, model used, branch, base, wave, e2e+screenshots when applicable, 5–15 line summary); `waves/wave-<N>.md` for each integration merge. It is a directory rather than one file so concurrent lanes never write the same path — each phase's entry is committed on that phase's own branch, which keeps wave merges clean. Acts as the durable context handoff between phase prompts, scoped per phase to its own dependencies. Deleted on plan completion.
|
|
130
136
|
|
|
131
137
|
**Phases the orchestrator never auto-executes:**
|
|
132
138
|
|
|
@@ -218,7 +224,7 @@ The 0.2.0 alpha line adds five foundation skills and restructures plan execution
|
|
|
218
224
|
|
|
219
225
|
- **`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.
|
|
220
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").
|
|
221
|
-
- **`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 decides per ignored path whether to symlink, copy, or fork (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.
|
|
227
|
+
- **`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 decides per ignored path whether to symlink, copy, or fork (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.
|
|
222
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.
|
|
223
229
|
- **`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`).
|
|
224
230
|
|
|
@@ -246,7 +252,7 @@ Land at `ai-tools/skills/<name>/SKILL.md`. Always-on unless flagged optional.
|
|
|
246
252
|
| `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. |
|
|
247
253
|
| `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). |
|
|
248
254
|
| [`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. |
|
|
249
|
-
| [`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 decides per ignored path whether to **symlink / copy / fork** (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. |
|
|
255
|
+
| [`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 decides per ignored path whether to **symlink / copy / fork** (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. |
|
|
250
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. |
|
|
251
257
|
| `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). |
|
|
252
258
|
|
|
@@ -572,6 +578,8 @@ vinta-ai-workflows/
|
|
|
572
578
|
|
|
573
579
|
`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.
|
|
574
580
|
|
|
581
|
+
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.
|
|
582
|
+
|
|
575
583
|
### Why the `vinta-` prefix?
|
|
576
584
|
|
|
577
585
|
Once installed, these skills sit alongside the user's own project skills in the same `.<vendor>/skills/` directory. The prefix makes ownership obvious in slash menus and on disk: anything under `vinta-*` is managed by this package and gets removed by `uninstall`; anything else belongs to the project.
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vinta-ai-workflows",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0-alpha2",
|
|
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
|
+
"packageManager": "pnpm@10.33.0",
|
|
6
7
|
"bin": {
|
|
7
8
|
"vinta-ai-workflows": "./vinta-ai-workflows.mjs"
|
|
8
9
|
},
|
package/schemas/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Schemas
|
|
2
2
|
|
|
3
|
-
JSON Schema (Draft 2020-12) contracts for every YAML
|
|
3
|
+
JSON Schema (Draft 2020-12) contracts for every YAML or JSON payload the vinta-ai-workflows toolchain produces or consumes. Every payload carries a `schema_version` integer at its top level; that integer matches the suffix on the schema filename.
|
|
4
4
|
|
|
5
5
|
## Inventory
|
|
6
6
|
|
|
@@ -12,6 +12,10 @@ JSON Schema (Draft 2020-12) contracts for every YAML file the vinta-ai-workflows
|
|
|
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
14
|
| 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
|
+
| Workflow (executable plan) | `ai-plans/<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
|
+
| 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
|
+
|
|
18
|
+
> `workflow.v1.schema.json` and `postmortem.v1.schema.json` are the two schemas here that are **generated, not hand-written**. 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 `packages/vinta-ai-maestro/src/postmortem/postmortem.ts`; regenerate with `node --experimental-strip-types src/postmortem/generate.ts` from `packages/vinta-ai-maestro`, verify with the same command plus `--check` — `tests/postmortem.test.ts` runs that byte comparison too. Edit the zod schemas, never the JSON.
|
|
15
19
|
|
|
16
20
|
## Versioning rules
|
|
17
21
|
|