| name | quality-gate |
| description | Run parallel quality reviews (React, SOLID, Security, Simplification, Slop) on branch changes and auto-fix issues |
| argument-hint | [base-branch] |
Quality Gate
!IMPORTANT: Follow this process exactly. Do not skip steps.
Arguments: $0 (optional) — base branch to diff against. If omitted, auto-detect.
Step 0: Verify Dependencies
This skill invokes four external skills plus one Claude Code built-in. Before doing anything else, verify each is installed at ~/.claude/skills/<name>/SKILL.md (or as a built-in). simplify is a Claude Code built-in command and does not require installation.
Check each path in a single shell call:
for s in vercel-react-best-practices applying-solid-principles security-review code-slop; do
[ -f ~/.claude/skills/$s/SKILL.md ] && echo "OK $s" || echo "MISS $s"
done
If any report MISS, stop and tell the user which skills are missing with the exact install command for each. Do not proceed until the user confirms they are installed.
| Skill | Install command |
|---|
vercel-react-best-practices | npx skills add https://github.com/vercel-labs/agent-skills --skill vercel-react-best-practices -g |
applying-solid-principles | npx skills add https://github.com/BenjaminG/ai-skills --skill applying-solid-principles -g |
security-review | npx skills add https://github.com/getsentry/skills --skill security-review -g |
code-slop | npx skills add https://github.com/BenjaminG/ai-skills --skill code-slop -g |
simplify | Built-in to Claude Code — no install needed |
If the project does not use React/Next.js, vercel-react-best-practices is optional (Task 1 in Step 2 is skipped anyway).
Soft dependencies for Step 3.5 (Context Check). The context-fetcher degrades gracefully when these are missing — log which one is unavailable in the bundle and continue, do not abort the skill:
| Tool | Used for | Probe |
|---|
linear-cli skill | Linear issue + comments | [ -f ~/.claude/skills/linear-cli/SKILL.md ] |
devsql CLI | Past Claude Code sessions | command -v devsql |
gh CLI | Open PR body + comments | command -v gh && gh auth status |
Step 1: Get the Diff
Detect the base branch:
git rev-parse --verify main >/dev/null 2>&1 && echo "main" || (git rev-parse --verify master >/dev/null 2>&1 && echo "master" || echo "develop")
Then get the full diff and changed file list:
git diff <base>...HEAD --name-only
git diff <base>...HEAD
Store the diff output — you will pass it to review agents.
Also detect the project stack:
cat package.json 2>/dev/null | jq -r '.dependencies // {} | keys[]' | grep -E '^(react|next)$'
Step 2: Parallel Review (Agent Team)
2a. Create Team
TeamCreate team_name: "quality-gate" description: "Parallel quality review of branch changes"
2b. Create Review Tasks
Create one TaskCreate per review dimension. Skip Task 1 if the project does not use React/Next.js.
Each task description MUST include:
- The full diff from Step 1 (if diff exceeds ~50KB, list changed files and instruct teammate to read files directly)
- The list of changed files
- The skill command to invoke and review instructions (see table below)
- The classification rules (see below)
- The required output format (see below)
- Instruction: Do NOT modify any files. Report findings only.
- Instruction: Write the full findings to
/tmp/quality-gate-findings-<reviewer-name>.md using the Write tool (e.g. /tmp/quality-gate-findings-solid-reviewer.md)
- Instruction: Send a brief "done" notification to the lead via
SendMessage with type: "message" and recipient: "lead" (the lead will read findings from the file, no need to include full findings in the message)
- Instruction: Mark task completed via
TaskUpdate with status: "completed" after sending findings
| Task | subject | activeForm | Skill command & instructions |
|---|
| 1 | Review React/Next.js best practices | Reviewing React best practices | /vercel-react-best-practices Review ONLY the changed code in the diff against the rules. Categorize each finding as FIX or NITPICK |
| 2 | Review SOLID principles | Reviewing SOLID principles | /applying-solid-principles Review ONLY the changed code in the diff against SOLID principles and clean code practices. Categorize each finding as FIX or NITPICK |
| 3 | Review security | Reviewing security | /security-review Review ONLY the changed code in the diff against the security checklist. Categorize each finding as FIX or NITPICK |
| 4 | Review simplification opportunities | Reviewing simplification | /simplify Review ONLY the changed code in the diff for simplification opportunities (clarity, consistency, maintainability). Categorize each finding as FIX or NITPICK. Do NOT modify any files — report only. |
| 5 | Review code slop | Reviewing code slop | /code-slop but override: Do NOT modify any files. Instead, identify all slop issues and report them in FIX/NITPICK format below. |
| 6 | Fetch historical context | Fetching historical context | See Task 6 spec below. Gathers Linear issue, PR body/comments, and past Claude Code sessions that touched the changed files. Output is consumed in Step 3.5 (Context Check). |
Task 6 spec — context-fetcher
Goal: assemble a context bundle so Step 3.5 can detect FIX suggestions that contradict prior decisions.
The task description MUST instruct the teammate to:
- Detect Linear issue ID from the current branch name. Common patterns:
<prefix>/<TEAM>-<NUM>-<slug>, <TEAM>-<NUM>-<slug>, feature/<TEAM>-<NUM>. If a match is found, fetch the issue and all its comments via the linear-cli skill (/linear-cli). If no ID is detected, record Linear: not found.
- Detect open PR for the current branch via
gh pr view --json number,title,body,comments,reviews. If a PR exists, capture body, review comments, and conversation comments. If none, record PR: none.
- Query past Claude Code sessions that touched the changed files via
devsql. For each changed file, run a query similar to:
SELECT t.session_id, datetime(t.timestamp/1000, 'unixepoch') AS ts, t.text
FROM transcripts t
WHERE t.project LIKE '%<basename of cwd>%'
AND (t.tool_use LIKE '%<file path>%' OR t.text LIKE '%<file basename>%')
ORDER BY t.timestamp DESC
LIMIT 20;
Cap total at ~80 rows across all files. If devsql is unavailable, record Past sessions: devsql unavailable and continue — do not fail the task.
- Do NOT modify any files. Read-only.
- Write the bundle to
/tmp/quality-gate-context-bundle.md with this structure:
## Linear
<issue id, title, status, body, comments — or "not found">
## PR
<number, title, body, review comments, conversation comments — or "none">
## Past Claude Code sessions (per file)
### <file/path.ts>
- <ts> session <id…>: <one-line excerpt of the prompt or tool_use that touched this file>
- …
Quote verbatim where possible — Step 3.5 needs textual citations.
- Send a "done" notification to
lead via SendMessage and mark the task completed via TaskUpdate.
2c. Spawn Teammates (all in parallel)
Spawn all teammates in a single response using the Task tool with team_name: "quality-gate" and each teammate's name:
| name | Assigned task |
|---|
react-reviewer | Task 1 (skip if not React) |
solid-reviewer | Task 2 |
security-reviewer | Task 3 |
simplify-reviewer | Task 4 |
slop-cleaner | Task 5 |
context-fetcher | Task 6 |
Each teammate's prompt must instruct them to:
- Check
TaskList and claim their assigned task via TaskUpdate with status: "in_progress" and owner: "<their-name>"
- Invoke the designated skill via the
Skill tool with the review instructions
- Format findings per the output format below
- Write the full formatted findings to
/tmp/quality-gate-findings-<their-name>.md using the Write tool (e.g. /tmp/quality-gate-findings-solid-reviewer.md)
- Send a brief "done" notification to the lead via
SendMessage with type: "message", recipient: "lead", and summary: "<reviewer-name> done — findings written to /tmp/quality-gate-findings-<their-name>.md"
- Mark task completed via
TaskUpdate with status: "completed"
2d. Assign Tasks
After spawning, assign each task to its teammate via TaskUpdate with owner: "<teammate-name>".
Classification Rules (include in each task description)
FIX (will be auto-applied):
- Bugs or logic errors
- Security vulnerabilities
- Performance issues with measurable impact
- Clear violations of critical rules
- Obvious simplifications that reduce complexity without trade-offs
NITPICK (user decides):
- Style preferences or formatting (e.g. unused imports, line wrapping) — not variable renames or block restructuring
- Debatable architectural choices
- Low-impact optimizations
- "Nice to have" improvements
Required Output Format (include in each task description)
## FIX
- `file/path.ts:42` — [RULE-ID] Description of the issue. Suggested fix: <concrete suggestion>
- `file/path.ts:85` — [RULE-ID] Description. Suggested fix: <suggestion>
## NITPICK
- `file/path.ts:15` — [RULE-ID] Description. Suggestion: <suggestion>
## NO ISSUES
(use this section if nothing found in a category)
If no issues at all, return: No issues found.
Step 3: Consolidate Findings and Tear Down Team
3a. Collect Results
Monitor TaskList until all review tasks reach completed status. Once all tasks are completed, read findings from each reviewer's output file using the Read tool:
/tmp/quality-gate-findings-solid-reviewer.md
/tmp/quality-gate-findings-security-reviewer.md
/tmp/quality-gate-findings-simplify-reviewer.md
/tmp/quality-gate-findings-slop-cleaner.md
/tmp/quality-gate-findings-react-reviewer.md (if spawned)
/tmp/quality-gate-context-bundle.md (from context-fetcher — consumed in Step 3.5)
Do NOT rely on SendMessage content for findings — those are "done" pings only. The files are the source of truth.
3b. Shut Down Team
Send SendMessage with type: "shutdown_request" to each teammate. After all teammates confirm shutdown, call TeamDelete. Do not delete temp files yet — Step 3.5 reads /tmp/quality-gate-context-bundle.md. Cleanup happens at the end of Step 3.5.
3c. Consolidate and Detect Conflicts
- Collect all FIX items across all reviewers
- Group by
file:line
- For each group with ≥2 FIX items, classify the group:
- Duplicate: suggestions describe the same edit (same intent, same code outcome) → collapse to one item, keep the most specific wording
- Conflict: suggestions describe different edits on the same location (e.g., SOLID says "extract into hook", Simplify says "inline it") → flag as a conflict candidate
- If any conflict candidates exist → proceed to Step 3d (Arbitrate)
- If no conflicts → skip Step 3d and proceed directly to Step 4
Once the final FIX list is settled (after Step 3d if needed), display the summary:
### Quality Gate Results
**Fixes to auto-apply:** N items
- [React] file:line — description (x items)
- [SOLID] file:line — description (x items)
- [Security] file:line — description (x items)
- [Simplify] file:line — description (x items)
- [Slop Cleaner] file:line — description (x items)
**Conflicts arbitrated:** N items ← include only if Step 3d ran
**Nitpicks for review:** N items
Step 3d: Arbitrate Conflicts (conditional)
Skip this step entirely if Step 3c found zero conflicts.
Spawn a single standalone arbitrator via the Agent tool (NOT part of the team):
- subagent_type:
general-purpose
- description:
Arbitrate FIX conflicts
- prompt: Provide the arbitrator with:
- The conflict groups only (not all findings) — each group is one
file:line with the competing FIX items from different reviewers, including the reviewer name and their suggested fix
- The relevant file excerpts (read each conflicted file's surrounding context and include it in the prompt)
- The fixed priority chain: Security > Correctness > SOLID > Simplify > Style. Within the same tier, prefer the fix with the smallest blast radius (fewer lines changed, no new abstractions)
- Instruction: return a JSON-like block per conflict with
file:line, winner: <reviewer-name>, chosen_fix: <verbatim fix>, reason: <one sentence>. Optionally, if two fixes are compatible and can be merged, return merged instead with the combined edit
- Instruction: read-only — do NOT edit any files
Merge the arbitrator's winning fixes back into the FIX list (replacing the conflict groups). Non-conflicted FIX items pass through unchanged. Record the count for the summary line **Conflicts arbitrated:** N.
Step 3.5: Context Check (always runs)
Goal: catch FIX items that would undo a deliberate decision documented in Linear, the PR, or past Claude Code sessions. Runs after consolidation/arbitration, before auto-apply.
Skip this step only if the FIX list is empty AND there are zero nitpicks worth checking (in practice: skip iff the consolidated FIX list is empty).
Spawn a single standalone context-checker via the Agent tool (NOT part of the team):
- subagent_type:
general-purpose
- description:
Check FIX list against historical context
- prompt: Provide the checker with:
- The full consolidated FIX list (post-arbitration), each item with
file:line, reviewer, rule id, description, suggested fix
- The full content of
/tmp/quality-gate-context-bundle.md
- The diff (or list of changed files if the diff is too large)
- Decision rule (strict): for each FIX, classify as
- OK — no contradiction with the bundle, or bundle silent on the topic and the FIX is low-risk style (e.g. unused import, formatting)
- CONFLICT — bundle contains evidence (issue comment, PR review, past session prompt/decision) that this code was written this way on purpose
- UNCERTAIN — bundle mentions the file/symbol but the intent is ambiguous (no clear verdict)
- Strict posture: treat
UNCERTAIN the same as CONFLICT. Only OK allows the FIX to be auto-applied. Confidence threshold for OK is ≥ 80%.
- Required output: a JSON-like block per FIX with
file:line, verdict: OK | CONFLICT | UNCERTAIN, source: <linear|pr|session|none>, citation: "<verbatim excerpt from bundle, ≤ 240 chars>" (omit if OK), reason: <one sentence>
- Instruction: read-only — do NOT edit any files
Process the verdicts:
- OK items stay in the FIX list
- CONFLICT and UNCERTAIN items are removed from the FIX list and inserted into a new bucket
HISTORICAL_CONFLICTS with their citation and source. They will be displayed at the head of the nitpick section in Step 5 — they are NOT auto-applied.
Update the Step 3c summary block accordingly:
### Quality Gate Results
**Fixes to auto-apply:** N items
- [React] file:line — description (x items)
- [SOLID] file:line — description (x items)
- ...
**Conflicts arbitrated:** N items ← include only if Step 3d ran
**Historical conflicts (rerouted to nitpicks):** N items ← include only if Step 3.5 found any
**Nitpicks for review:** N items
After the checker returns, clean up temp files:
rm -f /tmp/quality-gate-findings-*.md /tmp/quality-gate-context-bundle.md
Step 4: Auto-Fix
Apply all FIX items to the codebase:
- Read each affected file
- Apply the suggested fixes using the Edit tool
- After all fixes, run the project's linter/formatter if configured (check package.json scripts for lint/format)
Step 5: Present Nitpicks
If there are nitpicks OR historical conflicts, display them and use AskUserQuestion. Render the historical-conflicts section FIRST (header position) so it is impossible to miss:
### Nitpicks for your review
#### ⚠️ Conflicts with past decisions (rerouted from FIX)
These FIX items were demoted because the historical context suggests the code was written this way on purpose. Review the citation before applying.
- `file:line` — [reviewer/RULE-ID] description
- Suggested fix: <suggestion>
- Source: <linear|pr|session> — <reason>
- Citation: "<verbatim excerpt>"
#### React/Next.js
- `file:line` — description — suggestion
#### SOLID
- `file:line` — description — suggestion
#### Security
- `file:line` — description — suggestion
#### Simplification
- `file:line` — description — suggestion
#### Slop Cleaner
- `file:line` — description — suggestion
Omit the ⚠️ Conflicts with past decisions block if Step 3.5 found none. Omit any reviewer subsection that has no items.
Ask: "Which nitpicks should I apply?" with options:
- All of them
- None
- Let me pick (then list individually)
Step 6: Apply Selected Nitpicks
Apply whichever nitpicks the user selected.
Step 7: Post-Fix Validation
Run this step only if any changes were applied in Step 4 or Step 6. Skip it if no fixes and no nitpicks were applied.
Spawn a single standalone validator via the Agent tool (NOT part of the team):
- subagent_type:
general-purpose
- description:
Validate post-fix diff
- prompt: Provide the validator with:
- The output of
git diff <base>...HEAD (the full branch diff, including the applied fixes and nitpicks)
- The list of FIX + nitpick items that were applied (from Step 4 and Step 6)
- Role: read-only semantic review of the final diff. Check for:
- Fixes that break another fix (e.g., partial renames, inconsistent refactors across files)
- Fixes that reintroduce an issue the original diff was meant to address
- Linter/formatter changes that masked a real problem
- Applied changes that do not match their stated intent (spot-check a sample)
- Required output format — exactly one of:
APPROVED on the first line, nothing else required
ISSUES_FOUND: on the first line, followed by a bulleted list of - file:line — problem description
- Instruction: read-only — do NOT edit any files
If the validator returns APPROVED: proceed to Step 8.
If the validator returns ISSUES_FOUND: display the issue list and git diff --stat, then use AskUserQuestion with:
- Proceed anyway — commit as-is (go to Step 8)
- Rollback fixes — run
git restore . to discard all applied fixes and nitpicks, then abort the skill and report which validator issues were flagged
- Let me review — exit without committing, leave the working tree dirty so the user can inspect and edit
Step 8: Commit & Push (if changes made)
If any changes were applied (fixes or nitpicks) and validation passed or the user chose to proceed:
git add .
git commit -m "refactor: apply quality gate fixes"
If a remote branch exists and the branch was already pushed:
git push
Execution Notes
- Requires:
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 environment variable in settings
- Agent roster: 5–6 parallel team members (4–5 reviewers — skip react-reviewer if not a React project — plus the
context-fetcher) + up to 3 sequential standalone specialists (conflict-arbitrator conditional, context-checker whenever the FIX list is non-empty, post-fix-validator whenever changes were applied)
- Standalone specialists (
conflict-arbitrator, context-checker, post-fix-validator) are spawned via the Agent tool and are NOT part of the quality-gate team — no TeamCreate/TeamDelete coupling, no shared TaskList
- Arbitrator fires only when ≥1 conflict is detected in Step 3c — zero cost when reviewers agree
- Arbitrator priority (deterministic): Security > Correctness > SOLID > Simplify > Style; within the same tier prefer the fix with the smallest blast radius
- Context fetcher runs in parallel with reviewers in Step 2 so the bundle is ready by Step 3.5 with no added latency
- Context checker is strict by default —
UNCERTAIN is treated as CONFLICT, both reroute to the historical-conflicts nitpick section. Never auto-apply a non-OK verdict.
- Context sources (in order of trust): Linear issue + comments → open PR body + reviews → past Claude Code sessions (devsql
transcripts/history)
- Team lifecycle:
TeamCreate at Step 2a, TeamDelete at Step 3b
- All review teammates and standalone specialists are read-only — only the lead edits files
- Teammate idle is normal — teammates go idle after each turn; do not treat idle notifications as errors
- Deduplication vs. arbitration vs. historical check — syntactic duplicates collapse in Step 3c; semantic conflicts between reviewers (different edits on same
file:line) route to Step 3d; conflicts with prior intent route to Step 3.5
- Preserve behavior — fixes must leave the existing test suite green; if a test fails after a fix, reject that fix
- Be surgical — only modify code that was part of the original diff, do not refactor unrelated code