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
|
@@ -79,6 +79,8 @@ For Python: read `pyproject.toml:[tool.poetry.scripts]` / `[project.scripts]` +
|
|
|
79
79
|
|
|
80
80
|
For other languages: read `Makefile` + `justfile` + language-specific files (`Cargo.toml:[bin]`, etc).
|
|
81
81
|
|
|
82
|
+
Worktree provisioning: look for an existing script that sets up a git worktree, such as `bin/*worktree*` / `scripts/*worktree*` files, a `Makefile` / `justfile` target or `package.json` script with `worktree` in its name, or a `.gtrconfig` / `git gtr` setup. Record each one in `commands.worktree_candidates`, with a matching teardown when one exists. The bootstrap's `prepare-worktree` question offers them as the project's own provisioning command.
|
|
83
|
+
|
|
82
84
|
Note: many repos have the test command in CI config but not surfaced as a top-level script. Read `.github/workflows/*.yml` / `.gitlab-ci.yml` / `.circleci/config.yml` / `Jenkinsfile` to confirm.
|
|
83
85
|
|
|
84
86
|
### 5. Monorepo shape
|
|
@@ -164,6 +166,7 @@ For each skill, also classify:
|
|
|
164
166
|
|
|
165
167
|
- `vinta-managed` — directory name starts with `vinta-` (installed by `vinta-ai-workflows`; can be left alone or refreshed via that CLI).
|
|
166
168
|
- `foundation-shape` — name matches the Vinta foundation set (`plan-feature`, `create-spec`, `create-qa-use-cases`, `implement-plan`, `implement-phase`, `review-phase`, `integrate-phase`, `amend-plan`, `add-e2e-test`, `add-env-var`, `write-unit-test`). `implement-phase` / `review-phase` / `integrate-phase` are the plan-execution sub-skills co-shipped with `implement-plan`.
|
|
169
|
+
- `integration` — installed by an external tool that the bootstrap's **Integrations** group knows about. The directory carries that tool's marker, such as `pr-review-canvas/` with a `.pr-review-install` file (installed by `pr-review install-skill`). The tool owns it. Record it, and also record `pr-review.config.yml` at the repo root when present, so the bootstrap can default the integration question to `Yes`.
|
|
167
170
|
- `project-custom` — anything else; written by the team.
|
|
168
171
|
|
|
169
172
|
**Sub-agents** — list every agent file with its name + description:
|
|
@@ -275,6 +278,8 @@ commands:
|
|
|
275
278
|
lint: <e.g. pnpm lint>
|
|
276
279
|
format: <e.g. pnpm format>
|
|
277
280
|
typecheck: <e.g. pnpm build (tsc) — or null if no separate command>
|
|
281
|
+
worktree_candidates: # existing worktree-provisioning scripts; [] when none
|
|
282
|
+
- { prepare: <e.g. ./bin/new-worktree>, teardown: <e.g. ./bin/rm-worktree — or null>, signal: <path of the script / Makefile / package.json> }
|
|
278
283
|
|
|
279
284
|
tests:
|
|
280
285
|
unit_framework: vitest | jest | pytest | ...
|
|
@@ -23,10 +23,11 @@ This orchestrator runs six sub-skills in order. Each is its own SKILL.md so it c
|
|
|
23
23
|
2. [vinta-write-agents-md](../vinta-write-agents-md/SKILL.md) — synthesize the root `AGENTS.md` from the inventory + a focused interview for what the analysis can't see.
|
|
24
24
|
3. [vinta-derive-subagents](../vinta-derive-subagents/SKILL.md) — author `ai-tools/agents/*.yaml`. Always emits the foundation trio (`implementer`, `reviewer`, `fixer`); adds stack-specific specialists when the user supplies a template for a matched stack.
|
|
25
25
|
4. [vinta-derive-skills](../vinta-derive-skills/SKILL.md) — author `ai-tools/skills/*/SKILL.md`. Always copies the project-agnostic foundation set (`plan-feature`, `create-spec`, `create-qa-use-cases`) verbatim from its bundled resources. Generates `implement-plan` from a parameterized template using project specifics. Asks the user whether the optional `add-e2e-test` and `add-env-var` skills are needed. Asks for stack-specific templates per matched stack.
|
|
26
|
-
|
|
26
|
+
- *Optional, after step 4:* [Generate the worktree command](#optional-step--generate-the-worktree-command) — only when the `prepare-worktree` answer was `generate a provisioning script`. Writes `prepare.sh` / `teardown.sh` into the project from bundled templates.
|
|
27
|
+
5. [vinta-install-ai-tools-setup](../vinta-install-ai-tools-setup/SKILL.md) — copy the canonical `setup-ai-tools.mjs` into `ai-tools/scripts/`, wire the package script alias, run setup, verify all vendor paths resolve. Then install the skills of any enabled integration (D.2) through that tool's own CLI.
|
|
27
28
|
6. [vinta-migrate-plans-specs](../vinta-migrate-plans-specs/SKILL.md) — find any pre-existing implementation plans / feature specs scattered across the repo (`docs/`, `specs/`, `plans/`, root markdown, etc.) and propose moving them to the canonical layout `ai-plans/YYYY-MM-DD-{FEATURE_NAME}_{PLAN|SPEC}.md`. Read-only by default; every rename is gated on per-file user approval. Skipped automatically when the analysis finds no candidates.
|
|
28
29
|
|
|
29
|
-
Each sub-skill returns a short status report. Don't run the next sub-skill until the previous finished cleanly. If a sub-skill fails or surfaces ambiguity,
|
|
30
|
+
Each sub-skill returns a short status report. Don't run the next sub-skill until the previous finished cleanly. If a sub-skill fails or surfaces ambiguity, resolve it with the user before continuing — as an `AskUserQuestion` with concrete options (e.g. `Retry <sub-skill> (Recommended)`, `Skip it, continue`, `Stop`), never as a prose question at the end of the status report.
|
|
30
31
|
|
|
31
32
|
### Sibling skill — `create-qa-use-cases`
|
|
32
33
|
|
|
@@ -47,7 +48,7 @@ If the repo already has an `AGENTS.md` (at the root, or at the legacy `ai-tools/
|
|
|
47
48
|
|
|
48
49
|
## Interview (Step 0 — before any sub-skill runs)
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
Every question goes through `AskUserQuestion` — the harness's structured question tool, which renders clickable options plus a free-text field. On harnesses other than Claude Code, use the equivalent tool listed in [asking-the-human](../vinta-write-agents-md/resources/asking-the-human.md), and follow its shape rules: 2–4 options, recommended first with ` (Recommended)`, no "Other" option, up to 4 questions per call (3 on Codex). For open-ended questions, offer the candidates the analysis found (detected commands, paths, environments, branch names) as options; the free-text field covers the rest. Plain prose only when there is no candidate at all, one question per message.
|
|
51
52
|
|
|
52
53
|
### A. Scope
|
|
53
54
|
|
|
@@ -93,11 +94,36 @@ These bleed across sub-skills, so capture once now:
|
|
|
93
94
|
|
|
94
95
|
**Additional conventions (optional).** Open prose: *"Any recurring test conventions the four fields above don't capture? (e.g. 'co-locate tests as `*.test.ts` next to source', 'name tests `should_<behavior>_when_<condition>`', 'mock HTTP with our recorded-cassette helper'.)"* On an existing project, seed this from the extras `vinta-analyze-codebase` surfaced and let the user trim. Each entry lands in `skills.write-unit-test.additional_conventions[]`. Leave empty when there's nothing project-specific — the universal rules + framework pack already cover the essentials.
|
|
95
96
|
|
|
96
|
-
10. **Agent model tiers (optional).** The plan-execution family picks the **implementer** model per phase from the plan itself,
|
|
97
|
+
10. **Agent model tiers (optional).** The plan-execution family picks the **implementer** model per phase from the plan itself, and `review-phase` runs its reviewer one tier above the implementer, so neither is asked here. The merge-conflict **fixer** and the mechanical steps (**worktree prep**, **opening the PR / integrate**) have no model input unless the project sets one. Offer to pin each to a **tier** (1–4) into the same table `plan-feature` uses — `ai-tools/skills/plan-feature/resources/ai-models.yaml` — so cheap mechanical work runs on a cheap model. `AskUserQuestion`: `Use recommended defaults (fixer 2, worktree prep 1, integrate 1)`, `Customize each`, `Leave unset — every spawn uses the runtime default`. On `Customize each`, ask a per-role tier (1–4) for `fixer` / `worktree_prep` / `integrate`. Never ask for or emit `reviewer`: `agent_models.reviewer` is deprecated and ignored. Land the chosen tiers in `.vinta-ai-workflows.yaml` `agent_models`; omit any role the user leaves unset (unset → runtime default). Recommend the defaults for most teams; recommend `Leave unset` only when the runtime exposes a single model anyway. Note `worktree_prep` is a no-op unless `prepare-worktree` is enabled, and setting `worktree_prep` / `integrate` makes `implement-plan` delegate those steps to a cheap subagent instead of running them inline.
|
|
98
|
+
|
|
99
|
+
11. **`vinta-ai-maestro` defaults (optional).** Every plan `plan-feature` writes ships a `.workflow.json` that [vinta-ai-maestro](https://github.com/vintasoftware/vinta-ai-workflows/tree/main/packages/vinta-ai-maestro) executes, and most of what is in it repeats from plan to plan: which gates every phase runs, the pool the test suite contends for, the review and comment-hygiene chores. A `maestro:` section here holds those once, and each plan states only what is different. `AskUserQuestion` (header `Maestro`): `Set project defaults (Recommended)`, `Skip — plans carry everything themselves`. Recommend skipping only when the team does not run maestro.
|
|
100
|
+
|
|
101
|
+
On `Set project defaults`, capture:
|
|
102
|
+
- **Gates every phase runs.** Multi-select `AskUserQuestion` over the types the commands above give a command for: `typecheck` (from `commands.build`), `lint`, `test` (from `commands.test_unit`), and `e2e` only when `add-e2e-test` is enabled. → `maestro.defaults.gates`.
|
|
103
|
+
- **A different command for maestro.** `AskUserQuestion` per selected type: `Same as commands.* (Recommended)`, `Different for maestro (I'll give it)`. Teams pick a different one when lanes need a flag the inner loop does not, e.g. `pytest --reuse-db -n auto`. → `maestro.gates.<type>.cmd`. `implement-plan` keeps running `commands.*`.
|
|
104
|
+
- **Scoped gates.** Only when `test` (or `lint`) is selected: should a phase's gate run narrowed to the files the phase changed until its review approves, with the full command run after the review and on every merged tree? `AskUserQuestion`: `Yes — scoped until review, full after (Recommended)`, `No — full command every time`. On `Yes`, propose a template with `{changed_files}` for the detected runner (`vitest related {changed_files} --run`, `jest --findRelatedTests {changed_files}`, `pytest --testmon {changed_files}`, `ruff check {changed_files}`) and confirm it. It lands in `commands.test_unit_scoped` / `commands.lint_scoped`, where `implement-plan` reads it too. `No` sets `maestro.defaults.gate_scope: full`.
|
|
105
|
+
- **Cold lanes.** Only when the scoped template narrows by a cache, as `pytest --testmon` does with `.testmondata`. A lane has no cache until a run builds one, and a testmon run without one runs **every** test, serially: one observed run spent 30–40 minutes per phase gate that way. Say so, and that `--testmon` together with `-n` (xdist) trades correctness for speed — testmon cannot see which tests a worker ran, so the project's scoped line normally runs without `-n`. `AskUserQuestion` (header `Cold lanes`): `Run the full suite in parallel until a lane has a cache (Recommended)`, `Keep the scoped command — it handles a missing cache itself`. On the first, emit `maestro.gates.test.scope_cache` (the cache path, relative to the repo, e.g. `apps/api/.testmondata`), `maestro.gates.test.cold_cmd` (the parallel full suite, e.g. `make test`), and `maestro.project.lane_seed` with the same paths, so a lane is handed a copy from its dependency's lane. When the scoped line is a task-runner target (`make test_changed`), also propose the fallback in the target itself, so `implement-plan` and a person get it too:
|
|
106
|
+
|
|
107
|
+
```make
|
|
108
|
+
test_changed:
|
|
109
|
+
@if [ ! -f .testmondata ]; then $(MAKE) test; else <the testmon command>; fi
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Show it as a proposed edit and apply it only on the user's yes.
|
|
113
|
+
- **Fresh database in the integration worktree.** Only when the test command keeps its database between runs (`--reuse-db`, `--keepdb`, a fixture that skips migrations on an existing schema). Maestro's integration worktree runs merges for different branches one after another, and a reused database applies each tree's migrations on top of the last tree's — one observed run had three merges fail on columns and tables that belonged to another branch. `AskUserQuestion` (header `Fresh DB`): `Recreate the database there when the tree changes (Recommended)`, `Keep reusing it`. On the first, propose the fresh form of the command (`--create-db` in place of `--reuse-db`, or `make test_reset test`), confirm it, and emit it as `maestro.gates.test.fresh_cmd`, plus `tuning.allowed_flags: ['--create-db']` when the flag form fits, so the run coordinator can add the flag without being refused for rewriting the command. Then name the migration files from the inventory as globs (`apps/*/migrations/*.py`, `db/migrate/*.rb`, `prisma/migrations/**`) and emit them as `maestro.gates.test.fresh_when`: a phase that rewrites or renames one of its own migrations moves the tree forward and still leaves a reused database recording the old one, and these globs are what tell maestro so. Offer them as candidates in the same confirmation rather than as a second question.
|
|
114
|
+
- **When the full suite runs.** Only on `Yes` above. `AskUserQuestion`: `After each review and on every merged tree (Recommended)`, `Only on merged trees`, `Only on merged waves`. The first is the default and emits nothing. `Only on merged trees` skips the per-phase full run after review (`maestro.defaults.verify_gates: scoped`), for a suite too slow to run once per phase. `Only on merged waves` also leaves multi-dependency bases unchecked (`verify_gates: scoped` and `base_gates: off`).
|
|
115
|
+
- **A test-suite pool.** `AskUserQuestion`: `One suite at a time (Recommended for DB-backed suites)`, `Two at a time`, `No limit`. A limit emits `maestro.resources.test-suite` (`kind: semaphore`, `capacity` 1 or 2, `scope: host`) and `maestro.gates.test.requires: [test-suite]`. `scope: host` makes the limit hold across every maestro run on the machine, not just within one: two runs on one laptop, each with a one-suite limit, otherwise run two suites at once — the contention the limit exists to prevent. Then offer the runner's command patterns as the pool's `match` (`pytest*`, `uv run pytest*`, `pnpm test*`), which makes agents take the lease before running tests by hand.
|
|
116
|
+
- **Files git does not carry.** A maestro lane is a worktree and has only what git tracks. Read `.gitignore` for entries with a tracked `*.example` / `*.sample` / `*.template` sibling, the compose file's `env_file:` lines, and the gitignored settings module the framework imports (`DJANGO_SETTINGS_MODULE`'s local module, typically). Propose the list in a multi-select `AskUserQuestion` (header `Env files`), each path pre-selected; the user confirms or drops entries. → `maestro.project.env_files`. Every hook, gate and `manage.py` call in a lane depends on these, and a plan that omits them fails in ways that look like code problems. Nothing found → omit the key and say so.
|
|
117
|
+
|
|
118
|
+
- **Test-tool caches git must not carry.** Gates in a lane write cache and report files into the worktree, and an agent's `git add -A` there commits whatever is not ignored. Read `.gitignore` for the outputs of the runners and gates selected above: `.testmondata*` (pytest-testmon's SQLite database, plus its `-shm` / `-wal` siblings — tens of MB), `.pytest_cache/`, `junit/` or `junit*.xml`, `coverage/`, `.coverage`, `.coverage.*`, `htmlcov/`, `coverage.xml`, `.nyc_output/`, `.vitest/` and `.jest-cache/` where those runners are in use. Then read `.pre-commit-config.yaml` (or the project's hook runner) for `check-added-large-files`: that hook checks staged files, so a testmon database that is not ignored fails every lane commit and every maestro merge commit (`project.hooks: run`), and looks like a hook problem rather than a missing ignore rule. Propose the missing entries in a multi-select `AskUserQuestion` (header `Cache ignores`), each pre-selected, with `Add the selected entries (Recommended)` meaning append them to `.gitignore` under a `# test-tool caches` comment. When one is already tracked, say so: ignoring it does not untrack it, and the human runs `git rm --cached <path>` themselves. Nothing missing → say so and add nothing.
|
|
119
|
+
- **CI checks.** Read the CI config (`.github/workflows/*.yml`, `.gitlab-ci.yml`) for each check it runs — tests, lint, type check, `makemigrations --check --dry-run`, `check --deploy --fail-level WARNING`, a "generated client is current" diff — and compare with the gates chosen above. For each check no gate runs, `AskUserQuestion` (header `CI check`): `Add it as a project gate (Recommended)`, `Leave it to CI — it needs CI (I'll say why)`. A gate lands as `maestro.gates.<id>.cmd` with its id added to `maestro.defaults.gates`. A check left to CI lands under `maestro.ci_only` with its command and the reason, which `vinta-ai-maestro doctor` reports as a decision rather than warning about it on every run. Never drop one silently: an unrecorded gap is a warning in every run's log that people learn to skip.
|
|
120
|
+
- **Generated files and append-only registries.** Read the project for generators — an API schema command (`spectacular`, an `openapi.json` dump), a generated client (`openapi-ts`, `orval`, `openapi-generator`, `graphql-codegen`; `*.gen.ts`), a route tree (`routeTree.gen.ts`) — and for file-modifying hooks in `.pre-commit-config.yaml` / `lefthook.yml` / `lint-staged` (a schema hook, `ruff format`, `prettier --write`). Propose each as a codegen step in a multi-select `AskUserQuestion` (header `Codegen`), pre-selected, showing its command, inputs and outputs; a formatter is `format: true` with `{changed_files}` in its command. → `maestro.codegen`. Then propose append-only registries — DI containers, URL route lists, notification-kind registries, beat schedules — in a second multi-select (header `Registries`). → `maestro.append_only`. Nothing found → omit both keys and say so.
|
|
121
|
+
|
|
122
|
+
Everything here is a default under every plan. A plan's own `.workflow.json` overrides any of it, and a commit to this file on a running plan's branch (`plan/<workflow-id>/base`) is applied to that run.
|
|
97
123
|
|
|
98
124
|
### D. Optional foundation skills
|
|
99
125
|
|
|
100
|
-
|
|
126
|
+
Eight skills are part of the foundation set but aren't always needed. Ask explicitly:
|
|
101
127
|
|
|
102
128
|
1. **`add-e2e-test`** — does the project have e2e tests (Playwright / Cypress / similar) or plan to add them? `AskUserQuestion` options: `Yes — already has them`, `Yes — planning to add`, `No — skip`. If yes, [vinta-derive-skills](../vinta-derive-skills/SKILL.md)'s **Optional — ask the user** bucket follows up to ask whether the user has a template or wants to draft from scratch. **This answer also governs `create-qa-use-cases` and the e2e content inside `plan-feature`**: on `No — skip`, set `foundation_skills.create-qa-use-cases: disabled` too — derive-skills won't ship `create-qa-use-cases` and strips `plan-feature`'s `<!-- e2e:start/end -->` regions so no-e2e projects carry zero Playwright / `QA_USE_CASES.md` / `pr-screenshots/` references. On either `Yes`, set both `add-e2e-test` and `create-qa-use-cases` to `enabled`.
|
|
103
129
|
2. **`add-env-var`** — does the project have a non-trivial env-var propagation flow (multiple files / build configs / CI updates per new var) or a single `.env` file is enough? `AskUserQuestion` options: `Yes — non-trivial flow`, `No — single .env is enough`. Skip if `No`.
|
|
@@ -109,11 +135,22 @@ Seven skills are part of the foundation set but aren't always needed. Ask explic
|
|
|
109
135
|
- **Primary language.** `AskUserQuestion`: `Python`, `TypeScript`. Auto-pick from `inventory.frameworks` when one language clearly dominates; ask only when polyglot. Drives which `BaseOneOffScript` template gets staged at `<scripts_dir>/_base.{py,ts}`.
|
|
110
136
|
- **S3 bucket + prefix.** Open prose. Empty bucket disables S3 upload (filesystem copy stays authoritative). The skill also reads the `ONE_OFF_S3_BUCKET` / `ONE_OFF_S3_PREFIX` env vars at runtime, so leaving the config blank is fine if the team prefers env-only.
|
|
111
137
|
|
|
112
|
-
5. **`prepare-worktree`** — does the team want to run long-running plans / experiments inside an isolated git worktree (its own runnable copy of the app, with its own dev + test DB, env files, docker-compose project name) instead of swapping branches in the main checkout? `AskUserQuestion` options: `Yes — enable`, `No — skip`. Recommend `Yes` for any project with long migrations, multi-day plans, or teams where parallel concurrent work in the same checkout is common (one dev shipping a feature while another runs a migration; an agent driving `implement-plan` for hours while the human keeps coding on `main`). Skip for solo projects where branch-switching in place is unproblematic.
|
|
138
|
+
5. **`prepare-worktree`** — does the team want to run long-running plans / experiments inside an isolated git worktree (its own runnable copy of the app, with its own dev + test DB, env files, docker-compose project name) instead of swapping branches in the main checkout? `AskUserQuestion` options: `Yes — enable the skill`, `Yes — we provision with our own script/command`, `Yes — generate a provisioning script for this project`, `No — skip`. The second option is for teams that already have a provisioning script, and the third writes one for them. Both make provisioning deterministic and LLM-free: `implement-plan` runs the command instead of the skill (see the follow-ups below). Recommend the third for teams that want worktrees but have no script, when runs are frequent or parallel: the provisioning decisions are made once at bootstrap instead of by a model on every lane. Recommend it over the skill when inventory found an existing worktree script (`commands.worktree_candidates`): a `bin/*worktree*` / `scripts/*worktree*` file, or a Makefile / `justfile` / `package.json` target with `worktree` in its name. Recommend `Yes` for any project with long migrations, multi-day plans, or teams where parallel concurrent work in the same checkout is common (one dev shipping a feature while another runs a migration; an agent driving `implement-plan` for hours while the human keeps coding on `main`). Skip for solo projects where branch-switching in place is unproblematic.
|
|
113
139
|
|
|
114
|
-
**Follow-up only when `prepare-worktree` =
|
|
140
|
+
**Follow-up only when `prepare-worktree` = own script/command.** The skill does not ship (`foundation_skills.prepare-worktree: disabled`). Worktrees stay available, because `implement-plan` treats a configured command as the provisioner.
|
|
141
|
+
- **Prepare command.** `AskUserQuestion` (header `Worktree cmd`): one option per `commands.worktree_candidates` entry, as its invocation (`./bin/new-worktree`, `make worktree`, …); free text for any other. Prose only when nothing was found. Lands in `commands.worktree_prepare`. Show the user the contract their script must honor. It runs from the repo root with `VINTA_WORKTREE_NAME`, `VINTA_WORKTREE_PATH`, `VINTA_WORKTREE_BRANCH`, `VINTA_WORKTREE_BASE_REF`, `VINTA_WORKTREE_KIND`, `VINTA_MAIN_CHECKOUT`, `VINTA_PLAN_PATH` and `VINTA_WORKTREE_SUMMARY` set. It must create a runnable worktree at that path on that new branch, and exit non-zero on failure. Writing the summary YAML is optional. The full text is the `commands.worktree_prepare` description in the config schema. If their existing script takes positional arguments instead, offer a wrapper invocation (`./bin/new-worktree "$VINTA_WORKTREE_NAME" "$VINTA_WORKTREE_PATH"`) as the candidate.
|
|
142
|
+
- **Teardown command.** `AskUserQuestion` (header `Teardown`): the candidates found, plus `No teardown command — just git worktree remove`. Note on that option that any DB, volume or cache the prepare command creates would be left behind. Lands in `commands.worktree_teardown`; omit the key on `No`.
|
|
143
|
+
- **Worktree root.** Same question as in the skill follow-up below. Lands in `skills.prepare-worktree.worktree_root`; the conductor uses it to build `VINTA_WORKTREE_PATH`. The deps / test-DB strategy questions are skill-only, so skip them.
|
|
144
|
+
- The `implement-plan` worktree default and the parallel-execution follow-ups below apply as they do for the skill.
|
|
145
|
+
|
|
146
|
+
**Follow-up only when `prepare-worktree` = generate a provisioning script.** The skill does not ship (`foundation_skills.prepare-worktree: disabled`). The scripts are written by the optional [Generate the worktree command](#optional-step--generate-the-worktree-command) step after derive-skills; here, capture only what Step 0.5 needs:
|
|
147
|
+
- **Script directory.** `AskUserQuestion` (header `Script dir`): `scripts/worktree (Recommended)`, `bin/worktree`, plus any existing scripts directory the inventory found. Free text covers other paths. Step 0.5 emits `commands.worktree_prepare: <dir>/prepare.sh` and `commands.worktree_teardown: <dir>/teardown.sh`.
|
|
148
|
+
- **Worktree root.** Same question as in the skill follow-up below; lands in `skills.prepare-worktree.worktree_root`.
|
|
149
|
+
- The `implement-plan` worktree default and the parallel-execution follow-ups below apply as they do for the skill.
|
|
150
|
+
|
|
151
|
+
**Follow-up only when `prepare-worktree` = Yes — enable the skill — worktree defaults.** Three short questions land under `skills.prepare-worktree.*`:
|
|
115
152
|
- **Worktree root.** `AskUserQuestion`: `.claude/worktrees` (claude-code convention; the runtime's `EnterWorktree` puts them there), `../<repo-name>-wt-` (sibling dirs of the main checkout — survives across runtimes; relative-path tooling that walks up still works). Auto-pick the first when claude-code is the only selected vendor; ask when multiple vendors are in the **Scope** group's vendor coverage answer.
|
|
116
|
-
- **Default deps strategy
|
|
153
|
+
- **Default deps strategy.** Every worktree gets its own dependency dirs and never symlinks main's. `AskUserQuestion`: `copy` (copy-on-write clone of main's `node_modules` / `vendor/` — fast and close to free on disk on APFS / btrfs / XFS; right for npm / pnpm / cargo / go / bundler), `reinstall` (run the package manager fresh in the worktree — slower, but always correct). Recommend `copy`, except `reinstall` for poetry / uv / venv / yarn PnP projects, whose trees store absolute paths into the main checkout. The skill reinstalls virtualenvs and yarn PnP regardless of this default.
|
|
117
154
|
- **Default test-DB strategy.** `AskUserQuestion`: `fork-on-schema-change` (default — only forks when the plan body shows migrations), `always-fork` (defensive — every worktree gets its own test DB regardless), `share` (only safe for solo work; flaky cross-worktree test runs are the cost).
|
|
118
155
|
|
|
119
156
|
**Follow-up — `implement-plan` default for worktree opt-in.** `AskUserQuestion`: should the `implement-plan` Step 0 question (c) — "run phases in a worktree?" — default to `Yes` or `No`? Lands in `run_options.implement-plan.use_worktree`. Recommend `No` for solo projects + short plans; `Yes` for teams that already use worktrees as part of their workflow.
|
|
@@ -122,9 +159,9 @@ Seven skills are part of the foundation set but aren't always needed. Ask explic
|
|
|
122
159
|
- **Default for Step 0 question (e)?** `AskUserQuestion`: when a plan's dependency graph says several phases are independent, should `implement-plan` implement them **concurrently** (one worktree lane each) by default, or one at a time? Lands in `run_options.implement-plan.parallel_phases`. **Recommend `Yes` (the schema default)** — it is the whole reason the plan carries a dependency graph. Recommend `No` when review capacity is the team's bottleneck (a fan of simultaneous PRs helps nobody), when the repo has a merge queue that serializes anyway, or when developer machines are too small to run several app copies.
|
|
123
160
|
- **Lane cap.** `AskUserQuestion`: `2`, `3` (default), `4`, `6`. Lands in `run_options.implement-plan.max_parallel_lanes`. Each lane is a full runnable checkout — deps, forked dev + test DBs, its own compose project. Size it to the machine, not to the plan; the runtime caps it again at the widest wave.
|
|
124
161
|
|
|
125
|
-
Both are skipped, and `parallel_phases` is emitted as `false`, when `prepare-worktree` = No — parallel execution has a hard worktree requirement and `implement-plan` refuses rather than degrading.
|
|
162
|
+
Both are skipped, and `parallel_phases` is emitted as `false`, when `prepare-worktree` = No (neither the skill nor a command) — parallel execution has a hard worktree requirement and `implement-plan` refuses rather than degrading.
|
|
126
163
|
|
|
127
|
-
**Follow-up only when `systematic-debugging` = Yes — observability MCP server inventory.**
|
|
164
|
+
**Follow-up only when `systematic-debugging` = Yes — observability MCP server inventory.** First read the MCP servers actually configured in the project's AI tooling (`.mcp.json`, `~/.claude/mcp_servers.json`, `.codex/mcp.json`, etc.). Then ask a multi-select `AskUserQuestion` (header `MCP servers`): *"Which of these MCP servers expose observability data (errors, traces, logs, metrics)?"*, one option per configured server (up to 4; split into further calls when there are more). The free-text field takes any server not listed, in whatever shorthand the team uses (`sentry`, `datadog`, `our-internal-traces`, `grafana-prod`, etc.). When nothing is configured, ask the same thing in prose. The intent is not to pick from a fixed catalogue — that goes stale fast — but to give the systematic-debugging agent a starter list of servers to introspect at Phase 0. The selection lands in `skills.systematic-debugging.observability_mcp_servers` of `.vinta-ai-workflows.yaml` (free-form string array). Empty array is allowed but warn the user that Phase 0 collapses to "local logs only" and production-only bugs without telemetry become a guess factory. The agent will discover specific tool names + categories (error tracking, traces, logs, metrics, alerts, deploys, dashboards) from the live MCP tool list at runtime — see [vinta-derive-skills/resources/systematic-debugging-mcp-tools.md](../vinta-derive-skills/resources/systematic-debugging-mcp-tools.md) for the evidence categories baked into the rendered SKILL.md.
|
|
128
165
|
|
|
129
166
|
**Cache scaffolding.** Preflight state lives at `.vinta-ai-workflows/cache.yaml` ([`mcp-preflight-cache.v1`](../../schemas/mcp-preflight-cache.v1.schema.json)). The bootstrap orchestrator must:
|
|
130
167
|
|
|
@@ -132,9 +169,11 @@ Seven skills are part of the foundation set but aren't always needed. Ask explic
|
|
|
132
169
|
- Do **not** seed the cache file at bootstrap. The first debug run preflights all configured servers and writes the file then. An empty / missing `.vinta-ai-workflows/cache.yaml` is a valid initial state.
|
|
133
170
|
- Mention to the user how to refresh: delete the file to re-preflight everything, or edit one entry's `status` to `dirty` to refresh that one server. Token rotated → cache will catch the auth error on the next call and flip the entry to `dirty` automatically.
|
|
134
171
|
|
|
135
|
-
6. **`thermo-nuclear-code-quality-review`** — does the team want an opt-in, deliberately harsh structural-maintainability audit available on demand (abstraction quality, giant files, spaghetti-condition growth), separate from the standard per-phase review? `AskUserQuestion` options: `Yes — enable`, `No — skip`. Recommend `Yes` for long-lived codebases where structural drift is a real cost, or teams that already run deep quality passes before merging large work. It ships as a user-invoked skill
|
|
172
|
+
6. **`thermo-nuclear-code-quality-review`** — does the team want an opt-in, deliberately harsh structural-maintainability audit available on demand (abstraction quality, giant files, spaghetti-condition growth), separate from the standard per-phase review? `AskUserQuestion` options: `Yes — enable`, `No — skip`. Recommend `Yes` for long-lived codebases where structural drift is a real cost, or teams that already run deep quality passes before merging large work. It ships as a user-invoked skill, a deeper pass on top of the structural lens the per-phase review loop already applies; it is never auto-run on every diff. No follow-up config — the body is project-agnostic.
|
|
173
|
+
|
|
174
|
+
7. **`interview-ui`** — does the team want spec interviews (and, later, other decision-heavy interviews) to run as a full-screen browser form instead of a chat exchange? One decision per screen, with the context the agent already knows, Markdown/Mermaid explainers, and each option's consequences in view; the in-page chat is for questions to the agent, not decisions. `AskUserQuestion` options: `Yes — enable`, `No — skip`. Recommend `Yes` for teams where product or non-engineering stakeholders answer the spec interview, or whenever specs carry state machines and trade-offs that are hard to weigh in chat. Skip for solo engineers who prefer staying in the terminal. The page is served by `vinta-ai-maestro interview` (Node ≥ 22; `npx vinta-ai-maestro`, or a devDependency) and needs a browser on the machine running the agent. No follow-up config — the body is project-agnostic; `create-spec` asks per interview whether to use the browser or chat.
|
|
136
175
|
|
|
137
|
-
|
|
176
|
+
8. **`handoff-to-client`** — is this an API-only repo whose consumers live in separate client codebases (mobile apps, SPAs, partner integrations) that need API changes documented for them? Ask **only when the inventory suggests an API-only shape** — backend framework with no co-located frontend app (no SPA package, no templates-rendered UI beyond an admin). `AskUserQuestion` options: `Yes — enable`, `No — skip`. Skip the question entirely (set `disabled`) for full-stack repos and monorepos that contain their own clients — there the API diff is visible to the client code in the same PR. When enabled, agents can generate a markdown API-change handoff document (endpoints added / changed / deprecated / removed vs the default branch, request/response shapes, breaking-change flags, per-platform migration notes) for client implementers who cannot read this repo.
|
|
138
177
|
|
|
139
178
|
**Follow-up only when `handoff-to-client` = Yes — client-handoff config.** Four short questions land under `skills.handoff-to-client.*`:
|
|
140
179
|
- **Client platforms.** Open prose → free-form string array, e.g. `iOS (Swift)`, `Android (Kotlin)`, `web SPA (React)`, `partner integrations`. Required, non-empty — this is the document's audience and drives the per-operation migration-notes sections.
|
|
@@ -142,7 +181,17 @@ Seven skills are part of the foundation set but aren't always needed. Ask explic
|
|
|
142
181
|
- **API spec path.** Open prose. Repo-relative path to a machine-readable spec (OpenAPI file, GraphQL schema, proto dir) plus the command that regenerates it, if one exists (e.g. `docs/openapi.yaml (regenerate: make openapi)`). Cross-check the inventory for spec files the user forgot. Empty is fine — the rendered skill then enumerates changes from route/serializer code alone.
|
|
143
182
|
- **Output dir.** Default `.vinta-ai-workflows/client-handoffs`. Override if the team wants handoffs committed (e.g. `docs/api-changes/`) — note that the default lives under the gitignored `.vinta-ai-workflows/`, so docs there must be shared manually.
|
|
144
183
|
|
|
145
|
-
If the user answers "No" to any of the
|
|
184
|
+
If the user answers "No" to any of the eight, that skill won't ship. If the user answers "Yes" to `add-e2e-test` / `add-env-var` but doesn't have a template, derive-skills drafts one via interview. `systematic-debugging` is always template-rendered — no per-project drafting interview, just the MCP-server inventory above. `add-one-off-script` is copied verbatim from [vinta-derive-skills/resources/foundation-skills/add-one-off-script/](../vinta-derive-skills/resources/foundation-skills/add-one-off-script/) — its body is project-agnostic; the per-project variability lives in the `skills.add-one-off-script.*` config block above and in env vars consumed at runtime. `prepare-worktree` is also copied verbatim from [vinta-derive-skills/resources/foundation-skills/prepare-worktree/](../vinta-derive-skills/resources/foundation-skills/prepare-worktree/) — same pattern: project-agnostic body, per-project defaults under `skills.prepare-worktree.*`. `thermo-nuclear-code-quality-review` is copied verbatim from [vinta-derive-skills/resources/foundation-skills/thermo-nuclear-code-quality-review/](../vinta-derive-skills/resources/foundation-skills/thermo-nuclear-code-quality-review/) with no follow-up config — its body is fully project-agnostic. `interview-ui` is copied verbatim from [vinta-derive-skills/resources/foundation-skills/interview-ui/](../vinta-derive-skills/resources/foundation-skills/interview-ui/) as a whole directory (SKILL.md + `resources/examples/`) with no follow-up config; the server and the page are `vinta-ai-maestro interview`'s, not bundled. `handoff-to-client` is always template-rendered from [vinta-derive-skills/resources/handoff-to-client-template.md](../vinta-derive-skills/resources/handoff-to-client-template.md) — no per-project drafting interview, just the client-handoff config follow-up above.
|
|
185
|
+
|
|
186
|
+
### D.2 Integrations (external tools)
|
|
187
|
+
|
|
188
|
+
Integrations are external tools that ship their own skill. They are not foundation skills: this package bundles none of their content. When one is enabled, the tool's own CLI installs its skill, and this flow only wires that skill in. Ask once per integration:
|
|
189
|
+
|
|
190
|
+
1. **`pr-review-canvas`** ([PR Review Canvas](https://github.com/vintasoftware/pr-review-canvas), CLI `pr-review`). Should agents generate a review canvas for every PR they open? A canvas is the PR's diff grouped by topic, with attention points for the reviewer. It is shared as a PR comment and read in a local review app (`pr-review serve`). Ask **only when** `project.code_host` is `github` or `gitlab` **and** the `pr_creation` policy (C.4) is `agents-create`. Otherwise set `disabled` without asking: the tool supports only those two hosts, and with `branches-only` no agent opens a PR to attach a canvas to. `AskUserQuestion` options: `Yes — enable`, `No — skip`. Recommend `Yes` for teams that review agent-written PRs, where a large multi-phase diff is the normal case. Default to `Yes` when [vinta-analyze-codebase](../vinta-analyze-codebase/SKILL.md) already found the tool in use: a `pr-review-canvas` skill classified `integration`, or a `pr-review.config.yml`.
|
|
191
|
+
|
|
192
|
+
Mention the requirements in the question: Node.js 22+, a logged-in `gh` or `glab`, and Claude Code or Codex as the agent. Do **not** install the CLI. Like `open-pr.sh`'s `yq` / `jq` / `gh`, it is a machine-level dependency the user installs. [vinta-install-ai-tools-setup](../vinta-install-ai-tools-setup/SKILL.md) checks for it and prints `npm install -g @vintasoftware/pr-review-canvas` when it is missing.
|
|
193
|
+
|
|
194
|
+
No follow-up config. The tool's own settings (sharing on/off, high-risk paths, prompt overrides) live in its `pr-review.config.yml` at the repo root, and the tool owns that file.
|
|
146
195
|
|
|
147
196
|
### E. Existing AI artifacts (per-artifact disposition)
|
|
148
197
|
|
|
@@ -162,7 +211,9 @@ For each artifact, read it (frontmatter + body), then ask the user via `AskUserQ
|
|
|
162
211
|
- `Keep in current vendor path, don't touch` — leaves it where it is. AGENTS.md may reference it; downstream skill setup won't manage it.
|
|
163
212
|
- `Drop` — delete (rare; usually the user wants to migrate).
|
|
164
213
|
|
|
165
|
-
|
|
214
|
+
**Integration-owned skills** (name matches an integration under D.2 — today `pr-review-canvas`) get no question. Leave them where they are. Their tool owns them through its own marker file (`.pr-review-install`), and its `doctor` / `upgrade` commands manage them. When the integration is `enabled` and the existing copy sits in a real `.claude/skills/` or `.agents/skills/` directory rather than in `ai-tools/skills/`, tell the user once. [vinta-install-ai-tools-setup](../vinta-install-ai-tools-setup/SKILL.md) installs a fresh copy into `ai-tools/skills/`, so the old copy becomes redundant once the vendor directory is a symlink.
|
|
215
|
+
|
|
216
|
+
Foundation-shape skills (name matches `plan-feature`, `create-spec`, `create-qa-use-cases`, `implement-plan`, `implement-phase`, `review-phase`, `integrate-phase`, `amend-plan`, `add-e2e-test`, `add-env-var`, `add-one-off-script`, `prepare-worktree`, `thermo-nuclear-code-quality-review`, `interview-ui`, `thermo-nuclear-review-loop`, `deslop-comments`, `handoff`, `handoff-to-client`, `write-unit-test`) get an extra option: `Replace with Vinta foundation version` — overwrites with the canonical foundation content, preserving the user's name. Useful when the existing version is stale. (`implement-phase` / `review-phase` / `integrate-phase` are the plan-execution sub-skills co-shipped with `implement-plan`; replace them as a unit.)
|
|
166
217
|
|
|
167
218
|
- **Sub-agents** (each under any vendor `agents/` dir):
|
|
168
219
|
- `Migrate to ai-tools/agents/<name>.yaml` — converts vendor-specific format → canonical YAML; `setup-ai-tools.mjs` re-emits per-vendor copies.
|
|
@@ -204,9 +255,9 @@ Rules:
|
|
|
204
255
|
- When in doubt, reference DESIGN.md — do not invent new values
|
|
205
256
|
```
|
|
206
257
|
|
|
207
|
-
Globs may need tuning for the project's actual UI file extensions (Svelte-only projects, RN `.tsx`, etc.).
|
|
258
|
+
Globs may need tuning for the project's actual UI file extensions (Svelte-only projects, RN `.tsx`, etc.). When the analysis surfaced a UI framework not covered by the default glob list, ask once via `AskUserQuestion`: `Add <framework> globs (Recommended)` (name the globs you'd add), `Ship the defaults`. Otherwise ship the defaults.
|
|
208
259
|
|
|
209
|
-
After Step 0: read back the captured decisions (including every per-artifact disposition), confirm via `AskUserQuestion` (`Looks good`, `Some corrections (I'll list)`, `Stop, rethink`).
|
|
260
|
+
After Step 0: read back the captured decisions (including every per-artifact disposition), confirm via `AskUserQuestion` (`Looks good (Recommended)`, `Some corrections (I'll list)`, `Stop, rethink`).
|
|
210
261
|
|
|
211
262
|
The dispositions become inputs to:
|
|
212
263
|
|
|
@@ -220,7 +271,7 @@ Captured interview state lands in **one** YAML file at the repo root: `.vinta-ai
|
|
|
220
271
|
|
|
221
272
|
This file is the **only** source of truth for project-wide settings. Every downstream sub-skill (4 → 6 below) reads from it instead of receiving values via in-conversation state. Every meta-skill ([vinta-sync-ai-tools](../vinta-sync-ai-tools/SKILL.md), [vinta-update-project-skills](../vinta-update-project-skills/SKILL.md)) reads + rewrites it.
|
|
222
273
|
|
|
223
|
-
Write the file now (before any sub-skill runs). Populate from the interview groups **Scope**, **Stack detection**, **Project conventions**, **Optional foundation skills**, and **Existing AI artifacts**:
|
|
274
|
+
Write the file now (before any sub-skill runs). Populate from the interview groups **Scope**, **Stack detection**, **Project conventions**, **Optional foundation skills**, **Integrations**, and **Existing AI artifacts**:
|
|
224
275
|
|
|
225
276
|
```yaml
|
|
226
277
|
# yaml-language-server: $schema=./node_modules/vinta-ai-workflows/schemas/vinta-ai-workflows-config.v1.schema.json
|
|
@@ -243,9 +294,13 @@ commands:
|
|
|
243
294
|
format: <derived>
|
|
244
295
|
build: <derived>
|
|
245
296
|
test_unit: <Project conventions → Test framework(s)>
|
|
246
|
-
test_unit_scoped: <derived from monorepo shape>
|
|
297
|
+
test_unit_scoped: <C.11 scoped-gates template with {changed_files} when confirmed; else derived from monorepo shape>
|
|
298
|
+
lint_scoped: <C.11 scoped lint template; omit unless confirmed>
|
|
247
299
|
test_unit_new_pattern: <derived>
|
|
248
300
|
e2e: <only when foundation_skills.add-e2e-test = enabled>
|
|
301
|
+
# Only when the prepare-worktree answer was "own script/command" or "generate".
|
|
302
|
+
worktree_prepare: <own-command follow-up → prepare command | generate follow-up → <script dir>/prepare.sh>
|
|
303
|
+
worktree_teardown: <own-command follow-up → teardown command, omitted on "No teardown command" | generate follow-up → <script dir>/teardown.sh>
|
|
249
304
|
|
|
250
305
|
policies:
|
|
251
306
|
pr_creation: <Project conventions → PR creation policy>
|
|
@@ -279,9 +334,11 @@ foundation_skills:
|
|
|
279
334
|
add-env-var: <Optional foundation skills → add-env-var answer → enabled | disabled>
|
|
280
335
|
systematic-debugging: <Optional foundation skills → systematic-debugging answer → enabled | disabled>
|
|
281
336
|
add-one-off-script: <Optional foundation skills → add-one-off-script answer → enabled | disabled>
|
|
282
|
-
prepare-worktree: <Optional foundation skills → prepare-worktree answer → enabled | disabled>
|
|
337
|
+
prepare-worktree: <Optional foundation skills → prepare-worktree answer → enabled | disabled; disabled for "own script/command" and "generate">
|
|
283
338
|
thermo-nuclear-code-quality-review: <Optional foundation skills → thermo-nuclear-code-quality-review answer → enabled | disabled>
|
|
284
|
-
|
|
339
|
+
interview-ui: <Optional foundation skills → interview-ui answer → enabled | disabled>
|
|
340
|
+
thermo-nuclear-review-loop: enabled # always ships — review-phase runs it over every phase, and so does the review chore of every maestro workflow plan-feature writes
|
|
341
|
+
deslop-comments: enabled # always ships — the integrate-phase / amend-plan PR-context prose pass and maestro's deslop chore depend on it
|
|
285
342
|
handoff: enabled # always ships — project-agnostic session-continuation handoff docs
|
|
286
343
|
handoff-to-client: <Optional foundation skills → handoff-to-client answer → enabled | disabled; only asked for API-only repos>
|
|
287
344
|
write-unit-test: <enabled when a unit-test framework was detected (Project conventions → Test framework(s)); disabled when none found — default-on, not an opt-in>
|
|
@@ -291,13 +348,15 @@ foundation_agents:
|
|
|
291
348
|
reviewer: enabled
|
|
292
349
|
fixer: enabled
|
|
293
350
|
|
|
351
|
+
integrations:
|
|
352
|
+
pr-review-canvas: <Integrations → pr-review-canvas answer → enabled | disabled; disabled without asking when code_host ∉ {github, gitlab} or pr_creation = branches-only>
|
|
353
|
+
|
|
294
354
|
# Only emit the roles the user chose in the "Agent model tiers" question (C.10).
|
|
295
355
|
# Omit the whole block on "Leave unset"; omit any individual role left unset.
|
|
296
356
|
# Each value is a tier (1–4) into ai-tools/skills/plan-feature/resources/ai-models.yaml.
|
|
297
357
|
agent_models:
|
|
298
|
-
reviewer: <C.10 → reviewer tier, default 3>
|
|
299
358
|
fixer: <C.10 → fixer tier, default 2>
|
|
300
|
-
worktree_prep: <C.10 → worktree_prep tier, default 1; omit when prepare-worktree disabled>
|
|
359
|
+
worktree_prep: <C.10 → worktree_prep tier, default 1; omit when prepare-worktree disabled (including the own-command case — a command runs inline)>
|
|
301
360
|
integrate: <C.10 → integrate tier, default 1>
|
|
302
361
|
|
|
303
362
|
stacks: <Stack detection → matched stacks>
|
|
@@ -309,11 +368,52 @@ run_options:
|
|
|
309
368
|
generate_inline_comments: false
|
|
310
369
|
full_test_suite: false # default: each phase's outer gate runs scoped tests only; set true to run the full suite every phase
|
|
311
370
|
use_worktree: <Optional foundation skills → prepare-worktree follow-up → default for Step 0 question (c); false unless team opted in>
|
|
312
|
-
parallel_phases: <Optional foundation skills → parallel-execution follow-up → default for Step 0 question (e); true when
|
|
371
|
+
parallel_phases: <Optional foundation skills → parallel-execution follow-up → default for Step 0 question (e); true when worktrees are available (skill enabled or own command) and the team didn't opt out, false otherwise>
|
|
313
372
|
max_parallel_lanes: <parallel-execution follow-up → lane cap, default 3; omit when parallel_phases is false>
|
|
314
373
|
amend-plan:
|
|
315
374
|
blast_radius_signal_threshold: 2
|
|
316
375
|
|
|
376
|
+
# Only emit on C.11 → "Set project defaults". Omit the whole block on "Skip".
|
|
377
|
+
# Defaults UNDER every plan's .workflow.json: the plan wins wherever it says
|
|
378
|
+
# something. Emit only the keys the user answered; nothing here repeats a
|
|
379
|
+
# value maestro would derive from `commands` on its own.
|
|
380
|
+
maestro:
|
|
381
|
+
defaults:
|
|
382
|
+
gates: <C.11 → gates every phase runs, e.g. [typecheck, lint, test]>
|
|
383
|
+
gate_scope: <C.11 → omit for "scoped" (the default); `full` on "No — full command every time">
|
|
384
|
+
verify_gates: <C.11 → omit (the default, `full`); `scoped` on "Only on merged trees" or "Only on merged waves">
|
|
385
|
+
base_gates: <C.11 → omit (the default, `full`); `off` on "Only on merged waves">
|
|
386
|
+
gates:
|
|
387
|
+
test:
|
|
388
|
+
cmd: <C.11 → maestro-only test command; omit to use commands.test_unit>
|
|
389
|
+
fresh_cmd: <C.11 "Fresh database in the integration worktree" → the same command from a fresh test database, e.g. pytest --create-db -n auto; omit when the suite keeps no database between runs>
|
|
390
|
+
fresh_when: <C.11 "Fresh database in the integration worktree" → globs of the migration files, e.g. ['apps/*/migrations/*.py']; only alongside fresh_cmd>
|
|
391
|
+
tuning:
|
|
392
|
+
allowed_flags: <C.11 → ['--create-db'] alongside fresh_cmd, so the coordinator may add it; omit otherwise>
|
|
393
|
+
cold_cmd: <C.11 "Cold lanes" → what runs while a lane has no scope cache, e.g. the parallel full suite; omit when the scoped template needs no cache>
|
|
394
|
+
scope_cache: <C.11 "Cold lanes" → the cache files the scoped template narrows by, e.g. [apps/api/.testmondata]; omit otherwise>
|
|
395
|
+
requires: [test-suite] # only with a test-suite pool
|
|
396
|
+
resources:
|
|
397
|
+
test-suite: # only on a pool limit
|
|
398
|
+
capacity: <1 | 2>
|
|
399
|
+
kind: semaphore
|
|
400
|
+
scope: host
|
|
401
|
+
match: <C.11 → runner command patterns, e.g. ['pytest*', 'uv run pytest*']>
|
|
402
|
+
codegen: # C.11 → generators and file-modifying hooks; omit when none
|
|
403
|
+
<step-id>:
|
|
404
|
+
cmd: <the generator command, e.g. uv run python manage.py spectacular --file schema.yml>
|
|
405
|
+
inputs: <globs it reads, e.g. ['**/serializers.py', '**/views.py']; omit to run every time>
|
|
406
|
+
outputs: <globs it writes, e.g. [schema.yml]>
|
|
407
|
+
after: <steps that run first, e.g. [schema]; omit when none>
|
|
408
|
+
format: <true for a formatter whose cmd takes {changed_files}; omit otherwise>
|
|
409
|
+
append_only: <C.11 → registries phases only append to, e.g. [app/containers.py, app/urls.py]; omit when none>
|
|
410
|
+
ci_only: # C.11 "CI checks" → each CI command deliberately left to CI; omit when every one has a gate
|
|
411
|
+
- command: <the CI command as CI runs it>
|
|
412
|
+
reason: <why no gate runs it: credentials, a deploy, a hosted service>
|
|
413
|
+
project:
|
|
414
|
+
env_files: <C.11 → gitignored files every lane needs its own copy of, e.g. [.env, .env.docker, app/settings/local.py]; omit when none>
|
|
415
|
+
lane_seed: <C.11 "Cold lanes" → the same scope-cache paths, so a new lane gets a copy; omit otherwise>
|
|
416
|
+
|
|
317
417
|
skills:
|
|
318
418
|
# Only emit this block when foundation_skills.systematic-debugging = enabled.
|
|
319
419
|
systematic-debugging:
|
|
@@ -337,10 +437,11 @@ skills:
|
|
|
337
437
|
db_isolation: <C.9 → transaction-rollback | truncate | recreate | framework-default>
|
|
338
438
|
additional_conventions: <C.9 → free-form array of extra conventions inferred/supplied; [] when none>
|
|
339
439
|
|
|
340
|
-
# Only emit this block when foundation_skills.prepare-worktree = enabled
|
|
440
|
+
# Only emit this block when foundation_skills.prepare-worktree = enabled, or when
|
|
441
|
+
# commands.worktree_prepare is set — then emit worktree_root + summary_dir only.
|
|
341
442
|
prepare-worktree:
|
|
342
443
|
worktree_root: <prepare-worktree follow-up — `.claude/worktrees` | `../<repo>-wt-`>
|
|
343
|
-
deps_strategy: <prepare-worktree follow-up —
|
|
444
|
+
deps_strategy: <prepare-worktree follow-up — copy | reinstall>
|
|
344
445
|
compose_network: per-worktree
|
|
345
446
|
test_db_strategy: <prepare-worktree follow-up — fork-on-schema-change | always-fork | share>
|
|
346
447
|
summary_dir: .vinta-ai-workflows/worktrees
|
|
@@ -364,6 +465,14 @@ Validate the file against the schema before writing — if any required field is
|
|
|
364
465
|
|
|
365
466
|
Existing-project case: `.vinta-ai-workflows.yaml` already present → that's a re-bootstrap. Show the existing config, ask via `AskUserQuestion`: `Keep existing config and refresh sub-skills only`, `Re-interview and overwrite`, `Stop`. The `Refresh sub-skills only` path is the common case for older projects whose config was written by an earlier `vinta-bootstrap-ai-tools`.
|
|
366
467
|
|
|
468
|
+
## Optional step — Generate the worktree command
|
|
469
|
+
|
|
470
|
+
Runs after [vinta-derive-skills](../vinta-derive-skills/SKILL.md) (step 4) and before the install step, **only** when the `prepare-worktree` answer (D.5) was `Yes — generate a provisioning script for this project`. Skip it silently otherwise.
|
|
471
|
+
|
|
472
|
+
It writes `<script dir>/lib.sh`, `prepare.sh` and `teardown.sh` into the project, plus `gen-compose-worktree-override.sh` when the project uses docker compose. The source is the bundled templates in [resources/worktree-command/](resources/worktree-command/). The templates carry the `commands.worktree_prepare` contract, already tested: env resolution, `--dry-run`, sanity checks, `git worktree add`, rollback of a half-made worktree, compose isolation, the full summary YAML, and a teardown that refuses dirty worktrees and never runs `down -v`. This step fills only the **PROJECT STEPS** regions with this project's dependency, env, database and service handling, decided from the inventory, plus a few structured questions.
|
|
473
|
+
|
|
474
|
+
Follow [resources/worktree-command/README.md](resources/worktree-command/README.md): read before write in the chosen directory, render the placeholders, fill the regions, then verify (`bash -n`, a `--dry-run`, and an optional real smoke test the user opts into). It returns a status report like every sub-skill. On failure, the README's fix question can fall back to the `prepare-worktree` skill, which also updates `.vinta-ai-workflows.yaml`.
|
|
475
|
+
|
|
367
476
|
## Stack templates — detection only, content is user-supplied
|
|
368
477
|
|
|
369
478
|
[`resources/stacks/<stack>/notes.md`](resources/stacks/) defines **detection signals** + lists the **categories of skills + sub-agents that typically belong** to each stack. **It does NOT ship ready-made skill / agent content.** The team's specific skill library lives wherever the team keeps it (a shared repo, a personal `~/skills/` dir, a published package, a private gist) — the bootstrap orchestrator asks the user to point at it when a stack matches.
|
|
@@ -411,7 +520,8 @@ ai-tools/
|
|
|
411
520
|
│ ├── plan-feature/SKILL.md ← always (copied verbatim from derive-skills resources)
|
|
412
521
|
│ ├── create-spec/SKILL.md ← always (copied verbatim)
|
|
413
522
|
│ ├── create-qa-use-cases/SKILL.md ← always (copied verbatim)
|
|
414
|
-
│ ├──
|
|
523
|
+
│ ├── thermo-nuclear-review-loop/SKILL.md ← always (copied verbatim; the review chore of every maestro workflow plan-feature writes runs it)
|
|
524
|
+
│ ├── deslop-comments/SKILL.md ← always (copied verbatim; the integrate-phase / amend-plan PR-context prose pass and maestro's deslop chore depend on it)
|
|
415
525
|
│ ├── handoff/SKILL.md ← always (copied verbatim; session-continuation handoff docs under .vinta-ai-workflows/handoffs/)
|
|
416
526
|
│ ├── implement-plan/SKILL.md ← always (conductor; generated from template, project-specific)
|
|
417
527
|
│ ├── implement-phase/SKILL.md ← always (plan-execution unit; co-shipped with implement-plan)
|
|
@@ -433,7 +543,12 @@ ai-tools/
|
|
|
433
543
|
│ │ ├── one_off_script_base.py
|
|
434
544
|
│ │ └── one_off_script_base.ts
|
|
435
545
|
│ ├── prepare-worktree/SKILL.md ← optional — only if user opts in (verbatim copy; project-agnostic body, defaults under skills.prepare-worktree.*)
|
|
436
|
-
│ ├── thermo-nuclear-code-quality-review/SKILL.md ← optional — only if user opts in (verbatim copy; deep structural-maintainability audit,
|
|
546
|
+
│ ├── thermo-nuclear-code-quality-review/SKILL.md ← optional — only if user opts in (verbatim copy; deliberate deep structural-maintainability audit, run on request)
|
|
547
|
+
│ ├── interview-ui/ ← optional — only if user opts in (verbatim copy of the whole dir; browser form for decision-heavy interviews, used by create-spec Step 0; the page is served by `vinta-ai-maestro interview`)
|
|
548
|
+
│ │ ├── SKILL.md
|
|
549
|
+
│ │ └── resources/
|
|
550
|
+
│ │ └── examples/ ← sample round + explainer doc
|
|
551
|
+
│ ├── pr-review-canvas/ ← integration — only when integrations.pr-review-canvas = enabled and `pr-review` is installed. Written by `pr-review install-skill`, never by this flow; owned through its `.pr-review-install` marker, refreshed by `pr-review upgrade`
|
|
437
552
|
│ ├── run-one-off-script-django/ ← optional sister skill — only when stack matches + user supplies template (authors Jupyter notebook / mgmt command runner + JupyterRuntime / DjangoMgmtRuntime adapter in the per-script folder)
|
|
438
553
|
│ ├── run-one-off-script-medplum/ ← optional sister skill — only when stack matches + user supplies template (authors Medplum bot + MedplumBotRuntime adapter in the per-script folder)
|
|
439
554
|
│ └── <stack-specific skills>/SKILL.md ← only if user supplied templates
|
|
@@ -446,6 +561,12 @@ ai-tools/
|
|
|
446
561
|
└── scripts/
|
|
447
562
|
└── setup-ai-tools.mjs ← copied from install-ai-tools-setup resources
|
|
448
563
|
|
|
564
|
+
<script dir>/ ← only when D.5 = generate (default scripts/worktree/); the project owns these
|
|
565
|
+
├── prepare.sh ← commands.worktree_prepare
|
|
566
|
+
├── teardown.sh ← commands.worktree_teardown
|
|
567
|
+
├── lib.sh ← shared plumbing, sourced by both
|
|
568
|
+
└── gen-compose-worktree-override.sh ← only when the project uses docker compose
|
|
569
|
+
|
|
449
570
|
DESIGN.md ← preserved at repo root if pre-existing (never overwritten)
|
|
450
571
|
.cursor/rules/design.mdc ← only when DESIGN.md exists, user opted Wire it in,
|
|
451
572
|
and `cursor` ∈ vendors (Cursor Project Rules, Option A
|
|
@@ -462,9 +583,9 @@ Plus the symlinks + per-vendor generated files, set up by the install step. The
|
|
|
462
583
|
|
|
463
584
|
Foundation skills break into three buckets — see [vinta-derive-skills](../vinta-derive-skills/SKILL.md) for the full mechanics:
|
|
464
585
|
|
|
465
|
-
- **Always copy verbatim**: `plan-feature`, `create-spec`, `create-qa-use-cases`, `deslop-comments`, `handoff`. Bundled with the bootstrap skill set; project-agnostic enough to ship as-is (with light path scrubs). `deslop-comments` always ships because `
|
|
586
|
+
- **Always copy verbatim**: `plan-feature`, `create-spec`, `create-qa-use-cases`, `thermo-nuclear-review-loop`, `deslop-comments`, `handoff`. Bundled with the bootstrap skill set; project-agnostic enough to ship as-is (with light path scrubs). `deslop-comments` always ships because `integrate-phase` / `amend-plan` run it over the PR-context file and maestro's `deslop` chore runs it on every phase. `thermo-nuclear-review-loop` always ships because it is the per-phase review on both execution paths: `review-phase` runs it with the conductor as host, and the `review` chore of every `vinta-ai-maestro` workflow `plan-feature` writes runs it on a phase once its gates are green. `handoff` always ships because its session-continuation body is fully project-agnostic.
|
|
466
587
|
- **Always generate**: the plan-execution unit — `implement-plan` (conductor) + its co-shipped sub-skills `implement-phase` / `review-phase` / `integrate-phase`, plus `amend-plan` (conductor). Bodies have too much project-specific content (test commands, branch convention, PR + co-author policy, agent dispatch) — generated from parameterized templates + shared partials using interview answers + inventory. The sub-skills are not independently opt-in; they always ship with the conductors. `write-unit-test` is also template-rendered but **conditionally generated** — it ships whenever a unit-test framework was detected (not an opt-in question, not ask-first): the rendered body bakes in the project's test command + captured `skills.write-unit-test.*` conventions, and the verbatim packs land in its `resources/packs/` — one runner pack for the detected test framework plus a stack pack per matched stack (Django / FastAPI / Flask / Medplum / React / Next.js / TanStack Start / React Router / Prisma / pure-package), so framework-specific advice only ships when that framework is present. A few stack packs also apply a one-time project-setup step at derive time (e.g. Medplum wires the two FHIR-indexing Vitest setup files — `test.globalSetup.ts` + `test.setup.ts` — into the Vitest config so `MockClient` search filtering works) — a project mutation done once, not per test.
|
|
467
|
-
- **Optional, ask first**: `add-e2e-test`, `add-env-var`, `systematic-debugging`, `add-one-off-script`, `prepare-worktree`, `thermo-nuclear-code-quality-review`, `handoff-to-client`. Skipped by default; orchestrator asks via `AskUserQuestion` whether the project has the relevant flow at all. `add-e2e-test` / `add-env-var`: if yes + user has a template → copy + adapt; if yes + no template → draft from scratch via interview; if no → don't ship. `systematic-debugging`: if yes → render the bundled template plus the per-tool MCP catalogue blocks for the observability tools selected in its follow-up; if no → don't ship. `add-one-off-script`: if yes → copy the bundled SKILL.md verbatim plus the language-specific `BaseOneOffScript` template (`one_off_script_base.py` / `one_off_script_base.ts`) chosen via its follow-up; if no → don't ship. `prepare-worktree`: if yes → copy the bundled SKILL.md verbatim, populate `skills.prepare-worktree.*` defaults from its follow-ups, (when the user opted in via the worktree-default follow-up) flip `run_options.implement-plan.use_worktree` to `true` so `implement-plan`'s Step 0 question (c) defaults to yes, and emit `run_options.implement-plan.parallel_phases` + `max_parallel_lanes` from the parallel-execution follow-up; if no → don't ship, and emit `parallel_phases: false` (parallel execution cannot run without worktrees). `thermo-nuclear-code-quality-review`: if yes → copy the bundled SKILL.md verbatim (no follow-up config); if no → don't ship. `handoff-to-client`: asked only for API-only repos; if yes → render the bundled template using `skills.handoff-to-client.*` (client platforms, API style, spec path, output dir) from its follow-ups; if no → don't ship.
|
|
588
|
+
- **Optional, ask first**: `add-e2e-test`, `add-env-var`, `systematic-debugging`, `add-one-off-script`, `prepare-worktree`, `thermo-nuclear-code-quality-review`, `interview-ui`, `handoff-to-client`. Skipped by default; orchestrator asks via `AskUserQuestion` whether the project has the relevant flow at all. `add-e2e-test` / `add-env-var`: if yes + user has a template → copy + adapt; if yes + no template → draft from scratch via interview; if no → don't ship. `systematic-debugging`: if yes → render the bundled template plus the per-tool MCP catalogue blocks for the observability tools selected in its follow-up; if no → don't ship. `add-one-off-script`: if yes → copy the bundled SKILL.md verbatim plus the language-specific `BaseOneOffScript` template (`one_off_script_base.py` / `one_off_script_base.ts`) chosen via its follow-up; if no → don't ship. `prepare-worktree`: if yes → copy the bundled SKILL.md verbatim, populate `skills.prepare-worktree.*` defaults from its follow-ups, (when the user opted in via the worktree-default follow-up) flip `run_options.implement-plan.use_worktree` to `true` so `implement-plan`'s Step 0 question (c) defaults to yes, and emit `run_options.implement-plan.parallel_phases` + `max_parallel_lanes` from the parallel-execution follow-up; if own script/command → don't ship, and emit `commands.worktree_prepare` / `commands.worktree_teardown`; if generate → don't ship, emit the same keys pointing at `<script dir>/prepare.sh` / `teardown.sh`, and run the [Generate the worktree command](#optional-step--generate-the-worktree-command) step after derive-skills; if no → don't ship, and emit `parallel_phases: false` (parallel execution cannot run without worktrees). `thermo-nuclear-code-quality-review`: if yes → copy the bundled SKILL.md verbatim (no follow-up config); if no → don't ship. `handoff-to-client`: asked only for API-only repos; if yes → render the bundled template using `skills.handoff-to-client.*` (client platforms, API style, spec path, output dir) from its follow-ups; if no → don't ship.
|
|
468
589
|
|
|
469
590
|
Stack-specific skills + agents land in the target only when the user provides templates for them. If they don't have templates yet, the orchestrator records the detected stacks + skill categories as a TODO list the user can address later via [vinta-derive-skills](../vinta-derive-skills/SKILL.md) / [vinta-derive-subagents](../vinta-derive-subagents/SKILL.md) standalone runs.
|
|
470
591
|
|
|
@@ -472,7 +593,8 @@ Stack-specific skills + agents land in the target only when the user provides te
|
|
|
472
593
|
|
|
473
594
|
- **Read before write.** Always check what's in the target repo first. Don't clobber existing AGENTS.md / skills / agents without an explicit confirmation in Step 0.
|
|
474
595
|
- **Stack templates are starting points, not finals.** Each copied skill / agent must be reviewed against the actual project (interview the user about specifics) and edited where the template's assumptions don't fit.
|
|
475
|
-
- **
|
|
596
|
+
- **Every stop for input is a structured question.** See [asking-the-human](../vinta-write-agents-md/resources/asking-the-human.md). A prose question at the end of a long report is the failure mode — the user has to hunt for it and type the answer.
|
|
597
|
+
- **Don't fabricate conventions.** If `vinta-analyze-codebase` doesn't find a thing, ask the user (`AskUserQuestion`, offering what you did find as candidates). Don't write "Use bulk_create instead of loop+save" into AGENTS.md just because Django was detected — confirm the team actually follows it.
|
|
476
598
|
- **Foundation skills are universal.** Every project gets `add-env-var`, `add-e2e-test`, `plan-feature`, `implement-plan`, `create-spec`, `create-qa-use-cases`. The bodies need light per-project edits (test commands, branch conventions) — `vinta-derive-skills` handles that.
|
|
477
599
|
- **Foundation agents are universal.** `implementer` / `reviewer` / `fixer` always. Stack specialists (`deploy-author` for Medplum, `migration-author` for Django) only when the stack matches.
|
|
478
600
|
- **Don't run install-ai-tools-setup until AGENTS.md + agents YAMLs + skills exist.** The setup script reads these files; running it on an empty `ai-tools/` produces nothing useful.
|
|
@@ -496,6 +618,7 @@ After all sub-skills finish:
|
|
|
496
618
|
3. Each selected vendor's directory has the expected files: `.claude/agents/*.md`, `.cursor/agents/*.md`, `.github/agents/*.agent.md`, `.codex/agents/*.toml`.
|
|
497
619
|
4. Spot-check one skill, one agent: open SKILL.md / `<agent>.yaml` and confirm content describes THIS project (not a copy-pasted template with `<placeholder>` strings).
|
|
498
620
|
5. If the project uses Claude Code: in a new session, ask Claude to invoke one of the project-specific skills. Confirm it loads + the body looks right.
|
|
499
|
-
6. If
|
|
621
|
+
6. If the worktree command was generated: `bash -n` passes on `<script dir>/*.sh`, `<script dir>/prepare.sh vinta-smoke --dry-run` prints a plausible plan, and `.vinta-ai-workflows.yaml` points `commands.worktree_prepare` / `commands.worktree_teardown` at the generated files.
|
|
622
|
+
7. If [vinta-migrate-plans-specs](../vinta-migrate-plans-specs/SKILL.md) ran: `ls ai-plans/` lists the migrated docs in canonical `YYYY-MM-DD-{FEATURE_NAME}_{PLAN|SPEC}.md` form. `git status` shows the renames staged (or already committed). No plan/spec markdown left orphaned in `docs/`, `specs/`, or repo root unless the user explicitly skipped them.
|
|
500
623
|
|
|
501
624
|
End the run with a one-paragraph summary: what was created, what was skipped (per `--only`), what manual edits the user should review.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Each subdirectory here defines a **stack** — a set of detection signals + a description of what kinds of skills + sub-agents typically belong to that stack. The bootstrap flow uses these to:
|
|
4
4
|
|
|
5
5
|
1. Detect (via [vinta-analyze-codebase](../../../vinta-analyze-codebase/SKILL.md)) which stacks the target project matches.
|
|
6
|
-
2. Ask the user "I detected stack X; do you have skill / sub-agent templates for it?
|
|
6
|
+
2. Ask the user via `AskUserQuestion` "I detected stack X; do you have skill / sub-agent templates for it?" (`Yes — I'll give the path` with the path typed into the free-text field, `No — record as gap`) — bootstrap doesn't ship pre-baked content.
|
|
7
7
|
3. Copy + adapt the user-provided templates into the target's `ai-tools/skills/` and `ai-tools/agents/`.
|
|
8
8
|
|
|
9
9
|
This keeps the bootstrap skill **infrastructure only**. Specific skill content (e.g. "how to add a Medplum bot") lives wherever the user keeps their personal / team skill library, not here.
|
|
@@ -25,7 +25,7 @@ If no multi-tenancy signals → single-tenant Django; the team's templates may s
|
|
|
25
25
|
- **Create-postgres-function** (if the project ships custom `CREATE FUNCTION` / aggregates) — versioned function migrations.
|
|
26
26
|
- **Create-data-import / create-data-export** — async import/export commands feeding integrations.
|
|
27
27
|
- **GraphQL-public-query** (if the project uses Strawberry or Graphene) — public-API mutation/query patterns.
|
|
28
|
-
- **REST-endpoint** (if the project uses Django REST Framework or django-ninja) - REST API endpoint patterns.
|
|
28
|
+
- **REST-endpoint** (if the project uses Django REST Framework or django-ninja) - REST API endpoint patterns. With drf-spectacular, ask whether the team's endpoint template requires every new `choices` field the API exposes to add its `ENUM_NAME_OVERRIDES` entry in the same change. Parallel phases that each add a `status` field with different choices otherwise collide on the generated enum name (`StatusEnum`), and the collision only shows at integration, in the schema test.
|
|
29
29
|
- **Run-one-off-script-django** — sister to the universal `add-one-off-script` foundation skill. Authors the *runner* artefact in the per-script folder (Jupyter notebook in `notebooks/` is the typical Vinta default; a thin `BaseCommand` under `<app>/management/commands/<name>.py` is the alternative for headless / cron / CI invocation) and ships the matching `Runtime` adapter at `<scripts_dir>/_runtime_django.py` (`JupyterRuntime` and/or `DjangoMgmtRuntime`). Adapter responsibilities: hook `BaseCommand.handle()` into `BaseOneOffScript.execute()`; respect `python manage.py <name> --apply` / `--resume` / `--status` / `--restore` flags; load Django settings + DB connection before the engine starts iterating; for the Jupyter variant, swap signal handlers for kernel-interrupt and skip the PID-file lease (notebook = single instance by construction). README in the per-script folder spells out `python manage.py shell < script.py`, `jupyter lab notebooks/<name>/runner.ipynb`, and `python manage.py <name> --apply` as the three legitimate entry points.
|
|
30
30
|
|
|
31
31
|
## Agent categories typically needed
|
|
@@ -45,6 +45,41 @@ If no multi-tenancy signals → single-tenant Django; the team's templates may s
|
|
|
45
45
|
- One-off script invocation surface (Jupyter notebook in `notebooks/<name>/`, Django management command, both) — drives the `run-one-off-script-django` skill's runner artefact + which `Runtime` adapter ships
|
|
46
46
|
- Notebook directory path (`notebooks/`, `<project>/notebooks/`) — only when Jupyter is selected as a runner surface
|
|
47
47
|
|
|
48
|
+
## Gates that should mirror CI
|
|
49
|
+
|
|
50
|
+
Ask which of these CI runs, and suggest each one it runs as a gate, so a phase cannot pass every gate and still fail CI. Declare each once, project-wide, as a custom gate under `maestro.gates.<id>` in `.vinta-ai-workflows.yaml` (e.g. `django-check: { cmd: ... }`, `api-client-fresh: { cmd: ... }`) and add its id to `maestro.defaults.gates` — every plan then runs it as its own gate, with its own verdict. Don't chain these onto the `typecheck` / `test` lines in `commands`: one verdict for several unrelated checks tells a fixer nothing about which one failed.
|
|
51
|
+
|
|
52
|
+
- **Deploy check at warning level** — `python manage.py check --deploy --fail-level WARNING` (with the CI settings module). Catches what `check` alone passes: URL patterns Django warns about (e.g. a `path()` route that looks like a regex), security settings, model warnings. One observed run added regex-style routes that passed every gate and failed this check in CI.
|
|
53
|
+
- **Migrations complete** — `python manage.py makemigrations --check --dry-run`.
|
|
54
|
+
- **Generated client / schema up to date** — when the project generates an OpenAPI/GraphQL schema or a typed frontend client from the Django API (drf-spectacular, Strawberry, django-ninja + an openapi codegen), a gate that regenerates it and fails on a diff (`<generate command> && git diff --exit-code <schema/client paths>`).
|
|
55
|
+
|
|
56
|
+
Placeholders to ask about: the settings module CI runs checks with, and the schema/client generate command and its output paths.
|
|
57
|
+
|
|
58
|
+
## Test commands in lanes
|
|
59
|
+
|
|
60
|
+
Ask how the suite runs, because maestro runs it in many worktrees at once, one merged tree after another in its integration worktree:
|
|
61
|
+
|
|
62
|
+
- **Database reuse.** With `pytest --reuse-db` (or `--keepdb`), a database a test run left behind applies forward migrations and never removes ones the current tree lacks. The integration worktree switches branches between merges, so its test gate needs a fresh-database form (`--create-db`, `make test_reset test`) — bootstrap emits it as `maestro.gates.test.fresh_cmd`.
|
|
63
|
+
- **Scoped runs with testmon.** `pytest --testmon` without a `.testmondata` runs every test, serially. A `test_changed` target should fall back to the full parallel run when the file is missing, and bootstrap declares the cache as `scope_cache` / `lane_seed`. `--testmon` with `-n` trades correctness for speed: testmon cannot attribute what an xdist worker ran.
|
|
64
|
+
- **One run at a time per lane.** A DB-backed suite shares its lane's test databases with any other run in that lane. Ask about the test-suite pool, and tell agents to check `docker ps` for a leftover `<lane>-api-run-*` container before starting another run.
|
|
65
|
+
|
|
66
|
+
Placeholders to ask about: the fresh-database form of the test command, the testmon cache path, the full parallel command.
|
|
67
|
+
|
|
68
|
+
## The dev container and the worktree
|
|
69
|
+
|
|
70
|
+
When `docker-compose.yml` bind-mounts the repository into the dev container, anything the container writes into the mount belongs to the container's user — root by default — and a lane whose `apps/api/.venv` is root-owned cannot be cleaned or recycled from the host (one observed phase failed six times on such a lane). Ask whether the compose file already keeps these out of the mount, and suggest, as changes the team makes to its own compose file:
|
|
71
|
+
|
|
72
|
+
- the virtual environment outside the mounted tree: `UV_PROJECT_ENVIRONMENT=/opt/venv` (uv), or a named volume over the `.venv` path;
|
|
73
|
+
- the dev service running as the host user: `user: "${UID}:${GID}"`, with `UID`/`GID` exported in the project's env file.
|
|
74
|
+
|
|
75
|
+
## Registries every phase appends to
|
|
76
|
+
|
|
77
|
+
URL route lists (`routes.py`), DI containers (`containers.py`), task packages (`tasks/__init__.py`) and drf-spectacular's `ENUM_NAME_OVERRIDES` are edited by nearly every phase of a plan, and they cause most of its merge work — including auto-merges git accepts that leave two list openers or a duplicated import. Ask which the project has, and suggest either a registry per feature module (`routes/<feature>.py` gathered by a loader, tasks found by autodiscovery), or listing them under `maestro.append_only` so maestro merges them with git's union driver. Either way the merged tree is gated.
|
|
78
|
+
|
|
79
|
+
## Test determinism
|
|
80
|
+
|
|
81
|
+
Tests that touch dates freeze the clock and set the timezone explicitly (`freezegun` / `time-machine` + `override_settings(TIME_ZONE=...)`), and schema generation reads no host state — timezone choices come from a pinned `tzdata`, not the OS tz database. Ask whether the project already has `freezegun`/`time-machine` and `tzdata` in its dev/lock dependencies; the `write-unit-test` Django pack assumes them.
|
|
82
|
+
|
|
48
83
|
## When this stack doesn't apply cleanly
|
|
49
84
|
|
|
50
85
|
- Django REST framework but no DB (read-only API on top of an external service) → most of these skills don't apply.
|