$npx -y skills add eduwxyz/my-awesome-skills --skill verifyVerify that a spec.md's Acceptance criteria are observably covered by green tests before opening a PR. Reads the spec, finds the tests that cover each AC, runs the suite to confirm everything green, and reports gaps (uncovered AC, skipped tests, missing edge-case coverage). When
| 1 | # Verify |
| 2 | |
| 3 | The closing gate of the SDD pipeline. Map every acceptance criterion in the spec to a green test, surface any gaps, decide whether the work is ready for review. |
| 4 | |
| 5 | ## Skip verify for |
| 6 | |
| 7 | - **Spike / scratch work** — there's no spec to verify against. |
| 8 | - **Tiny obvious changes** — typo fix, single-line bug, comment update. |
| 9 | - **Specs without an `## Acceptance criteria` section** — the upstream skill (`interview-to-spec` or `diagnose`) was abandoned mid-way. Finish that first. |
| 10 | |
| 11 | ## Before you start |
| 12 | |
| 13 | **Identify the spec.** A path or slug for an existing `spec/<slug>.md`. If neither was provided, ask the user — do not guess. |
| 14 | |
| 15 | **Validate it.** The spec must contain `## Acceptance criteria`. If missing, abort and tell the user to complete the spec first. |
| 16 | |
| 17 | ## The work |
| 18 | |
| 19 | 1. **Read the spec.** Focus on `Acceptance criteria` and `Edge cases` (or `Related risks` for bug specs). |
| 20 | |
| 21 | 2. **Find the tests.** Locate the relevant test files in the project's test directory (`tests/`, `__tests__/`, `*_test.go`, `*_spec.rb`, etc). Read them. |
| 22 | |
| 23 | 3. **Map AC → test.** For each acceptance criterion, find the test that **observably proves it**. Match on behaviour, not on naming similarity. A test named close to an AC does not count if it asserts something different. |
| 24 | |
| 25 | 4. **Find gaps.** Two categories — handled differently: |
| 26 | |
| 27 | **Blocking gaps** (auto-fixed via handoff to `tdd`): |
| 28 | - An AC (or edge case) with no test covering it. |
| 29 | - A test marked `skip` / `xfail` / `it.skip` / `@pytest.mark.skip` / `t.Skip` / equivalent. |
| 30 | - A test with `TODO`, commented-out assertions, or empty body. |
| 31 | - An edge case from the spec without observable coverage. |
| 32 | |
| 33 | **Warnings** (surface only, do **not** auto-fix): |
| 34 | - Tests that don't trace back to any AC or edge case in the spec. They might be intentional extra coverage or scope creep — that's the user's call. Listed in the report; do not affect the verdict. |
| 35 | |
| 36 | 5. **Confirm green.** Run the project's test command (from `.agents/tdd/test-command.txt` if it exists, otherwise infer it the same way the `tdd` skill does). All tests must pass. |
| 37 | |
| 38 | 6. **Report and persist the verdict.** Use the format below, and write the one-word verdict to `.agents/verify/last-verdict.txt` (see *Persisting the verdict*). |
| 39 | |
| 40 | ## Output format |
| 41 | |
| 42 | ```markdown |
| 43 | ## Verify report — <slug> |
| 44 | |
| 45 | ### Acceptance criteria coverage |
| 46 | - ✅ AC1 — `tests/auth/test_token.py::test_expired_tokens_rejected` |
| 47 | - ✅ AC2 — `tests/auth/test_token.py::test_valid_tokens_accepted` |
| 48 | - ❌ AC3 — no test found |
| 49 | |
| 50 | ### Edge cases |
| 51 | - ✅ Empty input — `tests/auth/test_token.py::test_empty_token_returns_400` |
| 52 | - ❌ Concurrent refresh — no test |
| 53 | |
| 54 | ### Tests without spec mapping (warning — your call) |
| 55 | - ⚠️ `tests/auth/test_token.py::test_token_internal_repr` — does not map to any AC. Intentional extra coverage, or scope-creep test to delete? |
| 56 | |
| 57 | ### Test run |
| 58 | ✅ 47 passed, 0 failed, 0 skipped. |
| 59 | |
| 60 | ### Verdict |
| 61 | **Not ready.** 2 items lack coverage. See gaps above. |
| 62 | ``` |
| 63 | |
| 64 | When all blocking gaps are absent and the suite is green, the verdict is **Ready for review.** Tests-without-mapping warnings do **not** affect the verdict. |
| 65 | |
| 66 | ## Persisting the verdict |
| 67 | |
| 68 | Every run of `verify` ends by writing the one-word verdict to `.agents/verify/last-verdict.txt` (create the directory if missing). The file is a single line, no trailing newline: |
| 69 | |
| 70 | - `Ready` — all blocking gaps resolved and the suite is green. |
| 71 | - `Not ready` — at least one blocking gap remains. |
| 72 | |
| 73 | The Stop hook reads this file. If you forget to write it, the previous run's verdict persists; if you never write it, the hook never blocks. **Always overwrite at the end of every run.** |
| 74 | |
| 75 | ## Where this skill ends |
| 76 | |
| 77 | - **Verdict = Ready for review** → hand off to `review` (built-in) or proceed to PR. |
| 78 | - **Verdict = Not ready** → **DO NOT END THE TURN.** Immediately hand off to `tdd` with the gap list as the new test queue. After `tdd` is green, re-invoke `verify`. Repeat until the verdict is `Ready`. |
| 79 | |
| 80 | The Stop hook **forces this iteration**: while the verdict file says `Not ready`, the turn cannot end. Do not try to skip the loop — fix the gaps via `tdd`, re-verify, repeat. |
| 81 | |
| 82 | Do not try to fix gaps inside `verify` itself — that's `tdd`'s job. Verify |