vinta-ai-workflows 0.2.0-alpha4 → 0.2.0-alpha5
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 +40 -2
- package/package.json +1 -1
- package/schemas/vinta-ai-workflows-config.v1.schema.json +42 -0
- package/skills/vinta-bootstrap-ai-tools/SKILL.md +24 -5
- package/skills/vinta-derive-skills/SKILL.md +11 -3
- package/skills/vinta-derive-skills/resources/foundation-skills/handoff/SKILL.md +100 -0
- package/skills/vinta-derive-skills/resources/handoff-to-client-template.md +107 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,10 +7,48 @@ the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
7
7
|
|
|
8
8
|
## [0.2.0] — YYYY-MM-DD
|
|
9
9
|
|
|
10
|
-
<!-- pre-release: 0.2.0-alpha4 on 2026-07-08 -->
|
|
11
|
-
|
|
12
10
|
### Added
|
|
13
11
|
|
|
12
|
+
<!-- pre-release: 0.2.0-alpha5 on 2026-07-13 -->
|
|
13
|
+
|
|
14
|
+
- **`handoff` foundation skill — session-continuation handoff docs between
|
|
15
|
+
agents.** Write mode captures the current task (goal, verified-vs-unverified
|
|
16
|
+
state, decisions + rejected alternatives, landmines, single concrete next
|
|
17
|
+
step) into `.vinta-ai-workflows/handoffs/{date}-{slug}.md`, gathering state
|
|
18
|
+
from the repo — never from memory; resume mode reads a handoff, verifies its
|
|
19
|
+
claims against the repo before trusting them, and continues from the doc's
|
|
20
|
+
next step. Ships at
|
|
21
|
+
[skills/vinta-derive-skills/resources/foundation-skills/handoff/SKILL.md](skills/vinta-derive-skills/resources/foundation-skills/handoff/SKILL.md).
|
|
22
|
+
Wired as an **always-ship** bucket-A skill: new
|
|
23
|
+
`foundation_skills.handoff` enum entry (schema), derive-skills bucket-A
|
|
24
|
+
table + always-ships note, bootstrap always-copy-verbatim list + outputs
|
|
25
|
+
tree + Step 0.5 YAML (`handoff: enabled`), and both foundation-shape
|
|
26
|
+
replace lists. No bootstrap interview question — it always ships.
|
|
27
|
+
|
|
28
|
+
- **`handoff-to-client` foundation skill — API-change handoff docs for
|
|
29
|
+
API-only repos (opt-in, template-rendered).** Generates a self-contained
|
|
30
|
+
markdown document for the client teams consuming the repo's API: every
|
|
31
|
+
endpoint/operation added / changed / deprecated / removed on the current
|
|
32
|
+
branch vs the default branch, with request/response shapes derived from the
|
|
33
|
+
code (or a regenerated API spec), auth/error changes, breaking-change flags
|
|
34
|
+
judged from the strictest plausible client, one realistic example per
|
|
35
|
+
operation, and per-platform migration notes. Template at
|
|
36
|
+
[skills/vinta-derive-skills/resources/handoff-to-client-template.md](skills/vinta-derive-skills/resources/handoff-to-client-template.md)
|
|
37
|
+
(bucket B + C). New schema fields: `foundation_skills.handoff-to-client`
|
|
38
|
+
enum entry and the `skills.handoff-to-client` config block
|
|
39
|
+
(`client_platforms` — required non-empty array, `api_style`,
|
|
40
|
+
`api_spec_path`, `output_dir` — default
|
|
41
|
+
`.vinta-ai-workflows/client-handoffs`). New template placeholders
|
|
42
|
+
`{{API_STYLE}}`, `{{CLIENT_PLATFORMS_LIST}}`, `{{CLIENT_HANDOFF_DIR}}`,
|
|
43
|
+
`{{API_SPEC_BLOCK}}` documented in the derive-skills placeholder table.
|
|
44
|
+
Bootstrap gains **Optional foundation skills question 7** (asked only when
|
|
45
|
+
the inventory suggests an API-only repo) plus a four-part config follow-up;
|
|
46
|
+
Step 0.5 YAML, outputs tree, optional-bucket lists, and both
|
|
47
|
+
foundation-shape replace lists updated. **Consumers**: API-only projects
|
|
48
|
+
re-sync + answer the new interview question to enable it.
|
|
49
|
+
|
|
50
|
+
<!-- pre-release: 0.2.0-alpha4 on 2026-07-08 -->
|
|
51
|
+
|
|
14
52
|
- **`implement-plan` outer-gate test scope is now configurable — and defaults
|
|
15
53
|
to the quick path.** Each phase's outer gate still always runs the repo-wide
|
|
16
54
|
type/build gate, but for tests it now runs **only the scoped suite** covering
|
package/package.json
CHANGED
|
@@ -222,6 +222,16 @@
|
|
|
222
222
|
"description": "Rewrite comments and doc blocks touched during the current task into Simple English — strip AI-slop vocabulary and negative framing, comment-only (no renames, no behavior change). Copy-verbatim foundation skill (bucket A), always shipped: the `review-phase` Layer 2 comment-hygiene check and fix loop depend on it. Set `disabled` only if a project deliberately opts out of the review flow's comment-hygiene step.",
|
|
223
223
|
"type": "string",
|
|
224
224
|
"enum": ["enabled", "disabled"]
|
|
225
|
+
},
|
|
226
|
+
"handoff": {
|
|
227
|
+
"description": "Write or consume a session-continuation handoff document under `.vinta-ai-workflows/handoffs/` so a fresh agent session (or a different agent / teammate) can resume in-flight work without re-deriving context. Copy-verbatim foundation skill (bucket A), always shipped — its body is fully project-agnostic. Set `disabled` only if a project deliberately opts out.",
|
|
228
|
+
"type": "string",
|
|
229
|
+
"enum": ["enabled", "disabled"]
|
|
230
|
+
},
|
|
231
|
+
"handoff-to-client": {
|
|
232
|
+
"description": "Generate a markdown API-change handoff document for client teams consuming an API-only repo — endpoints added/changed/deprecated/removed on the current branch vs the default branch, with request/response shapes, breaking-change flags, and per-platform migration notes. Template-rendered (bucket B) from `vinta-derive-skills/resources/handoff-to-client-template.md` and opt-in (bucket C) — only ships when the bootstrap interview confirms an API-only repo with separate client codebases. When `enabled`, project-level configuration lives under `skills.handoff-to-client` (client platforms, API style, spec path, output dir).",
|
|
233
|
+
"type": "string",
|
|
234
|
+
"enum": ["enabled", "disabled"]
|
|
225
235
|
}
|
|
226
236
|
}
|
|
227
237
|
},
|
|
@@ -318,6 +328,38 @@
|
|
|
318
328
|
}
|
|
319
329
|
}
|
|
320
330
|
},
|
|
331
|
+
"handoff-to-client": {
|
|
332
|
+
"description": "Configuration for the `handoff-to-client` foundation skill. Required when `foundation_skills.handoff-to-client` is `enabled`; ignored otherwise. Rendered into the skill body at derive time.",
|
|
333
|
+
"type": "object",
|
|
334
|
+
"required": ["client_platforms"],
|
|
335
|
+
"additionalProperties": false,
|
|
336
|
+
"properties": {
|
|
337
|
+
"client_platforms": {
|
|
338
|
+
"description": "Free-form list of the client codebases/platforms that consume this repo's API, as the team names them (e.g. `iOS (Swift)`, `Android (Kotlin)`, `web SPA (React)`, `partner integrations`). Rendered into the skill's audience line and per-operation migration-notes instruction. Must be non-empty — an API-only repo with no named consumers has no handoff audience.",
|
|
339
|
+
"type": "array",
|
|
340
|
+
"items": { "type": "string", "minLength": 1 },
|
|
341
|
+
"uniqueItems": true,
|
|
342
|
+
"minItems": 1
|
|
343
|
+
},
|
|
344
|
+
"api_style": {
|
|
345
|
+
"description": "The API paradigm, free-form (e.g. `REST`, `GraphQL`, `gRPC`, `REST + webhooks`). Drives how the rendered skill names operations (method+path vs query/mutation vs service/rpc).",
|
|
346
|
+
"type": "string",
|
|
347
|
+
"minLength": 1,
|
|
348
|
+
"default": "REST"
|
|
349
|
+
},
|
|
350
|
+
"api_spec_path": {
|
|
351
|
+
"description": "Repo-relative path to a machine-readable API spec (OpenAPI file, GraphQL schema, proto dir) plus, ideally, the command that regenerates it — e.g. `docs/openapi.yaml (regenerate: make openapi)`. When set, the rendered skill diffs the regenerated spec between base and branch as its primary change-enumeration source. Omit when no spec exists; the skill then works from route/serializer code alone.",
|
|
352
|
+
"type": "string",
|
|
353
|
+
"minLength": 1
|
|
354
|
+
},
|
|
355
|
+
"output_dir": {
|
|
356
|
+
"description": "Directory where generated client-handoff documents land, repo-relative.",
|
|
357
|
+
"type": "string",
|
|
358
|
+
"minLength": 1,
|
|
359
|
+
"default": ".vinta-ai-workflows/client-handoffs"
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
},
|
|
321
363
|
"prepare-worktree": {
|
|
322
364
|
"description": "Configuration for the `prepare-worktree` foundation skill. Optional when `foundation_skills.prepare-worktree` is `enabled` — every field has a sensible default. Consumed by the skill at runtime to bias the per-worktree symlink-vs-copy-vs-fork decisions.",
|
|
323
365
|
"type": "object",
|
|
@@ -83,7 +83,7 @@ These bleed across sub-skills, so capture once now:
|
|
|
83
83
|
|
|
84
84
|
### D. Optional foundation skills
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
Seven skills are part of the foundation set but aren't always needed. Ask explicitly:
|
|
87
87
|
|
|
88
88
|
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`.
|
|
89
89
|
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`.
|
|
@@ -114,7 +114,15 @@ Six skills are part of the foundation set but aren't always needed. Ask explicit
|
|
|
114
114
|
|
|
115
115
|
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 and is also the escalation target for the `review-phase` Layer 3 structural-simplification lens; it is never auto-run on every diff. No follow-up config — the body is project-agnostic.
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
7. **`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.
|
|
118
|
+
|
|
119
|
+
**Follow-up only when `handoff-to-client` = Yes — client-handoff config.** Four short questions land under `skills.handoff-to-client.*`:
|
|
120
|
+
- **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.
|
|
121
|
+
- **API style.** `AskUserQuestion`: `REST`, `GraphQL`, `gRPC`, other (free-form). Auto-pick from the inventory when unambiguous (e.g. DRF routers → REST, graphene/strawberry → GraphQL); ask only when mixed.
|
|
122
|
+
- **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.
|
|
123
|
+
- **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.
|
|
124
|
+
|
|
125
|
+
If the user answers "No" to any of the seven, 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. `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.
|
|
118
126
|
|
|
119
127
|
### E. Existing AI artifacts (per-artifact disposition)
|
|
120
128
|
|
|
@@ -134,7 +142,7 @@ For each artifact, read it (frontmatter + body), then ask the user via `AskUserQ
|
|
|
134
142
|
- `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.
|
|
135
143
|
- `Drop` — delete (rare; usually the user wants to migrate).
|
|
136
144
|
|
|
137
|
-
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`, `deslop-comments`) 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.)
|
|
145
|
+
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`, `deslop-comments`, `handoff`, `handoff-to-client`) 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.)
|
|
138
146
|
|
|
139
147
|
- **Sub-agents** (each under any vendor `agents/` dir):
|
|
140
148
|
- `Migrate to ai-tools/agents/<name>.yaml` — converts vendor-specific format → canonical YAML; `setup-ai-tools.mjs` re-emits per-vendor copies.
|
|
@@ -254,6 +262,8 @@ foundation_skills:
|
|
|
254
262
|
prepare-worktree: <Optional foundation skills → prepare-worktree answer → enabled | disabled>
|
|
255
263
|
thermo-nuclear-code-quality-review: <Optional foundation skills → thermo-nuclear-code-quality-review answer → enabled | disabled>
|
|
256
264
|
deslop-comments: enabled # always ships — review-phase Layer 2 comment-hygiene + fix loop depend on it
|
|
265
|
+
handoff: enabled # always ships — project-agnostic session-continuation handoff docs
|
|
266
|
+
handoff-to-client: <Optional foundation skills → handoff-to-client answer → enabled | disabled; only asked for API-only repos>
|
|
257
267
|
|
|
258
268
|
foundation_agents:
|
|
259
269
|
implementer: enabled
|
|
@@ -277,6 +287,13 @@ skills:
|
|
|
277
287
|
systematic-debugging:
|
|
278
288
|
observability_mcp_servers: <systematic-debugging follow-up — free-form array of MCP server identifiers, e.g. [sentry, datadog, our-internal-traces]>
|
|
279
289
|
|
|
290
|
+
# Only emit this block when foundation_skills.handoff-to-client = enabled.
|
|
291
|
+
handoff-to-client:
|
|
292
|
+
client_platforms: <handoff-to-client follow-up — free-form array, e.g. [iOS (Swift), Android (Kotlin), web SPA (React)]>
|
|
293
|
+
api_style: <handoff-to-client follow-up — REST | GraphQL | gRPC | free-form>
|
|
294
|
+
api_spec_path: <handoff-to-client follow-up — repo-relative spec path + regen command; omit when none>
|
|
295
|
+
output_dir: .vinta-ai-workflows/client-handoffs
|
|
296
|
+
|
|
280
297
|
# Only emit this block when foundation_skills.prepare-worktree = enabled.
|
|
281
298
|
prepare-worktree:
|
|
282
299
|
worktree_root: <prepare-worktree follow-up — `.claude/worktrees` | `../<repo>-wt-`>
|
|
@@ -346,6 +363,7 @@ ai-tools/
|
|
|
346
363
|
│ ├── create-spec/SKILL.md ← always (copied verbatim)
|
|
347
364
|
│ ├── create-qa-use-cases/SKILL.md ← always (copied verbatim)
|
|
348
365
|
│ ├── deslop-comments/SKILL.md ← always (copied verbatim; review-phase Layer 2 comment-hygiene + fix loop depend on it)
|
|
366
|
+
│ ├── handoff/SKILL.md ← always (copied verbatim; session-continuation handoff docs under .vinta-ai-workflows/handoffs/)
|
|
349
367
|
│ ├── implement-plan/SKILL.md ← always (conductor; generated from template, project-specific)
|
|
350
368
|
│ ├── implement-phase/SKILL.md ← always (plan-execution unit; co-shipped with implement-plan)
|
|
351
369
|
│ ├── review-phase/SKILL.md ← always (plan-execution unit; shared by implement-plan / amend-plan / systematic-debugging)
|
|
@@ -354,6 +372,7 @@ ai-tools/
|
|
|
354
372
|
│ ├── add-e2e-test/SKILL.md ← optional — only if user opts in
|
|
355
373
|
│ ├── add-env-var/SKILL.md ← optional — only if user opts in
|
|
356
374
|
│ ├── systematic-debugging/SKILL.md ← optional — only if user opts in (template-rendered)
|
|
375
|
+
│ ├── handoff-to-client/SKILL.md ← optional — only for API-only repos, if user opts in (template-rendered; config under skills.handoff-to-client.*)
|
|
357
376
|
│ ├── add-one-off-script/ ← optional — only if user opts in (verbatim copy + bundled BaseOneOffScript + LocalRuntime templates)
|
|
358
377
|
│ │ ├── SKILL.md
|
|
359
378
|
│ │ └── resources/
|
|
@@ -389,9 +408,9 @@ Plus the symlinks + per-vendor generated files, set up by the install step.
|
|
|
389
408
|
|
|
390
409
|
Foundation skills break into three buckets — see [vinta-derive-skills](../vinta-derive-skills/SKILL.md) for the full mechanics:
|
|
391
410
|
|
|
392
|
-
- **Always copy verbatim**: `plan-feature`, `create-spec`, `create-qa-use-cases`, `deslop-comments`. Bundled with the bootstrap skill set; project-agnostic enough to ship as-is (with light path scrubs). `deslop-comments` always ships because `review-phase`'s Layer 2 comment-hygiene check + fix loop dispatch it.
|
|
411
|
+
- **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 `review-phase`'s Layer 2 comment-hygiene check + fix loop dispatch it. `handoff` always ships because its session-continuation body is fully project-agnostic.
|
|
393
412
|
- **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.
|
|
394
|
-
- **Optional, ask first**: `add-e2e-test`, `add-env-var`, `systematic-debugging`, `add-one-off-script`, `prepare-worktree`, `thermo-nuclear-code-quality-review`. 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, and (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; if no → don't ship. `thermo-nuclear-code-quality-review`: if yes → copy the bundled SKILL.md verbatim (no follow-up config); if no → don't ship.
|
|
413
|
+
- **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, and (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; if no → don't ship. `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.
|
|
395
414
|
|
|
396
415
|
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.
|
|
397
416
|
|
|
@@ -26,7 +26,7 @@ Before drafting any new SKILL.md, walk through every entry in `existing_ai_artif
|
|
|
26
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
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
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`, `prepare-worktree`, `thermo-nuclear-code-quality-review`, `deslop-comments`) — proceed with the bucket A / B / C flow below for that name. The user has explicitly opted into overwriting their version.
|
|
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`, `prepare-worktree`, `thermo-nuclear-code-quality-review`, `deslop-comments`, `handoff`, `handoff-to-client`) — proceed with the bucket A / B / C flow below for that name. The user has explicitly opted into overwriting their version.
|
|
30
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
31
|
|
|
32
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**.
|
|
@@ -48,6 +48,7 @@ These are project-agnostic enough to ship as-is. Copy from this skill's [resourc
|
|
|
48
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. **E2E-gated** — ship only when `foundation_skills.add-e2e-test` is `enabled`; QA use-cases exist to seed e2e specs, so a no-e2e project has no use for it. |
|
|
49
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
50
|
| `deslop-comments` | [resources/foundation-skills/deslop-comments/SKILL.md](resources/foundation-skills/deslop-comments/SKILL.md) | Rewrite comments + doc blocks touched during a task into Simple English — strip AI-slop vocabulary and negative framing; comment-only, no renames or behavior change. **Always ships** — the `review-phase` Layer 2 comment-hygiene check + fix loop dispatch it, so it must exist in the target. Also user-invokable standalone ("deslop these comments"). |
|
|
51
|
+
| `handoff` | [resources/foundation-skills/handoff/SKILL.md](resources/foundation-skills/handoff/SKILL.md) | Write or consume a session-continuation handoff doc under `.vinta-ai-workflows/handoffs/` — goal, current state, decisions + rationale, landmines, next step — so a fresh agent session (or a teammate) resumes in-flight work without re-deriving context. **Always ships** — fully project-agnostic; standalone (no cross-links into the always-on trio). |
|
|
51
52
|
| `prepare-worktree` | [resources/foundation-skills/prepare-worktree/](resources/foundation-skills/prepare-worktree/) | Provision a runnable, isolated git worktree for parallel feature work — symlink dep dirs (or copy / reinstall when the plan churns deps), copy + mutate env files, fork dev + test DBs when migrations are in scope, namespace docker-compose project + network, OS-sandbox the worktree so main-checkout writes are blocked (bundled [scripts/sandbox-run.sh](resources/foundation-skills/prepare-worktree/scripts/sandbox-run.sh) — `sandbox-exec` / `bwrap`), write a teardown-ready summary YAML. Used by `implement-plan` when Step 0 question (c) opts in; standalone for ad-hoc isolation. Opt-in (bucket A + ask-first via the bootstrap's **Optional foundation skills** interview). |
|
|
52
53
|
| `thermo-nuclear-code-quality-review` | [resources/foundation-skills/thermo-nuclear-code-quality-review/SKILL.md](resources/foundation-skills/thermo-nuclear-code-quality-review/SKILL.md) | Opt-in deep structural-maintainability audit of a diff — abstraction quality, giant files, spaghetti-condition growth — harsher than the standard per-phase review; hunts for "code-judo" reframes that collapse branches / helpers / layers rather than polishing them. Read-only; hands each fix to the `fixer` agent. Invoked deliberately by the user, or escalated from the `review-phase` Layer 3 structural-simplification lens. Opt-in (bucket A + ask-first via the bootstrap's **Optional foundation skills** interview). |
|
|
53
54
|
|
|
@@ -56,7 +57,7 @@ These reference each other:
|
|
|
56
57
|
- `plan-feature` reads spec; dispatches `create-qa-use-cases` when the doc is missing (e2e-enabled projects only — see below).
|
|
57
58
|
- `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.
|
|
58
59
|
|
|
59
|
-
The **always-on unit** is `plan-feature` + `create-spec` + `open-pr-from-context` — copy all three or none. `deslop-comments` also always ships (independently — it doesn't cross-reference the trio), because the `review-phase` Layer 2 comment-hygiene check + fix loop dispatch it; a target missing it would leave that review step dangling. `create-qa-use-cases` joins the unit **only when `foundation_skills.add-e2e-test` is `enabled`**; when add-e2e-test is disabled (or absent), don't ship it and set `foundation_skills.create-qa-use-cases: disabled` in `.vinta-ai-workflows.yaml` to match.
|
|
60
|
+
The **always-on unit** is `plan-feature` + `create-spec` + `open-pr-from-context` — copy all three or none. `deslop-comments` also always ships (independently — it doesn't cross-reference the trio), because the `review-phase` Layer 2 comment-hygiene check + fix loop dispatch it; a target missing it would leave that review step dangling. `handoff` also always ships independently — its body is fully project-agnostic and nothing else depends on it. `create-qa-use-cases` joins the unit **only when `foundation_skills.add-e2e-test` is `enabled`**; when add-e2e-test is disabled (or absent), don't ship it and set `foundation_skills.create-qa-use-cases: disabled` in `.vinta-ai-workflows.yaml` to match.
|
|
60
61
|
|
|
61
62
|
**E2E stripping in `plan-feature`.** `plan-feature` ships verbatim but carries e2e-only regions delimited by `<!-- e2e:start -->` / `<!-- e2e:end -->` lines. When copying it, run an e2e pass:
|
|
62
63
|
|
|
@@ -82,6 +83,8 @@ The five are a **co-shipped unit**: `implement-plan` is always generated, so `im
|
|
|
82
83
|
|
|
83
84
|
- **`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. It reuses `review-phase` for its Phase 4 review gate (an `invoke [review-phase]` reference — always resolvable because the plan-execution unit is always shipped).
|
|
84
85
|
|
|
86
|
+
- **`handoff-to-client`** — generate a markdown API-change handoff document for the client teams consuming an API-only repo: endpoints/operations added / changed / deprecated / removed on the current branch vs the default branch, with request/response shapes, breaking-change flags, and per-platform migration notes. From [resources/handoff-to-client-template.md](resources/handoff-to-client-template.md). **Opt-in** — only generated when `foundation_skills.handoff-to-client` is `enabled` in `.vinta-ai-workflows.yaml` (the bootstrap interview asks only when the repo looks API-only with separate client codebases). The rendered body bakes in `skills.handoff-to-client.*` config: client platforms, API style, optional API spec path, output dir. Standalone — no cross-links into the plan-execution unit.
|
|
87
|
+
|
|
85
88
|
Every plan-execution shell + `systematic-debugging` consumes the 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.
|
|
86
89
|
|
|
87
90
|
#### Rendering the plan-execution unit
|
|
@@ -137,6 +140,10 @@ The remaining per-shell placeholders:
|
|
|
137
140
|
| `{{INTEGRATE_PHASE_LINK}}` | derived from `policies.commit_strategy` | Path used by `amend-plan`'s PR-template cross-reference. `../integrate-phase/SKILL.md` for `stacked` / `modular`; `../integrate-phase-stacked/SKILL.md` for `ask` (amend-plan only runs under the stacked topology). |
|
|
138
141
|
| `{{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. |
|
|
139
142
|
| `{{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. |
|
|
143
|
+
| `{{API_STYLE}}` | `skills.handoff-to-client.api_style` (handoff-to-client only) | `REST`, `GraphQL`, `gRPC`, `REST + webhooks` |
|
|
144
|
+
| `{{CLIENT_PLATFORMS_LIST}}` | `skills.handoff-to-client.client_platforms` (handoff-to-client only) | comma-separated, e.g. `iOS (Swift), Android (Kotlin), web SPA (React)` |
|
|
145
|
+
| `{{CLIENT_HANDOFF_DIR}}` | `skills.handoff-to-client.output_dir` (handoff-to-client only) | `.vinta-ai-workflows/client-handoffs` (default) |
|
|
146
|
+
| `{{API_SPEC_BLOCK}}` | derived from `skills.handoff-to-client.api_spec_path` (handoff-to-client only) | when set: a paragraph instructing the agent to regenerate/read the spec at that path on both base and branch and diff the two as the primary change-enumeration source (cross-checking against the code diff). When absent: a one-line note that no machine-readable spec exists, so shapes come from route/serializer code alone. |
|
|
140
147
|
| `{{DEPENDENCY_LICENSE_BLOCK}}` | derived from `policies.dependency_licenses` | Top-level `## Adding new third-party dependencies` section. Empty string when `enforcement: off` or the block is absent. When `block` / `warn`: short paragraph naming the enforcement mode + the forbidden SPDX list + the pre-install check (`npm view <pkg> license`, PyPI metadata, etc.) + a one-line pointer to the **Dependency licenses** section in [AGENTS.md](AGENTS.md) for the full table including `allowed_overrides` and `notes`. See [resources/dependency-license-block.md](resources/dependency-license-block.md) for the canonical body. |
|
|
141
148
|
| `{{DEPENDENCY_LICENSE_LAYER1_CHECK}}` | derived from `policies.dependency_licenses` | Layer 1 review checklist item. Empty string when `enforcement: off`. When `block` / `warn`: `6. **Dependency license scan**: \`git diff package.json pyproject.toml ...\` (project-relevant manifests) — for every added dep look up its SPDX license (\`npm view <pkg> license\`, PyPI metadata, repo \`LICENSE\`). A license in \`policies.dependency_licenses.forbidden_spdx\` and not in \`allowed_overrides\` is a BLOCKER (when \`block\`) or a SHOULD-FIX (when \`warn\`). A missing / \`UNKNOWN\` / undeclared license is **always a BLOCKER** regardless of enforcement mode — there is no override to silently bless undisclosed terms.` |
|
|
142
149
|
| `{{DEPENDENCY_LICENSE_RULE_LINE}}` | derived from `policies.dependency_licenses` | Important-rules bullet. Empty string when `enforcement: off`. When `block`: `- **License check before any new dep.** Refuse \`npm add\` / \`pnpm add\` / \`pip install\` / \`poetry add\` / \`uv add\` / \`cargo add\` / \`go get\` when the package's SPDX license is in the forbidden list — see AGENTS.md **Dependency licenses**. User can grant a one-off override after acknowledging the violation; record the override in \`policies.dependency_licenses.allowed_overrides\` before re-running.` When `warn`: same line but `Proceed but record the violation in the phase report` instead of `Refuse`. |
|
|
@@ -207,6 +214,7 @@ Render each template (expand includes → substitute placeholders → write), pr
|
|
|
207
214
|
- `ai-tools/skills/integrate-phase/SKILL.md` (from `plan-execution/shell/integrate-phase-template.md`) — **or**, under `ask`, `ai-tools/skills/integrate-phase-stacked/SKILL.md` + `ai-tools/skills/integrate-phase-modular/SKILL.md` (same template rendered twice)
|
|
208
215
|
- `ai-tools/skills/amend-plan/SKILL.md` (from `plan-execution/shell/amend-plan-template.md`)
|
|
209
216
|
- `ai-tools/skills/systematic-debugging/SKILL.md` (from `systematic-debugging-template.md`) — only when `foundation_skills.systematic-debugging: enabled`
|
|
217
|
+
- `ai-tools/skills/handoff-to-client/SKILL.md` (from `handoff-to-client-template.md`) — only when `foundation_skills.handoff-to-client: enabled`
|
|
210
218
|
|
|
211
219
|
The first five are the **plan-execution unit** — render them together (they share partials + placeholders + cross-links); a change to one partial ripples to every shell that includes it.
|
|
212
220
|
|
|
@@ -284,7 +292,7 @@ Length: 100–300 lines. Shorter = under-specified. Longer = should probably spl
|
|
|
284
292
|
- **Don't ship copy-pasted source-project SKILL.md files unchanged.** Run search-and-replace for source project names / paths / commands before saving.
|
|
285
293
|
- **Foundation set is a unit.** Always copy `plan-feature` + `create-spec` + `open-pr-from-context` together — they reference each other. `create-qa-use-cases` joins only when `add-e2e-test` is enabled; when it's not, strip `plan-feature`'s e2e regions (the `<!-- e2e:start/end -->` pass) so no cross-link dangles.
|
|
286
294
|
- **The plan-execution unit is generated, not copied.** `implement-plan` + `implement-phase` + `review-phase` + `integrate-phase` + `amend-plan` all have too much project-specific content for verbatim shipping. They are separate files but a **co-shipped unit** — never emit the conductors without the three sub-skills; a conductor whose `[implement-phase]` / `[review-phase]` / integrate link dangles is a broken skill.
|
|
287
|
-
- **Optional skills (`add-e2e-test`, `add-env-var`, `add-one-off-script`, `prepare-worktree`, `thermo-nuclear-code-quality-review`) are gated by user answer.** Don't ship them by default.
|
|
295
|
+
- **Optional skills (`add-e2e-test`, `add-env-var`, `add-one-off-script`, `prepare-worktree`, `thermo-nuclear-code-quality-review`, `handoff-to-client`) are gated by user answer.** Don't ship them by default. `handoff-to-client` is additionally template-rendered (bucket B) — its config lives under `skills.handoff-to-client.*`.
|
|
288
296
|
- **Each skill solves one job.** Two unrelated checklists → split.
|
|
289
297
|
- **Reference real files in the target.** Skill links must point to existing paths.
|
|
290
298
|
- **Skills auto-load by description.** Specific triggers, specific outcomes.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: handoff
|
|
3
|
+
description: Write or consume a session-continuation handoff document under `.vinta-ai-workflows/handoffs/` so a fresh agent session (or a different agent / teammate) can resume in-flight work without re-deriving context. Use when the user says "hand this off", "write a handoff", "wrap this up for another agent", "prepare a handoff doc", or — in resume mode — "pick up from the handoff", "resume from handoff", or points at a handoff file. Captures goal, current state, decisions with rationale, files touched, verification status, and the exact next step.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Handoff
|
|
7
|
+
|
|
8
|
+
Context dies with the session. A handoff document is the bridge: everything a fresh agent needs to continue the work, written down while the outgoing agent still knows it. The reader has none of your conversation history — write for someone who knows the codebase conventions but nothing about this task.
|
|
9
|
+
|
|
10
|
+
Two modes. Pick by what the user asked for:
|
|
11
|
+
|
|
12
|
+
- **Write mode** — capture the current task into a handoff doc. Trigger: "hand this off", "wrap up for another agent", "write a handoff before we stop".
|
|
13
|
+
- **Resume mode** — start from an existing handoff doc. Trigger: "resume from the handoff", "pick up where the last session left off", or the user pastes/points at a handoff file.
|
|
14
|
+
|
|
15
|
+
## Write mode
|
|
16
|
+
|
|
17
|
+
### 1. Gather real state — never from memory alone
|
|
18
|
+
|
|
19
|
+
Collect each of these from the repo, not from what you recall doing:
|
|
20
|
+
|
|
21
|
+
1. `git status --short` + `git diff --stat` — uncommitted work.
|
|
22
|
+
2. `git log --oneline <default-branch>..HEAD` — commits this task produced (skip if on the default branch).
|
|
23
|
+
3. Current branch name and its upstream/base.
|
|
24
|
+
4. Any in-flight plan or tracking artifacts: `ai-plans/*_IMPLEMENTATION_PLAN.md`, `TRACKING_*.md`, `.vinta-ai-workflows/prs-context/` files with `status: pending`.
|
|
25
|
+
5. Open PRs for this branch, if a PR CLI is available (`gh pr view` / `glab mr view`).
|
|
26
|
+
6. Test / lint / build status: what was last run, and did it pass? If you don't know, say "not verified" — do not guess.
|
|
27
|
+
|
|
28
|
+
### 2. Write the document
|
|
29
|
+
|
|
30
|
+
Path: `.vinta-ai-workflows/handoffs/{YYYY-MM-DD}-{task-slug}.md` (e.g. `2026-07-11-fix-invoice-rounding.md`). Create the directory if missing. If a handoff for the same task slug already exists, supersede it: write the new file with today's date and add a `supersedes:` line pointing at the old one — never silently overwrite.
|
|
31
|
+
|
|
32
|
+
Structure:
|
|
33
|
+
|
|
34
|
+
```markdown
|
|
35
|
+
# Handoff: {one-line task title}
|
|
36
|
+
|
|
37
|
+
- **Date:** {YYYY-MM-DD}
|
|
38
|
+
- **Branch:** {branch} (base: {base-branch})
|
|
39
|
+
- **Status:** {in-progress | blocked | ready-for-review}
|
|
40
|
+
- **Supersedes:** {path to previous handoff, or omit}
|
|
41
|
+
|
|
42
|
+
## Goal
|
|
43
|
+
What the task is trying to achieve and why — the original ask, plus any scope changes agreed with the user since.
|
|
44
|
+
|
|
45
|
+
## Current state
|
|
46
|
+
What is DONE and verified, what is done but NOT verified, what is not started.
|
|
47
|
+
Cite commits (`abc1234`) and files. Include the exact uncommitted-work summary
|
|
48
|
+
from `git status` if anything is uncommitted.
|
|
49
|
+
|
|
50
|
+
## Decisions made
|
|
51
|
+
Each decision the next agent must not accidentally relitigate:
|
|
52
|
+
- **{decision}** — {rationale}. Alternatives considered: {…, and why rejected}.
|
|
53
|
+
|
|
54
|
+
## Landmines
|
|
55
|
+
Gotchas discovered the hard way: flaky tests, misleading names, code that looks
|
|
56
|
+
wrong but is correct (and why), env quirks, anything you'd warn a teammate about.
|
|
57
|
+
|
|
58
|
+
## Next step
|
|
59
|
+
The SINGLE most important next action, concrete enough to start immediately
|
|
60
|
+
(file, command, expected outcome). Then the rest of the remaining work as an
|
|
61
|
+
ordered list.
|
|
62
|
+
|
|
63
|
+
## Verification
|
|
64
|
+
How to confirm the finished work is correct: commands to run, flows to exercise,
|
|
65
|
+
what "passing" looks like.
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 3. Quality gate before saving
|
|
69
|
+
|
|
70
|
+
- Every claim of "done" is backed by a commit hash or a passing command you actually ran this session. Anything else is labeled "not verified".
|
|
71
|
+
- No references to "the conversation", "as discussed above", or "earlier" — the reader has no conversation.
|
|
72
|
+
- A stranger could execute **Next step** without asking a question.
|
|
73
|
+
|
|
74
|
+
### 4. Tell the user where it landed
|
|
75
|
+
|
|
76
|
+
Report the file path. Note that `.vinta-ai-workflows/` is typically gitignored — if the handoff must reach another machine or teammate, they should share the file explicitly or commit it deliberately.
|
|
77
|
+
|
|
78
|
+
## Resume mode
|
|
79
|
+
|
|
80
|
+
1. **Read the handoff doc** in full. If the user didn't name one, list `.vinta-ai-workflows/handoffs/` and pick the most recent that isn't superseded; confirm the pick with the user if more than one task is plausible.
|
|
81
|
+
2. **Verify its claims against the repo before trusting them.** The repo may have moved since the handoff was written:
|
|
82
|
+
- Named branch exists and you're on it (or switch after confirming with the user).
|
|
83
|
+
- Cited commits exist (`git log`), cited files exist, `git status` matches the described uncommitted state.
|
|
84
|
+
- Re-run the cheapest verification command from the **Verification** section to confirm the "done" claims still hold.
|
|
85
|
+
3. **On mismatch, stop and reconcile** — tell the user what the handoff claims vs. what the repo shows. Never continue from stale premises.
|
|
86
|
+
4. **Adopt the decisions.** Treat **Decisions made** as settled unless the user reopens one; do not re-explore rejected alternatives.
|
|
87
|
+
5. **Continue from Next step.** When the work later stops again unfinished, write a fresh handoff (write mode) superseding this one.
|
|
88
|
+
|
|
89
|
+
## Pitfalls
|
|
90
|
+
|
|
91
|
+
- **Writing the handoff from memory.** The doc says "tests pass" but they were never run after the last edit. Gather state from the repo (step 1) — every time.
|
|
92
|
+
- **Recording what happened instead of what's next.** A chronological diary of the session is not a handoff. The reader needs current state + next action, not the journey.
|
|
93
|
+
- **Omitting rejected alternatives.** The next agent re-derives the rejected approach, spends an hour, and hits the same wall. One line per rejection prevents this.
|
|
94
|
+
- **Vague next step.** "Continue the refactor" is useless. "Extract the retry logic in `client.py` into `retry.py`, then make `test_client.py` pass again" is a handoff.
|
|
95
|
+
- **Resume mode trusting the doc blindly.** Handoffs go stale — a teammate may have pushed to the branch since. Verify (resume step 2) before building on it.
|
|
96
|
+
|
|
97
|
+
## Verification
|
|
98
|
+
|
|
99
|
+
- Write mode: the file exists at the reported path, follows the structure above, and contains no unverified "done" claims.
|
|
100
|
+
- Resume mode: repo state matched the doc (or mismatches were surfaced), and work continued from the doc's **Next step** — not from a fresh re-derivation.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: handoff-to-client
|
|
3
|
+
description: Generate a markdown API-change handoff document for the client teams consuming {{PROJECT_NAME}}'s {{API_STYLE}} API ({{CLIENT_PLATFORMS_LIST}}). Documents every endpoint/operation added, changed, deprecated, or removed on the current branch relative to `{{DEFAULT_BRANCH}}` — request/response shapes, auth, errors, breaking-change flags, and per-platform migration notes — so client implementers can adopt the changes without reading this repo's source. Use when the user says "write the client handoff", "document the API changes for the clients", "hand off to the frontend/mobile team", or before merging an API-changing branch.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Handoff to client
|
|
7
|
+
|
|
8
|
+
{{PROJECT_NAME}} ({{STACK_SUMMARY}}) is an API-only repo — its consumers live in separate codebases: {{CLIENT_PLATFORMS_LIST}}. Client implementers cannot read this repo's diff; this skill turns an API-changing branch into a self-contained markdown document they implement against.
|
|
9
|
+
|
|
10
|
+
The document is a contract description, not a changelog: every change carries enough shape detail (fields, types, nullability, examples) that a client engineer can code against it without opening this repo.
|
|
11
|
+
|
|
12
|
+
## Step 0 — Resolve the scope
|
|
13
|
+
|
|
14
|
+
Default scope is the **current branch vs `{{DEFAULT_BRANCH}}`**:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
git fetch origin {{DEFAULT_BRANCH}}
|
|
18
|
+
git diff origin/{{DEFAULT_BRANCH}}...HEAD --stat
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Overrides, when the user asks: an explicit commit range (`<from>..<to>`), a merged PR, or a whole feature plan (enumerate the plan's phase branches/commits from its tracking file and union their diffs). State the resolved scope in the output doc's header.
|
|
22
|
+
|
|
23
|
+
If the resolved diff touches no API surface at all, say so and stop — do not fabricate a document.
|
|
24
|
+
|
|
25
|
+
## Step 1 — Enumerate the API surface changes
|
|
26
|
+
|
|
27
|
+
Work from the diff, never from memory:
|
|
28
|
+
|
|
29
|
+
1. List changed files in the scope and keep the API-relevant ones: route/URL declarations, controllers/views/resolvers, serializers/schemas/DTOs, auth/permission code, error handlers, API versioning config.
|
|
30
|
+
2. For each, read the changed hunks and map them to concrete operations (method + path for REST; query/mutation/subscription for GraphQL; service/rpc for gRPC).
|
|
31
|
+
3. Classify every operation touched: **added**, **changed**, **deprecated**, or **removed**.
|
|
32
|
+
4. For each **changed** operation, diff the request and response shapes field by field: added fields, removed fields, type changes, nullability changes, renamed fields, default changes, new/changed validation rules, pagination or filtering changes.
|
|
33
|
+
5. Flag **breaking** vs **non-breaking**. Breaking = anything an existing client call could fail or misbehave on: removed/renamed field or endpoint, narrowed type, newly-required request field, changed status code or error shape, auth/permission tightening. Additive-and-optional is non-breaking.
|
|
34
|
+
|
|
35
|
+
{{API_SPEC_BLOCK}}
|
|
36
|
+
|
|
37
|
+
Also sweep for non-endpoint contract changes clients still feel: auth flows (token lifetimes, scopes, header names), rate limits, webhooks/event payloads, websocket messages, file-upload conventions, and deprecation timelines.
|
|
38
|
+
|
|
39
|
+
## Step 2 — Write the document
|
|
40
|
+
|
|
41
|
+
Path: `{{CLIENT_HANDOFF_DIR}}/{YYYY-MM-DD}-{branch-or-feature-slug}.md`. Create the directory if missing.
|
|
42
|
+
|
|
43
|
+
```markdown
|
|
44
|
+
# API changes: {feature / branch title}
|
|
45
|
+
|
|
46
|
+
- **Date:** {YYYY-MM-DD}
|
|
47
|
+
- **Scope:** {branch} vs {{DEFAULT_BRANCH}} ({short-sha range})
|
|
48
|
+
- **Audience:** {{CLIENT_PLATFORMS_LIST}}
|
|
49
|
+
- **Breaking changes:** {count, or "none"}
|
|
50
|
+
|
|
51
|
+
## Summary
|
|
52
|
+
2–5 sentences: what shipped and why clients care. Lead with breaking changes.
|
|
53
|
+
|
|
54
|
+
## Breaking changes ← omit section if none; never bury these
|
|
55
|
+
Per change: what breaks, which operations, what the client must do, and the
|
|
56
|
+
deadline/version after which the old behavior disappears.
|
|
57
|
+
|
|
58
|
+
## {Operation-by-operation sections, grouped added / changed / deprecated / removed}
|
|
59
|
+
|
|
60
|
+
### {METHOD /path} or {operationName}
|
|
61
|
+
- **Status:** added | changed | deprecated | removed — {breaking? yes/no}
|
|
62
|
+
- **Auth:** {scheme, required scopes/permissions}
|
|
63
|
+
- **Request:** field table or annotated example — name, type, required?,
|
|
64
|
+
constraints, default. For *changed*: call out exactly what differs from before.
|
|
65
|
+
- **Response:** per status code — annotated example JSON with field meanings,
|
|
66
|
+
nullability, enum values spelled out.
|
|
67
|
+
- **Errors:** status codes + error body shape + when each fires.
|
|
68
|
+
- **Example:** one complete request/response pair with realistic (fake) data.
|
|
69
|
+
- **Client migration notes:** what each platform ({{CLIENT_PLATFORMS_LIST}})
|
|
70
|
+
concretely changes — omit platforms unaffected by this operation.
|
|
71
|
+
|
|
72
|
+
## Other contract changes
|
|
73
|
+
Auth flow / rate limits / webhooks / versioning changes from the Step 1 sweep.
|
|
74
|
+
|
|
75
|
+
## Rollout
|
|
76
|
+
Is the change live, behind a flag, or awaiting deploy? Environment availability
|
|
77
|
+
(staging first?), and the sequencing clients must respect.
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Rules for the body:
|
|
81
|
+
|
|
82
|
+
- **Examples over prose.** Every operation gets at least one realistic request/response example. Use plausible fake data — never real user data, tokens, or secrets copied from fixtures or logs.
|
|
83
|
+
- **Shape from code, not intent.** Derive field names, types, and nullability from the serializer/schema/resolver code in the diff (or the regenerated spec), not from the plan document or commit messages.
|
|
84
|
+
- **Self-contained.** No links into this repo's source as the primary explanation; the audience may not have repo access. Citing paths as *provenance* is fine.
|
|
85
|
+
- **Neutral tone for migration notes.** Describe what the client must handle; don't prescribe their internal architecture.
|
|
86
|
+
|
|
87
|
+
## Step 3 — Verify before handing off
|
|
88
|
+
|
|
89
|
+
1. Re-read each documented operation against the actual code one final time — signatures drift during writing.
|
|
90
|
+
2. Grep the diff for API-relevant files you did NOT document and confirm each is genuinely client-invisible (internal refactor, tests, comments).
|
|
91
|
+
3. Confirm every **breaking** flag: would an unmodified existing client call still succeed? If unsure, mark it breaking — false alarms are cheaper than silent breakage.
|
|
92
|
+
4. Exercise at least one added/changed endpoint against a locally running instance when feasible, and paste the real (redacted) response into the doc's example.
|
|
93
|
+
5. Report the doc path to the user, flag the breaking-change count, and remind them `{{CLIENT_HANDOFF_DIR}}` may be gitignored — share or commit the file deliberately so it actually reaches the client teams.
|
|
94
|
+
|
|
95
|
+
## Pitfalls
|
|
96
|
+
|
|
97
|
+
- **Documenting the plan instead of the code.** Plans drift during implementation; the diff is the truth. Always derive shapes from what actually merged into the branch.
|
|
98
|
+
- **Missing error-shape changes.** Clients parse error bodies too. A changed error envelope breaks clients just as hard as a changed success payload.
|
|
99
|
+
- **"Non-breaking" by wishful thinking.** A field that changed from `string` to `string | null` breaks any client that never null-checks. Judge breakage from the strictest plausible client, not the friendliest.
|
|
100
|
+
- **Serializer-level changes hidden behind unchanged routes.** A diff can change a response shape without touching any route file — sweep serializers/schemas/DTOs even when the route list looks untouched.
|
|
101
|
+
- **Stale doc after review fixes.** If review feedback changes the API after the handoff was written, regenerate the doc — a superseded handoff to clients is worse than none.
|
|
102
|
+
|
|
103
|
+
## Verification
|
|
104
|
+
|
|
105
|
+
- The doc exists under `{{CLIENT_HANDOFF_DIR}}/`, is scoped-and-dated, and every API-relevant file in the diff is either documented or consciously excluded.
|
|
106
|
+
- Every breaking change appears in the **Breaking changes** section, not only in its per-operation entry.
|
|
107
|
+
- A client engineer with zero access to this repo could implement every documented change from the doc alone.
|