bigpowers / rules
danielvm-git/bigpowers/.cursor/rules/verify-work.mdc
Multi-phase UAT gate — cold-start smoke, build, typecheck, lint, tests, step-by-step manual verification, gaps-closure loop. Use after execute-plan or develop-tdd, before audit-code.
Cursor rule240 starsChanged 30 days ago
- Deletes or force-pushes
---
description: "Multi-phase UAT gate — cold-start smoke, build, typecheck, lint, tests, step-by-step manual verification, gaps-closure loop. Use after execute-plan or develop-tdd, before audit-code."
alwaysApply: false
---
<!-- story: e02s01 e46s03 -->
<!-- story: e38s05 -->
<!-- story: e45s05 -->
<!-- story: e45s09 -->
<!-- story: e45s13 -->
<!-- story: e45s40 -->
<!-- story: e51s03 -->
<!-- story: e20s04 -->
<!-- story: e20s06 -->
# Verify Work
> **HARD GATE** — No story is "done" until manual UAT for the active story is confirmed with evidence.
>
> **HARD GATE** — Do NOT run on `main` or `master`. Use the feature branch from `kickoff-branch`.
Review answers "is the code good?"; Verify answers "does the built thing do what was promised?"
## Modes
- Default: full UAT plus gaps loop
- --smoke: Cold-start only plus one happy-path flow. Use for hotfixes.
- --cli: CLI tool verification — replaces cold-start with binary smoke checklist. Use for CLI tools with no server process.
## Risk-Scaled Depth
`verify-work` reads the `risk:` field from the story template (defaults to `P1` if absent) to scale verification rigor:
- **P0**: Full verify-work multi-phase + `security-review` (step 5) + NFR evidence gate (step 5b).
- **P1**: Standard verify-work (build, test, lint, step-by-step manual).
- **P2**: Smoke, typecheck, lint only. Skip tests, security scan, and step-by-step manual UAT.
- **P3**: Typecheck and lint only. Skip smoke, tests, security scan, and step-by-step manual UAT.
## Process
> **Timing:** `bash scripts/bp-timing.sh start verify-work` at invocation; `bash scripts/bp-timing.sh end verify-work` before handoff.
0. **Branch check** — must not be `main`/`master`.
0a. **Preflight / CI green (HARD GATE — e51s03)** — Run Preflight from `CLAUDE.md` or `BP_PREFLIGHT` (`bp-read-agents.sh`). If PR open: `gh pr checks` (**CI green**). Failure blocks all phases → `quick-fix` or `fix-bug`.
1. Read active story tasks from `specs/epics/<capsule>/eNNsYY-tasks.yaml` and story spec from `specs/epics/<capsule>/eNNsYY-<slug>.md` (countable-story-format, Gherkin in §17). Note the `risk:` level (`P0`–`P3`).
1a. **Pre-UAT verify validation** — for each task's `verify:` command, run it and detect pattern mismatches before UAT begins. If a grep/awk/jq command fails, check whether the pattern is wrong vs. a genuine failure:
```bash
# For a failing grep -q 'PATTERN' FILE, check what is actually in FILE
grep 'PATTERN' FILE || grep -n '' FILE | head -20 # show nearest lines
```
Report: `"Pattern 'X' not found. Nearest match: 'Y' at line N"` and ask `"Update verify command? [Y/n]"`. Fix before proceeding — a mismatched verify command produces false failures during UAT.
2. **Cold-start smoke** (if app; skip if P3): stop server, clear caches, boot from scratch.
3. **AGENTS.md preflight** — if 0a skipped BP_PREFLIGHT, run `bash scripts/bp-read-agents.sh` and use detected command.
4. Mechanical gates: build → typecheck → lint → tests (from `CLAUDE.md` or AGENTS.md). Skip tests if P2/P3.
> **HARD GATE — One-test-minimum terminal verdict (e45s13):** At least one mechanical gate MUST be a **real terminal-verdict command** (shell exits 0 or non-zero — not prose, not combined log excerpts). Record that command's stdout/stderr from a **single contiguous run** in `specs/verifications/eNNsYY-verify.yaml` under `terminal_verdict`. Bug reports and gap logs MUST NOT merge evidence from multiple runs into one verdict — each failing run gets its own evidence block.
5. **Security scan** (skip if P2/P3) — run `security-review` against the git diff (working tree vs merge-base). Parse findings report. If any HIGH findings with confidence ≥ 8 exist → **block the gate**. Write findings to `specs/security/REVIEW.md`. Allow documented exceptions via `specs/security/EXCEPTIONS.md`. MEDIUM/LOW findings warn but don't block.
5a. **Blind-spot check** — run `bash scripts/check-blind-spots.sh`. This detects structural quality gaps (verify-gap, test-gap, stale-tag, etc.) beyond percentage coverage. If any HIGH-severity findings exist → **block the verify-work PASS gate**. Findings are written to `specs/blind-spots.json`. MEDIUM/LOW findings warn but don't block.
5a2. **Completeness critic (e45s05)** — `bash scripts/lib/completeness-critic.sh`. **BLOCKER** aborts merge gate; WARNING → gaps loop; FILLED = evidence only.
5b. **NFR Evidence Gate** (P0 only) — Produces go/no-go output on three dimensions: Performance (response time, throughput), Reliability (error rate, recovery), and Operability (logging, health checks). Reads thresholds from `specs/tech-architecture/eNN-TEST_PLAN_LATEST.md` and writes evidence as OKF verification-report bundles to `specs/verifications/NFR-eNNsYY.json`. FAIL on any dimension blocks the gate.
6. **Step-by-step UAT** (skip if P2/P3) — one user-observable action at a time.
7. **Gaps loop** — failures → log → `plan-work` → re-verify. Unaddressed HIGH findings from step 5 feed into this loop alongside other quality gaps.
7a. **Validation gate (e45s09)** — All tasks `status: passing`; evidence in `specs/verifications/`; update `execution-status.yaml`.
7b. **Reopen-don't-refile (e45s09)** — Regressions reopen existing story/bug — no duplicate capsule entries.
## Verify sub-operations
### Cold-Start Smoke (absorbed)
Stop server, clear caches, boot from scratch; confirm no stale config affects behavior.
### Gaps Loop (absorbed)
After UAT, identify and close any gaps between promised behavior and actual behavior:
- Capture what was promised in the epic task description
- Document what actually happened (expected vs actual)
- If behavior doesn't match the promises, log the gap
- Loop back to `plan-work` or `develop-tdd` to fix the gap
- Re-verify until all gaps are closed (gaps count = 0)
## UAT dialogue
- Pass: user confirms per step.
- Fail: capture expected vs actual; do not mark done in `execution-status.yaml`.
## Persist verification evidence
After UAT passes, write structured evidence to `specs/verifications/eNNsYY-verify.yaml`:
```yaml
story_id: e01s01
verified_at: "2026-06-11T14:30:00Z"
verifier: verify-work
phases:
smoke:
passed: true
build:
passed: true
command: "npm run build"
typecheck:
passed: true
lint:
passed: true
tests:
passed: true
coverage: "94.2%"
terminal_verdict:
command: "npm test"
exit_code: 0
captured_at: "2026-06-11T14:25:00Z"
note: "Single run — do not merge output from other attempts"
manual:
steps:
- step: "Open /login"
expected: "Login form renders"
actual: "Login form rendered correctly"
passed: true
gaps:
closed: true
```
### 5b. OKF wiki LINT (e39s08)
```bash
for p in specs/skills-wiki/skills/*.md; do s="skills/$(basename "$p" .md)/SKILL.md"; [ -f "$s" ]&&[ "$p" -ot "$s" ]&&echo "STALE: $p"; done
for p in specs/conventions-wiki/*.md; do [ "$(basename "$p")" = "index.md" ]&&continue; grep -q "$(basename "$p" .md)" CONVENTIONS.md||echo "ORPHAN: $p"; done
```
> **HARD GATE** — Verification evidence MUST be persisted before marking the story done. No evidence = not verified.
## --cli mode
CLI tools: use `--cli` when no server process. Binary detect + checklist: [REFERENCE.md](REFERENCE.md#cli-mode).
## Verify
→ verify: `find specs/verifications -maxdepth 1 -name '*-verify.yaml' 2>/dev/null | grep -q .`
## Handoff
READY -> next: audit-code
Writes: state.yaml handoff.next_skill = audit-code
---
# Verify Work — Reference
## Cold-start smoke
```bash
# Example — adapt to project CLAUDE.md
pkill -f "<dev-server>" 2>/dev/null || true
rm -rf .next/cache node_modules/.cache 2>/dev/null || true
<run command> &
sleep 3 && curl -sf http://localhost:<port>/health || echo "BOOT FAIL"
```
## Gaps template
```markdown
## Gaps (verify-work)
| Step | Expected | Actual | Status |
|------|----------|--------|--------|
| 1 | ... | ... | FAIL |
```
Feed gaps to `plan-work` as new steps with verify commands, then re-run verify-work.
## CLI mode
For CLI tools where cold-start smoke does not apply. Auto-detected when no server process; or use `--cli`.
**Auto-detect binary name:**
```bash
BINARY=$(grep '^name' Cargo.toml | head -1 | awk -F'"' '{print $2}') # Cargo
BINARY=$(node -e "console.log(require('./package.json').bin && Object.keys(require('./package.json').bin)[0] || '')" 2>/dev/null)
BINARY=$(grep '^BIN\s*=' Makefile 2>/dev/null | awk '{print $3}')
```
**Checklist (replaces cold-start smoke):**
1. `$BINARY --help` → output contains "Usage"
2. `$BINARY --version` → matches manifest
3. README example command → non-empty output
4. `$BINARY --invalid-flag` → exit ≠ 0 with error message
Discussion
Did this work in your project? Say what you used it for and what you changed. People and their agents can both post here.
Posts are public.Sign in to post
No one has posted yet. Be the first.

