vinta-ai-workflows 0.7.0-alpha25 → 0.7.0-alpha26
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 +129 -0
- package/package.json +1 -1
- package/schemas/README.md +1 -1
- package/schemas/vinta-ai-workflows-config.v1.schema.json +330 -7
- package/schemas/workflow.v1.schema.json +50 -13
- package/skills/vinta-analyze-codebase/SKILL.md +4 -0
- package/skills/vinta-bootstrap-ai-tools/SKILL.md +70 -10
- 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 +3 -3
- package/skills/vinta-derive-skills/resources/foundation-skills/plan-feature/SKILL.md +22 -7
- package/skills/vinta-derive-skills/resources/foundation-skills/prepare-worktree/SKILL.md +1 -0
- package/skills/vinta-derive-skills/resources/plan-execution/README.md +3 -1
- package/skills/vinta-derive-skills/resources/plan-execution/partials/agent-models.md +1 -1
- package/skills/vinta-derive-skills/resources/plan-execution/partials/implementer-prompt.md +1 -1
- package/skills/vinta-derive-skills/resources/plan-execution/partials/parallel-lanes.md +7 -5
- package/skills/vinta-derive-skills/resources/plan-execution/partials/worktree-seam.md +83 -14
- package/skills/vinta-derive-skills/resources/plan-execution/shell/implement-plan-template.md +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,95 @@ the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
30
30
|
|
|
31
31
|
### Added
|
|
32
32
|
|
|
33
|
+
- **Project defaults for maestro in `.vinta-ai-workflows.yaml`.** A new
|
|
34
|
+
`maestro:` section holds what every plan's `.workflow.json` used to repeat:
|
|
35
|
+
per-type gate defaults, resource pools, chores, run defaults and the
|
|
36
|
+
`project` block. Maestro layers each plan over it. The project's
|
|
37
|
+
`commands.*` come first, then `maestro.*`, then the plan, then the run's own
|
|
38
|
+
amendments. A plan now states only what is different, and editing the
|
|
39
|
+
project file reaches every plan that did not override it.
|
|
40
|
+
- **Gate types.** A gate with `"type": "test" | "lint" | "typecheck" |
|
|
41
|
+
"e2e"` takes its command from `maestro.gates.<type>`, else from
|
|
42
|
+
`commands.test_unit` / `lint` / `build` / `e2e`. A `maestro.gates.<type>.cmd`
|
|
43
|
+
gives maestro its own line, and `implement-plan` keeps running
|
|
44
|
+
`commands.*`. Every type the project has a command for is available under
|
|
45
|
+
the type's name, so a node can list `["typecheck", "test"]` with no gate
|
|
46
|
+
table.
|
|
47
|
+
- **`defaults.gates`**, the gates every phase runs unless it names its own.
|
|
48
|
+
`defaults.harness` and `defaults.pipeline` now default to `claude-code`
|
|
49
|
+
and `standard-phase`, and `base_branch` defaults to
|
|
50
|
+
`project.default_branch`.
|
|
51
|
+
- **The bootstrap asks for these** (interview item C.11) and writes the
|
|
52
|
+
section. `plan-feature` reads it and emits only plan-specific values.
|
|
53
|
+
- **Scoped and full gates.** A gate can carry a `scoped_cmd` with
|
|
54
|
+
`{changed_files}` / `{touches}`. Phase gates run it, and the full `cmd` runs
|
|
55
|
+
once on each wave's merged tree. A failure there is a regression between
|
|
56
|
+
phases, and it fails the merge (`defaults.gate_scope: scoped`, the default;
|
|
57
|
+
`full` runs `cmd` everywhere). `commands.test_unit_scoped` and the new
|
|
58
|
+
`commands.lint_scoped` are inherited as scoped commands when they contain a
|
|
59
|
+
placeholder. `implement-plan`'s scoped suite fills the same placeholders.
|
|
60
|
+
- **Every maestro run works on a plan branch, `plan/<workflow-id>/base`.**
|
|
61
|
+
It is cut from `base_branch` at start, and phases and waves build on it.
|
|
62
|
+
Pull requests still target `base_branch`. Commit a change to
|
|
63
|
+
`.vinta-ai-workflows.yaml` or the plan's `.workflow.json` on that branch,
|
|
64
|
+
and the running plan picks it up as a `config` amendment that names the
|
|
65
|
+
commit. A config change never undoes a change an operator or the monitor
|
|
66
|
+
made in the run, never rewrites a phase that has started, and ships with
|
|
67
|
+
the plan's PR. `run` warns when the checkout's config file differs from
|
|
68
|
+
what is committed on the plan branch.
|
|
69
|
+
- **The gate guard.** On claude-code, every maestro agent gets a
|
|
70
|
+
`PreToolUse` hook, in every permission mode, through the per-lane settings
|
|
71
|
+
file only. It refuses two things: a gate's full command typed by hand
|
|
72
|
+
(answer: `vinta-ai-maestro gate <id>`), and a command matching a pool's new
|
|
73
|
+
`match` patterns when run without the lease (answer:
|
|
74
|
+
`vinta-ai-maestro with <pool> --`). Refusals are journalled as
|
|
75
|
+
`bare_gate_blocked`. The hook fails open and never auto-approves anything.
|
|
76
|
+
On codex and opencode a matching command is recorded after the fact as
|
|
77
|
+
`bare_gate_detected`. `doctor` reports which you get as
|
|
78
|
+
`gate-guard:<harness>`.
|
|
79
|
+
|
|
80
|
+
- **Provision worktrees with your own script instead of the `prepare-worktree`
|
|
81
|
+
skill.** Set `commands.worktree_prepare` in `.vinta-ai-workflows.yaml` (and
|
|
82
|
+
optionally `commands.worktree_teardown`), and `implement-plan` runs that
|
|
83
|
+
command for the shared worktree, every lane and the integration worktree.
|
|
84
|
+
No LLM step and no `agent_models.worktree_prep` delegate are involved.
|
|
85
|
+
Worktrees, and therefore parallel phases, are now available when the skill
|
|
86
|
+
is enabled **or** the command is set. When both are set the command wins,
|
|
87
|
+
and the skill is offered as a fallback if the command fails.
|
|
88
|
+
- **The contract.** The command runs from the repo root with
|
|
89
|
+
`VINTA_WORKTREE_NAME`, `_PATH`, `_BRANCH`, `_BASE_REF`, `_KIND`
|
|
90
|
+
(`single` | `lane` | `integration`), `VINTA_MAIN_CHECKOUT`,
|
|
91
|
+
`VINTA_PLAN_PATH` and `VINTA_WORKTREE_SUMMARY` set. It must create a
|
|
92
|
+
runnable worktree at that path, on that new branch, and exit non-zero on
|
|
93
|
+
failure. The conductor then checks the result with git rather than
|
|
94
|
+
trusting the exit code: the right branch, the worktree registered, and
|
|
95
|
+
the main checkout's status unchanged. Writing the summary YAML is
|
|
96
|
+
optional. A summary carrying `reset_cmd`s lets a lane be reused across a
|
|
97
|
+
migration boundary. Without one the lane is re-provisioned (teardown,
|
|
98
|
+
then prepare again) instead. Lanes are provisioned one at a time, because
|
|
99
|
+
the command runs `git worktree add` itself.
|
|
100
|
+
- **Sandbox tier.** The conductor probes the tier itself. With the skill
|
|
101
|
+
disabled, its `sandbox-run.sh` is not installed, so the tier is `none` and
|
|
102
|
+
the review-phase stray-write check is the guard.
|
|
103
|
+
- **Bootstrap.** The `prepare-worktree` question gains a
|
|
104
|
+
`Yes — we provision with our own script/command` option.
|
|
105
|
+
`vinta-analyze-codebase` now records existing worktree scripts in
|
|
106
|
+
`commands.worktree_candidates`, and the interview offers them as the
|
|
107
|
+
command. Existing configs need no change.
|
|
108
|
+
- **The bootstrap can write the script for you.** A fourth answer,
|
|
109
|
+
`Yes — generate a provisioning script for this project`, adds an optional
|
|
110
|
+
step after `vinta-derive-skills`. It writes `prepare.sh`, `teardown.sh`
|
|
111
|
+
and a shared `lib.sh` (default `scripts/worktree/`) from bundled
|
|
112
|
+
templates, and points `commands.worktree_prepare` / `_teardown` at them.
|
|
113
|
+
The templates carry the contract: `--dry-run`, sanity checks, rollback of
|
|
114
|
+
a half-made worktree, generic compose isolation, the full summary YAML,
|
|
115
|
+
and a teardown that refuses a dirty worktree, drops only `*_wt_<name>`
|
|
116
|
+
databases and never runs `down -v`. They also refuse to fork or drop a
|
|
117
|
+
database on a non-local host. The bootstrap fills only the project's
|
|
118
|
+
dependency, env, database and service steps from the inventory, then
|
|
119
|
+
verifies with `bash -n`, a dry run, and an optional real smoke test. The
|
|
120
|
+
scripts are the project's to commit and edit; humans can run
|
|
121
|
+
`prepare.sh <name>` / `teardown.sh <name>` directly too.
|
|
33
122
|
- **Agents stop for input with clickable questions instead of prose.** When a
|
|
34
123
|
skill or a sub-agent needs a decision from you, it now asks through your
|
|
35
124
|
harness's structured question tool, so you get the options as buttons plus
|
|
@@ -294,6 +383,17 @@ the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
294
383
|
|
|
295
384
|
### Changed
|
|
296
385
|
|
|
386
|
+
- **Maestro: every `workflow_amended` row carries `targets`.** Operator and
|
|
387
|
+
config amendments get them too, computed from the snapshot and the
|
|
388
|
+
proposal. Before, only monitor amendments had them.
|
|
389
|
+
- **Maestro: a gate command can be amended after a phase that uses it is
|
|
390
|
+
done.** Changing a gate table no longer counts as rewriting a finished
|
|
391
|
+
phase. Before, such an amendment was refused as `body_changed_after_done`.
|
|
392
|
+
- **Maestro: the editor saves only what you changed.** It shows the workflow
|
|
393
|
+
resolved over the project config, and on save it writes back only the
|
|
394
|
+
edited values. A first save no longer copies every default, or the
|
|
395
|
+
project's values, into the plan file.
|
|
396
|
+
|
|
297
397
|
- **Maestro: the node view's right-hand column stays short.** Gate logs open
|
|
298
398
|
in a dialog instead of an inline accordion. The dialog opens at the end of
|
|
299
399
|
the log, keeps up with a running gate's output, numbers the lines, and has
|
|
@@ -393,6 +493,35 @@ the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
393
493
|
|
|
394
494
|
### Fixed
|
|
395
495
|
|
|
496
|
+
- **Maestro: wave merges again use the membership the executor counted.**
|
|
497
|
+
`RecordingIntegrator.mergeWave` dropped it, so in production a merge fell
|
|
498
|
+
back to the integrator's own reading of the wave. That reading could differ
|
|
499
|
+
from the count if an amendment landed in between.
|
|
500
|
+
- **Maestro: the gate run on a conflict resolution uses the amended gate
|
|
501
|
+
commands.** It used the workflow from the start of the run.
|
|
502
|
+
- **Maestro: the API serves a run's definition as amended.** It cached the
|
|
503
|
+
snapshot forever, so a monitor retune made in the run's own process never
|
|
504
|
+
reached the UI.
|
|
505
|
+
- **Maestro: an editor save from `ui` now reaches the run's job.** `ui`
|
|
506
|
+
is a separate process from the job hosting a run. A save to a running
|
|
507
|
+
plan's workflow used to replace the run's frozen snapshot from `ui` with no
|
|
508
|
+
runner: nothing adopted the change, and an amendment that needed a rebase
|
|
509
|
+
was refused. The job kept running the old definition until a resume. The
|
|
510
|
+
save is now sent to the job (`POST /api/runs/<id>/amend`), which applies it
|
|
511
|
+
under the usual amend rules, and `ui` writes the plan file only once the
|
|
512
|
+
job has accepted it. If the job does not answer, the save is refused
|
|
513
|
+
(`run_host_unreachable`) and nothing is written.
|
|
514
|
+
- **Maestro: saving in the editor during a run no longer reports a failure.**
|
|
515
|
+
The amendment response failed the client's schema check even though the
|
|
516
|
+
save had gone through.
|
|
517
|
+
|
|
518
|
+
- **`implement-plan`'s final report no longer suggests `docker compose down -v`
|
|
519
|
+
to tear down a lane.** `down -v` also deletes the compose volumes a worktree
|
|
520
|
+
deliberately shares with the main checkout (`shared_volumes`, such as a
|
|
521
|
+
dependency cache). The report now prints the same sequence the
|
|
522
|
+
`prepare-worktree` skill documents: `docker compose -p <project> down`, then
|
|
523
|
+
`docker volume rm` for each volume the worktree forked, then removal of the
|
|
524
|
+
generated compose override.
|
|
396
525
|
- **`open-pr.sh` posts inline comments on macOS and reports why a comment
|
|
397
526
|
failed.** Four bugs in the `open-pr-from-context` script, all seen while
|
|
398
527
|
publishing a stacked plan from a Mac:
|
package/package.json
CHANGED
package/schemas/README.md
CHANGED
|
@@ -6,7 +6,7 @@ JSON Schema (Draft 2020-12) contracts for every YAML or JSON payload the vinta-a
|
|
|
6
6
|
|
|
7
7
|
| Artifact | YAML location in target project | Schema file | Authored by | Read by |
|
|
8
8
|
|---|---|---|---|---|
|
|
9
|
-
| Project config | `.vinta-ai-workflows.yaml` (repo root) | [`vinta-ai-workflows-config.v1.schema.json`](vinta-ai-workflows-config.v1.schema.json) | `vinta-bootstrap-ai-tools` (initial) → `vinta-sync-ai-tools` (updates) | every builder skill, every template render, every meta-skill |
|
|
9
|
+
| Project config | `.vinta-ai-workflows.yaml` (repo root) | [`vinta-ai-workflows-config.v1.schema.json`](vinta-ai-workflows-config.v1.schema.json) | `vinta-bootstrap-ai-tools` (initial) → `vinta-sync-ai-tools` (updates) | every builder skill, every template render, every meta-skill ; `vinta-ai-maestro` reads `commands` + `maestro` and layers every workflow over them |
|
|
10
10
|
| Sub-agent definition | `ai-tools/agents/<name>.yaml` | [`sub-agent.v1.schema.json`](sub-agent.v1.schema.json) | `vinta-derive-subagents` | `setup-ai-tools.mjs` (emits per-vendor copies) |
|
|
11
11
|
| PR-context frontmatter | top-of-file YAML in `.vinta-ai-workflows/prs-context/{feature-kebab}/phase-{phase.id}.md` | [`prs-context-frontmatter.v1.schema.json`](prs-context-frontmatter.v1.schema.json) | `implement-plan` / `amend-plan` | `open-pr.sh` |
|
|
12
12
|
| PR-context inline comments | YAML inside the ` ```yaml ... ``` ` fence under `# Comments` of the same file | [`prs-context-comments.v1.schema.json`](prs-context-comments.v1.schema.json) | `implement-plan` / `amend-plan` | `open-pr.sh` |
|
|
@@ -69,20 +69,35 @@
|
|
|
69
69
|
"properties": {
|
|
70
70
|
"lint": { "type": "string" },
|
|
71
71
|
"format": { "type": "string" },
|
|
72
|
+
"lint_scoped": {
|
|
73
|
+
"description": "Lint narrowed to what a phase changed, as a template with `{changed_files}` or `{touches}` (e.g. `pnpm eslint {changed_files}`). `vinta-ai-maestro` inherits it as the `scoped_cmd` of `lint`-typed gates; see `test_unit_scoped` for how the placeholders are filled.",
|
|
74
|
+
"type": "string",
|
|
75
|
+
"minLength": 1
|
|
76
|
+
},
|
|
72
77
|
"build": {
|
|
73
78
|
"description": "Type-check / build gate. Often the same as the test command on Python projects.",
|
|
74
79
|
"type": "string"
|
|
75
80
|
},
|
|
76
81
|
"test_unit": { "type": "string" },
|
|
77
82
|
"test_unit_scoped": {
|
|
78
|
-
"description": "Per-package or per-app scoped suite (e.g. `pnpm test:patient`).",
|
|
83
|
+
"description": "Per-package or per-app scoped suite (e.g. `pnpm test:patient`). `implement-plan` reads it as guidance for the outer gate's scoped run. When it contains `{changed_files}` (the files the phase changed against its base) or `{touches}` (the phase's Touch List), it is also a template: `implement-plan` substitutes them, and `vinta-ai-maestro` inherits it as the `scoped_cmd` of `test`-typed gates — e.g. `pnpm vitest related {changed_files} --run`. A line without a placeholder is not inherited by maestro, which has no agent to decide what to scope it to.",
|
|
79
84
|
"type": "string"
|
|
80
85
|
},
|
|
81
86
|
"test_unit_new_pattern": {
|
|
82
87
|
"description": "Pattern for running a single new test file in isolation. Use placeholders like `<pkg>` / `<new-test-path>`.",
|
|
83
88
|
"type": "string"
|
|
84
89
|
},
|
|
85
|
-
"e2e": { "type": "string" }
|
|
90
|
+
"e2e": { "type": "string" },
|
|
91
|
+
"worktree_prepare": {
|
|
92
|
+
"description": "The project's own command for provisioning a runnable git worktree, used by `implement-plan` / `amend-plan` **instead of** the `prepare-worktree` skill. Set it when the team already has a script (`bin/new-worktree`, a Makefile target, `git gtr new`, …) or wants deterministic, LLM-free provisioning. Worktrees are available to the plan-execution family when this is set **or** `foundation_skills.prepare-worktree` is `enabled`; when both are set the command wins and the skill is offered as a fallback if the command fails. Runs from the main checkout root with `VINTA_WORKTREE_NAME`, `VINTA_WORKTREE_PATH`, `VINTA_WORKTREE_BRANCH`, `VINTA_WORKTREE_BASE_REF`, `VINTA_WORKTREE_KIND` (`single` | `lane` | `integration`), `VINTA_MAIN_CHECKOUT`, `VINTA_PLAN_PATH` and `VINTA_WORKTREE_SUMMARY` in its environment. It MUST create a worktree at `VINTA_WORKTREE_PATH` on a new branch `VINTA_WORKTREE_BRANCH` based on `VINTA_WORKTREE_BASE_REF`, and exit 0 only when that worktree is runnable. It MAY write the summary YAML at `VINTA_WORKTREE_SUMMARY` (the shape `prepare-worktree` writes); a summary carrying `reset_cmd`s lets a lane be reused across a migration boundary, and without one the conductor re-provisions the lane instead. The full contract is in the rendered `implement-plan` skill (Step 0.5). The bootstrap can generate a conforming `prepare.sh` / `teardown.sh` pair for the project (its `prepare-worktree` question, option `generate a provisioning script`).",
|
|
93
|
+
"type": "string",
|
|
94
|
+
"minLength": 1
|
|
95
|
+
},
|
|
96
|
+
"worktree_teardown": {
|
|
97
|
+
"description": "Optional counterpart to `worktree_prepare`: removes a worktree the prepare command created, plus any state it made outside git (forked DBs, compose volumes, caches). Receives the same `VINTA_WORKTREE_*` environment. Used when a lane is re-provisioned mid-run, when the user cancels at the worktree confirmation gate, and in the teardown commands the final report prints (never auto-run at the end of a run). Unset → teardown is `git worktree remove <path>`, which leaks anything the prepare command created outside the worktree; set it whenever the prepare command forks databases or volumes. Ignored when `worktree_prepare` is unset.",
|
|
98
|
+
"type": "string",
|
|
99
|
+
"minLength": 1
|
|
100
|
+
}
|
|
86
101
|
}
|
|
87
102
|
},
|
|
88
103
|
"policies": {
|
|
@@ -209,7 +224,7 @@
|
|
|
209
224
|
"enum": ["enabled", "disabled"]
|
|
210
225
|
},
|
|
211
226
|
"prepare-worktree": {
|
|
212
|
-
"description": "Provision a fully-runnable git worktree for parallel feature work — gives each worktree its own copy of the dep dirs, copies env files, forks dev / test DBs, namespaces docker-compose project + network, drops a summary YAML for mechanical teardown. Copy-verbatim foundation skill (bucket A). When `enabled`, project-level defaults (worktree root, deps strategy, compose network strategy) live under `skills.prepare-worktree`. Consumed by `implement-plan` when its Step 0 question (c) opts in — the orchestrator runs `prepare-worktree` once at the start of a plan run and threads the worktree path through every subagent's prompt so phases all stack inside the same isolated checkout.",
|
|
227
|
+
"description": "Provision a fully-runnable git worktree for parallel feature work — gives each worktree its own copy of the dep dirs, copies env files, forks dev / test DBs, namespaces docker-compose project + network, drops a summary YAML for mechanical teardown. Copy-verbatim foundation skill (bucket A). When `enabled`, project-level defaults (worktree root, deps strategy, compose network strategy) live under `skills.prepare-worktree`. Consumed by `implement-plan` when its Step 0 question (c) opts in — the orchestrator runs `prepare-worktree` once at the start of a plan run and threads the worktree path through every subagent's prompt so phases all stack inside the same isolated checkout. Set `disabled` when the project provisions worktrees with its own command instead (`commands.worktree_prepare`) — worktrees stay available to `implement-plan` either way.",
|
|
213
228
|
"type": "string",
|
|
214
229
|
"enum": ["enabled", "disabled"]
|
|
215
230
|
},
|
|
@@ -280,7 +295,7 @@
|
|
|
280
295
|
"maximum": 4
|
|
281
296
|
},
|
|
282
297
|
"worktree_prep": {
|
|
283
|
-
"description": "Tier for the mechanical worktree-provisioning step (`prepare-worktree`), which `implement-plan` / `amend-plan` run once at the start of a worktree-enabled run. When set, the conductor delegates the step to a subagent at this tier instead of running it inline in its own (usually pricier) session. Mechanical, precedent-driven work — Tier 1 is the usual default. Unset → conductor runs it inline. Irrelevant when `foundation_skills.prepare-worktree` is `disabled
|
|
298
|
+
"description": "Tier for the mechanical worktree-provisioning step (`prepare-worktree`), which `implement-plan` / `amend-plan` run once at the start of a worktree-enabled run. When set, the conductor delegates the step to a subagent at this tier instead of running it inline in its own (usually pricier) session. Mechanical, precedent-driven work — Tier 1 is the usual default. Unset → conductor runs it inline. Irrelevant when `foundation_skills.prepare-worktree` is `disabled`, and when `commands.worktree_prepare` is set — a shell command needs no model, so the conductor runs it directly.",
|
|
284
299
|
"type": "integer",
|
|
285
300
|
"minimum": 1,
|
|
286
301
|
"maximum": 4
|
|
@@ -307,6 +322,314 @@
|
|
|
307
322
|
"uniqueItems": true,
|
|
308
323
|
"default": []
|
|
309
324
|
},
|
|
325
|
+
"maestro": {
|
|
326
|
+
"description": "Project-wide defaults for `vinta-ai-maestro` runs, layered UNDER every plan's `ai-plans/*.workflow.json`: a plan's own value wins, and a run's mid-run amendments win over both. Maps keyed by id (`resources`, `chores`, `project.databases`, `project.services`) merge per id with the plan's entry replacing the project's whole; a typed gate merges field by field; lists replace. Shapes are the workflow schema's (`workflow.v1.schema.json`) — maestro validates them strictly at load. A run follows its plan branch (`plan/<workflow-id>/base`): committing a change to this file on that branch applies it to the live run. Absent: every plan carries everything itself.",
|
|
327
|
+
"type": "object",
|
|
328
|
+
"additionalProperties": false,
|
|
329
|
+
"properties": {
|
|
330
|
+
"defaults": {
|
|
331
|
+
"description": "Run defaults a plan's `defaults` overrides field by field: `harness`, `model`, `pipeline`, `chores`, `gates` (the gate ids every phase runs unless it names its own), `gate_scope` (`scoped` | `full`), `reviewer_model`, `max_session_turns`.",
|
|
332
|
+
"type": "object",
|
|
333
|
+
"properties": {
|
|
334
|
+
"harness": {
|
|
335
|
+
"type": "string",
|
|
336
|
+
"enum": [
|
|
337
|
+
"claude-code",
|
|
338
|
+
"codex",
|
|
339
|
+
"opencode"
|
|
340
|
+
]
|
|
341
|
+
},
|
|
342
|
+
"model": {
|
|
343
|
+
"type": "string",
|
|
344
|
+
"minLength": 1
|
|
345
|
+
},
|
|
346
|
+
"pipeline": {
|
|
347
|
+
"type": "string",
|
|
348
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
349
|
+
},
|
|
350
|
+
"chores": {
|
|
351
|
+
"type": "array",
|
|
352
|
+
"items": {
|
|
353
|
+
"type": "string",
|
|
354
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
355
|
+
}
|
|
356
|
+
},
|
|
357
|
+
"gates": {
|
|
358
|
+
"type": "array",
|
|
359
|
+
"items": {
|
|
360
|
+
"type": "string",
|
|
361
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
"gate_scope": {
|
|
365
|
+
"type": "string",
|
|
366
|
+
"enum": [
|
|
367
|
+
"scoped",
|
|
368
|
+
"full"
|
|
369
|
+
]
|
|
370
|
+
},
|
|
371
|
+
"reviewer_model": {
|
|
372
|
+
"type": "string",
|
|
373
|
+
"minLength": 1
|
|
374
|
+
},
|
|
375
|
+
"max_session_turns": {
|
|
376
|
+
"type": "integer",
|
|
377
|
+
"minimum": 1
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
"additionalProperties": false
|
|
381
|
+
},
|
|
382
|
+
"gates": {
|
|
383
|
+
"description": "Per gate type. Each type with a command is also available to every plan under the type's own name (`gates: [typecheck, test]` on a node, with no gate table).",
|
|
384
|
+
"type": "object",
|
|
385
|
+
"additionalProperties": false,
|
|
386
|
+
"properties": {
|
|
387
|
+
"test": {
|
|
388
|
+
"description": "Defaults a gate of this type inherits, over the matching `commands.*` line. Any field a plan's own gate sets wins over these.",
|
|
389
|
+
"type": "object",
|
|
390
|
+
"additionalProperties": false,
|
|
391
|
+
"properties": {
|
|
392
|
+
"cmd": {
|
|
393
|
+
"description": "The full check maestro runs for this type. Overrides the `commands.*` line for maestro only — `implement-plan` keeps running `commands.*`.",
|
|
394
|
+
"type": "string",
|
|
395
|
+
"minLength": 1
|
|
396
|
+
},
|
|
397
|
+
"scoped_cmd": {
|
|
398
|
+
"description": "The check narrowed to what a phase changed, with `{changed_files}` and/or `{touches}`. Run by phase gates under `gate_scope: scoped`; the full `cmd` runs once on each wave's merged tree.",
|
|
399
|
+
"type": "string",
|
|
400
|
+
"minLength": 1
|
|
401
|
+
},
|
|
402
|
+
"requires": {
|
|
403
|
+
"description": "Resource pools the gate holds while it runs, e.g. `[test-suite]`.",
|
|
404
|
+
"type": "array",
|
|
405
|
+
"items": {
|
|
406
|
+
"type": "string",
|
|
407
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
408
|
+
}
|
|
409
|
+
},
|
|
410
|
+
"timeout_s": {
|
|
411
|
+
"type": "integer",
|
|
412
|
+
"minimum": 1
|
|
413
|
+
},
|
|
414
|
+
"tuning": {
|
|
415
|
+
"description": "Flags the monitor may add to `cmd` when it retunes the gate mid-run. Same shape as a workflow gate's `tuning`.",
|
|
416
|
+
"type": "object",
|
|
417
|
+
"properties": {
|
|
418
|
+
"allowed_flags": {
|
|
419
|
+
"type": "array",
|
|
420
|
+
"items": {
|
|
421
|
+
"type": "string",
|
|
422
|
+
"minLength": 1
|
|
423
|
+
},
|
|
424
|
+
"minItems": 1
|
|
425
|
+
}
|
|
426
|
+
},
|
|
427
|
+
"required": [
|
|
428
|
+
"allowed_flags"
|
|
429
|
+
],
|
|
430
|
+
"additionalProperties": false
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
},
|
|
434
|
+
"lint": {
|
|
435
|
+
"description": "Defaults a gate of this type inherits, over the matching `commands.*` line. Any field a plan's own gate sets wins over these.",
|
|
436
|
+
"type": "object",
|
|
437
|
+
"additionalProperties": false,
|
|
438
|
+
"properties": {
|
|
439
|
+
"cmd": {
|
|
440
|
+
"description": "The full check maestro runs for this type. Overrides the `commands.*` line for maestro only — `implement-plan` keeps running `commands.*`.",
|
|
441
|
+
"type": "string",
|
|
442
|
+
"minLength": 1
|
|
443
|
+
},
|
|
444
|
+
"scoped_cmd": {
|
|
445
|
+
"description": "The check narrowed to what a phase changed, with `{changed_files}` and/or `{touches}`. Run by phase gates under `gate_scope: scoped`; the full `cmd` runs once on each wave's merged tree.",
|
|
446
|
+
"type": "string",
|
|
447
|
+
"minLength": 1
|
|
448
|
+
},
|
|
449
|
+
"requires": {
|
|
450
|
+
"description": "Resource pools the gate holds while it runs, e.g. `[test-suite]`.",
|
|
451
|
+
"type": "array",
|
|
452
|
+
"items": {
|
|
453
|
+
"type": "string",
|
|
454
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
455
|
+
}
|
|
456
|
+
},
|
|
457
|
+
"timeout_s": {
|
|
458
|
+
"type": "integer",
|
|
459
|
+
"minimum": 1
|
|
460
|
+
},
|
|
461
|
+
"tuning": {
|
|
462
|
+
"description": "Flags the monitor may add to `cmd` when it retunes the gate mid-run. Same shape as a workflow gate's `tuning`.",
|
|
463
|
+
"type": "object",
|
|
464
|
+
"properties": {
|
|
465
|
+
"allowed_flags": {
|
|
466
|
+
"type": "array",
|
|
467
|
+
"items": {
|
|
468
|
+
"type": "string",
|
|
469
|
+
"minLength": 1
|
|
470
|
+
},
|
|
471
|
+
"minItems": 1
|
|
472
|
+
}
|
|
473
|
+
},
|
|
474
|
+
"required": [
|
|
475
|
+
"allowed_flags"
|
|
476
|
+
],
|
|
477
|
+
"additionalProperties": false
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
},
|
|
481
|
+
"typecheck": {
|
|
482
|
+
"description": "Defaults a gate of this type inherits, over the matching `commands.*` line. Any field a plan's own gate sets wins over these.",
|
|
483
|
+
"type": "object",
|
|
484
|
+
"additionalProperties": false,
|
|
485
|
+
"properties": {
|
|
486
|
+
"cmd": {
|
|
487
|
+
"description": "The full check maestro runs for this type. Overrides the `commands.*` line for maestro only — `implement-plan` keeps running `commands.*`.",
|
|
488
|
+
"type": "string",
|
|
489
|
+
"minLength": 1
|
|
490
|
+
},
|
|
491
|
+
"scoped_cmd": {
|
|
492
|
+
"description": "The check narrowed to what a phase changed, with `{changed_files}` and/or `{touches}`. Run by phase gates under `gate_scope: scoped`; the full `cmd` runs once on each wave's merged tree.",
|
|
493
|
+
"type": "string",
|
|
494
|
+
"minLength": 1
|
|
495
|
+
},
|
|
496
|
+
"requires": {
|
|
497
|
+
"description": "Resource pools the gate holds while it runs, e.g. `[test-suite]`.",
|
|
498
|
+
"type": "array",
|
|
499
|
+
"items": {
|
|
500
|
+
"type": "string",
|
|
501
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
502
|
+
}
|
|
503
|
+
},
|
|
504
|
+
"timeout_s": {
|
|
505
|
+
"type": "integer",
|
|
506
|
+
"minimum": 1
|
|
507
|
+
},
|
|
508
|
+
"tuning": {
|
|
509
|
+
"description": "Flags the monitor may add to `cmd` when it retunes the gate mid-run. Same shape as a workflow gate's `tuning`.",
|
|
510
|
+
"type": "object",
|
|
511
|
+
"properties": {
|
|
512
|
+
"allowed_flags": {
|
|
513
|
+
"type": "array",
|
|
514
|
+
"items": {
|
|
515
|
+
"type": "string",
|
|
516
|
+
"minLength": 1
|
|
517
|
+
},
|
|
518
|
+
"minItems": 1
|
|
519
|
+
}
|
|
520
|
+
},
|
|
521
|
+
"required": [
|
|
522
|
+
"allowed_flags"
|
|
523
|
+
],
|
|
524
|
+
"additionalProperties": false
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
},
|
|
528
|
+
"e2e": {
|
|
529
|
+
"description": "Defaults a gate of this type inherits, over the matching `commands.*` line. Any field a plan's own gate sets wins over these.",
|
|
530
|
+
"type": "object",
|
|
531
|
+
"additionalProperties": false,
|
|
532
|
+
"properties": {
|
|
533
|
+
"cmd": {
|
|
534
|
+
"description": "The full check maestro runs for this type. Overrides the `commands.*` line for maestro only — `implement-plan` keeps running `commands.*`.",
|
|
535
|
+
"type": "string",
|
|
536
|
+
"minLength": 1
|
|
537
|
+
},
|
|
538
|
+
"scoped_cmd": {
|
|
539
|
+
"description": "The check narrowed to what a phase changed, with `{changed_files}` and/or `{touches}`. Run by phase gates under `gate_scope: scoped`; the full `cmd` runs once on each wave's merged tree.",
|
|
540
|
+
"type": "string",
|
|
541
|
+
"minLength": 1
|
|
542
|
+
},
|
|
543
|
+
"requires": {
|
|
544
|
+
"description": "Resource pools the gate holds while it runs, e.g. `[test-suite]`.",
|
|
545
|
+
"type": "array",
|
|
546
|
+
"items": {
|
|
547
|
+
"type": "string",
|
|
548
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
549
|
+
}
|
|
550
|
+
},
|
|
551
|
+
"timeout_s": {
|
|
552
|
+
"type": "integer",
|
|
553
|
+
"minimum": 1
|
|
554
|
+
},
|
|
555
|
+
"tuning": {
|
|
556
|
+
"description": "Flags the monitor may add to `cmd` when it retunes the gate mid-run. Same shape as a workflow gate's `tuning`.",
|
|
557
|
+
"type": "object",
|
|
558
|
+
"properties": {
|
|
559
|
+
"allowed_flags": {
|
|
560
|
+
"type": "array",
|
|
561
|
+
"items": {
|
|
562
|
+
"type": "string",
|
|
563
|
+
"minLength": 1
|
|
564
|
+
},
|
|
565
|
+
"minItems": 1
|
|
566
|
+
}
|
|
567
|
+
},
|
|
568
|
+
"required": [
|
|
569
|
+
"allowed_flags"
|
|
570
|
+
],
|
|
571
|
+
"additionalProperties": false
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
},
|
|
577
|
+
"resources": {
|
|
578
|
+
"description": "Capacity pools by id, e.g. a `test-suite` semaphore. `match` lists command patterns (`pytest*`) an agent must run under `vinta-ai-maestro with <pool> --`.",
|
|
579
|
+
"type": "object",
|
|
580
|
+
"propertyNames": {
|
|
581
|
+
"type": "string",
|
|
582
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
583
|
+
},
|
|
584
|
+
"additionalProperties": {
|
|
585
|
+
"type": "object",
|
|
586
|
+
"required": [
|
|
587
|
+
"capacity",
|
|
588
|
+
"kind"
|
|
589
|
+
],
|
|
590
|
+
"additionalProperties": false,
|
|
591
|
+
"properties": {
|
|
592
|
+
"capacity": {
|
|
593
|
+
"type": "integer",
|
|
594
|
+
"minimum": 1
|
|
595
|
+
},
|
|
596
|
+
"kind": {
|
|
597
|
+
"type": "string",
|
|
598
|
+
"enum": [
|
|
599
|
+
"worktree",
|
|
600
|
+
"semaphore"
|
|
601
|
+
]
|
|
602
|
+
},
|
|
603
|
+
"match": {
|
|
604
|
+
"type": "array",
|
|
605
|
+
"items": {
|
|
606
|
+
"type": "string",
|
|
607
|
+
"minLength": 1
|
|
608
|
+
}
|
|
609
|
+
},
|
|
610
|
+
"description": {
|
|
611
|
+
"type": "string"
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
},
|
|
616
|
+
"chores": {
|
|
617
|
+
"description": "Chore definitions by id (`prompt` or `prompt_ref`, `skill`, `session`, `model`, `when`, `on_failure`) — the workflow schema's `chores` entries.",
|
|
618
|
+
"type": "object",
|
|
619
|
+
"propertyNames": {
|
|
620
|
+
"type": "string",
|
|
621
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
622
|
+
},
|
|
623
|
+
"additionalProperties": {
|
|
624
|
+
"type": "object"
|
|
625
|
+
}
|
|
626
|
+
},
|
|
627
|
+
"project": {
|
|
628
|
+
"description": "The workflow schema's `project` block (`migrate_cmd`, `databases`, `env_files`, `commands`, `hooks`, `services`, `compose`, `prepare_cmd`, `setup_cmd`), merged under a plan's own field by field. `project.commands` additionally inherits `lint`, `typecheck` (from `commands.build`) and `test` (from `commands.test_unit`).",
|
|
629
|
+
"type": "object"
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
},
|
|
310
633
|
"run_options": {
|
|
311
634
|
"description": "Per-skill run-option defaults. Skills override via per-invocation prompts; values here are the defaults shown.",
|
|
312
635
|
"type": "object",
|
|
@@ -324,12 +647,12 @@
|
|
|
324
647
|
"default": false
|
|
325
648
|
},
|
|
326
649
|
"use_worktree": {
|
|
327
|
-
"description": "Default answer to Step 0 question (c) — whether `implement-plan` should provision isolated git worktrees (via `prepare-worktree`) and run phase subagents inside them. False = run in the current checkout. True = provision at the start of the plan run: one shared worktree for a sequential run, or one lane per concurrent phase plus an integration worktree when `parallel_phases` is on. Per-run prompt still asks; this is the suggested default shown.",
|
|
650
|
+
"description": "Default answer to Step 0 question (c) — whether `implement-plan` should provision isolated git worktrees (via `commands.worktree_prepare` when set, else the `prepare-worktree` skill) and run phase subagents inside them. False = run in the current checkout. True = provision at the start of the plan run: one shared worktree for a sequential run, or one lane per concurrent phase plus an integration worktree when `parallel_phases` is on. Per-run prompt still asks; this is the suggested default shown.",
|
|
328
651
|
"type": "boolean",
|
|
329
652
|
"default": false
|
|
330
653
|
},
|
|
331
654
|
"parallel_phases": {
|
|
332
|
-
"description": "Default answer to Step 0 question (e) — whether `implement-plan` implements independent phases concurrently, one git worktree lane per in-flight phase. The plan's per-phase `**Depends on**:` lines define the graph; a phase starts as soon as every phase it depends on is green. True (default) = run in parallel whenever the graph has a wave wider than one phase. False = one phase at a time. Requires `foundation_skills.prepare-worktree` enabled and `use_worktree` resolving true — several agents cannot share one working tree — and `implement-plan` refuses rather than silently degrading when that is not the case. Per-run prompt still asks; this is the suggested default shown.",
|
|
655
|
+
"description": "Default answer to Step 0 question (e) — whether `implement-plan` implements independent phases concurrently, one git worktree lane per in-flight phase. The plan's per-phase `**Depends on**:` lines define the graph; a phase starts as soon as every phase it depends on is green. True (default) = run in parallel whenever the graph has a wave wider than one phase. False = one phase at a time. Requires worktrees to be available (`foundation_skills.prepare-worktree` enabled or `commands.worktree_prepare` set) and `use_worktree` resolving true — several agents cannot share one working tree — and `implement-plan` refuses rather than silently degrading when that is not the case. Per-run prompt still asks; this is the suggested default shown.",
|
|
333
656
|
"type": "boolean",
|
|
334
657
|
"default": true
|
|
335
658
|
},
|
|
@@ -421,7 +744,7 @@
|
|
|
421
744
|
}
|
|
422
745
|
},
|
|
423
746
|
"prepare-worktree": {
|
|
424
|
-
"description": "Configuration for the `prepare-worktree` foundation skill. Optional when `foundation_skills.prepare-worktree` is `enabled` — every field has a sensible default. Consumed by the skill at runtime to bias the per-worktree copy-vs-reinstall-vs-fork decisions.",
|
|
747
|
+
"description": "Configuration for the `prepare-worktree` foundation skill. Optional when `foundation_skills.prepare-worktree` is `enabled` — every field has a sensible default. Consumed by the skill at runtime to bias the per-worktree copy-vs-reinstall-vs-fork decisions. When the project provisions with `commands.worktree_prepare` instead, the plan-execution conductor still reads `worktree_root` and `summary_dir` from here to compute `VINTA_WORKTREE_PATH` / `VINTA_WORKTREE_SUMMARY`; the other fields are skill-only and ignored.",
|
|
425
748
|
"type": "object",
|
|
426
749
|
"additionalProperties": false,
|
|
427
750
|
"properties": {
|