| name | safe-pr |
| description | Use to open a safe, reviewable pull request from a feature branch into main once a slice is built with red-green-refactor and green. Phase 4 of the TDD harness. It assembles everything a reviewer needs — the feature and slice description, evidence of the tests that ran (unit summaries plus Playwright screenshots and recordings for web slices, or terminal transcripts for CLI and API slices), a reviewer checklist, and a link to the plan — then pushes the branch and opens the PR with gh. Trigger on 'raise a PR', 'open a pull request', 'ship this slice', or 'create the PR with evidence'. Deliberately cautious — confirms before pushing, never force-pushes, only targets main. |
Safe PR — Evidence-Rich Pull Request (Phase 4)
Open a pull request a senior engineer can approve with confidence, because the evidence is right there. This is the final phase of a slice: build (red-green-refactor) → CI (tdd-ci) → PR. Treat opening a PR as an outward-facing action — be careful and confirm before pushing.
The harness builds web and non-web apps, so evidence comes in two shapes:
- Web slice → Playwright screenshots + a recording of the passing acceptance run (plus the HTML report).
- Non-web slice (CLI / HTTP API / service) → terminal transcripts: the test-run output and a real endpoint invocation (CLI stdout, or an HTTP request+response). Transcripts stand in for screenshots/recordings.
Bundled resources:
assets/pr-body-template.md — the PR description structure (with an <!-- EVIDENCE --> marker the script fills).
scripts/collect-evidence.mjs — collects evidence into the committed evidence folder and generates the PR body. For web slices it embeds screenshots and links the recording/report; for non-web slices (--type cli|api|service with --transcript) it embeds the transcripts as code blocks. Modality is auto-detected (Playwright artifacts → web) or forced with --type. It runs in two phases — --copy-only (copy + secret-scan) before you commit the evidence, then --body-only (build the body, pinned to the evidence commit) after — so embedded links resolve. It auto-detects repo visibility and, on private repos, renders screenshots as clickable blob links rather than inline images that wouldn't render. Run with Node.
Requires the GitHub CLI (gh) authenticated, and a GitHub remote. Confirm both early (gh auth status, git remote -v).
Preconditions (verify, don't assume)
- The slice is green. Re-run the full suite (unit + e2e) and confirm it passes. Never open a PR on red. If anything fails, stop and return to
red-green-refactor.
- CI workflow exists.
.github/workflows/ runs the unit + e2e tests (from tdd-ci). If missing, run tdd-ci first.
- On the slice's feature branch.
feat/<feature-slug>/<NN>-<slice-slug>. If you're on main or another branch, create/switch to the slice branch. Never develop or PR a slice from main.
- Working tree committed. All slice work is committed in small, green-only commits.
Procedure
-
Produce the evidence by actually running the tests. Show real run output, not claims. Always capture the unit-test summary (counts, pass/fail). Then, depending on the slice's boundary:
- Web slice: run the e2e suite with Playwright configured to capture screenshots + video (
video: 'on') + HTML report (see the red-green-refactor test-strategy reference). The PR must include a screenshot and a recording of the passing acceptance run — if none was produced, re-run with video on before continuing.
- Non-web slice (CLI / API / service): capture two transcripts to files — (a) the test-run output (e.g.
npm test / pytest -q), and (b) a real invocation through the boundary (the CLI run with its stdout + exit code, or the HTTP request + response). Redirect them to files so the collector can attach them, e.g. npm test > test-run.txt 2>&1 and node src/cli.js 2 3 > cli-demo.txt 2>&1.
Run tests from the slice's project directory if the app lives in a subfolder (see the plan's Project directory field).
-
Copy the evidence in (--copy-only). Run the collector from the repo root in copy-only mode — it copies the artifacts into docs/tdd-evidence/<feature>/<NN-slice>/ and scans them for secrets, but does not write the PR body yet. (Two phases matter: the body pins URLs to the current commit, so the evidence must be committed before the body is generated — otherwise the links point at a commit that doesn't contain the files. See step 5.) Plain Node, so the same invocation works on Windows/macOS/Linux:
Web slice — point --report-dir/--results-dir at the project dir if the app is in a subfolder (the collector resolves them from the repo root):
node "${CLAUDE_SKILL_DIR}/scripts/collect-evidence.mjs" --feature <feature-slug> --slice <NN-slice-slug> --report-dir <project-dir>/playwright-report --results-dir <project-dir>/test-results --copy-only
Non-web slice (--type cli|api|service, one or more --transcript):
node "${CLAUDE_SKILL_DIR}/scripts/collect-evidence.mjs" --feature <feature-slug> --slice <NN-slice-slug> --type cli --transcript test-run.txt --transcript cli-demo.txt --copy-only
By default it drops raw traces () and HAR files (which often carry auth tokens); pass only if you need them and have checked them.
Safety rules (non-negotiable)
- Confirm before any push or
gh pr create — these are outward-facing and visible to the team.
- Never force-push, never rewrite shared history, never push directly to
main.
- Base is always
main unless the user says otherwise.
- Open the PR only on green with evidence attached. A PR without real test evidence defeats the purpose.
- Don't include secrets, tokens, or large binaries beyond the necessary evidence. Keep videos short; rely on
'retain-on-failure' if artifacts get heavy.
What the reviewer gets
A PR whose description proves the slice works: the behaviour described in plain language, the failing-then-passing acceptance test, the unit-test summary, a checklist, a link back to the execution plan, and modality-appropriate evidence of it working — embedded screenshots plus a linked recording and HTML report for a web slice, or the embedded test-run and real-invocation transcripts for a CLI/API/service slice. That is "everything a developer needs to review it and know the desired feature was built."