/qa-gate - Quality Gate Decision
Description
Generate a quality gate decision with persistent YAML output. Runs automated checks and optional specialist reviews, then produces a gate file that can be tracked and referenced.
Key Features:
-
Persistent YAML gate files for traceability
-
Standardized severity scale (low, medium, high)
-
Issue ID prefixes for categorization (SEC-, PERF-, TEST-, etc.)
-
WAIVED status with approval tracking
-
Updates story file with gate reference
-
NFR validation (security, performance, reliability, accessibility)
Usage
Quick gate for a story (tests, types, lint only)
/qa-gate 3.1.5
Full gate with specialist reviews
/qa-gate 3.1.5 --deep
Gate for current branch (no story reference)
/qa-gate --branch
Gate with specific specialists
/qa-gate 3.1.5 --security --performance
Waive known issues
/qa-gate 3.1.5 --waive --reason "Accepted for MVP" --approved-by "Product Owner"
Quick check without persisting file
/qa-gate 3.1.5 --dry-run
Parameters
-
story - Story number (e.g., 3.1.5 ) or omit for branch-based review
-
--deep - Run all specialist reviews (security, performance, accessibility)
-
--security - Run security specialist review
-
--performance - Run performance specialist review
-
--accessibility - Run accessibility specialist review
-
--branch - Review current branch without story reference
-
--waive - Mark gate as WAIVED (requires --reason and --approved-by)
-
--reason - Reason for waiver
-
--approved-by - Who approved the waiver
-
--dry-run - Run checks but don't persist gate file
EXECUTION INSTRUCTIONS
Phase 1: Parse Arguments & Locate Files
- Parse story number or --branch flag
- If story provided:
- Find story file: docs/stories/{STORY_NUM}.*.md
- Extract story title and slug
- Determine gate file path: docs/qa/gates/{STORY_NUM}-{slug}.yml
- Check if gate file already exists (for history tracking)
Phase 2: Run Required Checks
Always run these checks first:
Run in parallel for speed
pnpm test --filter='...[origin/main]' pnpm check-types --filter='...[origin/main]' pnpm lint --filter='...[origin/main]'
Collect results:
checks: tests: { status: PASS|FAIL, details: "X tests passed" } types: { status: PASS|FAIL, details: "No type errors" } lint: { status: PASS|FAIL, details: "No lint errors" }
Phase 3: Specialist Reviews (if --deep or specific flags)
Use haiku model for fast, focused reviews:
Security Review (if --deep or --security)
Task( subagent_type: "general-purpose", model: "haiku", description: "Security review", prompt: "You are a security specialist. Review the code changes.
Check for:
- Authentication/authorization issues
- Injection vulnerabilities (SQL, XSS, command)
- Sensitive data exposure
- OWASP Top 10 issues
- Hardcoded secrets or credentials
For each finding, provide:
- id: SEC-{NNN}
- severity: low|medium|high
- finding: Brief description
- suggested_action: How to fix
- file: File path
- line: Line number (if applicable)
Return findings as YAML array."
)
Performance Review (if --deep or --performance)
Task( subagent_type: "general-purpose", model: "haiku", description: "Performance review", prompt: "You are a performance specialist. Review the code changes.
Check for:
- N+1 query patterns
- Missing database indexes
- Unnecessary re-renders in React
- Large bundle imports
- Missing memoization
- Inefficient algorithms
For each finding, provide:
- id: PERF-{NNN}
- severity: low|medium|high
- finding: Brief description
- suggested_action: How to fix
- file: File path
Return findings as YAML array."
)
Accessibility Review (if --deep or --accessibility)
Task( subagent_type: "general-purpose", model: "haiku", description: "Accessibility review", prompt: "You are an accessibility specialist. Review the code changes.
Check for:
- WCAG 2.1 AA compliance
- Keyboard navigation support
- Screen reader compatibility
- Missing ARIA labels/roles
- Color contrast issues
- Focus management
For each finding, provide:
- id: A11Y-{NNN}
- severity: low|medium|high
- finding: Brief description with WCAG criterion
- suggested_action: How to fix
- file: File path
Return findings as YAML array."
)
Phase 4: Determine Gate Decision
Decision logic:
IF --waive flag provided: gate = WAIVED ELSE IF any check FAILED OR any high severity issue: gate = FAIL ELSE IF any medium severity issue: gate = CONCERNS ELSE: gate = PASS
Status reason (1-2 sentences):
-
PASS: "All checks passed with no significant issues."
-
CONCERNS: "Non-blocking issues found that should be addressed."
-
FAIL: "{reason for failure - e.g., 'Tests failing' or 'High severity security issue'}"
-
WAIVED: "{user-provided reason}"
Phase 5: Generate Gate File
Write YAML to docs/qa/gates/{STORY_NUM}-{slug}.yml :
schema: 1 story: "{STORY_NUM}" story_title: "{STORY_TITLE}" gate: PASS|CONCERNS|FAIL|WAIVED status_reason: "{1-2 sentence explanation}" reviewer: "Claude Code" updated: "{ISO-8601 timestamp}"
Waiver (only active if WAIVED)
waiver: active: false # or true if WAIVED reason: "" # populated if WAIVED approved_by: "" # populated if WAIVED
All issues found
top_issues: []
Example:
- id: "SEC-001"
severity: high
finding: "No rate limiting on login endpoint"
suggested_action: "Add rate limiting middleware"
file: "src/api/auth/login.ts"
NFR validation summary
nfr_validation: security: { status: PASS|CONCERNS|FAIL|SKIPPED, issue_count: 0 } performance: { status: PASS|CONCERNS|FAIL|SKIPPED, issue_count: 0 } accessibility: { status: PASS|CONCERNS|FAIL|SKIPPED, issue_count: 0 } tests: { status: PASS|FAIL, details: "" } types: { status: PASS|FAIL, details: "" } lint: { status: PASS|FAIL, details: "" }
Risk summary
risk_summary: totals: { high: 0, medium: 0, low: 0 } recommendations: must_fix: [] # high severity items should_fix: [] # medium severity items
Phase 6: Update Story File (if story provided)
Append to story's QA Results section:
QA Results
Gate Status
Gate: {STATUS} → docs/qa/gates/{STORY_NUM}-{slug}.yml Updated: {ISO-8601 timestamp} Reviewer: Claude Code
{If issues found:} Top Issues:
- [{ID}] {severity}: {finding}
Phase 7: Report Summary
═══════════════════════════════════════════════════════ Quality Gate: {STORY_NUM} - {STORY_TITLE} ═══════════════════════════════════════════════════════
Gate: {PASS|CONCERNS|FAIL|WAIVED} Reason: {status_reason}
Checks: Tests: {PASS|FAIL} Types: {PASS|FAIL} Lint: {PASS|FAIL}
{If specialist reviews run:} NFR Validation: Security: {STATUS} ({N} issues) Performance: {STATUS} ({N} issues) Accessibility: {STATUS} ({N} issues)
{If issues found:} Top Issues ({N} total): [{ID}] {severity}: {finding} ...
Gate File: docs/qa/gates/{STORY_NUM}-{slug}.yml
{If FAIL:} Recommendation: Address high-severity issues before proceeding.
{If CONCERNS:} Recommendation: Review issues and proceed with awareness.
{If WAIVED:} Waiver: {reason} Approved By: {approved_by} ═══════════════════════════════════════════════════════
Issue ID Prefixes
Prefix Category
SEC- Security issues
PERF- Performance issues
A11Y- Accessibility issues
TEST- Testing gaps
REL- Reliability issues
MNT- Maintainability concerns
ARCH- Architecture issues
DOC- Documentation gaps
REQ- Requirements issues
Severity Scale
Fixed values - no variations:
Severity Description Action
high
Critical issues, should block Must fix before release
medium
Should fix soon, not blocking Schedule for soon
low
Minor issues, cosmetic Fix when convenient
Gate Statuses
Status Meaning When to Use
PASS
All good No issues or only low severity
CONCERNS
Proceed with awareness Medium severity issues present
FAIL
Should not proceed High severity issues or check failures
WAIVED
Accepted despite issues Explicitly approved to proceed
Sub-Agent Architecture
Main Orchestrator (/qa-gate) │ ├─▶ Required Checks (inline) │ ├── pnpm test │ ├── pnpm check-types │ └── pnpm lint │ └─▶ Specialist Reviews (parallel, haiku) ├── Security specialist ├── Performance specialist └── Accessibility specialist
Integration with /implement
The /implement skill calls /qa-gate for its QA phase:
/implement 3.1.5 │ ├─▶ ... implementation phases ... │ └─▶ /qa-gate 3.1.5 --deep └── Produces gate file and updates story
Examples
Quick Gate (tests only)
/qa-gate 3.1.5
Runs: tests, types, lint
Output: docs/qa/gates/3.1.5-my-story.yml
Deep Gate (all specialists)
/qa-gate 3.1.5 --deep
Runs: tests, types, lint + security, performance, accessibility
Output: docs/qa/gates/3.1.5-my-story.yml
Waive Known Issues
/qa-gate 3.1.5 --waive --reason "MVP release, will fix in v2" --approved-by "Tech Lead"
Sets gate to WAIVED with approval tracking
Branch Review (no story)
/qa-gate --branch --deep