@benjaminthomas/spec-driven-dev 0.0.0-stage → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +483 -2
- package/bin/cli.mjs +357 -0
- package/package.json +12 -4
- package/skills/generative-seo/SKILL.md +255 -0
- package/skills/generative-seo/assets/citation-log-template.md +17 -0
- package/skills/generative-seo/assets/competitor-analysis-template.md +20 -0
- package/skills/generative-seo/assets/content-plan-template.md +15 -0
- package/skills/generative-seo/assets/geo-config-template.md +33 -0
- package/skills/generative-seo/assets/geo-playbook-template.md +22 -0
- package/skills/generative-seo/assets/social-queue-template.md +8 -0
- package/skills/generative-seo/references/geo-methodology.md +143 -0
- package/skills/spec-checkpoint/SKILL.md +106 -0
- package/skills/spec-create/SKILL.md +149 -0
- package/skills/spec-create/references/action-required-template.md +53 -0
- package/skills/spec-create/references/readme-template.md +53 -0
- package/skills/spec-create/references/requirements-template.md +54 -0
- package/skills/spec-create/references/task-template.md +86 -0
- package/skills/spec-implement/SKILL.md +236 -0
- package/skills/spec-implement/references/coder-prompt-template.md +48 -0
- package/skills/spec-implement/references/fix-prompt-template.md +38 -0
- package/skills/spec-implement/references/review-prompt-template.md +50 -0
- package/skills/spec-investigate/SKILL.md +323 -0
- package/skills/spec-investigate/references/report-template.md +53 -0
- package/skills/spec-setup/SKILL.md +99 -0
- package/skills/spec-setup/references/config-template.yml +45 -0
- package/skills/spec-ship/SKILL.md +218 -0
- package/skills/spec-verify/SKILL.md +153 -0
- package/skills/spec-verify/references/report-template.md +57 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec-ship
|
|
3
|
+
description: >
|
|
4
|
+
Push the current branch to GitHub and create a pull request. Use this skill when the user says
|
|
5
|
+
"ship it", "ship this", "push to github", "create a pr", "open a pull request", "send for review",
|
|
6
|
+
"get this reviewed", or wants to push their work and open a PR. Also use when the user says
|
|
7
|
+
"/spec-ship" (or their host's equivalent invocation syntax). This skill handles prerequisites,
|
|
8
|
+
branching, pushing, and PR creation — it does not commit or run quality checks (use
|
|
9
|
+
spec-checkpoint for that first).
|
|
10
|
+
license: MIT
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Ship It
|
|
14
|
+
|
|
15
|
+
Push your work to GitHub and open a pull request — handling prerequisites, branch creation, pushing, and PR generation automatically.
|
|
16
|
+
|
|
17
|
+
This skill complements `spec-checkpoint`. Use `spec-checkpoint` to commit locally (with quality gates), then `spec-ship` to get the code to GitHub for review.
|
|
18
|
+
|
|
19
|
+
## Project config (read first)
|
|
20
|
+
|
|
21
|
+
Load `.spec-driven.yml`: walk up from the current directory to the home folder, and the first one
|
|
22
|
+
found wins (a `multi-repo` config only applies inside the repos it lists). Its values beat anything
|
|
23
|
+
you would detect or assume. This skill uses `git.remote`, `git.pr_target`, `git.branch_name`, `tracker` (to link the ticket in the PR), and `layout`/`repos`.
|
|
24
|
+
|
|
25
|
+
**Multi-repo:** push and open one PR per repo that has unpushed commits, and list the sibling PRs in each PR's body so reviewers see the whole change.
|
|
26
|
+
|
|
27
|
+
**No config?** If the `spec-setup` skill is available, run it first, then continue here. If it
|
|
28
|
+
isn't, detect what this skill needs from the repo, ask about anything ambiguous, and offer to save
|
|
29
|
+
the answers to `.spec-driven.yml` (keys: `layout`, `repos`, `tracker`, `git`, `commands`,
|
|
30
|
+
`specs_dir`).
|
|
31
|
+
|
|
32
|
+
## Instructions
|
|
33
|
+
|
|
34
|
+
### Step 0: Prerequisites
|
|
35
|
+
|
|
36
|
+
Verify tooling before doing anything else.
|
|
37
|
+
|
|
38
|
+
1. **GitHub CLI installed?**
|
|
39
|
+
```bash
|
|
40
|
+
gh --version
|
|
41
|
+
```
|
|
42
|
+
If the command fails (not found):
|
|
43
|
+
- Detect the platform and attempt to install:
|
|
44
|
+
- **Windows:** `winget install --id GitHub.cli`
|
|
45
|
+
- **macOS:** `brew install gh`
|
|
46
|
+
- **Linux (Debian/Ubuntu):** follow the official apt instructions
|
|
47
|
+
- If auto-install fails, tell the user what to install and stop.
|
|
48
|
+
|
|
49
|
+
2. **GitHub CLI authenticated?**
|
|
50
|
+
```bash
|
|
51
|
+
gh auth status
|
|
52
|
+
```
|
|
53
|
+
If not authenticated, tell the user:
|
|
54
|
+
```
|
|
55
|
+
GitHub CLI is not logged in. Please run this in the prompt:
|
|
56
|
+
! gh auth login
|
|
57
|
+
Then re-run /spec-ship.
|
|
58
|
+
```
|
|
59
|
+
Stop here — do not proceed until auth is confirmed.
|
|
60
|
+
|
|
61
|
+
3. **Git remote exists?**
|
|
62
|
+
```bash
|
|
63
|
+
git remote -v
|
|
64
|
+
```
|
|
65
|
+
If no remote named `origin` exists, stop and tell the user:
|
|
66
|
+
```
|
|
67
|
+
No git remote found. Add one with:
|
|
68
|
+
git remote add origin https://github.com/{user}/{repo}.git
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Step 1: Detect the Environment
|
|
72
|
+
|
|
73
|
+
Run these commands to understand the current state:
|
|
74
|
+
|
|
75
|
+
1. `git branch --show-current` — get the current branch name
|
|
76
|
+
2. Detect the default branch:
|
|
77
|
+
```bash
|
|
78
|
+
gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name'
|
|
79
|
+
```
|
|
80
|
+
3. `git status --porcelain` — check for uncommitted changes
|
|
81
|
+
|
|
82
|
+
If there are uncommitted changes, stop and tell the user:
|
|
83
|
+
```
|
|
84
|
+
You have uncommitted changes. Run /spec-checkpoint first to commit them, then /spec-ship to push.
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Store the default branch name for use throughout the remaining steps. If `.spec-driven.yml` sets
|
|
88
|
+
`git.pr_target` (anything other than `default`), use that as `{default_branch}` everywhere below,
|
|
89
|
+
including as the PR's `--base`. Use `git.remote` instead of `origin` if it's set.
|
|
90
|
+
|
|
91
|
+
### Step 2: Check for Unpushed Commits
|
|
92
|
+
|
|
93
|
+
Determine if there are commits that haven't been pushed yet.
|
|
94
|
+
|
|
95
|
+
**If on a feature branch with a remote tracking branch:**
|
|
96
|
+
```bash
|
|
97
|
+
git log @{upstream}..HEAD --oneline
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**If on a feature branch with no remote tracking branch, or on the default branch:**
|
|
101
|
+
```bash
|
|
102
|
+
git log origin/{default_branch}..HEAD --oneline
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
If there are **no unpushed commits**, stop and tell the user:
|
|
106
|
+
```
|
|
107
|
+
Nothing to ship — all commits are already pushed.
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Save the list of unpushed commit messages for use in later steps.
|
|
111
|
+
|
|
112
|
+
### Step 3: Handle Branching
|
|
113
|
+
|
|
114
|
+
**If already on a feature branch** (not the default branch):
|
|
115
|
+
- Stay on it. No branching needed.
|
|
116
|
+
- Skip to Step 4.
|
|
117
|
+
|
|
118
|
+
**If on the default branch:**
|
|
119
|
+
- If the config sets `git.branch_name`, fill in its placeholders (`{ticket}` from the commits or
|
|
120
|
+
investigation, `{slug}` and `{type}` as below) and skip the derivation that follows.
|
|
121
|
+
- Otherwise, generate a branch name from the unpushed commit messages:
|
|
122
|
+
- Read the commit subjects
|
|
123
|
+
- Derive a kebab-case branch name with a conventional prefix: `feat/`, `fix/`, `refactor/`, `chore/`, `docs/` based on the commit content
|
|
124
|
+
- Keep it short (3-5 words max after the prefix), e.g., `feat/add-user-auth`, `fix/login-redirect-loop`
|
|
125
|
+
- Strip special characters, lowercase everything
|
|
126
|
+
- Create and switch to the new branch:
|
|
127
|
+
```bash
|
|
128
|
+
git checkout -b {branch_name}
|
|
129
|
+
```
|
|
130
|
+
- Tell the user: `Created branch {branch_name}`
|
|
131
|
+
|
|
132
|
+
### Step 4: Confirm Before Pushing
|
|
133
|
+
|
|
134
|
+
Pushing and opening a PR are visible to others and not easily undone — confirm with the user
|
|
135
|
+
before proceeding, even if your host would otherwise run this skill non-interactively without
|
|
136
|
+
prompting. Show:
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
About to push and open a PR:
|
|
140
|
+
Branch: {branch_name}
|
|
141
|
+
Remote: origin
|
|
142
|
+
Commits:
|
|
143
|
+
{list of unpushed commit subjects, from Step 2}
|
|
144
|
+
|
|
145
|
+
Proceed? (yes/no)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Wait for an explicit yes. If the user declines or doesn't respond affirmatively, stop here —
|
|
149
|
+
do not push.
|
|
150
|
+
|
|
151
|
+
### Step 5: Push to Origin
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
git push -u origin {branch_name}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
If the branch already has a remote tracking branch, a regular `git push` is fine.
|
|
158
|
+
|
|
159
|
+
### Step 6: Check for Existing PR
|
|
160
|
+
|
|
161
|
+
Before creating a new PR, check if one already exists for this branch:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
gh pr view --json number,url,title,state 2>/dev/null
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
If a PR already exists and is **open**:
|
|
168
|
+
- Do NOT create a new one
|
|
169
|
+
- Skip to Step 8 and report the existing PR with a note that new commits were pushed.
|
|
170
|
+
|
|
171
|
+
If no PR exists (or it is closed/merged), proceed to Step 7.
|
|
172
|
+
|
|
173
|
+
### Step 7: Create the Pull Request
|
|
174
|
+
|
|
175
|
+
Generate the PR title and body from the unpushed commits:
|
|
176
|
+
|
|
177
|
+
- **Title**: concise summary under 70 chars. If single commit, use its subject. If multiple, synthesize a short summary. Imperative mood.
|
|
178
|
+
- **Body**: TL;DR of the changes in 2-4 bullet points max, plus a footer naming whichever
|
|
179
|
+
agent/model actually generated the PR — never hardcode a specific vendor or model name, since
|
|
180
|
+
this skill runs under many different hosts. Omit the footer entirely if your host has no clean
|
|
181
|
+
way to identify itself.
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
gh pr create --base {default_branch} --head {branch_name} --title "{title}" --body "$(cat <<'EOF'
|
|
185
|
+
## Summary
|
|
186
|
+
{2-4 bullet points}
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
Generated by {agent name}
|
|
190
|
+
EOF
|
|
191
|
+
)"
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Step 8: Report
|
|
195
|
+
|
|
196
|
+
Display the result clearly:
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
Shipped to GitHub:
|
|
200
|
+
Branch: {branch_name}
|
|
201
|
+
PR: #{number} — {title}
|
|
202
|
+
URL: {url}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Important
|
|
206
|
+
|
|
207
|
+
- Do NOT run lint, type-check, or build — that is spec-checkpoint's job
|
|
208
|
+
- Do NOT commit anything — only push existing commits and create a PR
|
|
209
|
+
- If the user has uncommitted changes, tell them to run /spec-checkpoint first
|
|
210
|
+
- Keep the PR body short — a TL;DR, not an essay
|
|
211
|
+
- Always check for an existing open PR before creating a new one to avoid duplicates
|
|
212
|
+
- Detect the default branch dynamically — do not hardcode `main` or `master`
|
|
213
|
+
- When creating a branch from the default branch, use conventional prefixes (`feat/`, `fix/`, etc.) with kebab-case names
|
|
214
|
+
- Never run destructive git operations (no `--force`, no `reset --hard`)
|
|
215
|
+
- If `gh` is not installed or authenticated, help the user get set up before proceeding
|
|
216
|
+
- Always get explicit user confirmation before pushing or opening a PR (Step 4) — do this even
|
|
217
|
+
if your host would otherwise let the skill run non-interactively, since pushing and opening a
|
|
218
|
+
PR are visible to others and not easily undone
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec-verify
|
|
3
|
+
description: >
|
|
4
|
+
Verify a completed feature spec by driving the real running app — not just lint/typecheck/build
|
|
5
|
+
— and checking off every acceptance criterion from its specs/{feature}/ folder one by one. Use
|
|
6
|
+
this after /spec-implement finishes a spec, when the user says "test this end to end",
|
|
7
|
+
"verify this feature actually works", "did we actually build this right", or "/spec-verify",
|
|
8
|
+
and before /spec-ship or opening a PR. This is the spec-aware sibling of the generic /verify and
|
|
9
|
+
/run skills — /verify checks an arbitrary diff's runtime behavior and /run just launches the
|
|
10
|
+
app, but this skill specifically reads a spec's requirements.md and task files, builds a master
|
|
11
|
+
checklist of acceptance criteria, and reports pass/fail per criterion with real evidence
|
|
12
|
+
(screenshots, API responses, DB state) instead of a vague "looks good." Always invoke this when
|
|
13
|
+
a specs/{feature}/ folder exists and its implementation just finished, even if the user only
|
|
14
|
+
says "does this work" or "test it."
|
|
15
|
+
license: MIT
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# Verify Feature
|
|
19
|
+
|
|
20
|
+
Close the loop that `spec-create` → `spec-implement` leaves open: passing lint, typecheck, and
|
|
21
|
+
build proves the code compiles, not that the feature does what the spec says it does. This skill
|
|
22
|
+
reads a spec's acceptance criteria and checks each one against the actual running application —
|
|
23
|
+
clicking through the UI, calling the real API routes, or inspecting real database state produced
|
|
24
|
+
by the real code path. It produces a report the user can trust before shipping.
|
|
25
|
+
|
|
26
|
+
## Project config (read first)
|
|
27
|
+
|
|
28
|
+
Load `.spec-driven.yml`: walk up from the current directory to the home folder, and the first one
|
|
29
|
+
found wins (a `multi-repo` config only applies inside the repos it lists). Its values beat anything
|
|
30
|
+
you would detect or assume. This skill uses `commands.dev`, `commands.dev_url`, and `layout`/`repos`.
|
|
31
|
+
|
|
32
|
+
**Monorepo / multi-repo:** start every app or service the criteria need (e.g. the API and the frontend), each with its own `dev` command.
|
|
33
|
+
|
|
34
|
+
**No config?** If the `spec-setup` skill is available, run it first, then continue here. If it
|
|
35
|
+
isn't, detect what this skill needs from the repo, ask about anything ambiguous, and offer to save
|
|
36
|
+
the answers to `.spec-driven.yml` (keys: `layout`, `repos`, `tracker`, `git`, `commands`,
|
|
37
|
+
`specs_dir`).
|
|
38
|
+
|
|
39
|
+
## When there's no spec folder
|
|
40
|
+
|
|
41
|
+
If the user asks to verify a feature that wasn't built through `spec-create`, don't refuse —
|
|
42
|
+
interview them briefly for what was built and what "working" means (the golden path, the edge
|
|
43
|
+
cases they care about), then skip to [Step 3](#step-3-prepare-the-environment) treating their
|
|
44
|
+
answers as the criteria list. The spec-driven path below is the common case, not the only one.
|
|
45
|
+
|
|
46
|
+
## Step 1: Locate the spec
|
|
47
|
+
|
|
48
|
+
1. If the user named a feature, use `specs/{feature}/`.
|
|
49
|
+
2. Otherwise look for a `specs/*/README.md` whose Task Status section is fully checked (all
|
|
50
|
+
tasks `- [x]`) but has no `verification-report.md` sibling yet — that's the most recently
|
|
51
|
+
completed, not-yet-verified feature.
|
|
52
|
+
3. If `spec-implement` hasn't finished all batches yet (some tasks still `- [ ]`), tell the user
|
|
53
|
+
and ask whether to verify what's done so far or wait for the rest — verifying half a feature
|
|
54
|
+
can produce confusing false failures for criteria that depend on an unbuilt task.
|
|
55
|
+
|
|
56
|
+
## Step 2: Build the master criteria checklist
|
|
57
|
+
|
|
58
|
+
Read `requirements.md`'s **Acceptance Criteria** section (feature-level, the whole thing working
|
|
59
|
+
end-to-end) and every `tasks/task-*.md`'s own **Acceptance Criteria** section (task-level). Merge
|
|
60
|
+
them into one ordered list, each item tagged with its source (`requirements` or the task
|
|
61
|
+
filename).
|
|
62
|
+
|
|
63
|
+
Split the merged list into two kinds, because they're verified completely differently:
|
|
64
|
+
|
|
65
|
+
- **Static criteria** — things like "lint passes" or "the production build succeeds."
|
|
66
|
+
`spec-implement`'s review gate already ran these during the build. Re-run them once quickly
|
|
67
|
+
to confirm nothing regressed since (uncommitted fix-ups, a rebase, etc.), but don't treat this
|
|
68
|
+
as the interesting part of verification.
|
|
69
|
+
- **Behavioral criteria** — anything that describes what a user, an API caller, or a scheduled
|
|
70
|
+
job actually observes ("a FREE user sees a Renew button," "the cron doesn't double-send,"
|
|
71
|
+
"removing a member revokes their access on next request"). These are why this skill exists —
|
|
72
|
+
they require driving the real app, not reading the diff.
|
|
73
|
+
|
|
74
|
+
## Step 3: Prepare the environment
|
|
75
|
+
|
|
76
|
+
Check whether the app is already running (`curl -sf {commands.dev_url}`, or the port the
|
|
77
|
+
project's dev script uses) before starting a new one, since a stray second instance just causes
|
|
78
|
+
confusing port conflicts. If nothing responds, start `commands.dev` from the config (or the
|
|
79
|
+
project's own dev script) in the background and poll until it's ready.
|
|
80
|
+
|
|
81
|
+
Look at what the behavioral criteria actually need before reaching for tools:
|
|
82
|
+
|
|
83
|
+
- **UI-observable** (a button appears, a page shows a value, a flow completes) → browser
|
|
84
|
+
automation. Use whatever browser-automation capability your host provides — a browser MCP
|
|
85
|
+
server (Playwright, Puppeteer, etc.), a built-in browser tool, or a browser extension — and
|
|
86
|
+
enable/load it per your host's own convention if it isn't active by default. Take a screenshot
|
|
87
|
+
as evidence for each criterion you check this way.
|
|
88
|
+
- **API-only** (no UI surface, e.g. a webhook or a cron route) → call the real route. For
|
|
89
|
+
session-gated routes, log in through the actual UI once (or reuse a session cookie from a
|
|
90
|
+
browser step) rather than fabricating auth state. For routes gated by a bearer secret (like a
|
|
91
|
+
cron's `CRON_SECRET`), call them directly with `curl`.
|
|
92
|
+
Note: if your browser tool can read console/network logs, that's useful when a criterion is
|
|
93
|
+
best confirmed by watching what the frontend actually sent/received rather than clicking
|
|
94
|
+
through screenshots.
|
|
95
|
+
- **DB-state-only** (a column got stamped correctly, a row was scoped the way it should be) →
|
|
96
|
+
drive the real write path first (through the UI or API — never insert the expected state
|
|
97
|
+
directly, that verifies nothing), then read the resulting row back with the project's own DB client or CLI to
|
|
98
|
+
confirm it. This mirrors how you'd sanity-check a migration: trust the app's own code path to
|
|
99
|
+
produce the state, and only use direct DB reads for the *assertion*, never the *setup*.
|
|
100
|
+
- **Timing-dependent** (a reminder email fires N days before expiry, idempotency across cron
|
|
101
|
+
runs) → don't wait real days. Insert or edit the relevant date field in the test data so it
|
|
102
|
+
already sits at the boundary the criterion describes, then invoke the real code path (call the
|
|
103
|
+
cron route, run the actual query) and observe what happens. You're still exercising the real
|
|
104
|
+
logic — you're just moving the clock via input data instead of a `sleep`.
|
|
105
|
+
|
|
106
|
+
Create whatever throwaway test data (a second test user, a lapsed subscription row, etc.) each
|
|
107
|
+
criterion needs. Note everything you create — you'll remove it in Step 5.
|
|
108
|
+
|
|
109
|
+
## Step 4: Verify each criterion
|
|
110
|
+
|
|
111
|
+
Work through the checklist in order. For each one, record:
|
|
112
|
+
|
|
113
|
+
- **Verdict**: PASS, FAIL, or SKIPPED (with a reason — e.g. "requires a live payment gateway
|
|
114
|
+
webhook, not reproducible locally").
|
|
115
|
+
- **Evidence**: a screenshot path, the exact `curl` command and response, or the DB query and
|
|
116
|
+
the row it returned. Evidence is what makes the report trustworthy instead of another
|
|
117
|
+
unverified claim — write down enough that someone who wasn't watching could confirm it.
|
|
118
|
+
- **For a FAIL**: the concrete scenario that breaks it (exact input/state → actual vs expected
|
|
119
|
+
output), not just "doesn't work." This is what turns a failure into something fixable.
|
|
120
|
+
|
|
121
|
+
Don't stop at the first failure — finish the checklist so the report reflects the feature's real
|
|
122
|
+
state, not just the first thing that went wrong.
|
|
123
|
+
|
|
124
|
+
## Step 5: Clean up
|
|
125
|
+
|
|
126
|
+
Remove every test user, record, or row you created in Step 3/4 so the dev database is left the
|
|
127
|
+
way you found it. Never delete data that predates this run — if you're not certain something is
|
|
128
|
+
yours, leave it. If you started the dev server yourself in Step 3, it's fine to leave it running
|
|
129
|
+
(the user likely wants it for their own follow-up testing) — just say so in the report.
|
|
130
|
+
|
|
131
|
+
## Step 6: Report
|
|
132
|
+
|
|
133
|
+
Write `specs/{feature}/verification-report.md` — see `references/report-template.md` for the
|
|
134
|
+
exact structure (a summary line, then a table of criterion → source → verdict → evidence, then a
|
|
135
|
+
"Failures" section with full repro detail for anything that didn't pass).
|
|
136
|
+
|
|
137
|
+
Update `specs/{feature}/README.md` with a short **Verification** section linking to the report
|
|
138
|
+
and stating the overall status (all pass / N of M pass).
|
|
139
|
+
|
|
140
|
+
Then tell the user directly:
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
Verified {feature}: {X}/{Y} criteria passed.
|
|
144
|
+
|
|
145
|
+
{If all pass:} Ready to ship.
|
|
146
|
+
{If failures:} {N} failing — see specs/{feature}/verification-report.md for exact repro steps.
|
|
147
|
+
Options: loop back to /spec-implement to fix, or fix manually.
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
This skill only verifies and reports — it does not fix failures itself. Mixing "test" and "fix"
|
|
151
|
+
in one pass makes it too easy to quietly patch a failure without recording that it happened;
|
|
152
|
+
keeping them separate means the report is always an honest snapshot of what was actually true
|
|
153
|
+
when you ran it.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Verification Report Template
|
|
2
|
+
|
|
3
|
+
Use this structure for `specs/{feature}/verification-report.md`.
|
|
4
|
+
|
|
5
|
+
## Template
|
|
6
|
+
|
|
7
|
+
```markdown
|
|
8
|
+
# Verification Report: {Feature Name}
|
|
9
|
+
|
|
10
|
+
Verified: {date} · {X}/{Y} criteria passed
|
|
11
|
+
|
|
12
|
+
## Summary
|
|
13
|
+
|
|
14
|
+
{One or two sentences: overall status, and anything a reviewer should know before reading
|
|
15
|
+
further — e.g. "All criteria pass; the Renew button was tested against all three checkout
|
|
16
|
+
providers by swapping ACTIVE_PAYMENT_PROVIDER." or "2 failures, both in the reminder-email
|
|
17
|
+
idempotency path — see Failures below."}
|
|
18
|
+
|
|
19
|
+
## Environment
|
|
20
|
+
|
|
21
|
+
- Dev server: {already running / started fresh, left running or stopped}
|
|
22
|
+
- Test data created: {brief list — removed in cleanup unless noted otherwise}
|
|
23
|
+
- Tools used: {browser automation / curl / psql/Prisma / combination}
|
|
24
|
+
|
|
25
|
+
## Criteria
|
|
26
|
+
|
|
27
|
+
| # | Criterion | Source | Verdict | Evidence |
|
|
28
|
+
|---|-----------|--------|---------|----------|
|
|
29
|
+
| 1 | {criterion text} | requirements.md | PASS | {screenshot path / curl command+response / query+result} |
|
|
30
|
+
| 2 | {criterion text} | task-01-{name}.md | PASS | ... |
|
|
31
|
+
| 3 | {criterion text} | task-02-{name}.md | FAIL | see Failures below |
|
|
32
|
+
|
|
33
|
+
## Failures
|
|
34
|
+
|
|
35
|
+
{Omit this section entirely if everything passed.}
|
|
36
|
+
|
|
37
|
+
### {Criterion text}
|
|
38
|
+
|
|
39
|
+
**Scenario:** {exact input/state that triggers it}
|
|
40
|
+
**Expected:** {what the criterion says should happen}
|
|
41
|
+
**Actual:** {what actually happened}
|
|
42
|
+
**Evidence:** {screenshot, response body, query result}
|
|
43
|
+
|
|
44
|
+
## Notes
|
|
45
|
+
|
|
46
|
+
{Anything verified as SKIPPED and why (e.g. requires a live third-party webhook), or edge cases
|
|
47
|
+
noticed but not in the original criteria list that are worth flagging back to the spec.}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Key Points
|
|
51
|
+
|
|
52
|
+
- The **Criteria** table is the core deliverable — it should let someone who wasn't in the room
|
|
53
|
+
trust that "PASS" actually means what it says, because the evidence column backs it up.
|
|
54
|
+
- Keep evidence concise (a path, a one-line command + result) — this file is a report, not a
|
|
55
|
+
transcript. Full detail belongs in the Failures section, only for things that need it.
|
|
56
|
+
- If a criterion is SKIPPED, say why in the Notes section rather than silently omitting it — a
|
|
57
|
+
missing row is indistinguishable from forgetting to check it.
|