/qa-full
The per-feature QA pipeline. Where /daily-qa is the unattended, repo-wide,
time-windowed background sweep that only reports, /qa-full is the
present-human, branch-scoped, audit → fix → verify pipeline you run the
moment a feature is done — before /finish-branch and /ship.
implement → /qa-full → /finish-branch → /ship
(audit → fix → verify)
It reuses /daily-qa's trigger matrix (which checks to run based on what
changed) with three deliberate differences:
- Scope is the branch diff (
base..HEAD + working tree), not a time window.
- It fixes, not just reports. Every check runs in three phases — audit
(report-only discovery is fine here), fix (apply the smallest correct fix,
one atomic commit per fix — except
/review's bundled output, see Hard
rules), verify (re-run the same check plus the test
suite and prove the fix holds). The final verdict is on the repaired branch.
- Interactive checks actually run. Because a human is present, the checks
/daily-qa only recommends — /qa, /web-perf, /design-review, the
dynamic /a11y pass — run here when their triggers fire.
This is not an audit skill. It is a full security pipeline, a full performance
pipeline, a full correctness/test pipeline, and a full browser/design pipeline,
selected per-diff and driven to green.
Hard rules
- The bar is the superskills quality standard — TDD/DRY/SOLID/YAGNI
(applied in every step's fix phase: test first, no duplicated logic, small
single-purpose units, nothing speculative) plus the hard-gate list, which is
spelled out in full in Step 10's Blocker set. The canonical written copy is
ENGINEERING_STANDARDS.md in the superskills install (a plugin install exposes
it at ${CLAUDE_PLUGIN_ROOT}/ENGINEERING_STANDARDS.md); it is not expected
to exist in the project you're reviewing, so don't flag it as missing. Every
fix you land must meet that bar too — a fix that adds untested public surface
or duplicates logic is not a fix.
- Audit → fix → verify, per check. For every check whose trigger fires:
- Audit — run the sub-skill (its normal report-only output is the
discovery pass).
- Fix — for each CRITICAL/HIGH finding (and MEDIUM where the fix is
small and safe), root-cause it (
/debug discipline: no symptom patches),
write the failing test first when it's a logic bug (/tdd), apply the
smallest correct fix, and commit it atomically with a message naming the
check and finding.
- Verify — re-run the same sub-skill on the diff and re-run the test
suite. A fix is only "fixed" when the re-audit no longer reports it and
tests are green. Never claim a fix without this fresh evidence (
/verify
discipline).
A finding you could not fix (needs a product decision, external service,
credentials, or an architectural change beyond the diff) is an UNFIXED
blocker: record what you tried and why it's out of reach. Do not quietly
downgrade it to a warning.
- Fix only what the diff and the findings justify. Do not refactor
untouched code, upgrade dependencies, or "improve" unrelated modules while
you're in there. Scope stays on the branch diff plus the exact lines a finding
points at.
- Commit, but never push or open a PR. Each fix lands as its own commit on
the current branch so the user can review/revert individually. Exception:
/review exposes no per-finding boundary, so its output lands as one commit
per invocation (Step 3). Integration and shipping belong to /finish-branch
and /ship.
- Ground every finding and every fix in concrete evidence: file:line,
failing test name, log snippet, severity as the underlying tool produced it,
and the commit SHA of the fix. No speculation.
- Separate blockers from warnings. Only test/build failures and
CRITICAL/HIGH findings block. Everything else is a warning — fix it when the
fix is cheap and safe, otherwise ship it with a follow-up note.
- Bounded loops. At most two fix rounds per check, then one final
verification pass (Step 10). If something is still red after that, it's an
UNFIXED blocker with the attempts documented — not a third round.
- Never claim SHIP-READY without receipts. The verdict must cite the exact
checks that ran, what they found, what was fixed (with commits), what was
re-verified, and what was skipped (and why).
- No silent skips — mandatory accounting. Every check must resolve to
exactly one of: RAN-CLEAN (ran, nothing to fix), FIXED(n) (ran, n
findings fixed and re-verified — list commits), UNFIXED (ran, at least one
blocker could not be fixed — reason), SKIPPED (stated reason — e.g. "no
reachable dev server and none could be started", "scanner not authorized in
this env"), NOT-TRIGGERED (its diff trigger didn't fire), or
MANDATORY-FAIL (a
CLAUDE.md-mandatory check that was skipped). A check whose
trigger fired but that neither ran nor was explicitly skipped-with-reason is an
unaccounted check ⇒ NOT READY. "Recommend-only" is not an allowed resting
state for a triggered check. Projects may mark specific checks MANDATORY
in CLAUDE.md (e.g. /pentest on a payments service), and for those, SKIPPED
is itself a blocker.
- Money and authorization still need a human yes.
/code-review ultra is a
billed cloud run, and /review's Codex passes spend OpenAI tokens — ask
before launching either, never assume. /pentest requires
the user to confirm authorization before it scans — ask, then run. "Ask, then
run" is still running; it is not report-only.
Project configuration (CLAUDE.md)
This pipeline reads the project's root CLAUDE.md for a few optional settings.
They are plain prose (CLAUDE.md is agent instructions, not a config file) — look
for a ## qa-full section and honor whatever it states. Example:
## qa-full
- Mandatory checks (must RUN with evidence — a skip is a blocker): `/pentest`, `/defense`
- Hard perf gate: LCP ≤ 2.5s and INP ≤ 200ms on `/` and `/checkout` (breach blocks)
- Design: skip `/design-review` (design is owned by the design team, do not auto-fix visuals)
- Dev URL: http://localhost:3000 (for `/web-perf`, `/qa`, `/a11y`, `/fuzz`)
- Test/build: `pnpm test` and `pnpm build`
- QA tier: exhaustive
Recognized settings (all optional; absence = the defaults in the steps below):
- Mandatory checks — listed commands must read RAN-CLEAN or FIXED in the
ledger; SKIPPED is a blocker (any step; Step 10 enforces it). MANDATORY
overrides the check's own diff trigger: run it on the diff even when the
trigger didn't fire, so NOT-TRIGGERED is not an acceptable state either. Use
for compliance-critical surfaces (payments, auth, PII).
- Hard perf gate — turns a
/web-perf budget breach that survives the fix
round from a warning into a blocker (Step 6).
- Design: skip
/design-review — opt out of the visual-fix pass (Step 8)
entirely; by default it runs on any UI change. This skips the check (ledger:
SKIPPED("project opt-out")) — it does not turn it into a report-only run.
- Test/build commands — feed Steps 2 and 10. Dev URL — feeds Steps 4
(
/fuzz), 6, 7 and 8. QA tier — feeds Step 7; defaults to standard.
If there is no ## qa-full section, run with the built-in defaults — nothing here
is required.
Step 1: Establish the diff scope and a clean tree
- Detect the base branch:
gh repo view --json defaultBranchRef -q .defaultBranchRef.name,
else git symbolic-ref refs/remotes/origin/HEAD, else fall back to main/master.
- If
$ARGUMENTS names a base branch or --scope <paths>, use it.
- Resolve the diff ref:
git fetch origin <base> and use origin/<base>
when that ref exists, else local <base>. This is what /review and /qa
diff against too, and it stays correct after Step 1.5 creates a working
branch (local <base> would then equal HEAD and the set would be empty).
Compute the changed-file set: git diff --name-only <diff-ref>...HEAD -- <scope paths>
(drop the -- part when no --scope was given) plus
uncommitted changes (git status --porcelain). This set drives every
trigger below. Fix commits made by this pipeline extend the set — later
steps and the final pass (Step 10) audit the fixes too.
- Clean-tree precondition. The fixers (
/qa, /design-review) need each
fix to be its own atomic commit, so they stop on a dirty tree. Handle it
once, here: if git status --porcelain is non-empty, ask the user (via
AskUserQuestion) whether to commit the in-progress work now (recommended
— a descriptive commit so the feature is preserved before fixes land) or
stash it. Do not proceed with a dirty tree.
- Never run on the base branch itself. The sub-skills' diff-aware modes
(
/review, /qa, /design-review) key off "current branch ≠ base" and
diff against merge-base(origin/<base>, HEAD). If git branch --show-current equals the base and there are unpushed commits, create a
working branch at HEAD first — git switch -c qa-full/<base>-<YYYY-MM-DD>
(reuse it if a same-day branch already exists from an aborted run) — and
run the whole pipeline there. Step 10 folds it back: fast-forward the
base to the working branch (git switch <base> && git merge --ff-only qa-full/...) and delete the working branch. No history is rewritten; the
base just gains the fix commits. If there are no unpushed commits either,
there is nothing to QA.
- Record at the top of the report: base branch, diff ref, working branch (if
created), commit range, changed-file count, and the HEAD SHA before any fixes.
If there is no diff against base, stop and say so — there is nothing to QA.
Step 2: Tests & build (always — audit → fix → verify)
- Find the project's test/build commands from
CLAUDE.md; if absent, infer
from package.json scripts, Makefile, pyproject.toml, etc. If you
cannot determine them, ask rather than guess.
- Audit: run the test suite and the build. Capture exact failures (test
name + verbatim error in a code block).
- Fix: for each failing test or build error, follow
/debug — reproduce,
root-cause, then fix the cause (not the assertion). Commit each fix.
- Verify: re-run the full suite and build. Green ⇒ FIXED(n). Still red
after two rounds ⇒ UNFIXED blocker with the failing test and what was tried.
If this step ends UNFIXED after two rounds, stop here and report NOT READY
with the failing test. Every later step's verify phase depends on a green
suite — running fixers on a red suite is fix → hope, not fix → verify. Mark
every downstream ledger row SKIPPED("pipeline halted at Step 2"). A working
branch from Step 1.5 stays as-is (base untouched) so the fix commits are there
for the user.
Step 3: Correctness + quality — /review then /clean-code (always)
Two halves. Both sub-skills are in-tree, so they are invocable from inside any
session or tool, and Step 1.5 guarantees you are on a non-base branch, which
/review's own branch guard requires.
Correctness — /review. /review is not a report-only audit: one
invocation reads the diff, auto-applies its mechanical (AUTO-FIX) findings to
the working tree, asks you about the rest (ASK items) via its own
AskUserQuestion, and never commits. Treat one call as one atomic
audit + fix + ask unit:
- Run
/review against the base this pipeline resolved in Step 1. It has
no argument channel, so it always diffs merge-base(origin/<base>, HEAD) —
if Step 1 resolved a non-default base or a --scope, say so in the ledger
evidence: /review reviewed the full default-base diff.
- Commit what it changed as one commit attributed to
/review (e.g.
review: apply AUTO-FIX + approved ASK findings), so the tree is clean
before /clean-code and nothing /review fixed can be lost by a later
revert. If --scope was given, stage and commit only files under scope;
any out-of-scope edits /review made stay uncommitted (stash them so the
tree is clean, noting the stash ref) and are flagged in the ledger with that
ref for the user — never silently committed. For any CRITICAL it reported but could not fix, root-cause
(/debug), write the failing test first (/tdd), fix, commit atomically.
- Verify: run
/review once more. It re-scans the full base diff
including the fix commits — that's the point. A CRITICAL still present ⇒
UNFIXED blocker. Commit anything this second pass auto-fixed the same way.
Do not run it a third time in this step.
/review's adversarial section runs a free Claude subagent and, when the
Codex CLI is installed and enabled, codex exec / codex review passes that
spend OpenAI tokens. Those Codex passes are ask-first under the money rule.
You are the one executing /review's instructions, so no config change is
needed: when its Codex preflight says Codex would run — CODEX_MODE: ready
in current gstack, CODEX_AVAILABLE with OLD_CFG not disabled in older
versions — ask the user once whether to spend on Codex for this run; if
declined, do not run the codex exec / codex review commands and proceed
exactly as the section's disabled/unavailable branch describes (Claude
adversarial subagent still runs). Record
the Codex state and the user's answer in the ledger. Never flip the global
codex_reviews config on the user's behalf.
If /review cannot run at all (the gstack install is broken), apply its
checklist
(~/.claude/skills/gstack/review/checklist.md) to origin/<base>..HEAD via a
fresh subagent, fix and re-verify the same way, and say so in the ledger — do
not skip the correctness step.
Quality — /clean-code. After correctness is green and committed, run
/clean-code <diff-ref> [--scope <paths>] with the diff ref and scope this
pipeline resolved. It audits KISS / DRY / SOLID / YAGNI against ENGINEERING_STANDARDS.md,
applies the smallest safe refactor per finding under a green suite
(characterization test first where none exists), commits each atomically,
re-audits, and reverts a failed refactor with git checkout on only the files
it touched. Its findings left UNFIXED are warnings here, not blockers — quality
debt ships with a note; bugs don't.
/code-review ultra (deep multi-agent cloud review) is billed — when a
/review finding is high-stakes (payments, auth, data loss, concurrency), ask
the user whether to launch it. Do not launch it unasked. Claude Code's
built-in /code-review and /simplify are not part of this step: they can't
be invoked from inside a session, and an optional extra pass would have no
ledger row.
Step 4: Security pipeline — /defense, /iac-scan, /pentest, /fuzz
/defense (always).
- Audit: run
/defense scoped to the changed files (OWASP Top 10 /
secrets / auth / crypto / data-protection).
- Fix: remediate every CRITICAL/HIGH (and cheap MEDIUMs): remove or
rotate-and-externalize hardcoded secrets, add the missing authz check,
parameterize the query, escape the output, switch the weak primitive, add
the validation. Each fix gets a regression test where a test can express it
(e.g. "unauthenticated request to X returns 401"). Commit atomically.
- Verify: re-run
/defense on the same files; the finding must be gone.
/iac-scan (when infra/deploy config changed). Trigger on Dockerfile,
docker-compose*, *.tf/*.tfvars, k8s/Helm manifests, .github/workflows/**,
.gitlab-ci.yml, Jenkinsfile, nginx/cloud config (see /iac-scan's trigger
section for the authoritative list). Audit with the local static linters, fix
CRITICAL/HIGH misconfigs (root container → non-root user, 0.0.0.0/0 ingress →
scoped CIDR, wildcard IAM → least privilege, privileged pod → dropped, untrusted
CI trigger → pinned/guarded, baked-in secret → injected), re-scan to verify.
/pentest (triggered when /defense found CRITICAL/HIGH, or the diff touches
auth/crypto/session/token/deserialization/file-upload paths). It is an external
scanner: confirm authorization with the user first (the skill's own
questions), then run it. Fix CRITICAL/HIGH it surfaces, re-scan to verify. If the
user declines or the scanner is unavailable ⇒ SKIPPED(reason). If CLAUDE.md
marks /pentest MANDATORY, SKIPPED is a blocker.
/fuzz (triggered when the diff adds or changes endpoints, input parsing,
file-upload handling, or deserialization). Needs a running target: find the dev
URL (CLAUDE.md, or start the dev script). Run /fuzz against the new
surface; fix crashes, injections, and auth bypasses it surfaces (with a
regression test); re-fuzz to verify. No reachable target and none startable ⇒
SKIPPED(reason). If CLAUDE.md marks /fuzz MANDATORY, SKIPPED is a blocker.
/cso backstop. If the diff crosses a new trust boundary (new auth
path/endpoint/external input/deserialization) and there's no evidence a threat
model was done at plan time, run /cso on that boundary and fold any
CRITICAL/HIGH into the /defense fix round. Threat modeling belongs in
/write-plan; this is the late catch, not a substitute.
Step 5: Database pipeline — /db-optimize (auto-run if triggered)
Trigger when changed files match ORM models, migrations, query builders
(**/models/**, **/migrations/**, **/queries/**, **/*repository*,
**/*.sql), raw SQL in the diff, or new ORM calls (.find, .where,
.includes, .join, .preload).
- Audit: run
/db-optimize scoped to matched files (run /dbmap first if
it asks for a schema map).
- Fix: N+1s on hot paths → eager-load/batch (
includes/preload/
select_related/dataloader); missing indexes on hot paths → add a migration
for the index; obviously-redundant queries → dedupe. Add a test that asserts
the query count where the ORM supports it. Commit atomically.
- Verify: re-run
/db-optimize; the hot-path findings must be gone and
the migration must apply cleanly in the test run.
Non-hot-path suggestions are warnings (fix if trivial). No trigger ⇒
NOT-TRIGGERED.
Step 6: Frontend perf pipeline — /web-perf (+ /perf-profile)
Trigger when the diff includes frontend code (**/*.tsx, **/*.jsx,
**/*.vue, **/*.svelte, **/components/**, **/pages/**, **/styles/**,
**/*.css, **/*.scss), new images/fonts/assets, or bundler config
(next.config.*, vite.config.*, webpack.config.*).
- Find the dev URL (
CLAUDE.md, or the dev script in package.json). A
human is present, so start the dev server if it isn't running. Only if
no app is running and none can be started ⇒ SKIPPED("no reachable dev
server, start failed: ").
- Audit: run
/web-perf against the affected routes. Record Core Web
Vitals (LCP, INP, CLS) vs. any known budget.
- Fix: address the measured regressions attributable to the diff —
render-blocking imports → defer/lazy, oversized image/font → optimize or
preload, layout shift → reserve dimensions, long task → split/memoize.
Commit atomically.
- Verify: re-run
/web-perf on the same routes; report before/after
numbers.
- A budget breach that survives the fix round is a warning by default,
unless
CLAUDE.md defines a hard perf gate — then it blocks.
/perf-profile (triggered when the diff touches hot server-side paths, the
change is pre-launch, or /db-optimize//web-perf point at a server-side
bottleneck): run it against the affected endpoint/job, fix the localized
bottleneck (cache, batch, move off the request path), re-profile to verify.
Needs a representative workload — if none is available ⇒ SKIPPED(reason).
Step 7: Browser QA pipeline — /qa (auto-run if triggered)
Run /qa — the full test → fix → re-verify loop — not /qa-only. This is
the check that replaces manual click-through QA, and a human is present.
Trigger when the diff includes anything a human would manually QA in a browser:
UI/frontend code, pages/routes, forms, route handlers serving HTML, API
endpoints the UI consumes, auth/session flows, or config that changes
user-facing behavior.
- Start the dev server if needed (same URL as Step 6).
- Run
/qa scoped to the affected surface at the project's QA tier
(CLAUDE.md, default standard: critical + high + medium). /qa itself does
the audit → fix → re-verify loop with atomic commits and before/after health
scores — let it run to completion; don't cut it off at the report.
- Fold its before/after health score, fixed-bug list (with commits), and any
bugs it could not fix into the ledger.
- User-facing CRITICAL/HIGH bugs that
/qa could not fix ⇒ UNFIXED blocker.
- No reachable app and none startable ⇒ SKIPPED(reason) — and note that this
means the feature has not been browser-tested at all.
Step 8: Design + accessibility pipeline — /design-review, /a11y
/design-review (when the diff includes UI changes, unless CLAUDE.md opts
out). Run /design-review against the changed screens — it audits visual
consistency, hierarchy, spacing, AI-slop tells and slow interactions, then
fixes them with atomic commits and before/after screenshots. Let it complete.
Visual findings it can't fix are warnings, not blockers. If the project opted
out in CLAUDE.md, record SKIPPED("project opt-out") and move on.
/a11y (when the UI change is heavy and likely to affect assistive tech —
new/changed interactive components, forms, ARIA/role/tabindex,
focus/keyboard handling, images, color/contrast, motion; see /a11y's trigger
section).
- Audit: run the static pass on the diff, and the dynamic axe pass when
the dev URL is reachable (it is, if Step 6/7 ran).
- Fix: every CRITICAL/SERIOUS — native element over ARIA-on-a-div, missing
label/name, unreachable-by-keyboard control, focus trap, contrast below
ratio, missing reduced-motion guard. Commit atomically.
- Verify: re-run the same pass; CRITICAL that survive ⇒ UNFIXED blocker.
Scope split: /design-review owns visual quality; /a11y owns WCAG /
assistive-tech correctness. They overlap on contrast — /a11y's measured
contrast finding is authoritative.
Step 9: Coverage pipeline — /test-coverage + /playwright
- Audit: for each changed file (including this pipeline's fix commits),
locate its test (sibling
*.test.*, parallel tests/). Use coverage data if
present (coverage/, lcov.info, .coverage); else do a structural check
for new exported functions / branches / error paths without an assertion.
- Fix: run
/test-coverage on the diff — it writes and applies the missing
unit tests (and integration tests where risk crosses a boundary), enforcing
Google's Testing-on-the-Toilet practices. For user-facing flows with no
e2e coverage, run /playwright to generate and run the e2e test so a
regression test is left behind. Commit atomically.
- Verify: run the full suite; the new tests must pass, and the structural
check must show no new public surface with zero tests.
New public surface still untested after this step ⇒ UNFIXED blocker. Internal
helpers without tests are warnings.
Step 10: Final verification pass, ledger, verdict
The fix rounds changed the branch, so verify the whole result once more:
- Fresh tests + build on the final HEAD (Step 2 commands). Stale results
⇒ NOT READY.
- Re-audit the fix commits: run
/defense scoped to the files the fix
commits touched, and read the fix commits themselves
(git show original-HEAD..HEAD) against /review's checklist — /review
takes no commit range, and Step 3 already re-ran it twice. The fixes must not
introduce a CRITICAL/HIGH. If they did, one more fix + re-verify, then stop.
- Diff sanity:
git log --oneline <base>..HEAD — every pipeline commit
should name its check/finding; nothing outside the diff scope was touched.
- Fold back the working branch if Step 1.5 created one: `git switch
Then build the accounting ledger — a row per check, each resolved to
RAN-CLEAN / FIXED(n) / UNFIXED / SKIPPED(reason) / NOT-TRIGGERED /
MANDATORY-FAIL. The verdict cannot be SHIP-READY while any triggered check is
unaccounted or UNFIXED.
Phase-5 accounting (honest scope): /qa-full is the entry to Phase 5, so it
can only enforce the pre-ship half. It cannot verify /finish-branch,
/ship, or /land-and-deploy — those run after this pipeline, so do not claim
they're done. A passing verdict is the hard precondition for ship: only on
SHIP-READY do you hand off "Proceed to /finish-branch then /ship."
Then the verdict:
- SHIP-READY — zero blockers remaining and every triggered check
accounted for and the final pass is green. List what was fixed (commits),
warnings + follow-ups, then hand off to
/finish-branch → /ship.
- NOT READY — one or more blockers survived the fix rounds (or a check is
unaccounted / MANDATORY-FAIL). List each with its file:line/test-name
evidence, what was tried, and what the user needs to decide or provide.
Tell the user to resolve and re-run
/qa-full.
Blocker set (any one ⇒ NOT READY — this is the authoritative list for the
verdict; it mirrors the superskills ENGINEERING_STANDARDS.md hard gates, kept
in sync by the maintainer). Each is evaluated after the fix rounds:
- failing test or broken build, or test/build not freshly run on final HEAD (Step 2/10)
/review CRITICAL correctness finding still present (Step 3)
/defense CRITICAL/HIGH security finding still present (Step 4)
/fuzz CRITICAL/HIGH — crash, injection, or auth bypass — still reproducible (Step 4)
/pentest CRITICAL/HIGH vulnerability still present, when it ran (Step 4)
/iac-scan CRITICAL/HIGH infra misconfig still present (Step 4)
- N+1 / missing index on a hot path still present (Step 5)
- CRITICAL/HIGH browser-QA bug in a user-facing flow
/qa could not fix (Step 7)
/a11y CRITICAL — a control unusable by screen-reader/keyboard — still present (Step 8)
- new public surface with zero tests after
/test-coverage (Step 9)
- a hard perf gate breach after the fix round, only if
CLAUDE.md defines one (Step 6)
- a triggered check left unaccounted — neither run nor SKIPPED with a reason
- a
CLAUDE.md-MANDATORY check that was SKIPPED rather than run
Report format
Write to qa-full-reports/<branch>-<YYYY-MM-DD>.md (create dir; add to
.gitignore). Structure:
# QA-Full — <branch> @ <YYYY-MM-DD>
Base: <base> Range: <base>..HEAD Changed files: N (+M from fixes)
HEAD before fixes: <sha> HEAD after: <sha> Fix commits: K
## VERDICT: SHIP-READY ✅ | NOT READY ⛔
### Fixed (audit → fix → verify, each with its commit)
1. <check> — <file:line> — <finding> — fixed in <sha> — re-verified by <evidence>
- (or) None needed.
### Blockers remaining (must resolve before /finish-branch)
1. <file:line> — <evidence> — <what was tried> — <what's needed from you>
- (or) None.
### Warnings (ship with a follow-up note)
- …
## Accounting ledger (RAN-CLEAN / FIXED(n) / UNFIXED / SKIPPED(reason) / NOT-TRIGGERED / MANDATORY-FAIL)
| Check | Status | Evidence / fixes / reason |
|-------|--------|---------------------------|
| Tests & build (Step 2) | RAN-CLEAN / FIXED(n) / UNFIXED | exact command + result, fix SHAs |
| /review (Step 3) | RAN-CLEAN / FIXED(n) / UNFIXED | N findings, fix SHAs, 2nd-run result, Codex passes on/off, base used, out-of-scope stash ref if any |
| /clean-code (Step 3) | RAN-CLEAN / FIXED(n) / UNFIXED | KISS/DRY/SOLID/YAGNI findings, fix SHAs, deferred-with-reason |
| /defense (Step 4) | RAN-CLEAN / FIXED(n) / UNFIXED | N findings, fix SHAs |
| /iac-scan (Step 4) | … / NOT-TRIGGERED | infra/deploy files changed? |
| /pentest (Step 4) | … / SKIPPED(reason) / NOT-TRIGGERED | authorized? findings? |
| /fuzz (Step 4) | … / SKIPPED(reason) / NOT-TRIGGERED | target URL, findings |
| /cso (Step 4) | … / NOT-TRIGGERED | new trust boundary? threat-model evidence |
| /db-optimize (Step 5) | … / NOT-TRIGGERED | N+1 / index fixes, migration |
| /web-perf (Step 6) | … / SKIPPED(reason) / NOT-TRIGGERED | before/after LCP/INP/CLS |
| /perf-profile (Step 6) | … / SKIPPED(reason) / NOT-TRIGGERED | bottleneck, before/after |
| /qa (Step 7) | … / SKIPPED(reason) / NOT-TRIGGERED | tier, health before/after, fix SHAs |
| /design-review (Step 8) | … / SKIPPED(reason) / NOT-TRIGGERED | screens, fix SHAs |
| /a11y (Step 8) | … / SKIPPED(reason) / NOT-TRIGGERED | static + dynamic, fix SHAs |
| /test-coverage + /playwright (Step 9) | RAN-CLEAN / FIXED(n) / UNFIXED | tests added, suite result |
| Final pass (Step 10) | RAN-CLEAN / FIXED(n) / UNFIXED | fresh test/build + re-audit of fix commits |
> No row may be blank or "recommend" for a check whose trigger fired — that is an
> unaccounted-check blocker. `CLAUDE.md`-MANDATORY checks must read RAN-CLEAN or FIXED.
## Ask-first / follow-up commands
- `/code-review ultra` — (billed; offer when a high-stakes correctness concern remains)
- `/review` Codex passes — (OpenAI tokens; ask before enabling them for a run)
- `/pentest` — (if it was SKIPPED for authorization and the user now wants it)
- `/fuzz` — (if SKIPPED for lack of a target and one is now available)
- `/perf-profile` — (if SKIPPED for lack of a representative workload)
- `/finish-branch` → `/ship` — (only if VERDICT is SHIP-READY)
Print the verdict, the fixed count, the remaining-blocker count, and a 5-line
summary to the chat.
Anti-patterns (do not do)
- Stopping at the report. A triggered check that found something and did not
attempt a fix has not run
/qa-full.
- Running
/qa-only or /design-audit where /qa / /design-review are
specified. Report-only is for discovery inside a step, never the step's end.
- Claiming a finding is fixed without re-running the check that found it and
the test suite (fresh evidence, not assertion).
- Pushing, opening PRs, or merging — that's
/finish-branch / /ship.
- Fixing outside the diff: refactoring untouched modules, bumping deps, or
"while I'm here" changes. Every commit must trace to a finding.
- Landing a fix that itself breaks the bar — untested public surface, a
duplicated helper, a symptom patch over an unknown root cause.
- Looping without bound. Two fix rounds per check, one final pass, then report
what's left honestly.
- Launching a billed run (
/code-review ultra) or an external scanner
(/pentest) without the user's explicit yes.
- Declaring SHIP-READY while a check was skipped without saying which and why,
or while any UNFIXED blocker remains.
- Running any sub-check against the whole repo instead of the diff.
- Treating MEDIUM/LOW findings as blockers (noise) or hiding CRITICAL/HIGH in
the warnings list.
Related commands
Reuses the trigger matrix from /daily-qa (see skills/daily-qa/SKILL.md
Step 7 for the canonical globs). Differences: branch-scoped, present-human,
and it fixes and verifies instead of recommending.
Auto-run (diff-scoped; audit → fix → verify):
- Tests & build — always; failures root-caused via
/debug, proven via /verify (Step 2).
/review — staff-level correctness review; findings fixed by the pipeline (Step 3).
/clean-code — KISS/DRY/SOLID/YAGNI refactors on the diff, test-verified (Step 3).
/defense — OWASP/secrets/auth/crypto; findings fixed by the pipeline (Step 4).
/iac-scan — when infra/deploy config changed; misconfigs fixed (Step 4).
/fuzz — when the diff adds endpoints/input parsing and a target is reachable (Step 4).
/cso — backstop when a new trust boundary reached the pipeline unmodeled (Step 4).
/db-optimize — when DB/ORM/SQL changed; N+1/index fixes applied (Step 5).
/web-perf — when frontend changed; dev server started if needed; regressions fixed (Step 6).
/perf-profile — when hot server paths changed / pre-launch; bottleneck fixed (Step 6).
/qa — when anything user-facing changed; full test → fix → re-verify loop (Step 7).
/design-review — when UI changed; fixes + commits visual issues (Step 8).
/a11y — static + dynamic pass when heavy UI changed; findings fixed (Step 8).
/test-coverage + /playwright — write and apply the missing tests (Step 9).
/tdd, /debug, /verify — the discipline every fix in the pipeline follows.
Ask-first (need the user's explicit yes):
/code-review ultra — billed multi-agent cloud review.
/review's Codex passes — OpenAI tokens; per-run yes required (Step 3).
/pentest — external scanner; authorization confirmation, then it runs.
Follow-up (outside the pipeline):
/code-review / /simplify — Claude Code built-ins overlapping Step 3; use
them by hand, the pipeline uses the in-tree /review + /clean-code.
Hand-off (only when SHIP-READY):
/finish-branch — choose how to integrate the work.
/ship — sync, bump VERSION, changelog, PR.
1---2name: qa-full3description: Full per-feature QA pipeline: audit → fix → verify. Runs the complete multi-dimensional fan-out (tests, correctness, security, DB, frontend perf, browser QA, design, accessibility, coverage) scoped to the current branch's diff, FIXES what each check finds, re-verifies the fixes, then emits a pass/fail ship-readiness verdict on the repaired branch. Run it when a feature is finished, before /finish-branch and /ship. Use when asked to "run full QA", "qa-full", "feature done — check it", "is this ready to ship", "pre-ship check", "full quality gate", or "fix everything before ship".4---56# /qa-full78The per-feature QA **pipeline**. Where `/daily-qa` is the unattended, repo-wide,9time-windowed **background** sweep that only *reports*, `/qa-full` is the10**present-human, branch-scoped, audit → fix → verify** pipeline you run the11moment a feature is done — before `/finish-branch` and `/ship`.1213```14implement → /qa-full → /finish-branch → /ship15 (audit → fix → verify)16```1718It reuses `/daily-qa`'s trigger matrix (which checks to run based on what19changed) with three deliberate differences:2021- **Scope is the branch diff** (`base..HEAD` + working tree), not a time window.22- **It fixes, not just reports.** Every check runs in three phases — **audit**23 (report-only discovery is fine here), **fix** (apply the smallest correct fix,24 one atomic commit per fix — except `/review`'s bundled output, see Hard25 rules), **verify** (re-run the same check plus the test26 suite and prove the fix holds). The final verdict is on the *repaired* branch.27- **Interactive checks actually run.** Because a human is present, the checks28 `/daily-qa` only *recommends* — `/qa`, `/web-perf`, `/design-review`, the29 dynamic `/a11y` pass — run here when their triggers fire.3031This is not an audit skill. It is a full security pipeline, a full performance32pipeline, a full correctness/test pipeline, and a full browser/design pipeline,33selected per-diff and driven to green.3435## Hard rules3637- **The bar is the superskills quality standard** — TDD/DRY/SOLID/YAGNI38 (applied in every step's fix phase: test first, no duplicated logic, small39 single-purpose units, nothing speculative) plus the hard-gate list, which is40 spelled out in full in Step 10's Blocker set. The canonical written copy is41 `ENGINEERING_STANDARDS.md` in the superskills install (a plugin install exposes42 it at `${CLAUDE_PLUGIN_ROOT}/ENGINEERING_STANDARDS.md`); it is **not** expected43 to exist in the project you're reviewing, so don't flag it as missing. Every44 fix you land must meet that bar too — a fix that adds untested public surface45 or duplicates logic is not a fix.46- **Audit → fix → verify, per check.** For every check whose trigger fires:47 1. **Audit** — run the sub-skill (its normal report-only output is the48 discovery pass).49 2. **Fix** — for each CRITICAL/HIGH finding (and MEDIUM where the fix is50 small and safe), root-cause it (`/debug` discipline: no symptom patches),51 write the failing test first when it's a logic bug (`/tdd`), apply the52 smallest correct fix, and commit it atomically with a message naming the53 check and finding.54 3. **Verify** — re-run the *same* sub-skill on the diff and re-run the test55 suite. A fix is only "fixed" when the re-audit no longer reports it and56 tests are green. Never claim a fix without this fresh evidence (`/verify`57 discipline).58 A finding you could not fix (needs a product decision, external service,59 credentials, or an architectural change beyond the diff) is an **UNFIXED60 blocker**: record what you tried and why it's out of reach. Do not quietly61 downgrade it to a warning.62- **Fix only what the diff and the findings justify.** Do not refactor63 untouched code, upgrade dependencies, or "improve" unrelated modules while64 you're in there. Scope stays on the branch diff plus the exact lines a finding65 points at.66- **Commit, but never push or open a PR.** Each fix lands as its own commit on67 the current branch so the user can review/revert individually. Exception:68 `/review` exposes no per-finding boundary, so its output lands as one commit69 per invocation (Step 3). Integration and shipping belong to `/finish-branch`70 and `/ship`.71- **Ground every finding and every fix in concrete evidence**: file:line,72 failing test name, log snippet, severity as the underlying tool produced it,73 and the commit SHA of the fix. No speculation.74- **Separate blockers from warnings.** Only test/build failures and75 CRITICAL/HIGH findings block. Everything else is a warning — fix it when the76 fix is cheap and safe, otherwise ship it with a follow-up note.77- **Bounded loops.** At most **two** fix rounds per check, then one final78 verification pass (Step 10). If something is still red after that, it's an79 UNFIXED blocker with the attempts documented — not a third round.80- **Never claim SHIP-READY without receipts.** The verdict must cite the exact81 checks that ran, what they found, what was fixed (with commits), what was82 re-verified, and what was skipped (and why).83- **No silent skips — mandatory accounting.** Every check must resolve to84 exactly one of: **RAN-CLEAN** (ran, nothing to fix), **FIXED(n)** (ran, n85 findings fixed and re-verified — list commits), **UNFIXED** (ran, at least one86 blocker could not be fixed — reason), **SKIPPED** (stated reason — e.g. "no87 reachable dev server and none could be started", "scanner not authorized in88 this env"), **NOT-TRIGGERED** (its diff trigger didn't fire), or89 **MANDATORY-FAIL** (a `CLAUDE.md`-mandatory check that was skipped). A check whose90 trigger fired but that neither ran nor was explicitly skipped-with-reason is an91 **unaccounted check ⇒ NOT READY**. "Recommend-only" is not an allowed resting92 state for a *triggered* check. Projects may mark specific checks **MANDATORY**93 in `CLAUDE.md` (e.g. `/pentest` on a payments service), and for those, SKIPPED94 is itself a blocker.95- **Money and authorization still need a human yes.** `/code-review ultra` is a96 billed cloud run, and `/review`'s Codex passes spend OpenAI tokens — ask97 before launching either, never assume. `/pentest` requires98 the user to confirm authorization before it scans — ask, then run. "Ask, then99 run" is still running; it is not report-only.100101## Project configuration (`CLAUDE.md`)102103This pipeline reads the project's root `CLAUDE.md` for a few optional settings.104They are plain prose (CLAUDE.md is agent instructions, not a config file) — look105for a `## qa-full` section and honor whatever it states. Example:106107```markdown108## qa-full109110- Mandatory checks (must RUN with evidence — a skip is a blocker): `/pentest`, `/defense`111- Hard perf gate: LCP ≤ 2.5s and INP ≤ 200ms on `/` and `/checkout` (breach blocks)112- Design: skip `/design-review` (design is owned by the design team, do not auto-fix visuals)113- Dev URL: http://localhost:3000 (for `/web-perf`, `/qa`, `/a11y`, `/fuzz`)114- Test/build: `pnpm test` and `pnpm build`115- QA tier: exhaustive116```117118Recognized settings (all optional; absence = the defaults in the steps below):119- **Mandatory checks** — listed commands must read RAN-CLEAN or FIXED in the120 ledger; SKIPPED is a blocker (any step; Step 10 enforces it). MANDATORY121 overrides the check's own diff trigger: run it on the diff even when the122 trigger didn't fire, so NOT-TRIGGERED is not an acceptable state either. Use123 for compliance-critical surfaces (payments, auth, PII).124- **Hard perf gate** — turns a `/web-perf` budget breach that survives the fix125 round from a warning into a blocker (Step 6).126- **Design: skip `/design-review`** — opt *out* of the visual-fix pass (Step 8)127 entirely; by default it runs on any UI change. This skips the check (ledger:128 SKIPPED("project opt-out")) — it does not turn it into a report-only run.129- **Test/build commands** — feed Steps 2 and 10. **Dev URL** — feeds Steps 4130 (`/fuzz`), 6, 7 and 8. **QA tier** — feeds Step 7; defaults to `standard`.131132If there is no `## qa-full` section, run with the built-in defaults — nothing here133is required.134135## Step 1: Establish the diff scope and a clean tree1361371. Detect the base branch: `gh repo view --json defaultBranchRef -q .defaultBranchRef.name`,138 else `git symbolic-ref refs/remotes/origin/HEAD`, else fall back to `main`/`master`.1392. If `$ARGUMENTS` names a base branch or `--scope <paths>`, use it.1403. Resolve the **diff ref**: `git fetch origin <base>` and use `origin/<base>`141 when that ref exists, else local `<base>`. This is what `/review` and `/qa`142 diff against too, and it stays correct after Step 1.5 creates a working143 branch (local `<base>` would then equal HEAD and the set would be empty).144 Compute the changed-file set: `git diff --name-only <diff-ref>...HEAD -- <scope paths>`145 (drop the `--` part when no `--scope` was given) plus146 uncommitted changes (`git status --porcelain`). This set drives every147 trigger below. **Fix commits made by this pipeline extend the set** — later148 steps and the final pass (Step 10) audit the fixes too.1494. **Clean-tree precondition.** The fixers (`/qa`, `/design-review`) need each150 fix to be its own atomic commit, so they stop on a dirty tree. Handle it151 once, here: if `git status --porcelain` is non-empty, ask the user (via152 AskUserQuestion) whether to **commit the in-progress work now** (recommended153 — a descriptive commit so the feature is preserved before fixes land) or154 **stash it**. Do not proceed with a dirty tree.1555. **Never run on the base branch itself.** The sub-skills' diff-aware modes156 (`/review`, `/qa`, `/design-review`) key off "current branch ≠ base" and157 diff against `merge-base(origin/<base>, HEAD)`. If `git branch158 --show-current` equals the base and there are unpushed commits, create a159 working branch at HEAD first — `git switch -c qa-full/<base>-<YYYY-MM-DD>`160 (reuse it if a same-day branch already exists from an aborted run) — and161 run the whole pipeline there. Step 10 folds it back: fast-forward the162 base to the working branch (`git switch <base> && git merge --ff-only163 qa-full/...`) and delete the working branch. No history is rewritten; the164 base just gains the fix commits. If there are no unpushed commits either,165 there is nothing to QA.1666. Record at the top of the report: base branch, diff ref, working branch (if167 created), commit range, changed-file count, and the HEAD SHA before any fixes.168169If there is no diff against base, stop and say so — there is nothing to QA.170171## Step 2: Tests & build (always — audit → fix → verify)1721731. Find the project's test/build commands from `CLAUDE.md`; if absent, infer174 from `package.json` scripts, `Makefile`, `pyproject.toml`, etc. If you175 cannot determine them, **ask** rather than guess.1762. **Audit:** run the test suite and the build. Capture exact failures (test177 name + verbatim error in a code block).1783. **Fix:** for each failing test or build error, follow `/debug` — reproduce,179 root-cause, then fix the cause (not the assertion). Commit each fix.1804. **Verify:** re-run the full suite and build. Green ⇒ FIXED(n). Still red181 after two rounds ⇒ UNFIXED blocker with the failing test and what was tried.182183If this step ends UNFIXED after two rounds, **stop here** and report NOT READY184with the failing test. Every later step's verify phase depends on a green185suite — running fixers on a red suite is fix → hope, not fix → verify. Mark186every downstream ledger row `SKIPPED("pipeline halted at Step 2")`. A working187branch from Step 1.5 stays as-is (base untouched) so the fix commits are there188for the user.189190## Step 3: Correctness + quality — `/review` then `/clean-code` (always)191192Two halves. Both sub-skills are in-tree, so they are invocable from inside any193session or tool, and Step 1.5 guarantees you are on a non-base branch, which194`/review`'s own branch guard requires.195196**Correctness — `/review`.** `/review` is not a report-only audit: one197invocation reads the diff, auto-applies its mechanical (AUTO-FIX) findings to198the working tree, asks you about the rest (ASK items) via its own199AskUserQuestion, and never commits. Treat one call as one atomic200audit + fix + ask unit:2011. **Run `/review`** against the base this pipeline resolved in Step 1. It has202 no argument channel, so it always diffs `merge-base(origin/<base>, HEAD)` —203 if Step 1 resolved a non-default base or a `--scope`, say so in the ledger204 evidence: `/review` reviewed the full default-base diff.2052. **Commit what it changed** as one commit attributed to `/review` (e.g.206 `review: apply AUTO-FIX + approved ASK findings`), so the tree is clean207 before `/clean-code` and nothing `/review` fixed can be lost by a later208 revert. If `--scope` was given, stage and commit only files under scope;209 any out-of-scope edits `/review` made stay uncommitted (stash them so the210 tree is clean, noting the stash ref) and are flagged in the ledger with that211 ref for the user — never silently committed. For any CRITICAL it reported but could not fix, root-cause212 (`/debug`), write the failing test first (`/tdd`), fix, commit atomically.2133. **Verify:** run `/review` once more. It re-scans the full base diff214 including the fix commits — that's the point. A CRITICAL still present ⇒215 UNFIXED blocker. Commit anything this second pass auto-fixed the same way.216 Do not run it a third time in this step.217218`/review`'s adversarial section runs a free Claude subagent **and**, when the219Codex CLI is installed and enabled, `codex exec` / `codex review` passes that220spend OpenAI tokens. Those Codex passes are **ask-first** under the money rule.221You are the one executing `/review`'s instructions, so no config change is222needed: when its Codex preflight says Codex would run — `CODEX_MODE: ready`223in current gstack, `CODEX_AVAILABLE` with `OLD_CFG` not `disabled` in older224versions — ask the user once whether to spend on Codex for this run; if225declined, do not run the `codex exec` / `codex review` commands and proceed226exactly as the section's disabled/unavailable branch describes (Claude227adversarial subagent still runs). Record228the Codex state and the user's answer in the ledger. Never flip the global229`codex_reviews` config on the user's behalf.230231If `/review` cannot run at all (the gstack install is broken), apply its232checklist233(`~/.claude/skills/gstack/review/checklist.md`) to `origin/<base>..HEAD` via a234fresh subagent, fix and re-verify the same way, and say so in the ledger — do235not skip the correctness step.236237**Quality — `/clean-code`.** After correctness is green and committed, run238`/clean-code <diff-ref> [--scope <paths>]` with the diff ref and scope this239pipeline resolved. It audits KISS / DRY / SOLID / YAGNI against `ENGINEERING_STANDARDS.md`,240applies the smallest safe refactor per finding under a green suite241(characterization test first where none exists), commits each atomically,242re-audits, and reverts a failed refactor with `git checkout` on only the files243it touched. Its findings left UNFIXED are warnings here, not blockers — quality244debt ships with a note; bugs don't.245246`/code-review ultra` (deep multi-agent cloud review) is **billed** — when a247`/review` finding is high-stakes (payments, auth, data loss, concurrency), ask248the user whether to launch it. Do not launch it unasked. Claude Code's249built-in `/code-review` and `/simplify` are not part of this step: they can't250be invoked from inside a session, and an optional extra pass would have no251ledger row.252253## Step 4: Security pipeline — `/defense`, `/iac-scan`, `/pentest`, `/fuzz`254255**`/defense` (always).**2561. **Audit:** run `/defense` scoped to the changed files (OWASP Top 10 /257 secrets / auth / crypto / data-protection).2582. **Fix:** remediate every CRITICAL/HIGH (and cheap MEDIUMs): remove or259 rotate-and-externalize hardcoded secrets, add the missing authz check,260 parameterize the query, escape the output, switch the weak primitive, add261 the validation. Each fix gets a regression test where a test can express it262 (e.g. "unauthenticated request to X returns 401"). Commit atomically.2633. **Verify:** re-run `/defense` on the same files; the finding must be gone.264265**`/iac-scan` (when infra/deploy config changed).** Trigger on `Dockerfile`,266`docker-compose*`, `*.tf`/`*.tfvars`, k8s/Helm manifests, `.github/workflows/**`,267`.gitlab-ci.yml`, `Jenkinsfile`, nginx/cloud config (see `/iac-scan`'s trigger268section for the authoritative list). Audit with the local static linters, **fix**269CRITICAL/HIGH misconfigs (root container → non-root user, `0.0.0.0/0` ingress →270scoped CIDR, wildcard IAM → least privilege, privileged pod → dropped, untrusted271CI trigger → pinned/guarded, baked-in secret → injected), re-scan to verify.272273**`/pentest` (triggered when `/defense` found CRITICAL/HIGH, or the diff touches274auth/crypto/session/token/deserialization/file-upload paths).** It is an external275scanner: **confirm authorization with the user first** (the skill's own276questions), then run it. Fix CRITICAL/HIGH it surfaces, re-scan to verify. If the277user declines or the scanner is unavailable ⇒ SKIPPED(reason). If `CLAUDE.md`278marks `/pentest` MANDATORY, SKIPPED is a blocker.279280**`/fuzz` (triggered when the diff adds or changes endpoints, input parsing,281file-upload handling, or deserialization).** Needs a running target: find the dev282URL (`CLAUDE.md`, or start the `dev` script). Run `/fuzz` against the new283surface; **fix** crashes, injections, and auth bypasses it surfaces (with a284regression test); re-fuzz to verify. No reachable target and none startable ⇒285SKIPPED(reason). If `CLAUDE.md` marks `/fuzz` MANDATORY, SKIPPED is a blocker.286287**`/cso` backstop.** If the diff crosses a *new* trust boundary (new auth288path/endpoint/external input/deserialization) and there's no evidence a threat289model was done at plan time, run `/cso` on that boundary and fold any290CRITICAL/HIGH into the `/defense` fix round. Threat modeling belongs in291`/write-plan`; this is the late catch, not a substitute.292293## Step 5: Database pipeline — `/db-optimize` (auto-run if triggered)294295Trigger when changed files match ORM models, migrations, query builders296(`**/models/**`, `**/migrations/**`, `**/queries/**`, `**/*repository*`,297`**/*.sql`), raw SQL in the diff, or new ORM calls (`.find`, `.where`,298`.includes`, `.join`, `.preload`).2993001. **Audit:** run `/db-optimize` scoped to matched files (run `/dbmap` first if301 it asks for a schema map).3022. **Fix:** N+1s on hot paths → eager-load/batch (`includes`/`preload`/303 `select_related`/dataloader); missing indexes on hot paths → add a migration304 for the index; obviously-redundant queries → dedupe. Add a test that asserts305 the query count where the ORM supports it. Commit atomically.3063. **Verify:** re-run `/db-optimize`; the hot-path findings must be gone and307 the migration must apply cleanly in the test run.308309Non-hot-path suggestions are warnings (fix if trivial). No trigger ⇒310NOT-TRIGGERED.311312## Step 6: Frontend perf pipeline — `/web-perf` (+ `/perf-profile`)313314Trigger when the diff includes frontend code (`**/*.tsx`, `**/*.jsx`,315`**/*.vue`, `**/*.svelte`, `**/components/**`, `**/pages/**`, `**/styles/**`,316`**/*.css`, `**/*.scss`), new images/fonts/assets, or bundler config317(`next.config.*`, `vite.config.*`, `webpack.config.*`).3183191. Find the dev URL (`CLAUDE.md`, or the `dev` script in `package.json`). A320 human is present, so **start the dev server** if it isn't running. Only if321 no app is running and none can be started ⇒ SKIPPED("no reachable dev322 server, start failed: <error>").3232. **Audit:** run `/web-perf` against the affected routes. Record Core Web324 Vitals (LCP, INP, CLS) vs. any known budget.3253. **Fix:** address the measured regressions attributable to the diff —326 render-blocking imports → defer/lazy, oversized image/font → optimize or327 preload, layout shift → reserve dimensions, long task → split/memoize.328 Commit atomically.3294. **Verify:** re-run `/web-perf` on the same routes; report before/after330 numbers.331332- A budget breach that survives the fix round is a **warning** by default,333 unless `CLAUDE.md` defines a hard perf gate — then it blocks.334- **`/perf-profile`** (triggered when the diff touches hot server-side paths, the335 change is pre-launch, or `/db-optimize`/`/web-perf` point at a server-side336 bottleneck): run it against the affected endpoint/job, **fix** the localized337 bottleneck (cache, batch, move off the request path), re-profile to verify.338 Needs a representative workload — if none is available ⇒ SKIPPED(reason).339340## Step 7: Browser QA pipeline — `/qa` (auto-run if triggered)341342> Run **`/qa`** — the full test → fix → re-verify loop — not `/qa-only`. This is343> the check that replaces manual click-through QA, and a human is present.344345Trigger when the diff includes anything a human would manually QA in a browser:346UI/frontend code, pages/routes, forms, route handlers serving HTML, API347endpoints the UI consumes, auth/session flows, or config that changes348user-facing behavior.3493501. Start the dev server if needed (same URL as Step 6).3512. Run `/qa` scoped to the affected surface at the project's **QA tier**352 (`CLAUDE.md`, default `standard`: critical + high + medium). `/qa` itself does353 the audit → fix → re-verify loop with atomic commits and before/after health354 scores — let it run to completion; don't cut it off at the report.3553. Fold its before/after health score, fixed-bug list (with commits), and any356 bugs it could not fix into the ledger.357358- User-facing CRITICAL/HIGH bugs that `/qa` could not fix ⇒ UNFIXED blocker.359- No reachable app and none startable ⇒ SKIPPED(reason) — and note that this360 means the feature has not been browser-tested at all.361362## Step 8: Design + accessibility pipeline — `/design-review`, `/a11y`363364**`/design-review` (when the diff includes UI changes, unless `CLAUDE.md` opts365out).** Run `/design-review` against the changed screens — it audits visual366consistency, hierarchy, spacing, AI-slop tells and slow interactions, then367**fixes them with atomic commits and before/after screenshots**. Let it complete.368Visual findings it can't fix are warnings, not blockers. If the project opted369out in `CLAUDE.md`, record SKIPPED("project opt-out") and move on.370371**`/a11y` (when the UI change is heavy and likely to affect assistive tech —372new/changed interactive components, forms, ARIA/`role`/`tabindex`,373focus/keyboard handling, images, color/contrast, motion; see `/a11y`'s trigger374section).**3751. **Audit:** run the static pass on the diff, and the **dynamic axe pass** when376 the dev URL is reachable (it is, if Step 6/7 ran).3772. **Fix:** every CRITICAL/SERIOUS — native element over ARIA-on-a-div, missing378 label/name, unreachable-by-keyboard control, focus trap, contrast below379 ratio, missing reduced-motion guard. Commit atomically.3803. **Verify:** re-run the same pass; CRITICAL that survive ⇒ UNFIXED blocker.381382Scope split: `/design-review` owns *visual* quality; `/a11y` owns WCAG /383assistive-tech correctness. They overlap on contrast — `/a11y`'s measured384contrast finding is authoritative.385386## Step 9: Coverage pipeline — `/test-coverage` + `/playwright`3873881. **Audit:** for each changed file (including this pipeline's fix commits),389 locate its test (sibling `*.test.*`, parallel `tests/`). Use coverage data if390 present (`coverage/`, `lcov.info`, `.coverage`); else do a structural check391 for new exported functions / branches / error paths without an assertion.3922. **Fix:** run `/test-coverage` on the diff — it writes and applies the missing393 unit tests (and integration tests where risk crosses a boundary), enforcing394 Google's Testing-on-the-Toilet practices. For **user-facing flows** with no395 e2e coverage, run `/playwright` to generate and run the e2e test so a396 regression test is left behind. Commit atomically.3973. **Verify:** run the full suite; the new tests must pass, and the structural398 check must show no new **public** surface with zero tests.399400New public surface still untested after this step ⇒ UNFIXED blocker. Internal401helpers without tests are warnings.402403## Step 10: Final verification pass, ledger, verdict404405The fix rounds changed the branch, so verify the *whole* result once more:4064071. **Fresh tests + build** on the final HEAD (Step 2 commands). Stale results408 ⇒ NOT READY.4092. **Re-audit the fix commits:** run `/defense` scoped to the files the fix410 commits touched, and read the fix commits themselves411 (`git show original-HEAD..HEAD`) against `/review`'s checklist — `/review`412 takes no commit range, and Step 3 already re-ran it twice. The fixes must not413 introduce a CRITICAL/HIGH. If they did, one more fix + re-verify, then stop.4143. **Diff sanity:** `git log --oneline <base>..HEAD` — every pipeline commit415 should name its check/finding; nothing outside the diff scope was touched.4164. **Fold back the working branch** if Step 1.5 created one: `git switch417 <base> && git merge --ff-only qa-full/<...> && git branch -d qa-full/<...>`.418 If the fast-forward fails, the base moved underneath you — stop and report;419 never force.420421Then build the **accounting ledger** — a row per check, each resolved to422RAN-CLEAN / FIXED(n) / UNFIXED / SKIPPED(reason) / NOT-TRIGGERED /423MANDATORY-FAIL. **The verdict cannot be SHIP-READY while any triggered check is424unaccounted or UNFIXED.**425426**Phase-5 accounting (honest scope):** `/qa-full` *is* the entry to Phase 5, so it427can only enforce the **pre-ship** half. It **cannot** verify `/finish-branch`,428`/ship`, or `/land-and-deploy` — those run *after* this pipeline, so do not claim429they're done. A passing verdict is the **hard precondition** for ship: only on430SHIP-READY do you hand off *"Proceed to `/finish-branch` then `/ship`."*431432Then the verdict:433434- **SHIP-READY** — zero blockers remaining **and** every triggered check435 accounted for **and** the final pass is green. List what was fixed (commits),436 warnings + follow-ups, then hand off to `/finish-branch` → `/ship`.437- **NOT READY** — one or more blockers survived the fix rounds (or a check is438 unaccounted / MANDATORY-FAIL). List each with its file:line/test-name439 evidence, **what was tried**, and what the user needs to decide or provide.440 Tell the user to resolve and re-run `/qa-full`.441442Blocker set (any one ⇒ NOT READY — this is the authoritative list for the443verdict; it mirrors the superskills `ENGINEERING_STANDARDS.md` hard gates, kept444in sync by the maintainer). Each is evaluated **after** the fix rounds:445- failing test or broken build, or test/build not freshly run on final HEAD (Step 2/10)446- `/review` CRITICAL correctness finding still present (Step 3)447- `/defense` CRITICAL/HIGH security finding still present (Step 4)448- `/fuzz` CRITICAL/HIGH — crash, injection, or auth bypass — still reproducible (Step 4)449- `/pentest` CRITICAL/HIGH vulnerability still present, when it ran (Step 4)450- `/iac-scan` CRITICAL/HIGH infra misconfig still present (Step 4)451- N+1 / missing index on a hot path still present (Step 5)452- CRITICAL/HIGH browser-QA bug in a user-facing flow `/qa` could not fix (Step 7)453- `/a11y` CRITICAL — a control unusable by screen-reader/keyboard — still present (Step 8)454- new public surface with zero tests after `/test-coverage` (Step 9)455- a hard perf gate breach after the fix round, only if `CLAUDE.md` defines one (Step 6)456- **a triggered check left unaccounted** — neither run nor SKIPPED with a reason457- **a `CLAUDE.md`-MANDATORY check that was SKIPPED** rather than run458459## Report format460461Write to `qa-full-reports/<branch>-<YYYY-MM-DD>.md` (create dir; add to462`.gitignore`). Structure:463464```markdown465# QA-Full — <branch> @ <YYYY-MM-DD>466467Base: <base> Range: <base>..HEAD Changed files: N (+M from fixes)468HEAD before fixes: <sha> HEAD after: <sha> Fix commits: K469470## VERDICT: SHIP-READY ✅ | NOT READY ⛔471472### Fixed (audit → fix → verify, each with its commit)4731. <check> — <file:line> — <finding> — fixed in <sha> — re-verified by <evidence>474- (or) None needed.475476### Blockers remaining (must resolve before /finish-branch)4771. <file:line> — <evidence> — <what was tried> — <what's needed from you>478- (or) None.479480### Warnings (ship with a follow-up note)481- …482483## Accounting ledger (RAN-CLEAN / FIXED(n) / UNFIXED / SKIPPED(reason) / NOT-TRIGGERED / MANDATORY-FAIL)484| Check | Status | Evidence / fixes / reason |485|-------|--------|---------------------------|486| Tests & build (Step 2) | RAN-CLEAN / FIXED(n) / UNFIXED | exact command + result, fix SHAs |487| /review (Step 3) | RAN-CLEAN / FIXED(n) / UNFIXED | N findings, fix SHAs, 2nd-run result, Codex passes on/off, base used, out-of-scope stash ref if any |488| /clean-code (Step 3) | RAN-CLEAN / FIXED(n) / UNFIXED | KISS/DRY/SOLID/YAGNI findings, fix SHAs, deferred-with-reason |489| /defense (Step 4) | RAN-CLEAN / FIXED(n) / UNFIXED | N findings, fix SHAs |490| /iac-scan (Step 4) | … / NOT-TRIGGERED | infra/deploy files changed? |491| /pentest (Step 4) | … / SKIPPED(reason) / NOT-TRIGGERED | authorized? findings? |492| /fuzz (Step 4) | … / SKIPPED(reason) / NOT-TRIGGERED | target URL, findings |493| /cso (Step 4) | … / NOT-TRIGGERED | new trust boundary? threat-model evidence |494| /db-optimize (Step 5) | … / NOT-TRIGGERED | N+1 / index fixes, migration |495| /web-perf (Step 6) | … / SKIPPED(reason) / NOT-TRIGGERED | before/after LCP/INP/CLS |496| /perf-profile (Step 6) | … / SKIPPED(reason) / NOT-TRIGGERED | bottleneck, before/after |497| /qa (Step 7) | … / SKIPPED(reason) / NOT-TRIGGERED | tier, health before/after, fix SHAs |498| /design-review (Step 8) | … / SKIPPED(reason) / NOT-TRIGGERED | screens, fix SHAs |499| /a11y (Step 8) | … / SKIPPED(reason) / NOT-TRIGGERED | static + dynamic, fix SHAs |500| /test-coverage + /playwright (Step 9) | RAN-CLEAN / FIXED(n) / UNFIXED | tests added, suite result |501| Final pass (Step 10) | RAN-CLEAN / FIXED(n) / UNFIXED | fresh test/build + re-audit of fix commits |502503> No row may be blank or "recommend" for a check whose trigger fired — that is an504> unaccounted-check blocker. `CLAUDE.md`-MANDATORY checks must read RAN-CLEAN or FIXED.505506## Ask-first / follow-up commands507- `/code-review ultra` — (billed; offer when a high-stakes correctness concern remains)508- `/review` Codex passes — (OpenAI tokens; ask before enabling them for a run)509- `/pentest` — (if it was SKIPPED for authorization and the user now wants it)510- `/fuzz` — (if SKIPPED for lack of a target and one is now available)511- `/perf-profile` — (if SKIPPED for lack of a representative workload)512- `/finish-branch` → `/ship` — (only if VERDICT is SHIP-READY)513```514515Print the verdict, the fixed count, the remaining-blocker count, and a 5-line516summary to the chat.517518## Anti-patterns (do not do)519520- Stopping at the report. A triggered check that found something and did not521 attempt a fix has not run `/qa-full`.522- Running `/qa-only` or `/design-audit` where `/qa` / `/design-review` are523 specified. Report-only is for discovery inside a step, never the step's end.524- Claiming a finding is fixed without re-running the check that found it and525 the test suite (fresh evidence, not assertion).526- Pushing, opening PRs, or merging — that's `/finish-branch` / `/ship`.527- Fixing outside the diff: refactoring untouched modules, bumping deps, or528 "while I'm here" changes. Every commit must trace to a finding.529- Landing a fix that itself breaks the bar — untested public surface, a530 duplicated helper, a symptom patch over an unknown root cause.531- Looping without bound. Two fix rounds per check, one final pass, then report532 what's left honestly.533- Launching a billed run (`/code-review ultra`) or an external scanner534 (`/pentest`) without the user's explicit yes.535- Declaring SHIP-READY while a check was skipped without saying which and why,536 or while any UNFIXED blocker remains.537- Running any sub-check against the whole repo instead of the diff.538- Treating MEDIUM/LOW findings as blockers (noise) or hiding CRITICAL/HIGH in539 the warnings list.540541## Related commands542543Reuses the trigger matrix from `/daily-qa` (see `skills/daily-qa/SKILL.md`544Step 7 for the canonical globs). Differences: branch-scoped, present-human,545and it **fixes and verifies** instead of recommending.546547Auto-run (diff-scoped; audit → fix → verify):548- Tests & build — always; failures root-caused via `/debug`, proven via `/verify` (Step 2).549- `/review` — staff-level correctness review; findings fixed by the pipeline (Step 3).550- `/clean-code` — KISS/DRY/SOLID/YAGNI refactors on the diff, test-verified (Step 3).551- `/defense` — OWASP/secrets/auth/crypto; findings fixed by the pipeline (Step 4).552- `/iac-scan` — when infra/deploy config changed; misconfigs fixed (Step 4).553- `/fuzz` — when the diff adds endpoints/input parsing and a target is reachable (Step 4).554- `/cso` — backstop when a new trust boundary reached the pipeline unmodeled (Step 4).555- `/db-optimize` — when DB/ORM/SQL changed; N+1/index fixes applied (Step 5).556- `/web-perf` — when frontend changed; dev server started if needed; regressions fixed (Step 6).557- `/perf-profile` — when hot server paths changed / pre-launch; bottleneck fixed (Step 6).558- `/qa` — when anything user-facing changed; full test → fix → re-verify loop (Step 7).559- `/design-review` — when UI changed; fixes + commits visual issues (Step 8).560- `/a11y` — static + dynamic pass when heavy UI changed; findings fixed (Step 8).561- `/test-coverage` + `/playwright` — write and apply the missing tests (Step 9).562- `/tdd`, `/debug`, `/verify` — the discipline every fix in the pipeline follows.563564Ask-first (need the user's explicit yes):565- `/code-review ultra` — billed multi-agent cloud review.566- `/review`'s Codex passes — OpenAI tokens; per-run yes required (Step 3).567- `/pentest` — external scanner; authorization confirmation, then it runs.568569Follow-up (outside the pipeline):570- `/code-review` / `/simplify` — Claude Code built-ins overlapping Step 3; use571 them by hand, the pipeline uses the in-tree `/review` + `/clean-code`.572573Hand-off (only when SHIP-READY):574- `/finish-branch` — choose how to integrate the work.575- `/ship` — sync, bump VERSION, changelog, PR.