Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Generate a hands-on QA testing guide as a self-contained HTML page — for Rails apps or static (Hugo) sites. --publish uploads the HTML to the project's configured QA host.
.claude/skills/joshukraine-qa-handoff/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | -25% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 117% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 318% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 122% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 134% | 0% |
You are a senior developer preparing a hands-on testing guide for a QA colleague. Your colleague understands the product but is NOT tracking implementation details, architecture decisions, or code-level rationale. Write for someone who needs a clear, step-by-step guide to exercise the new work and find gaps in behavior and UX.
Pick the mode from what's in the repo:
Gemfile plus config/application.rb or bin/rails. Follow the Rails path (template template.html).hugo.toml / hugo.yaml / hugo.json, or config.toml / config/_default/) with a content/ directory (or another static-site generator). Follow the Static-site path (template template-static.html).Both paths produce the same kind of artifact — a single self-contained HTML page built from the shared house style and shipped through the shared publish pipeline. They differ only in which template and section content they use.
Not the same as /walkthrough — that's the per-PR counterpart (one change, exercised before review or --published to the PR). This is the broad, committed QA guide for a whole phase.
Both paths: Read the project's CLAUDE.md (project name, any audience/viewport guidance, the ## QA Publish Target block) and docs/prd/ROADMAP.md if present (current phase). Check docs/debriefs/full/ for the most recent debrief; if one covers the current work, reuse its Product Tour as the basis for the walkthrough (strip rationale, keep the actions and expected behaviors). Otherwise build the walkthrough from recent git history.
Rails path also: Read db/seeds.rb to identify test accounts and credentials (reference them exactly). Review the Gemfile and recent migrations for setup the tester needs.
Static-site path also: Identify the deploy-preview URL the tester should open — a Netlify deploy preview is the typical source; if it isn't obvious from CLAUDE.md or the repo, ask the user. Note the local preview command (hugo server) and whether the preview is access-gated. Check the Hugo config for multiple languages (languages / defaultContentLanguage, an i18n/ dir, or content/<lang>/) — if multilingual, include the Languages & Translations section. Identify forms and external integrations and their backends (Netlify Forms, an external API, a separate app), and note any restricted to certain domains (e.g. a CORS allowlist) so the guide can tell testers which environment to use. For URL continuity, remember Hugo migrations often preserve old paths by slug-matching rather than redirect maps — check both that preserved URLs still resolve and that removed URLs are intentionally gone.
Render the handoff as a single self-contained HTML page using the shared house style — not a Markdown document. Use the template for your mode:
template.htmltemplate-static.html../_shared/house-style.html for the look. The template's head comment documents every token.<style> block in place of the <!-- HOUSE STYLE ... --> marker in <head>, and its <script> block in place of the second marker before </body>. The output must be a single self-contained .html (no external assets). Do not link a stylesheet.{{REPORT_URL}}). Find the project's GitHub repo via gh repo view --json nameWithOwner --jq .nameWithOwner. Look in .github/ISSUE_TEMPLATE/ for a QA template (filename matching qa, case-insensitive — prefer YAML issue forms over plain Markdown). Build the URL:https://github.com/<owner>/<repo>/issues/new?template=<filename>. Leave the title blank so the template's own placeholder guides the tester.https://github.com/<owner>/<repo>/issues/new.{{PROJECT}}, {{TITLE}} (e.g. Phase N: Phase Title), {{DATE}}, {{BRANCH}}, {{COMMIT}} (short SHA from HEAD), {{REPORT_URL}} (step 4); then the mode-specific one — Rails: {{DEBRIEF_REF}} (path to the related debrief, or N/A); static: {{PREVIEW_URL}} (the deploy-preview URL).<button type="button" class="copy" data-copy="VALUE">VALUE</button>.Credentials. The handoff HTML is a single file that is both committed and (with --publish) uploaded to a public QA host. A login may be a click-to-copy control only when it is a _reserved, non-routable example identity_: an RFC 2606 reserved domain (example.com/.net/.org) or the .example TLD, with any password an obviously-fake seed value (e.g. password). Such fakes are documentation, not credentials. Any real or real-looking login (real domain, actual person, live tenant, real password/token) must be a plain placeholder (<code><your-admin-email></code>), never a copy control; add a one-line note (Rails local: seeded logins from db/seeds.rb; production: your own account). Static sites usually have no logins at all — but if the deploy preview is password-gated, treat that access the same way: a placeholder plus a one-line note, never a real secret. Never publish a real secret in any form.
Fill each token with the content below.
What's New ({{WHATS_NEW}}) — a plain-language summary of what was built. 2–4 short paragraphs; connect to the roadmap. No file paths, class names, or architecture jargon.
Getting Current ({{SETUP}}) — exact setup steps, each command a copy control: pull/install (git pull, bundle install, bin/rails db:migrate, bin/rails db:seed), whether a full bin/rails db:reset is needed, new gems/system packages, new env vars or credentials, and the command to start the app plus the URL to confirm it boots. List specifics — never "some dependencies changed." Say "None" where a category is unchanged.
Guided Walkthrough ({{WALKTHROUGH}}) — one <div class="story"> per scenario, in order. Each: a descriptive .story-head with a .role-pill for the user type; a click-to-copy login when it is a reserved-example identity, otherwise a placeholder (see Credentials), plus a copyable starting URL; extremely literal numbered steps; and a .expect expected result precise enough that a deviation is obvious. Include at least one scenario per affected role. Read CLAUDE.md for audience/viewport guidance and add matching scenarios.
Exploratory Testing ({{EXPLORATORY}}) — an interactive <ul class="checklist">; each item <li><label><input type="checkbox" data-check="..."> ...</label></li>. Draw from debrief-flagged thin coverage, permission boundaries (accessing another user's data, role escalation), responsive/mobile checks, and edge cases a developer might skip. Make each item self-describing.
Test Suite ({{TESTS}}) — commands to run the full suite and the targeted files most relevant to the new work, each a copy control. Note any known skips or expected failures.
Feedback — built into the template: a CTA button linking to the QA issue form via {{REPORT_URL}}. Do not reconstruct the form.
Fill each token with the content below. The checklist sections use an interactive <ul class="checklist"> (each item <li><label><input type="checkbox" data-check="..."> ...</label></li>).
What's New ({{WHATS_NEW}}) — a plain-language summary of what changed on the site (new or updated pages, redesigns, migrated content). 2–4 short paragraphs connecting to the goal. No jargon.
Where to Test ({{WHERE}}) — the deploy-preview URL as a copy control (a Netlify deploy preview is typical). Add the local option for testers who clone: git pull, then hugo server, and the localhost URL — each a copy control. If the preview is access-gated, add a one-line preview-access note (placeholder only — see Credentials). Call out environment limits: some checks cannot be done on a per-PR deploy preview — an external API with a CORS allowlist, or form-email notifications that only fire in production. For each, say which environment it must be done in (per-PR preview vs. branch deploy vs. production) so testers don't file false "broken form" reports.
Guided Walkthrough ({{WALKTHROUGH}}) — one <div class="story"> per key page or flow, in reading order. The .role-pill is the visitor type (Visitor / Donor / Mobile visitor). Give a copyable starting URL (preview URL + path), literal numbered steps, and a .expect result. Cover the new/changed pages; add a mobile scenario per any CLAUDE.md viewport guidance.
Content & Links ({{CONTENT}}) — checklist: copy accuracy (no lorem/placeholder; names, dates, figures, and contact info correct); every nav/footer/CTA link resolves; navigation works (menu, breadcrumbs, footer). URL continuity from the old site: Hugo migrations often preserve URLs by slug-matching rather than redirect maps, so check both directions — (a) every preserved old URL still resolves at the same path, and (b) every _removed_ old URL is intentionally gone (redirect it if it was indexed/linked, or accept the 404).
Languages & Translations ({{I18N}}) — optional — include only for multilingual sites; delete the section and its TOC entry for a single-language site. Checklist: the language switcher works and appears only where a translation actually exists (not on single-language pages); each language's URLs resolve (e.g. / and /en/...) and routes with no translation 404 intentionally rather than rendering a broken page; hreflang tags are present linking the language variants; translated pages show the target language throughout (no silent fallback to the default language); language-specific metadata (og:locale) is correct.
Key Flows & Forms ({{FLOWS}}) — optional — include for sites with conversion/action paths; delete the section and its TOC entry for a purely informational site. Exercise the site's primary actions end to end as a checklist:
Responsive & Visual ({{RESPONSIVE}}) — checklist: mobile/tablet/desktop layouts; images load and aren't distorted; logos, brand colors, favicon, and any PWA manifest render; no horizontal overflow; text readable; nav collapses correctly on small screens; no flash-of-unstyled-content (FOUC) on load, especially for sticky or scroll-reactive headers.
Meta & Sharing ({{META}}) — checklist: page titles and meta descriptions present and accurate; social share cards (og:image, og:title, twitter:*) render when a page is shared; canonical URLs correct.
Accessibility ({{A11Y}}) — checklist: images have meaningful alt text in the site's language(s); color contrast is sufficient; keyboard navigation reaches all interactive elements with a visible focus state; heading order is logical. Spot checks, not an exhaustive audit.
Build & Health ({{BUILD}}) — commands as copy controls: a clean production build (hugo --gc --minify) with no errors or warnings. A green build is not enough — also verify: interactive JS still works _after_ minification (tree-shaking can silently drop handlers a dev build kept, shipping a clean build with broken forms); the pinned Hugo version matches across deploy config and CI (netlify.toml, .github/workflows/); on the preview, no browser console errors and no mixed-content (all https). Actual broken-link crawling stays out of scope — Content & Links covers links by hand.
Feedback — built into the template: a CTA button linking to the QA issue form via {{REPORT_URL}}. Do not reconstruct the form.
Save the completed handoff to:
textdocs/qa-handoffs/YYYY-MM-DD-[brief-topic].html
Create docs/qa-handoffs/ if it doesn't exist; use the same date-and-slug convention as debriefs. After saving, open it so the result is in front of you (single self-contained file — instant, no server):
bashopen docs/qa-handoffs/YYYY-MM-DD-[brief-topic].html
Then tell the user where the file is and how the tester should use it: Rails — follow Getting Current, work the walkthrough, tick the exploratory checklist; static — open the deploy-preview URL from Where to Test, work the walkthrough, tick the checklists. In both cases, click File a QA report for any findings so it lands in the tracker.
--publish)A remote tester who is not cloning the repo needs a hosted copy. With --publish, the skill uploads the saved HTML to the project's configured QA host so the tester can open it from a URL. (This is unchanged across modes — the publish pipeline is framework-agnostic.)
--publish operates on the saved file; it does not regenerate it.tmp/qa-handoff-comment.md describing what is inside the HTML so a PR reader has context. One short paragraph — the HTML is the artifact, not a Markdown twin.--pr <N> is given, posts a PR comment. Get explicit approval first.bash ~/.claude/skills/_shared/publish-artifact.sh \ --html docs/qa-handoffs/YYYY-MM-DD-[brief-topic].html \ --label "QA handoff: <Title>" \ [--pr <N>] \ [--comment-body tmp/qa-handoff-comment.md]
Behaviour:
--pr → uploads the HTML, prints the live Pages URL. Share that URL with the tester.--pr <N> given → also posts a PR comment with the live link above the blurb.--md-fallback-only is not used here because the HTML is the artifact — a Markdown twin would lose the click-to-copy controls and the interactive checklists that make the handoff useful).| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 30,887 | 4,792 | -84% | 1 | 1 | 0% | 6,209 | 4,131 | -33% | 0 | 0 | — |
case-02 | fail→fail | 31,440 | 4,552 | -86% | 1 | 1 | 0% | 6,206 | 4,105 | -34% | 0 | 0 | — |
case-13 | pass→pass | 12,502 | 6,788 | -46% | 1 | 1 | 0% | 1,812 | 4,936 | +172% | 0 | 0 | — |
case-03 | fail→fail | 15,551 | 7,317 | -53% | 1 | 1 | 0% | 2,840 | 4,110 | +45% | 0 | 0 | — |
case-04 | fail→pass | 31,026 | 3,798 | -88% | 1 | 1 | 0% | 6,176 | 4,606 | -25% | 0 | 0 | — |
case-05 | pass→fail | 20,200 | 6,134 | -70% | 1 | 1 | 0% | 3,753 | 4,243 | +13% | 0 | 0 | — |
case-06 | pass→fail | 26,066 | 6,204 | -76% | 1 | 1 | 0% | 5,446 | 4,193 | -23% | 0 | 0 | — |
case-07 | fail→pass | 15,382 | 6,109 | -60% | 1 | 1 | 0% | 2,314 | 5,028 | +117% | 0 | 0 | — |
case-08 | fail→pass | 6,473 | 2,660 | -59% | 1 | 1 | 0% | 1,057 | 4,420 | +318% | 0 | 0 | — |
case-09 | fail→pass | 12,515 | 3,347 | -73% | 1 | 1 | 0% | 1,966 | 4,364 | +122% | 0 | 0 | — |
case-10 | fail→fail | 12,450 | 3,803 | -69% | 1 | 1 | 0% | 2,022 | 4,494 | +122% | 0 | 0 | — |
case-11 | fail→pass | 16,345 | 11,412 | -30% | 1 | 1 | 0% | 2,491 | 5,828 | +134% | 0 | 0 | — |
case-12 | fail→pass | 12,172 | 5,372 | -56% | 1 | 1 | 0% | 2,020 | 4,759 | +136% | 0 | 0 | — |
case-14 | pass→fail | 5,186 | 2,093 | -60% | 1 | 1 | 0% | 897 | 4,243 | +373% | 0 | 0 | — |
case-15 | fail→pass | 12,393 | 7,979 | -36% | 1 | 1 | 0% | 1,956 | 5,232 | +167% | 0 | 0 | — |
case-16 | fail→fail | 13,620 | 6,213 | -54% | 1 | 1 | 0% | 2,157 | 4,867 | +126% | 0 | 0 | — |
case-17 | fail→pass | 14,096 | 5,446 | -61% | 1 | 1 | 0% | 2,485 | 4,730 | +90% | 0 | 0 | — |
case-18 | pass→fail | 11,423 | 4,284 | -62% | 1 | 1 | 0% | 1,764 | 4,604 | +161% | 0 | 0 | — |
case-19 | pass→fail | 9,222 | 7,769 | -16% | 1 | 1 | 0% | 1,418 | 4,480 | +216% | 0 | 0 | — |
case-20 | pass→fail | 8,307 | 6,963 | -16% | 1 | 1 | 0% | 1,377 | 4,195 | +205% | 0 | 0 | — |
case-21 | pass→pass | 9,445 | 5,108 | -46% | 1 | 1 | 0% | 1,749 | 4,748 | +171% | 0 | 0 | — |
case-22 | fail→pass | 17,437 | 10,420 | -40% | 1 | 1 | 0% | 2,577 | 5,507 | +114% | 0 | 0 | — |
case-23 | fail→pass | 10,562 | 2,244 | -79% | 1 | 1 | 0% | 1,567 | 4,177 | +167% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted, and 16 counted toward the lift figure. The other 7 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +17 percentage points is the difference between those two pass rates over the 16 comparable cases. 6 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.