vinta-ai-workflows 0.1.7
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 +830 -0
- package/LICENSE +21 -0
- package/README.md +547 -0
- package/package.json +27 -0
- package/schemas/README.md +84 -0
- package/schemas/mcp-preflight-cache.v1.schema.json +50 -0
- package/schemas/prs-context-comments.v1.schema.json +51 -0
- package/schemas/prs-context-frontmatter.v1.schema.json +77 -0
- package/schemas/sub-agent.v1.schema.json +105 -0
- package/schemas/vinta-ai-workflows-config.v1.schema.json +283 -0
- package/skills/vinta-analyze-codebase/SKILL.md +325 -0
- package/skills/vinta-bootstrap-ai-tools/SKILL.md +375 -0
- package/skills/vinta-bootstrap-ai-tools/resources/stacks/README.md +50 -0
- package/skills/vinta-bootstrap-ai-tools/resources/stacks/django/notes.md +52 -0
- package/skills/vinta-bootstrap-ai-tools/resources/stacks/medplum/notes.md +45 -0
- package/skills/vinta-bootstrap-ai-tools/resources/stacks/nextjs-app-router/notes.md +35 -0
- package/skills/vinta-bootstrap-ai-tools/resources/stacks/python-package/notes.md +31 -0
- package/skills/vinta-bootstrap-ai-tools/resources/stacks/typescript-monorepo/notes.md +32 -0
- package/skills/vinta-derive-skills/SKILL.md +200 -0
- package/skills/vinta-derive-skills/resources/amend-plan-template.md +355 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/add-one-off-script/SKILL.md +292 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/add-one-off-script/resources/one_off_script_base.py +602 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/add-one-off-script/resources/one_off_script_base.ts +624 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/create-qa-use-cases/SKILL.md +232 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/create-spec/SKILL.md +235 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/open-pr-from-context/SKILL.md +78 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/open-pr-from-context/scripts/open-pr.sh +357 -0
- package/skills/vinta-derive-skills/resources/foundation-skills/plan-feature/SKILL.md +418 -0
- package/skills/vinta-derive-skills/resources/implement-plan-template.md +375 -0
- package/skills/vinta-derive-skills/resources/prs-context-template.md +91 -0
- package/skills/vinta-derive-skills/resources/systematic-debugging-mcp-tools.md +125 -0
- package/skills/vinta-derive-skills/resources/systematic-debugging-template.md +167 -0
- package/skills/vinta-derive-subagents/SKILL.md +192 -0
- package/skills/vinta-install-ai-tools-setup/SKILL.md +138 -0
- package/skills/vinta-install-ai-tools-setup/resources/setup-ai-tools.mjs +392 -0
- package/skills/vinta-migrate-plans-specs/SKILL.md +229 -0
- package/skills/vinta-sync-ai-tools/SKILL.md +184 -0
- package/skills/vinta-update-project-skills/SKILL.md +178 -0
- package/skills/vinta-write-agents-md/SKILL.md +192 -0
- package/vinta-ai-workflows.mjs +316 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# TypeScript monorepo stack
|
|
2
|
+
|
|
3
|
+
## Detection signals
|
|
4
|
+
|
|
5
|
+
- `turbo.json` at repo root, OR `pnpm-workspace.yaml` / `package.json:workspaces`, OR `nx.json`.
|
|
6
|
+
- Multi-app layout: `apps/` + (`lib/` | `packages/`).
|
|
7
|
+
- Per-app `package.json` with framework deps.
|
|
8
|
+
|
|
9
|
+
## Skill categories typically needed
|
|
10
|
+
|
|
11
|
+
This stack is **foundation-level** — no domain-specific skills are mandatory. The patterns it influences are mostly cross-cutting:
|
|
12
|
+
|
|
13
|
+
- **Add-env-var** (always) — propagation across `.env.example`, Vite/Next/whatever envPrefix allowlist, `turbo.json` per-task `env` lists, app config modules, AGENTS.md env section, CI workflows.
|
|
14
|
+
- **Add-shared-package / add-shared-lib** (sometimes) — when the team has a convention for new `lib/<name>` or `packages/<name>` subprojects (workspace name, exports map, build/test wiring).
|
|
15
|
+
|
|
16
|
+
## Agent categories typically needed
|
|
17
|
+
|
|
18
|
+
None specific — the foundation trio (`implementer`, `reviewer`, `fixer`) covers TS monorepo work.
|
|
19
|
+
|
|
20
|
+
## Placeholders the orchestrator should ask about
|
|
21
|
+
|
|
22
|
+
- Package manager (`pnpm`, `npm`, `yarn`)
|
|
23
|
+
- Build orchestrator (`turbo`, `nx`, `lerna`, plain workspaces)
|
|
24
|
+
- App directories pattern (`apps/`, `services/`, `examples/`)
|
|
25
|
+
- Shared lib directories pattern (`lib/`, `packages/`, `shared/`)
|
|
26
|
+
- Lint+format tool (`biome`, `eslint+prettier`, `dprint`)
|
|
27
|
+
- Test runner (`vitest`, `jest`)
|
|
28
|
+
- Type check command (`tsc --noEmit`, `pnpm build`, none)
|
|
29
|
+
|
|
30
|
+
## When this stack doesn't apply
|
|
31
|
+
|
|
32
|
+
- Single-package TS repo → don't add monorepo-specific skills; foundation is enough.
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vinta-derive-skills
|
|
3
|
+
description: Author project-specific skills under `ai-tools/skills/`. Always copies the project-agnostic foundation set (`plan-feature`, `create-spec`, `create-qa-use-cases`) verbatim from this skill's bundled resources. Generates `implement-plan` from a parameterized template using project-specific commands + branch / commit / PR conventions captured in the bootstrap interview. Asks the user whether `add-e2e-test` and `add-env-var` are needed (optional foundation skills — only ship if applicable). Stack-specific skills (Medplum, Django, etc) come from user-supplied templates pointed at by the orchestrator — see [bootstrap-ai-tools/resources/stacks/<stack>/notes.md](../vinta-bootstrap-ai-tools/resources/stacks/) for the categories per stack.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Derive skills
|
|
7
|
+
|
|
8
|
+
Author the project's `ai-tools/skills/<name>/SKILL.md` files. Skills are reusable instruction sets the agent invokes when a task matches their description.
|
|
9
|
+
|
|
10
|
+
## Output
|
|
11
|
+
|
|
12
|
+
`ai-tools/skills/<name>/SKILL.md` for each skill. Some skills bring resources (templates, scripts) — those go under `ai-tools/skills/<name>/resources/`.
|
|
13
|
+
|
|
14
|
+
## Inputs
|
|
15
|
+
|
|
16
|
+
1. Inventory from [vinta-analyze-codebase](../vinta-analyze-codebase/SKILL.md), specifically `existing_ai_artifacts.skills` — every skill file already in the repo with name, description, classification (`vinta-managed` / `foundation-shape` / `project-custom`).
|
|
17
|
+
2. AGENTS.md from [vinta-write-agents-md](../vinta-write-agents-md/SKILL.md).
|
|
18
|
+
3. Step 0 interview answers from [vinta-bootstrap-ai-tools](../vinta-bootstrap-ai-tools/SKILL.md), including the [Existing AI artifacts](../vinta-bootstrap-ai-tools/SKILL.md#e-existing-ai-artifacts-per-artifact-disposition) group's **per-skill disposition** (migrate / keep / drop / replace).
|
|
19
|
+
4. Stack matches from the inventory; for each, the skill categories listed in [bootstrap-ai-tools/resources/stacks/<stack>/notes.md](../vinta-bootstrap-ai-tools/resources/stacks/).
|
|
20
|
+
5. User-supplied stack templates for matched stacks (path / URL / package — asked at runtime).
|
|
21
|
+
|
|
22
|
+
## Reconcile against existing skills (do this FIRST)
|
|
23
|
+
|
|
24
|
+
Before drafting any new SKILL.md, walk through every entry in `existing_ai_artifacts.skills` and apply the disposition the user picked in the bootstrap interview's [Existing AI artifacts](../vinta-bootstrap-ai-tools/SKILL.md#e-existing-ai-artifacts-per-artifact-disposition) group:
|
|
25
|
+
|
|
26
|
+
- **Migrate to `ai-tools/skills/<name>/`** — `git mv` the existing skill folder (with all its resources) into the canonical layout. After move, scan the body for hard-coded vendor paths that no longer apply (`.cursor/skills/...` self-references, etc.) and rewrite to the new path. `setup-ai-tools.mjs` will re-link to the chosen vendors.
|
|
27
|
+
- **Keep in current vendor path, don't touch** — leave it where it is; AGENTS.md may reference it; downstream skill setup won't manage it. **Don't ship a foundation duplicate that would shadow it.**
|
|
28
|
+
- **Drop** — log removal; don't emit anything.
|
|
29
|
+
- **Replace with Vinta foundation version** (foundation-shape only — `plan-feature`, `create-spec`, `create-qa-use-cases`, `implement-plan`, `add-e2e-test`, `add-env-var`, `add-one-off-script`) — proceed with the bucket A / B / C flow below for that name. The user has explicitly opted into overwriting their version.
|
|
30
|
+
- **`vinta-managed`** (any skill whose dir starts with `vinta-`) — leave alone. These come from the `vinta-ai-workflows` CLI; `vinta-derive-skills` doesn't manage them.
|
|
31
|
+
|
|
32
|
+
For each name in the foundation set: only emit it (verbatim copy / generate from template / interview-draft) when no existing skill of that name is being migrated or kept. If the user said `Migrate` or `Keep` for an existing `plan-feature/SKILL.md`, **do not overwrite**.
|
|
33
|
+
|
|
34
|
+
For project-custom skills: never auto-generate something the user already has under a different name. If the user has `<their-name>/SKILL.md` covering ground a stack template would also cover, ask before adding the stack-template version.
|
|
35
|
+
|
|
36
|
+
## Foundation set
|
|
37
|
+
|
|
38
|
+
Three buckets:
|
|
39
|
+
|
|
40
|
+
### A. Always copy — verbatim from bundled resources
|
|
41
|
+
|
|
42
|
+
These are project-agnostic enough to ship as-is. Copy from this skill's [resources/foundation-skills/](resources/foundation-skills/) into the target's `ai-tools/skills/<name>/SKILL.md`.
|
|
43
|
+
|
|
44
|
+
| Skill | Source | What it does |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| `plan-feature` | [resources/foundation-skills/plan-feature/SKILL.md](resources/foundation-skills/plan-feature/SKILL.md) | Author phased implementation plans for a new feature, with interview-driven scoping. |
|
|
47
|
+
| `create-spec` | [resources/foundation-skills/create-spec/SKILL.md](resources/foundation-skills/create-spec/SKILL.md) | Turn a raw feature prompt into a structured spec doc. |
|
|
48
|
+
| `create-qa-use-cases` | [resources/foundation-skills/create-qa-use-cases/SKILL.md](resources/foundation-skills/create-qa-use-cases/SKILL.md) | Bootstrap a project's `QA_USE_CASES.md` from the active spec/plan. |
|
|
49
|
+
| `open-pr-from-context` | [resources/foundation-skills/open-pr-from-context/](resources/foundation-skills/open-pr-from-context/) | Thin SKILL.md wrapper around [scripts/open-pr.sh](resources/foundation-skills/open-pr-from-context/scripts/open-pr.sh) — bash script that publishes one `.vinta-ai-workflows/prs-context/{feature}/{phase}.md` file as a real PR + inline comments via the project's PR CLI (`gh` / `glab`). Used by `implement-plan` (when CLI + `yq`/`jq` are available) and standalone (to publish a `pending` file later). |
|
|
50
|
+
|
|
51
|
+
These four reference each other:
|
|
52
|
+
|
|
53
|
+
- `plan-feature` reads spec; dispatches `create-qa-use-cases` when the doc is missing.
|
|
54
|
+
- `implement-plan` (bucket B below) writes per-phase PR-context files following [resources/prs-context-template.md](resources/prs-context-template.md), then invokes `open-pr-from-context` when a PR CLI is detected.
|
|
55
|
+
|
|
56
|
+
Copy all four or none — they form a unit.
|
|
57
|
+
|
|
58
|
+
After copying, scan each for project-specific path references that no longer match the target (the bundled copies may still carry source-repo paths such as `<source-repo>/ai-plans/` or `apps/<service>/`). Replace with the target's paths from the inventory.
|
|
59
|
+
|
|
60
|
+
### B. Generate — `implement-plan`, `amend-plan`, `systematic-debugging` from templates
|
|
61
|
+
|
|
62
|
+
Project-specific skills, generated from templates because their bodies cite real test commands, branch conventions, agent dispatch table, PR / co-author policy, or selected MCP tools:
|
|
63
|
+
|
|
64
|
+
- **`implement-plan`** — forward execution: drives a fresh plan phase-by-phase. From [resources/implement-plan-template.md](resources/implement-plan-template.md).
|
|
65
|
+
- **`amend-plan`** — history rewriting: revises an in-flight plan, amends already-implemented phase commits, force-pushes, rebases stacked downstream branches. From [resources/amend-plan-template.md](resources/amend-plan-template.md). Companion to `implement-plan` — same agents, same review gates, same PR-context flow, opposite git topology direction.
|
|
66
|
+
- **`systematic-debugging`** — root-cause-first debugging flow with project-specific reproduction commands and enforced observability MCP evidence-gathering. From [resources/systematic-debugging-template.md](resources/systematic-debugging-template.md) plus the **MCP-agnostic** evidence-categories block at [resources/systematic-debugging-mcp-tools.md](resources/systematic-debugging-mcp-tools.md) — the rendered SKILL.md instructs the agent to list available MCP tools at runtime and map them to evidence categories (error tracking, traces, logs, metrics, alerts, deploys, dashboards), instead of hardcoding tool names that go stale. **Opt-in** — only generated when `foundation_skills.systematic-debugging` is `enabled` in `.vinta-ai-workflows.yaml`. The free-form list of MCP server identifiers rendered into the body comes from `skills.systematic-debugging.observability_mcp_servers` in the same config.
|
|
67
|
+
|
|
68
|
+
`implement-plan` and `amend-plan` consume the same placeholder set below — render each by substituting from the inventory + Step 0 interview answers. `systematic-debugging` reuses the same set plus two extra placeholders (`{{OBSERVABILITY_MCP_BLOCK}}`, `{{OBSERVABILITY_MCP_LIST}}`) rendered from the catalogue.
|
|
69
|
+
|
|
70
|
+
| Placeholder | Source | Example |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| `{{PROJECT_NAME}}` | inventory.repo.name | `ACME Sleep` |
|
|
73
|
+
| `{{STACK_SUMMARY}}` | inventory.frameworks one-liner | `pnpm + Turbo + Vite + React + Medplum + Playwright` |
|
|
74
|
+
| `{{PLAN_DIR}}` | derived from where `*_IMPLEMENTATION_PLAN.md` lives | `ai-plans` or `apps/<service>/ai-plans` |
|
|
75
|
+
| `{{LINT_CMD}}` | inventory.commands.lint | `pnpm lint:fix` or `pre-commit run --files <changed>` or `ruff check` |
|
|
76
|
+
| `{{FORMAT_CMD}}` | inventory.commands.format | `pnpm format` or `ruff format` |
|
|
77
|
+
| `{{BUILD_CMD}}` | inventory.commands.build | `pnpm build` or `make all-tests` (when build is the type gate) |
|
|
78
|
+
| `{{TYPECHECK_NOTE}}` | derived | empty, or ` plus full mypy via 'mypy app/'` |
|
|
79
|
+
| `{{TEST_CMD}}` | inventory.commands.test_unit | `pnpm test`, `make all-tests`, `pytest` |
|
|
80
|
+
| `{{SCOPED_TEST_NOTE}}` | derived | empty, or `; per-app via 'pnpm test:patient' / 'pnpm test:provider'` |
|
|
81
|
+
| `{{NEW_TEST_CMD_PATTERN}}` | derived | `pnpm --filter <pkg> test -- <new-test-path>` or `pytest path/to/new_test.py -x` |
|
|
82
|
+
| `{{SCOPED_TEST_PATTERN}}` | derived | `pnpm test:patient`, `pytest tests/{unit,integration}/{app}/` |
|
|
83
|
+
| `{{E2E_BLOCK}}` | populated only if e2e selected — see C below | block describing e2e command + screenshot copy |
|
|
84
|
+
| `{{E2E_OUTER_GATE_LINE}}` | depends on e2e selected | ` c. **E2E:** ...` or empty |
|
|
85
|
+
| `{{E2E_LAYER1_NOTE}}`, `{{E2E_LAYER2_CHECK}}`, `{{E2E_REPORT_FIELD}}`, `{{E2E_OUTER_GATE_CHECKLIST}}`, `{{UI_E2E_RULE_LINE}}` | depends on e2e selected | populated or empty strings |
|
|
86
|
+
| `{{STACK_SPECIFIC_DEPLOY_BLOCK}}` | from matched stacks | `- Bots: \`pnpm bots:build\`, \`pnpm bots:deploy --env=dev-<handle>\`...` for Medplum, or empty |
|
|
87
|
+
| `{{CODE_HOST}}` | Step 0 interview | `GitHub`, `GitLab`, `Bitbucket` |
|
|
88
|
+
| `{{DEFAULT_BRANCH}}` | inventory.repo.default_branch | `main` or `master` |
|
|
89
|
+
| `{{PR_*}}` family (`{{PR_POLICY_DESCRIPTION}}`, `{{PR_POLICY_BLOCK}}`, `{{PR_REMINDER_LINE}}`, `{{BRANCH_PUSH_HEADING}}`, `{{PR_LINK_NOTE}}`, `{{FINAL_REPORT_PR_NOTE}}`, `{{PR_RULE_TAIL}}`, `{{PR_CHECKLIST_NOTE}}`, `{{FINAL_CHECKLIST_PR_NOTE}}`, `{{PUSH_INSTRUCTION_LINE}}`) | Step 0 (PR creation policy) | Describes whether agents create PRs vs only push branches. **Note:** PR creation itself goes through the rendered skill's **Open PR via context file** step (`prs-context` file + bundled `open-pr.sh`), not raw `gh pr create` lines. These placeholders cover the framing (description, push instructions, checklist + summary phrasing) — the **Open PR via context file** matrix consumes the policy directly. |
|
|
90
|
+
| `{{COAUTHOR_*}}` family (`{{COAUTHOR_POLICY_BLOCK}}`, `{{COAUTHOR_INSTRUCTION_LINE}}`, `{{COAUTHOR_LAYER1_CHECK}}`, `{{COAUTHOR_RULE_LINE}}`, `{{COAUTHOR_CHECKLIST_NOTE}}`) | Step 0 (AI co-author policy) | If "forbidden": "Do NOT add `Co-Authored-By: Claude` ..." everywhere. If "allowed": empty / softer language. |
|
|
91
|
+
| `{{COMMIT_STYLE_LINE}}` | Step 0 (commit style) + repo log | `Default subject: short imperative, ≤72 chars` or `Conventional Commits format: type(scope): subject` |
|
|
92
|
+
| `{{ANTI_GIT_ADD_ALL_REASON}}` | derived from common artifacts in target | `secrets, .env files, build artifacts, .auth/ live in the tree` |
|
|
93
|
+
| `{{STAGE_PATTERN}}` | derived from monorepo shape | `apps/... lib/... e2e/... ai-plans/...` or `<app>/... tests/... ai-plans/...` |
|
|
94
|
+
| `{{PROJECT_SKILLS_LIST}}` | computed from skills emitted | comma-separated names of the skills the project actually has |
|
|
95
|
+
| `{{AGENT_DISPATCH_TABLE}}` | from [vinta-derive-subagents](../vinta-derive-subagents/SKILL.md) output | markdown table mapping phase shapes → agent type |
|
|
96
|
+
| `{{OBSERVABILITY_MCP_BLOCK}}` | rendered from [resources/systematic-debugging-mcp-tools.md](resources/systematic-debugging-mcp-tools.md) | the verbatim "Phase 0 evidence categories" block — same content for every project. When `skills.systematic-debugging.observability_mcp_servers` is empty, renders the no-tools fallback paragraph instead. The block is MCP-agnostic on purpose: tool names are discovered at runtime, not baked at generation time. |
|
|
97
|
+
| `{{OBSERVABILITY_MCP_LIST}}` | derived from `skills.systematic-debugging.observability_mcp_servers` | comma-separated MCP server identifiers as the user named them at bootstrap (e.g. `sentry, datadog, our-internal-traces`). Renders `none configured` when empty. |
|
|
98
|
+
|
|
99
|
+
Render each template with substitutions, write to:
|
|
100
|
+
|
|
101
|
+
- `ai-tools/skills/implement-plan/SKILL.md` (from `implement-plan-template.md`)
|
|
102
|
+
- `ai-tools/skills/amend-plan/SKILL.md` (from `amend-plan-template.md`)
|
|
103
|
+
- `ai-tools/skills/systematic-debugging/SKILL.md` (from `systematic-debugging-template.md`) — only when `foundation_skills.systematic-debugging: enabled`
|
|
104
|
+
|
|
105
|
+
Validate each output: every `{{PLACEHOLDER}}` should be replaced; if any survive, the template needs a new substitution rule. `implement-plan` and `amend-plan` share the same placeholder set — fix substitutions for both at the same time. `systematic-debugging` adds the two MCP-related placeholders; if a project picks an observability tool the catalogue doesn't list, ask the user for a free-form snippet (heading, required calls, fields to extract) and inline it before saving — and consider upstreaming the snippet to [resources/systematic-debugging-mcp-tools.md](resources/systematic-debugging-mcp-tools.md).
|
|
106
|
+
|
|
107
|
+
### C. Optional — ask the user
|
|
108
|
+
|
|
109
|
+
Two skills depend on whether the project actually does the thing. Ask via `AskUserQuestion`:
|
|
110
|
+
|
|
111
|
+
| Skill | Question | If yes |
|
|
112
|
+
|---|---|---|
|
|
113
|
+
| `add-e2e-test` | "Does this project have e2e tests, or plan to add them?" Options: `Yes — already has them`, `Yes — planning to add`, `No — skip` | Ask if user has an existing template (path / URL). If yes → copy + adapt. If no → draft from scratch using the canonical structure (see "Skill SKILL.md structure" below) interviewing user about: e2e framework, page-object pattern, auth/storage-state pattern, seed-helpers location, tenant scoping in seeds, screenshot conventions for PRs. |
|
|
114
|
+
| `add-env-var` | "Does this project have a non-trivial env-var propagation flow (multiple files / build configs / CI to update for one new var)?" Options: `Yes`, `No — single .env file is enough` | Ask if user has an existing template. If yes → copy + adapt. If no → draft from scratch interviewing user about every layer the new var must touch (`.env.example`, build tool envPrefix allowlist, build cache hash inputs, app config module, AGENTS.md env section, CI workflows, deploy-time injection). |
|
|
115
|
+
| `add-one-off-script` | "Does this project ever need one-off operational scripts — backfills, cleanups, ad-hoc data fixes?" Options: `Yes — enable`, `No — skip`. Recommend `Yes` for any project with a relational DB; the skill bundles a `BaseOneOffScript` class enforcing dry-run-by-default, idempotent re-runs, batched DB ops, streamed reads, segmented CSV backups (1M cells/file, never nested across tables), interruption-safe signal handlers, and console + filesystem + S3 logging. | Copy [resources/foundation-skills/add-one-off-script/](resources/foundation-skills/add-one-off-script/) into `ai-tools/skills/add-one-off-script/` (SKILL.md + the bundled `resources/one_off_script_base.{py,ts}` templates). Then ask the user whether they want the base class file pre-staged at `<scripts_dir>/one_off/_base.{py,ts}` — default `Yes` for projects whose primary lang is Python or TS. The skill itself prompts to copy the base class on first use if the user said `No` here. |
|
|
116
|
+
|
|
117
|
+
If user answers "No" to any: don't ship that skill. Record nothing — the foundation set is just smaller.
|
|
118
|
+
|
|
119
|
+
If user answers "Yes" but has no template: draft from scratch via interview. The orchestrator can defer this to a separate `vinta-derive-skills` standalone run if the user wants to ship the rest first.
|
|
120
|
+
|
|
121
|
+
## Stack-specific skills (user-supplied)
|
|
122
|
+
|
|
123
|
+
[bootstrap-ai-tools/resources/stacks/<stack>/notes.md](../vinta-bootstrap-ai-tools/resources/stacks/) describes **detection signals + skill categories typically needed** for each stack — NOT ready-made content. The team's specific skill library lives wherever they keep it.
|
|
124
|
+
|
|
125
|
+
For each stack the inventory matched, surface to the user:
|
|
126
|
+
|
|
127
|
+
> Detected stack `<X>`. The notes for this stack list these skill categories: A, B, C. Do you have existing skill templates for any of these?
|
|
128
|
+
|
|
129
|
+
`AskUserQuestion`-style prompts:
|
|
130
|
+
- *"Do you have a skill template for `<category>`?"* → `Yes — at this path/URL`, `No — record as gap`, `Skip this category for now`.
|
|
131
|
+
|
|
132
|
+
When the user provides a path:
|
|
133
|
+
1. Read the source SKILL.md (or YAML — both formats supported).
|
|
134
|
+
2. Replace placeholder paths / dep names / command names with the target's specifics, using the placeholder list from [resources/stacks/<stack>/notes.md](../vinta-bootstrap-ai-tools/resources/stacks/).
|
|
135
|
+
3. Drop sections that don't apply.
|
|
136
|
+
4. Save to `ai-tools/skills/<name>/SKILL.md`.
|
|
137
|
+
|
|
138
|
+
When the user has no template: record the category as a gap. Output as part of the orchestrator's final summary.
|
|
139
|
+
|
|
140
|
+
## Skill SKILL.md structure (for any skill drafted from scratch)
|
|
141
|
+
|
|
142
|
+
```markdown
|
|
143
|
+
---
|
|
144
|
+
name: <kebab-case> # required, matches dir name
|
|
145
|
+
description: <text> # required, dense one-liner of what + when
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
# {Skill name}
|
|
149
|
+
|
|
150
|
+
Short framing: what this is, why it exists.
|
|
151
|
+
|
|
152
|
+
## Decision questions (when applicable)
|
|
153
|
+
The questions to answer before doing the thing.
|
|
154
|
+
|
|
155
|
+
## Checklist
|
|
156
|
+
Step-by-step, numbered. Each step names files + commands.
|
|
157
|
+
|
|
158
|
+
## Pitfalls
|
|
159
|
+
The "we got burned by this" list.
|
|
160
|
+
|
|
161
|
+
## Verification
|
|
162
|
+
How to confirm the work is done correctly.
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Length: 100–300 lines. Shorter = under-specified. Longer = should probably split.
|
|
166
|
+
|
|
167
|
+
## Naming
|
|
168
|
+
|
|
169
|
+
- Lowercase, kebab-case.
|
|
170
|
+
- Verb-led for skills that DO something: `add-bot`, `create-spec`, `manage-access-policy`, `plan-feature`.
|
|
171
|
+
- Match the dir name to the `name` field exactly (Cursor + VS Code Copilot constraint).
|
|
172
|
+
|
|
173
|
+
## Rules
|
|
174
|
+
|
|
175
|
+
- **Don't ship copy-pasted source-project SKILL.md files unchanged.** Run search-and-replace for source project names / paths / commands before saving.
|
|
176
|
+
- **Foundation set is a unit.** Always copy `plan-feature` + `create-spec` + `create-qa-use-cases` together — they reference each other.
|
|
177
|
+
- **`implement-plan` is generated, not copied.** Its body has too much project-specific content for verbatim shipping.
|
|
178
|
+
- **Optional skills (`add-e2e-test`, `add-env-var`, `add-one-off-script`) are gated by user answer.** Don't ship them by default.
|
|
179
|
+
- **Each skill solves one job.** Two unrelated checklists → split.
|
|
180
|
+
- **Reference real files in the target.** Skill links must point to existing paths.
|
|
181
|
+
- **Skills auto-load by description.** Specific triggers, specific outcomes.
|
|
182
|
+
- **Never use `§N` shorthand to point at sections in any drafted SKILL.md body, agent prompt, or rendered template.** Use the section's full name (and a markdown anchor link when the link target is reachable). `§N` shorthand makes cross-references hard for humans to follow and breaks when section numbering shifts. This rule applies to both the foundation skills shipped verbatim and the template-rendered ones.
|
|
183
|
+
|
|
184
|
+
## Pitfalls
|
|
185
|
+
|
|
186
|
+
- **Forgetting to substitute placeholders in `implement-plan`.** A surviving `{{TEST_CMD}}` is a runtime confusion. Validate before saving.
|
|
187
|
+
- **Copying foundation skills and forgetting to scrub source-project paths.** Bundled copies may still carry source-repo paths (e.g. `<source-repo>/ai-plans/`, `apps/<service>/`). Replace with the target's paths.
|
|
188
|
+
- **Asking too many questions for optional skills.** If `vinta-analyze-codebase` shows no e2e dir and the user clearly has no e2e setup, it's OK to skip the question and not ship `add-e2e-test`. Use judgment.
|
|
189
|
+
- **Skipping the foundation copy because "the user already has them".** They probably don't. Confirm by reading the target's `ai-tools/skills/` (if it exists at all). If it does have these, ask the user "refresh from bundled copies, or keep what you have?".
|
|
190
|
+
|
|
191
|
+
## Verification
|
|
192
|
+
|
|
193
|
+
After all skills written:
|
|
194
|
+
|
|
195
|
+
1. Each `ai-tools/skills/<name>/SKILL.md` has frontmatter `name` + `description`, plus markdown body.
|
|
196
|
+
2. `name` field matches dir name.
|
|
197
|
+
3. No `{{PLACEHOLDER}}` strings survive in any output skill.
|
|
198
|
+
4. Foundation skills (plan-feature, create-spec, create-qa-use-cases) reference each other correctly via `[name](../<name>/SKILL.md)` links.
|
|
199
|
+
5. `implement-plan` body cites real commands + the project's actual code host + branch / PR / co-author policy.
|
|
200
|
+
6. Setup script ([vinta-install-ai-tools-setup](../vinta-install-ai-tools-setup/SKILL.md)) runs cleanly with the new skills in place.
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: amend-plan
|
|
3
|
+
description: Adjust an existing implementation plan in `{{PLAN_DIR}}/` after implementation has started or finished. Updates the plan file (revising existing phases or appending new ones), then for each affected phase that was already implemented adjusts its commits (`git commit --amend` or new commits) on the phase branch, force-pushes the rewritten branch, rebases every downstream stacked phase branch, force-pushes each, and refreshes the PR-context files. Use when the user says "amend the plan", "update phase N", "add a phase to plan X", "the spec changed, fix the plan", or "rewrite the implementation for phase N". NOT for one-off changes to a single file unrelated to a plan; use the regular implement skill for that. {{PR_POLICY_DESCRIPTION}}
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Amend Plan
|
|
7
|
+
|
|
8
|
+
Revise a plan in [`{{PLAN_DIR}}/`]({{PLAN_DIR}}/) after work has begun. Companion to [implement-plan](../implement-plan/SKILL.md): same agents, same review gates, same PR-context flow — but the orchestrator's job here is **history rewriting** instead of forward execution.
|
|
9
|
+
|
|
10
|
+
The flow is destructive (force-push). Every modification is gated on user confirmation. Default disposition for any ambiguous case is "stop and ask" — never force-push without an explicit per-branch `Confirm` from the user.
|
|
11
|
+
|
|
12
|
+
## Working assumptions
|
|
13
|
+
|
|
14
|
+
- Repo: {{PROJECT_NAME}} ({{STACK_SUMMARY}}). Conventions: [AGENTS.md](AGENTS.md).
|
|
15
|
+
- Plan files: [`{{PLAN_DIR}}/YYYY-MM-DD-FEATURE_NAME_PLAN.md`]({{PLAN_DIR}}/).
|
|
16
|
+
- Lint: `{{LINT_CMD}}`. Format: `{{FORMAT_CMD}}`.
|
|
17
|
+
- Type / build gate: `{{BUILD_CMD}}`{{TYPECHECK_NOTE}}.
|
|
18
|
+
- Unit / integration tests: `{{TEST_CMD}}`{{SCOPED_TEST_NOTE}}.
|
|
19
|
+
{{E2E_BLOCK}}
|
|
20
|
+
{{STACK_SPECIFIC_DEPLOY_BLOCK}}
|
|
21
|
+
- Code host: **{{CODE_HOST}}**. {{PR_POLICY_BLOCK}}
|
|
22
|
+
- {{COAUTHOR_POLICY_BLOCK}}
|
|
23
|
+
- Default branch: `{{DEFAULT_BRANCH}}`.
|
|
24
|
+
- Branch naming convention (set by [implement-plan](../implement-plan/SKILL.md)): `plan/{plan-id-kebab}/phase-{phase.id}`.
|
|
25
|
+
|
|
26
|
+
## When to use
|
|
27
|
+
|
|
28
|
+
- A spec change forces a phase body rewrite (different acceptance, different decisions in the plan's **Guiding Decisions**).
|
|
29
|
+
- A phase was implemented but the resulting diff is wrong / incomplete (caught post-merge to the phase branch but pre-merge to `{{DEFAULT_BRANCH}}`).
|
|
30
|
+
- A new phase needs to slot in between two existing ones, or be appended.
|
|
31
|
+
- A guiding decision in **Guiding Decisions** changed and it cascades into multiple phases.
|
|
32
|
+
|
|
33
|
+
## When NOT to use
|
|
34
|
+
|
|
35
|
+
- **Phase already merged to `{{DEFAULT_BRANCH}}`.** History cannot be retroactively rewritten on `{{DEFAULT_BRANCH}}`. The change must go in as a new phase appended to the plan, implemented forward via [implement-plan](../implement-plan/SKILL.md). This skill detects this case and refuses to force-push a merged branch.
|
|
36
|
+
- **Single-file change unrelated to a plan.** Use the regular implement skill / direct edit.
|
|
37
|
+
- **The plan never started.** No commits to amend; just edit the plan file and run [implement-plan](../implement-plan/SKILL.md) normally.
|
|
38
|
+
|
|
39
|
+
## Step 0 — Understand the change + parse the plan
|
|
40
|
+
|
|
41
|
+
1. **Identify the plan file.** Same logic as the [implement-plan "Locate + parse plan" step](../implement-plan/SKILL.md#step-0--locate--parse-plan): ask the user (path or feature name); `ls {{PLAN_DIR}}/` + grep; confirm before proceeding.
|
|
42
|
+
|
|
43
|
+
2. **Capture the requested change.** The user's prompt is the source. If vague, interview via `AskUserQuestion`:
|
|
44
|
+
- *"Which phases are affected?"* — enumerate phase ids from the plan's **Phased Rollout** section.
|
|
45
|
+
- *"Is this a body rewrite of an existing phase, a new phase to slot in, or a **Guiding Decisions** change that cascades?"*
|
|
46
|
+
- *"What's the new acceptance criterion / change list?"* — verbatim.
|
|
47
|
+
Don't infer scope. The plan-amend is the user's contract, not yours.
|
|
48
|
+
|
|
49
|
+
3. **Parse the plan.** Same structured fields as [implement-plan's "Extract structured fields" step](../implement-plan/SKILL.md#step-0--locate--parse-plan): plan id, **Goals + Non-goals** / **Guiding Decisions** / **Data Model Changes** / phase records from **Phased Rollout** / **Risk & Rollout Notes** through **Touch List**.
|
|
50
|
+
|
|
51
|
+
4. **Read the tracking file** `{{PLAN_DIR}}/TRACKING_{plan-id}.md` if present. Its `Completed Phases` section tells you which phase branches were pushed and which model + base were used. If absent → `git branch -a | grep plan/{plan-id-kebab}` to enumerate pushed phase branches.
|
|
52
|
+
|
|
53
|
+
5. **Build a per-phase state map.** For every phase in the plan, record:
|
|
54
|
+
|
|
55
|
+
| Field | Source |
|
|
56
|
+
|---|---|
|
|
57
|
+
| `phase.id`, `phase.title` | plan's **Phased Rollout** section |
|
|
58
|
+
| `state` | one of `not-started` / `in-progress` / `implemented-not-merged` / `merged-to-default` |
|
|
59
|
+
| `branch` | tracking file or git, pattern `plan/{plan-id-kebab}/phase-{id}` |
|
|
60
|
+
| `base` | tracking file or `git merge-base origin/<branch> <prev-branch>`; root phase bases on `{{DEFAULT_BRANCH}}` |
|
|
61
|
+
| `pr_status` | `.vinta-ai-workflows/prs-context/{feature-kebab}/phase-{id}.md` frontmatter (`pending` / `published`) when the file exists |
|
|
62
|
+
| `merged_to_default` | `git branch --merged origin/{{DEFAULT_BRANCH}} | grep` against the branch |
|
|
63
|
+
|
|
64
|
+
`merged-to-default = true` blocks any commit rewrite for that phase — see [Step 3 — Refuse force-pushes that can't work](#step-3--refuse-force-pushes-that-cant-work) below.
|
|
65
|
+
|
|
66
|
+
6. **Classify the requested change** by phase impact, in priority order:
|
|
67
|
+
|
|
68
|
+
- **`body-rewrite`** — existing phase keeps its id; body changes. Cascades downstream because rewritten commits get new SHAs.
|
|
69
|
+
- **`insert-new`** — new phase between existing ones. Cascades downstream because every later phase rebases onto the new branch.
|
|
70
|
+
- **`append-new`** — new phase tacked on after the last one. No downstream cascade. Implementation runs forward via [implement-plan](../implement-plan/SKILL.md) — this skill hands off after editing the plan file.
|
|
71
|
+
- **`guiding-decisions-change`** — change inside the plan's **Guiding Decisions** section. Cascades into every phase that referenced the decision.
|
|
72
|
+
|
|
73
|
+
7. **Evaluate amendment blast radius — recommend restart when too big.** Amending in place stops being a good deal once the rewrite work approaches re-implementation. Compute these signals from the per-phase state map + the requested change:
|
|
74
|
+
|
|
75
|
+
| Signal | Threshold suggesting RESTART |
|
|
76
|
+
|---|---|
|
|
77
|
+
| Phases needing `body-rewrite` ÷ total implemented phases | ≥ 50% |
|
|
78
|
+
| `guiding-decisions-change` cascading into | ≥ 50% of implemented phases |
|
|
79
|
+
| Phases in `merged-to-default` (immutable, must be `append-new`) | ≥ 2, AND remaining work also rewrites earlier phases |
|
|
80
|
+
| New body materially changes the data-model contract from **Data Model Changes** | rewrite of >2 phases hinges on it |
|
|
81
|
+
| Estimated touched LoC across rewrites | ≥ 70% of original implementation diff size (rough estimate via `git diff --stat <base>..<branch>` summed across affected branches) |
|
|
82
|
+
| Multi-author phase branches in the rewrite queue | ≥ 1 (force-push erases collaborator local state) |
|
|
83
|
+
| Approved PRs in the rewrite queue | ≥ 2 (re-review burden becomes non-trivial) |
|
|
84
|
+
|
|
85
|
+
Any **two** signals tripping → mark the amendment as `high-blast-radius`. **Three or more** → mark as `restart-recommended`.
|
|
86
|
+
|
|
87
|
+
When `high-blast-radius` or `restart-recommended`, surface to the user via `AskUserQuestion` **before** showing the standard step-8 confirmation:
|
|
88
|
+
|
|
89
|
+
- *"This amendment looks large enough that restarting from scratch may cost less than rewriting in place. Tripping signals: <list>. Restarting means: rewrite the plan as a fresh `YYYY-MM-DD-FEATURE_NAME_PLAN.md` (today's date), abandon the current phase branches (leave them in place for audit), run [implement-plan](../implement-plan/SKILL.md) on the new plan from scratch. Amending in place keeps history but force-pushes <N> branches and re-spawns implementer/reviewer/fixer agents per phase."*
|
|
90
|
+
|
|
91
|
+
Options:
|
|
92
|
+
|
|
93
|
+
- `Restart — draft a new plan, abandon current branches`
|
|
94
|
+
- `Amend in place — proceed knowing the cost (you'll show me the force-push plan next)`
|
|
95
|
+
- `Stop — let me think / talk to the team first`
|
|
96
|
+
|
|
97
|
+
On `Restart`:
|
|
98
|
+
|
|
99
|
+
1. Help the user draft a new `YYYY-MM-DD-FEATURE_NAME_PLAN.md` with today's date (paired with the spec, same `FEATURE_NAME`). This skill does not write the new plan body — point at [plan-feature](../plan-feature/SKILL.md) (or [create-spec](../create-spec/SKILL.md) first if the spec also changed).
|
|
100
|
+
2. Annotate the **old** plan: at the top, add `**Superseded YYYY-MM-DD by ../YYYY-MM-DD-FEATURE_NAME_PLAN.md** — reason: <one line>`. Append the same line under `## Amendments`.
|
|
101
|
+
3. Leave the old phase branches alone — useful audit trail, no force-push needed.
|
|
102
|
+
4. Update `TRACKING_{plan-id}.md` to mark the plan superseded; preserve all completed-phase entries.
|
|
103
|
+
5. Hand off to [plan-feature](../plan-feature/SKILL.md). This skill exits.
|
|
104
|
+
|
|
105
|
+
On `Amend in place`: proceed to step 8 (the original confirmation gate, renumbered). On `Stop`: exit cleanly; nothing written.
|
|
106
|
+
|
|
107
|
+
When the signals show `low-blast-radius` (≤1 tripping), skip the recommendation entirely and go straight to step 8. Don't pad easy amendments with restart questions.
|
|
108
|
+
|
|
109
|
+
8. **Confirm with user before any write.** Show: requested change, classified type, list of affected phase branches with their state + merge status, downstream branches that will be rebased, the force-push plan. Use `AskUserQuestion`:
|
|
110
|
+
|
|
111
|
+
- `Proceed — I authorize the force-pushes listed`
|
|
112
|
+
- `Refine — let me adjust scope` (loop back to step 2)
|
|
113
|
+
- `Stop`
|
|
114
|
+
|
|
115
|
+
Anything in `merged-to-default` state shown explicitly with a warning. **Do not** include those in the force-push list — user must convert those to `append-new` phases instead.
|
|
116
|
+
|
|
117
|
+
## Step 1 — Edit the plan file
|
|
118
|
+
|
|
119
|
+
Always the first write. Plan file is durable; commits get rewritten next.
|
|
120
|
+
|
|
121
|
+
1. **Body rewrites** — replace the affected `## Phase {id}` block inside **Phased Rollout** verbatim with the new body. Keep `phase.id` stable so branch naming stays valid.
|
|
122
|
+
|
|
123
|
+
2. **Inserts** — choose a new id. Two conventions are common:
|
|
124
|
+
- Decimal: `1.5` between `1` and `2` (matches existing patterns in some Vinta plans). Branch becomes `plan/{plan-id-kebab}/phase-1.5`.
|
|
125
|
+
- Letter: `1b` between `1` (relabeled `1a`) and `2`. Requires renaming `1` → `1a` inside **Phased Rollout** + updating downstream references.
|
|
126
|
+
Ask the user. Default: decimal — no rename of existing ids.
|
|
127
|
+
|
|
128
|
+
3. **Appends** — new `## Phase N+1` block at end of **Phased Rollout**. Same shape as siblings: Goal, Suggested AI model, reusable_skills, Changes, Tests, Acceptance.
|
|
129
|
+
|
|
130
|
+
4. **Guiding Decisions changes** — rewrite the affected row. Add a one-line note at the top of **Guiding Decisions** ("**Amended YYYY-MM-DD**: replaced storage shape from X to Y; affects phases 2, 3, 4.") so reviewers see what shifted. Reference the changed row by its **Decision** column name, not by a `§N.M` shorthand.
|
|
131
|
+
|
|
132
|
+
5. **Bump the amendment log.** At the bottom of the plan, under `## Amendments`, append:
|
|
133
|
+
|
|
134
|
+
```markdown
|
|
135
|
+
- **YYYY-MM-DD** — <one-line summary of change>. Affected phases: <ids>. Branches force-pushed: <branch-list>.
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Create the section if it doesn't exist. This is the audit trail; preserve every entry.
|
|
139
|
+
|
|
140
|
+
6. Commit the plan edit on `{{DEFAULT_BRANCH}}` (or wherever the plan file lives — the plan file itself is not branched per phase). Commit message: `Amend plan: <summary>`. {{COMMIT_STYLE_LINE}}.
|
|
141
|
+
|
|
142
|
+
## Step 2 — Build the rewrite queue
|
|
143
|
+
|
|
144
|
+
For each phase classified as needing commit rewrites (`body-rewrite` for already-implemented phases, downstream phases for `insert-new` / `body-rewrite` / `section-2-decision-change`), build a queue ordered by branch stack depth: parent first, children after.
|
|
145
|
+
|
|
146
|
+
For each entry record:
|
|
147
|
+
|
|
148
|
+
- `branch`, `base` (parent in the stack — may be `{{DEFAULT_BRANCH}}` or another phase branch).
|
|
149
|
+
- `change_kind`: `amend-existing` (modify the phase body's effect on the diff) or `rebase-only` (parent moved, no body change for this phase).
|
|
150
|
+
- `commits_to_amend`: list of SHAs the orchestrator may rewrite (look at `git log <base>..<branch>`).
|
|
151
|
+
|
|
152
|
+
Phases in `not-started` state are deferred to [implement-plan](../implement-plan/SKILL.md) — not rewritten here.
|
|
153
|
+
|
|
154
|
+
## Step 3 — Refuse force-pushes that can't work
|
|
155
|
+
|
|
156
|
+
Before any write to remote, **block on these conditions**:
|
|
157
|
+
|
|
158
|
+
1. **Phase merged to `{{DEFAULT_BRANCH}}`.** History on `{{DEFAULT_BRANCH}}` is immutable in practice. Tell the user: "Phase X already merged to `{{DEFAULT_BRANCH}}`. The amendment must be a new phase appended to the plan, not a rewrite. Re-run with classification `append-new` and execute via [implement-plan](../implement-plan/SKILL.md)."
|
|
159
|
+
|
|
160
|
+
2. **Branch's PR was reviewed and approved.** Force-pushing destroys reviewer context. Surface: list approved PRs by URL, ask `AskUserQuestion`:
|
|
161
|
+
- `Proceed — I'll re-request review after force-push`
|
|
162
|
+
- `Stop — too disruptive, redesign as forward phase`
|
|
163
|
+
|
|
164
|
+
3. **Branch protection rules block force-push.** `gh api repos/{owner}/{repo}/branches/{branch}/protection` (or `glab` equivalent). If the branch is protected, force-push will fail noisily — surface the rule, stop.
|
|
165
|
+
|
|
166
|
+
4. **Multiple authors on the branch.** `git log --pretty=format:%ae <base>..<branch> | sort -u | wc -l` > 1 → other developers committed too. Force-push erases their local state. Surface, require explicit `Yes, I've coordinated with <names>` confirmation.
|
|
167
|
+
|
|
168
|
+
If any block triggers and the user can't dismiss it: stop. Don't proceed further. Tell the user the rewrite path is unavailable; suggest an `append-new` phase as the fallback.
|
|
169
|
+
|
|
170
|
+
## Step 4 — Per-phase rewrite loop
|
|
171
|
+
|
|
172
|
+
For each entry in the rewrite queue, in stack order:
|
|
173
|
+
|
|
174
|
+
### 4a. Check out the branch
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
git fetch origin
|
|
178
|
+
git checkout {branch}
|
|
179
|
+
git reset --hard origin/{branch}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### 4b. For `change_kind = amend-existing` only — apply the body change
|
|
183
|
+
|
|
184
|
+
Spawn an implementer subagent. Prompt shape (token-efficient, mirrors the [implement-plan "Prepare agent prompt" step](../implement-plan/SKILL.md#1a-prepare-agent-prompt-token-efficient)):
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
You are amending {phase.id}: {phase.title} of plan {plan.id}.
|
|
188
|
+
|
|
189
|
+
## Repo
|
|
190
|
+
{{PROJECT_NAME}} ({{STACK_SUMMARY}}).
|
|
191
|
+
|
|
192
|
+
## Read first
|
|
193
|
+
1. AGENTS.md — repo conventions.
|
|
194
|
+
2. {{PLAN_DIR}}/{plan-filename}, the **Goals + Non-goals**, **Guiding Decisions**, and **Data Model Changes** sections, plus the rewritten phase body inside **Phased Rollout**.
|
|
195
|
+
3. The current diff: `git diff {base}...HEAD` — what's already on this branch.
|
|
196
|
+
|
|
197
|
+
## What changed in the plan (verbatim)
|
|
198
|
+
{Diff between old phase body and new — produce via `diff <(old-body) <(new-body)`. Or, if the plan was rewritten in place, the new body verbatim with a note "this replaces what was here before".}
|
|
199
|
+
|
|
200
|
+
## Your task
|
|
201
|
+
Bring the diff on this branch into compliance with the new phase body. You may:
|
|
202
|
+
- Edit existing files this branch already modified.
|
|
203
|
+
- Add new files when the new body requires them.
|
|
204
|
+
- Remove files this branch added that the new body no longer needs.
|
|
205
|
+
|
|
206
|
+
## How to record the change
|
|
207
|
+
Default: ADD A NEW COMMIT on top of the existing branch. Title: "Amend phase {phase.id}: <summary>". This preserves the original implementation as a separate commit and makes the amendment auditable in `git log`.
|
|
208
|
+
|
|
209
|
+
Use `git commit --amend` ONLY when:
|
|
210
|
+
- The branch has exactly one commit, AND
|
|
211
|
+
- The amendment is small (≤30% of the original diff size), AND
|
|
212
|
+
- The user explicitly authorized amend in Step 0.
|
|
213
|
+
|
|
214
|
+
## Working instructions (same loops as implement-plan)
|
|
215
|
+
1. Read existing code paths your changes touch.
|
|
216
|
+
2. Edit. Match existing patterns.
|
|
217
|
+
3. Inner loop: `{{LINT_CMD}}` → {{NEW_TEST_CMD_PATTERN}} → scoped suite ({{SCOPED_TEST_PATTERN}}).
|
|
218
|
+
4. Iterate 2–3 until green.
|
|
219
|
+
5. Outer gate: `{{BUILD_CMD}}` AND `{{TEST_CMD}}`{{E2E_OUTER_GATE_LINE}}.
|
|
220
|
+
6. Stage explicitly: `git add {{STAGE_PATTERN}}`.
|
|
221
|
+
7. Commit. {{COMMIT_STYLE_LINE}}.
|
|
222
|
+
8. {{COAUTHOR_INSTRUCTION_LINE}}
|
|
223
|
+
9. **Do NOT push. Do NOT force-push.** Orchestrator owns the remote.
|
|
224
|
+
|
|
225
|
+
## Required output
|
|
226
|
+
- Status: SUCCESS or FAILURE.
|
|
227
|
+
- New commit SHA(s) added (or amended SHA).
|
|
228
|
+
- 5–15 line summary.
|
|
229
|
+
- Deviations from new body + reasoning.
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
For `change_kind = rebase-only` (downstream phase whose parent moved): skip the agent. The work is purely git topology.
|
|
233
|
+
|
|
234
|
+
### 4c. Run the three-layer review (same as implement-plan)
|
|
235
|
+
|
|
236
|
+
Same Layer 1 / 2 / 3 / fix-loop as the [implement-plan "Thorough review" step](../implement-plan/SKILL.md#1d-thorough-review). The reviewer agent gets the **new** phase body to walk against. Layer 2 walks: every "Changes" item in the new body, every "Tests" entry, the new acceptance line.
|
|
237
|
+
|
|
238
|
+
Skip Layer 3 only when `change_kind = rebase-only` (no body change → no compliance walk). Layers 1 + 2 still apply (verify the rebase didn't lose unrelated work).
|
|
239
|
+
|
|
240
|
+
### 4d. Rebase onto the (possibly-rewritten) parent
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
# parent's tip may have moved if it was rewritten earlier in the queue.
|
|
244
|
+
git fetch origin
|
|
245
|
+
PARENT_TIP=$(git rev-parse origin/{base})
|
|
246
|
+
git rebase $PARENT_TIP
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Conflicts:
|
|
250
|
+
|
|
251
|
+
1. **Spawn a fixer subagent** with the conflict body + new phase body + parent's tip diff. Same agent type as the [implement-plan "Fix loop" subsection](../implement-plan/SKILL.md#fix-loop).
|
|
252
|
+
2. Fixer resolves, runs inner + outer gate.
|
|
253
|
+
3. Orchestrator continues the rebase: `git rebase --continue`.
|
|
254
|
+
|
|
255
|
+
Repeat until the rebase finishes clean. If the fixer can't resolve after one retry → stop. Surface to user; do not push a half-rebased branch.
|
|
256
|
+
|
|
257
|
+
### 4e. Force-push (with confirmation)
|
|
258
|
+
|
|
259
|
+
`AskUserQuestion`:
|
|
260
|
+
|
|
261
|
+
- `Force-push <branch> now (was authorized in Step 0)`
|
|
262
|
+
- `Pause — let me look at the local state first`
|
|
263
|
+
|
|
264
|
+
On confirm:
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
git push --force-with-lease origin {branch}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**Use `--force-with-lease`, not `--force`.** It refuses to overwrite if the remote moved since the last fetch — protects against another developer's pushes the orchestrator didn't see.
|
|
271
|
+
|
|
272
|
+
If `--force-with-lease` rejects: another developer pushed. Stop. Re-fetch, re-apply, re-confirm.
|
|
273
|
+
|
|
274
|
+
### 4f. Refresh the PR-context file (when present)
|
|
275
|
+
|
|
276
|
+
For the rewritten branch, look for `.vinta-ai-workflows/prs-context/{feature-kebab}/phase-{phase.id}.md`:
|
|
277
|
+
|
|
278
|
+
- **File missing** — skip; nothing to refresh.
|
|
279
|
+
- **File `status: pending`** — rewrite the file to reflect new title / description / comments per the [prs-context-template](prs-context-template.md). Status stays `pending`. The user will publish later via [open-pr-from-context](../foundation-skills/open-pr-from-context/SKILL.md).
|
|
280
|
+
- **File `status: published`** — the existing PR is auto-updated by the force-push (GitHub/GitLab pick up the new tip). But:
|
|
281
|
+
- Inline comments may now reference SHAs that no longer exist. They'll appear as "outdated" in the PR UI.
|
|
282
|
+
- If the new diff has materially different comment-worthy spots, regenerate the `# Comments` block, set `status: pending`, and re-run [open-pr.sh](../foundation-skills/open-pr-from-context/scripts/open-pr.sh) on the file. The script reuses the existing PR, posts new comments. Old "outdated" comments stay visible in the PR for audit; that's the platform's behavior.
|
|
283
|
+
|
|
284
|
+
When rewriting the `# Description` body, **honor `project.pr_template_paths`** from `.vinta-ai-workflows.yaml` — same rule as step 2 of the [implement-plan "Open PR via context file" step](../implement-plan/SKILL.md#1f-open-pr-via-context-file): follow the project's PR template structure, fill new sections with phase-specific content from the rewritten body, leave un-fillable placeholders untouched. If the prior file used a different template than the project now declares (template was added or swapped between the original `implement-plan` run and this amend), prefer the current `pr_template_paths` choice — surface the change to the user when the body shape shifts visibly.
|
|
285
|
+
|
|
286
|
+
Always include in the publish-log block at the bottom of the file:
|
|
287
|
+
|
|
288
|
+
```markdown
|
|
289
|
+
- YYYY-MM-DDThh:mm:ssZ — branch force-pushed (amend-plan); old SHA <x>, new SHA <y>
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### 4g. Update tracking file
|
|
293
|
+
|
|
294
|
+
Update `{{PLAN_DIR}}/TRACKING_{plan-id}.md` for the rewritten phase:
|
|
295
|
+
- Append to its `Completed Phases` entry: `Amended YYYY-MM-DD: <summary>; new SHA <x>; force-pushed`.
|
|
296
|
+
- Don't remove the original summary — keep history.
|
|
297
|
+
|
|
298
|
+
## Step 5 — Final report
|
|
299
|
+
|
|
300
|
+
After every queue entry processes:
|
|
301
|
+
|
|
302
|
+
1. Print a per-branch summary:
|
|
303
|
+
|
|
304
|
+
```
|
|
305
|
+
plan/{plan-id-kebab}/phase-1 amended (commits added: 1; force-pushed)
|
|
306
|
+
plan/{plan-id-kebab}/phase-2 rebased (no body change; force-pushed)
|
|
307
|
+
plan/{plan-id-kebab}/phase-3 rebased (no body change; force-pushed)
|
|
308
|
+
plan/{plan-id-kebab}/phase-4 pending (not yet implemented; will use new parent next implement-plan run)
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
2. List any PR-context files now at `status: pending` that need re-publishing.
|
|
312
|
+
3. List any phases blocked from rewrite (Step 3 refusals) with the recommended forward path.
|
|
313
|
+
4. Reminder: reviewers on existing PRs need a re-review request — force-push erases context. Send a short comment on each affected PR (the orchestrator can do this via the PR CLI if the project's PR policy = "agents create PRs"; otherwise hand off to the human).
|
|
314
|
+
|
|
315
|
+
## Important rules
|
|
316
|
+
|
|
317
|
+
- **Never `--force`. Always `--force-with-lease`.** Protects against silent overwrites.
|
|
318
|
+
- **Plan file edit is the first write.** Commit the new plan body before any branch rewrite. The plan is the contract; the branches are the artifact.
|
|
319
|
+
- **Recommend restart when blast radius is high.** The blast-radius step inside Step 0 evaluates signals; ≥2 tripping signals → surface a restart option to the user before any force-push plan is shown. Don't quietly amend a half-rewrite of the whole plan.
|
|
320
|
+
- **Never use `§N` shorthand to point at sections** — neither in this skill body, the rewritten plan body, the amendment log entry, nor any prs-context refresh. Always use the section's full name (and link when possible). `§N` references are hard for humans to follow and shift when section numbering moves.
|
|
321
|
+
- **Phases merged to `{{DEFAULT_BRANCH}}` are immutable.** Convert to `append-new` phases. Refuse to attempt rewrites.
|
|
322
|
+
- **Confirm every force-push individually.** No batch "confirm all".
|
|
323
|
+
- **Use `--force-with-lease`** (already stated; worth restating).
|
|
324
|
+
- **Three-layer review on every rewritten branch.** Same standard as [implement-plan](../implement-plan/SKILL.md). The amendment isn't done until Layer 3 passes.
|
|
325
|
+
- **PR-context file is a derived artifact.** Refresh it after the rewrite; never edit the file as a substitute for fixing the diff.
|
|
326
|
+
- **Subagents commit but never push.** Orchestrator owns force-push. {{PR_RULE_TAIL}}.
|
|
327
|
+
{{COAUTHOR_RULE_LINE}}
|
|
328
|
+
- **Stop on Tier-4 failure** (model escalation, same rules as the [implement-plan "Pick model" step](../implement-plan/SKILL.md#1b-pick-model-from-plans-per-phase-suggestion)).
|
|
329
|
+
- **Stop on rebase failure** the fixer can't resolve in one retry. Don't ship half-rebased branches.
|
|
330
|
+
|
|
331
|
+
## Quick checklist (orchestrator, per amendment run)
|
|
332
|
+
|
|
333
|
+
- [ ] User-requested change captured verbatim; classification determined (`body-rewrite` / `insert-new` / `append-new` / `guiding-decisions-change`).
|
|
334
|
+
- [ ] Plan parsed; per-phase state map built (state, branch, base, pr_status, merged_to_default).
|
|
335
|
+
- [ ] Blast-radius signals computed; `low` → straight to confirmation, `high-blast-radius` / `restart-recommended` → user offered `Restart` / `Amend in place` / `Stop` before the force-push plan is shown.
|
|
336
|
+
- [ ] On `Restart` choice: new plan drafted (or hand-off to [plan-feature](../plan-feature/SKILL.md)); old plan annotated `Superseded`; tracking marked; this skill exits.
|
|
337
|
+
- [ ] Step 3 refusals surfaced; force-push plan confirmed by user.
|
|
338
|
+
- [ ] Plan file edited; amendment log entry appended; committed on `{{DEFAULT_BRANCH}}`.
|
|
339
|
+
- [ ] Rewrite queue ordered by stack depth (parent first).
|
|
340
|
+
- [ ] For each entry: body change applied (when `amend-existing`); inner + outer gate green.
|
|
341
|
+
- [ ] Three-layer review on each rewritten branch; BLOCKERs fixed; SHOULD-FIX noted.
|
|
342
|
+
- [ ] Rebase onto rewritten parent; conflicts resolved via fixer; tests re-run.
|
|
343
|
+
- [ ] `--force-with-lease` push confirmed and executed per branch.
|
|
344
|
+
- [ ] PR-context file refreshed (pending or republished).
|
|
345
|
+
- [ ] Tracking file updated with amendment notes.
|
|
346
|
+
- [ ] Final summary lists every branch state, all `pending` PR-context files, all blocked rewrites with forward-phase suggestions, and a reviewer re-request reminder.
|
|
347
|
+
- [ ] If any phase was `append-new`: hand off to [implement-plan](../implement-plan/SKILL.md) for forward execution. This skill does NOT execute new phases.
|
|
348
|
+
|
|
349
|
+
## What this skill does NOT do
|
|
350
|
+
|
|
351
|
+
- **Does not execute new (`not-started`) phases.** That's [implement-plan](../implement-plan/SKILL.md)'s job. Edit the plan, then hand off.
|
|
352
|
+
- **Does not rewrite history on `{{DEFAULT_BRANCH}}`.** Refuses up front.
|
|
353
|
+
- **Does not auto-bypass branch protection.** Surface the rule, stop.
|
|
354
|
+
- **Does not amend commits made by humans on the branch unless explicitly authorized.** Multi-author branches require explicit confirmation.
|
|
355
|
+
- **Does not delete the plan file or its branches** even when an amendment makes some phases obsolete. Mark obsolete phases in the plan body with `**Superseded YYYY-MM-DD by phase {new-id}**`; leave their branches alone (or let the user delete manually).
|