agentleFS
the-Sreejiththe-Sreejith/claude-pr-test-plan/skills/pr-test-plan/SKILL.md

pr-test-plan

Skill0 starsChanged 2 months agoMITView on GitHub

Analyze one or more pull requests, map every code change to the existing and new functionality it touches (including cross-repo, mirrored-route and shipped-client blast radius), and produce a manual click-through QA test plan with numbered steps, expected results, and traceability back to the diff. Use when asked "what do I need to test for this PR", to build a QA or regression plan for a PR/branch, to assess the blast radius or impact of changes, or to prepare a manual test pass before merging.

  • Reads credentials

1 other project uses a version of this.

Adopted by

Most recently taken up by

  • Other versions1 project uses a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 1

    1. PAIR-code/deliberate-lab★ 97same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • In this repositoryOne other file it gives its agents.

The file

We split this skill into the rules it gives an agent

10 rules. About 0 are common, 5 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈5

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Read-only against the repos: Never git checkout, git stash, git add, git pull, or switch branches — other sessions may hold uncommitted …

    line 18
  2. Distinctive:

    Ask only if no PR is identifiable.

    line 28
  3. Very specific:

    Look for a project-supplied one, in this order, and use it verbatim if found: .claude/pr-test-plan/surface-map.md, then …

    line 54
  4. Very specific:

    If none exists, derive one — see references/surface-mapping.md — and offer to save it to .claude/pr-test-plan/surface-map.md so the next …

    line 56
  5. Very specific:

    Use note when a likely-looking failure is a known pre-existing state — it stops false bug reports.

    line 124
  6. Distinctive:

    Before handing over, check against the Step 2 inventory:

    line 129
  7. Very specific:

    Every changed file appears in a case's why or in the "no user-visible surface" table with a reason.

    line 131
  8. Distinctive:

    Every mirrored/duplicated route has a case for both copies.

    line 132
  9. Distinctive:

    Every changed API request/response shape has a case for each shipped client that calls it.

    line 133
  10. Distinctive:

    Every migration in the PR appears in the preconditions, with its applied state stated as verified or unknown.

    line 134

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

PR Test Plan

Turn a PR (or a set of related PRs across repos) into a manual click-through test plan a human can execute without reading the diff.

Two questions drive everything:

  1. What is new? — functionality that did not exist before and has never been exercised.
  2. What is now different? — functionality that already existed, shipped, and could regress because this diff reached it.

Question 2 is where releases break, so it gets equal weight. A plan that only tests the feature is a failed plan.

Hard rules

  • Read-only against the repos. Never git checkout, git stash, git add, git pull, or switch branches — other sessions may hold uncommitted work in the same tree. Use gh pr diff and read files in place.
  • Every test case cites the change that motivates it (repo/path/file.ts plus a line or commit). No citation = you invented it, delete it.
  • Every changed file lands somewhere: in a test case, or in the "no user-visible surface" list with a one-line reason. This is the completion check.
  • Never claim a surface was verified. This skill produces a plan for a human. It does not run the flows.
  • Steps are clicks and screens, not code. "Open Settings → Billing, click Add card" — never "call createPaymentMethod".

Step 1 — Collect the PRs

Accept one or more PR URLs, owner/repo#N, or "the current branch". If PRs from several repos are given, they are one feature: produce one merged plan, not N plans.

Ask only if no PR is identifiable. Otherwise proceed.

for U in <pr urls>; do
  gh pr view "$U" --json number,title,body,url,state,isDraft,headRefName,baseRefName,headRefOid,additions,deletions,changedFiles,files
  gh pr diff "$U" --patch > "<scratch>/pr-<n>.patch"
done

Then read the commit messages in the patch (gh pr view "$U" --json commits, and the Subject:/body blocks inside --patch output). On a dev → main style bundle these are the fastest accurate description of what actually changed — PR titles routinely name one of several streams. Record repo, PR number, title, head SHA, base branch, and state for the plan header.

Step 2 — Build the change inventory

From each patch, produce a table before writing any test case:

repofile+/-kindwhat changed (one line)

kind is one of: ui-page, ui-component, api-route, schema/validation, service/lib, db-migration, rpc/sql, config/env, middleware/auth, mobile-screen, mobile-api-client, job/cron, test, docs, generated.

Then read the actual changed hunks of the highest-signal files (routes, migrations, auth, pricing, anything shared). Do not test from filenames alone — a renamed field or a changed status code is invisible at the filename level and is exactly what breaks shipped clients.

Step 3 — Load or derive the surface map

A surface map answers "a change in this path means a human must click what, as whom, at which URL".

  1. Look for a project-supplied one, in this order, and use it verbatim if found: .claude/pr-test-plan/surface-map.md, then docs/surface-map.md, then a "surfaces"/"apps" table in AGENTS.md, CLAUDE.md or README.md.
  2. If none exists, derive one — see references/surface-mapping.md — and offer to save it to .claude/pr-test-plan/surface-map.md so the next run is cheaper and more accurate. Keep that path even outside Claude Code — it is the shared location every agent reads.

Apply the map's mandatory pairings (mirrored/duplicated routes, shared APIs and their clients, one schema serving many apps) and its risk amplifiers (auth, migrations, money, checkout, stock, RLS) — each amplifier adds regression cases whether or not anyone edited the screen.

Step 4 — Trace the blast radius

For each changed exported symbol, route path, request/response field, DB column, or RPC, find who consumes it. Search the whole workspace, not just the PR's repo — sibling repos, mobile clients, and jobs often call the same API or table.

grep -rn "<symbol|route path|field name>" --include=*.{ts,tsx,js,kt,swift,py,go,sql} <repo roots> | grep -v node_modules

For a PR touching >40 files or >3 repos, fan out one read-only Explore agent per repo to collect call sites in parallel, then merge. Otherwise grep directly.

Step 5 — Classify functionality

Split every affected behaviour into three buckets. Name the user-facing capability, not the module.

  • NEW — did not exist before. Needs happy path + the failure/edge cases the diff's validation and error branches imply.
  • CHANGED — existed, behaves differently now. Needs the new behaviour and the parts of the old behaviour that must survive.
  • REGRESSION-RISK — untouched functionality reached through changed shared code (a helper, a schema, a shared component, a migrated column). Nobody edited it; it can still break.

Rank each P0/P1/P2:

  • P0 — money, auth, checkout/payment, stock/oversell, data loss, security properties (open redirect, privilege boundary), anything a shipped client calls.
  • P1 — a primary flow of the feature, or a mirrored route.
  • P2 — cosmetic, admin-only, easily noticed later.

Step 6 — Derive preconditions

The plan is useless if the tester can't reach the screen. From the diff, extract:

  • Migrations — list each file explicitly as a numbered pre-step, in order. If the project applies them by hand, say so and say the plan fails closed without them. Check applied state against a live-schema snapshot if the repo has one rather than assuming a file in the PR means the change is live.
  • Env vars / config — new keys in .env.example, CI config, build config, mobile local.properties / plists.
  • Feature flags / rollout gates — new booleans, *_enabled columns, rollout percentages, migration-group flags. Say which must be ON, where to flip them, and whether the flip needs a rebuild (build-time inlined) or takes effect live.
  • Seed / fixture data — the exact records needed (a user in state X, an order in status Y, a product with 2+ variants).
  • Accounts — every role the plan needs, including the negative-test role that must be refused.
  • Builds to install / servers to boot, with the command for each.

Step 7 — Write the plan as a local HTML file

The deliverable is a single self-contained .html file on disk. Do not write a Markdown plan, and do not publish an Artifact — not even as a follow-up offer. The user opens the file in a browser.

Copy references/page-template.html to TEST_PLAN_<pr-refs>.html — at the workspace root when the PRs span repos, so neither repo's working tree gains an untracked file — then fill it in:

  1. Masthead — eyebrow, page name, a two-to-three sentence summary that says what the PRs actually change (especially where that differs from their titles), the PR chips, and the five stat tiles.
  2. Section 0 — preconditions, in the template's five subsections.
  3. The S array in the <script> — one object per section, each holding its cases. This is the bulk of the work; the page renders the cases, the table of contents, the per-section counts and the progress meter from this array alone.
  4. Sections 7, 8, 9 and Coverage, and the footer.

The template already carries everything else: light and dark themes, the sticky rail, the P0/P1/P2 filter, per-case checkboxes persisted to localStorage, a print stylesheet, and Google-Fonts typography. Do not restyle it. The page must work from a file:// URL with no network: no CDN scripts, no fetches, no images that are not data URIs. The one exception is the Google Fonts <link> already in the template — it degrades silently to the declared fallback stacks offline, so never remove those stacks.

Writing conventions inside the S array:

  • Inline code in any string is written @like this@. Angle brackets inside @...@ are escaped for you, so @<API>/v1/x@ and @<id>@ survive; prose outside the markers may use <b>.
  • One action per numbered step. Max ~8 steps per case; split if longer.
  • expect states an observable on-screen fact, including the exact number, label or status where the diff makes it predictable.
  • Use note when a likely-looking failure is a known pre-existing state — it stops false bug reports.
  • Give each section a time estimate, and order cases so preconditions flow forward.

Step 8 — Verify, then deliver

Before handing over, check against the Step 2 inventory:

  1. Every changed file appears in a case's why or in the "no user-visible surface" table with a reason.
  2. Every mirrored/duplicated route has a case for both copies.
  3. Every changed API request/response shape has a case for each shipped client that calls it.
  4. Every migration in the PR appears in the preconditions, with its applied state stated as verified or unknown.
  5. The masthead's case and priority counts match the S array — count them, do not estimate.

Then check the file actually works before claiming it does:

node -e "const fs=require('fs');const h=fs.readFileSync('<plan>.html','utf8');
fs.writeFileSync('/tmp/_pt.js', h.match(/<script>([\s\S]*)<\/script>/)[1]);" \
  && node --check /tmp/_pt.js && echo "JS OK"
grep -c "id:'TC-" <plan>.html   # must equal the masthead case count

A syntax error in the S array renders a blank page, so this check is not optional.

Report the file path, the case and P0 counts, and the total estimated minutes. Tell the user to open it in a browser (open <plan>.html). Mention that checkmarks persist per browser and are not shared.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.