Use after hyperpowers:executing-plans completes all tasks - verifies implementation against bd spec, all success criteria met, anti-patterns avoided
/plugin marketplace add withzombies/hyperpowers/plugin install withzombies-hyper@withzombies-hyperThis skill inherits all available tools. When active, it can use any tool Claude has access to.
<skill_overview> Review completed implementation against bd epic to catch gaps before claiming completion; spec is contract, implementation must fulfill contract completely. </skill_overview>
<rigidity_level> LOW FREEDOM - Follow the 4-step review process exactly. Review with Google Fellow-level scrutiny. Never skip automated checks, quality gates, or code reading. No approval without evidence for every criterion. </rigidity_level>
<quick_reference>
| Step | Action | Deliverable |
|---|---|---|
| 1 | Load bd epic + all tasks | TodoWrite with tasks to review |
| 2 | Review each task (automated checks, quality gates, read code, audit tests, verify criteria) | Findings per task |
| 3 | Report findings (approved / gaps found) | Review decision |
| 4 | Gate: If approved → finishing-a-development-branch, If gaps → STOP | Next action |
Review Perspective: Google Fellow-level SRE with 20+ years experience reviewing junior engineer code.
Test Quality Gate: Every new test must catch a real bug. Tautological tests (pass by definition, test mocks, verify compiler-checked facts) = GAPS FOUND. </quick_reference>
<when_to_use>
Don't use for:
<the_process>
Announce: "I'm using hyperpowers:review-implementation to verify implementation matches spec. Reviewing with Google Fellow-level scrutiny."
Get epic and tasks:
bd show bd-1 # Epic specification
bd dep tree bd-1 # Task tree
bd list --parent bd-1 # All tasks
Create TodoWrite tracker:
TodoWrite todos:
- Review bd-2: Task Name
- Review bd-3: Task Name
- Review bd-4: Task Name
- Compile findings and make decision
For each task:
bd show bd-3
Extract:
# TODOs/FIXMEs without issue numbers
rg -i "todo|fixme" src/ tests/ || echo "✅ None"
# Stub implementations
rg "unimplemented!|todo!|unreachable!|panic!\(\"not implemented" src/ || echo "✅ None"
# Unsafe patterns in production
rg "\.unwrap\(\)|\.expect\(" src/ | grep -v "/tests/" || echo "✅ None"
# Ignored/skipped tests
rg "#\[ignore\]|#\[skip\]|\.skip\(\)" tests/ src/ || echo "✅ None"
IMPORTANT: Use hyperpowers:test-runner agent to avoid context pollution.
Dispatch hyperpowers:test-runner: "Run: cargo test"
Dispatch hyperpowers:test-runner: "Run: cargo fmt --check"
Dispatch hyperpowers:test-runner: "Run: cargo clippy -- -D warnings"
Dispatch hyperpowers:test-runner: "Run: .git/hooks/pre-commit"
CRITICAL: READ actual files, not just git diff.
# See changes
git diff main...HEAD -- src/auth/jwt.ts
# THEN READ FULL FILE
Read tool: src/auth/jwt.ts
While reading, check:
Assume code written by junior engineer. Apply production-grade scrutiny.
Error Handling:
Safety:
Clarity:
Testing (CRITICAL - Apply strict scrutiny):
Production Readiness:
CRITICAL: Review every new/modified test for meaningfulness. Tautological tests are WORSE than no tests - they give false confidence.
For each test, ask:
expect(result != nil) is weaker than expect(result == expectedValue)Red flags (REJECT implementation until fixed):
expect(builder.build() != nil) when build() can't return nil)Examples of meaningless tests to reject:
// ❌ REJECT: Tautological - compiler ensures enum has cases
func testEnumHasCases() {
_ = MyEnum.caseOne // This proves nothing
_ = MyEnum.caseTwo
}
// ❌ REJECT: Tautological - build() returns non-optional, can't be nil
func testBuilderReturnsValue() {
let result = Builder().build()
#expect(result != nil) // Always passes by type system
}
// ❌ REJECT: Tests mock, not production code
func testServiceCallsAPI() {
let mock = MockAPI()
let service = Service(api: mock)
service.fetchData()
#expect(mock.fetchCalled) // Tests mock behavior, not real logic
}
// ❌ REJECT: Happy path only, no edge cases
func testCodable() {
let original = User(name: "John", age: 30)
let data = try! encoder.encode(original)
let decoded = try! decoder.decode(User.self, from: data)
#expect(decoded == original) // What about empty name? Max age? Unicode?
}
Examples of meaningful tests to approve:
// ✅ APPROVE: Catches missing validation bug
func testEmptyPayloadReturnsValidationError() {
let result = validator.validate(payload: "")
#expect(result == .error(.emptyPayload))
}
// ✅ APPROVE: Catches race condition bug
func testConcurrentWritesDontCorruptData() {
let store = ThreadSafeStore()
DispatchQueue.concurrentPerform(iterations: 1000) { i in
store.write(key: "k\(i)", value: i)
}
#expect(store.count == 1000) // Would fail if race condition exists
}
// ✅ APPROVE: Catches error handling bug
func testMalformedJSONReturns400Not500() {
let response = api.parse(json: "{invalid")
#expect(response.status == 400) // Not 500 which would indicate unhandled exception
}
// ✅ APPROVE: Catches encoding bug with edge case
func testUnicodeNamePreservedAfterRoundtrip() {
let original = User(name: "日本語テスト 🎉")
let decoded = roundtrip(original)
#expect(decoded.name == original.name)
}
Audit process:
# Find all new/modified test files
git diff main...HEAD --name-only | grep -E "(test|spec)"
# Read each test file
Read tool: tests/new_feature_test.swift
# For EACH test function, document:
# - Test name
# - What bug it catches (or "TAUTOLOGICAL" if none)
# - Verdict: ✅ Keep / ⚠️ Strengthen / ❌ Remove/Replace
If tautological tests found:
## Test Quality Audit: GAPS FOUND ❌
### Tautological/Meaningless Tests
| Test | Problem | Action |
|------|---------|--------|
| testEnumHasCases | Compiler already ensures this | ❌ Remove |
| testBuilderReturns | Non-optional return, can't be nil | ❌ Remove |
| testCodable | Happy path only, no edge cases | ⚠️ Add: empty, unicode, max values |
| testServiceCalls | Tests mock, not production | ❌ Replace with integration test |
**Cannot approve until tests are meaningful.**
For EACH criterion in bd task:
Example:
Criterion: "All tests passing"
Command: cargo test
Evidence: "127 tests passed, 0 failures"
Result: ✅ Met
Criterion: "No unwrap in production"
Command: rg "\.unwrap\(\)" src/
Evidence: "No matches"
Result: ✅ Met
Search for each prohibited pattern from bd task:
# Example anti-patterns from task
rg "\.unwrap\(\)" src/ # If task prohibits unwrap
rg "TODO" src/ # If task prohibits untracked TODOs
rg "\.skip\(\)" tests/ # If task prohibits skipped tests
Read code to confirm edge cases handled:
Example: Task says "Must handle empty payload" → Find validation code for empty payload.
### Task: bd-3 - Implement JWT authentication
#### Automated Checks
- TODOs: ✅ None
- Stubs: ✅ None
- Unsafe patterns: ❌ Found `.unwrap()` at src/auth/jwt.ts:45
- Ignored tests: ✅ None
#### Quality Gates
- Tests: ✅ Pass (127 tests)
- Formatting: ✅ Pass
- Linting: ❌ 3 warnings
- Pre-commit: ❌ Fails due to linting
#### Files Reviewed
- src/auth/jwt.ts: ⚠️ Contains `.unwrap()` at line 45
- tests/auth/jwt_test.rs: ✅ Complete
#### Code Quality
- Error Handling: ⚠️ Uses unwrap instead of proper error propagation
- Safety: ✅ Good
- Clarity: ✅ Good
- Testing: See Test Quality Audit below
#### Test Quality Audit (New/Modified Tests)
| Test | Bug It Catches | Verdict |
|------|----------------|---------|
| test_valid_token_accepted | Missing validation | ✅ Keep |
| test_expired_token_rejected | Expiration bypass | ✅ Keep |
| test_jwt_struct_exists | Nothing (tautological) | ❌ Remove |
| test_encode_decode | Encoding bug (but happy path only) | ⚠️ Add edge cases |
**Tautological tests found:** 1 (test_jwt_struct_exists)
**Weak tests found:** 1 (test_encode_decode needs edge cases)
#### Success Criteria
1. "All tests pass": ✅ Met - Evidence: 127 tests passed
2. "Pre-commit passes": ❌ Not met - Evidence: clippy warnings
3. "No unwrap in production": ❌ Not met - Evidence: Found at jwt.ts:45
#### Anti-Patterns
- "NO unwrap in production": ❌ Violated at src/auth/jwt.ts:45
#### Issues
**Critical:**
1. unwrap() at jwt.ts:45 - violates anti-pattern, must use proper error handling
2. Tautological test: test_jwt_struct_exists must be removed
**Important:**
3. 3 clippy warnings block pre-commit hook
4. test_encode_decode needs edge cases (empty, unicode, max length)
After reviewing ALL tasks:
If NO gaps:
## Implementation Review: APPROVED ✅
Reviewed bd-1 (OAuth Authentication) against implementation.
### Tasks Reviewed
- bd-2: Configure OAuth provider ✅
- bd-3: Implement token exchange ✅
- bd-4: Add refresh logic ✅
### Verification Summary
- All success criteria verified
- No anti-patterns detected
- All key considerations addressed
- All files implemented per spec
### Evidence
- Tests: 127 passed, 0 failures (2.3s)
- Linting: No warnings
- Pre-commit: Pass
- Code review: Production-ready
Ready to proceed to hyperpowers:finishing-a-development-branch.
If gaps found:
## Implementation Review: GAPS FOUND ❌
Reviewed bd-1 (OAuth Authentication) against implementation.
### Tasks with Gaps
#### bd-3: Implement token exchange
**Gaps:**
- ❌ Success criterion not met: "Pre-commit hooks pass"
- Evidence: cargo clippy shows 3 warnings
- ❌ Anti-pattern violation: Found `.unwrap()` at src/auth/jwt.ts:45
- ⚠️ Key consideration not addressed: "Empty payload validation"
- No check for empty payload in generateToken()
#### bd-4: Add refresh logic
**Gaps:**
- ❌ Success criterion not met: "All tests passing"
- Evidence: test_verify_expired_token failing
### Cannot Proceed
Implementation does not match spec. Fix gaps before completing.
If APPROVED:
Announce: "I'm using hyperpowers:finishing-a-development-branch to complete this work."
Use Skill tool: hyperpowers:finishing-a-development-branch
If GAPS FOUND:
STOP. Do not proceed to finishing-a-development-branch.
Fix gaps or discuss with partner.
Re-run review after fixes.
</the_process>
<examples> <example> <scenario>Developer only checks git diff, doesn't read actual files</scenario> <code> # Review process git diff main...HEAD # Shows changes"Looks good, token generation implemented ✅"
function generateToken(payload) { // No validation of payload! // No check for empty payload (key consideration) // No error handling if jwt.sign fails return jwt.sign(payload, secret); } </code>
<why_it_fails>
# See changes
git diff main...HEAD -- src/auth/jwt.ts
# THEN READ FULL FILE
Read tool: src/auth/jwt.ts
Reading full file reveals:
function generateToken(payload) {
// Missing: empty payload check (key consideration from bd task)
// Missing: error handling for jwt.sign failure
return jwt.sign(payload, secret);
}
Record in findings:
⚠️ Key consideration not addressed: "Empty payload validation"
- No check for empty payload in generateToken()
- Code at src/auth/jwt.ts:15-17
⚠️ Error handling: jwt.sign can throw, not handled
What you gain:
"Tests pass, implementation complete ✅"
<why_it_fails>
bd task has 5 success criteria:
1. "All tests pass" ✅ - Evidence: 127 passed
2. "Pre-commit passes" ❌ - Evidence: clippy warns (3 warnings)
3. "No unwrap in production" ❌ - Evidence: Found at jwt.ts:45
4. "Unicode handling tested" ⚠️ - Need to verify test exists
5. "Rate limiting implemented" ⚠️ - Need to check code
Result: 1/5 criteria verified met. GAPS EXIST.
Run additional checks:
# Check criterion 2
cargo clippy
# 3 warnings found ❌
# Check criterion 3
rg "\.unwrap\(\)" src/
# src/auth/jwt.ts:45 ❌
# Check criterion 4
rg "unicode" tests/
# No matches ⚠️ Need to verify
Decision: GAPS FOUND, cannot proceed
What you gain:
"Logging added ✅"
<why_it_fails>
# Automated checks
rg "console\.log" src/
# Found at error-handler.ts:12, 15 ⚠️
# Read bd task
bd show bd-5
# Success criteria:
# 1. "All error paths logged"
# 2. "No sensitive data in logs"
# 3. "Test verifies log output"
# Check criterion 1
grep -n "throw new Error" src/
# 5 locations found
# Only 2 have logging ❌ Incomplete
# Check criterion 2
Read tool: src/error-handler.ts
# Logs contain password field ❌ Security issue
# Check criterion 3
rg "test.*log" tests/
# No matches ❌ Test missing
Decision: GAPS FOUND
What you gain:
"Tests pass with 92% coverage, implementation complete ✅"
<why_it_fails>
expect(validator != nil) - always passes, doesn't test validation logicexpect(lock.acquire()) - tests mock, not thread safetyexpect(encoded.count > 0) - tests non-empty, not correctness# Find new tests
git diff main...HEAD --name-only | grep test
# Read and audit each test
Read tool: tests/validator_test.swift
For each test, document:
#### Test Quality Audit
| Test | Assertion | Bug Caught? | Verdict |
|------|-----------|-------------|---------|
| testValidatorExists | `!= nil` | ❌ None (compiler checks) | ❌ Remove |
| testValidInput | `isValid == true` | ⚠️ Happy path only | ⚠️ Add edge cases |
| testEmptyInputFails | `isValid == false` | ✅ Missing validation | ✅ Keep |
| testLockAcquired | mock.acquireCalled | ❌ Tests mock | ❌ Replace |
| testConcurrentAccess | count == expected | ✅ Race condition | ✅ Keep |
| testEncodeNotNil | `!= nil` | ❌ Type guarantees this | ❌ Remove |
| testUnicodeRoundtrip | decoded == original | ✅ Encoding corruption | ✅ Keep |
**Tautological tests:** 3 (must remove)
**Weak tests:** 1 (must strengthen)
**Meaningful tests:** 3 (keep)
Decision: GAPS FOUND ❌
## Test Quality Audit: GAPS FOUND
### Tautological Tests (Must Remove)
- testValidatorExists: Compiler ensures non-nil, test proves nothing
- testLockAcquired: Tests mock behavior, not actual thread safety
- testEncodeNotNil: Return type is non-optional, can never be nil
### Weak Tests (Must Strengthen)
- testValidInput: Only happy path, add:
- testEmptyStringRejected
- testMaxLengthRejected
- testUnicodeNormalized
### Action Required
Remove 3 tautological tests, add 3 edge case tests, then re-review.
What you gain:
<critical_rules>
All of these mean: STOP. Follow full review process.
</critical_rules>
<verification_checklist> Before approving implementation:
Per task:
Overall:
Can't check all boxes? Return to Step 2 and complete review. </verification_checklist>
<integration> **This skill is called by:** - hyperpowers:executing-plans (Step 5, after all tasks executed)This skill calls:
This skill uses:
Call chain:
hyperpowers:executing-plans → hyperpowers:review-implementation → hyperpowers:finishing-a-development-branch
↓
(if gaps: STOP)
CRITICAL: Use bd commands (bd show, bd list, bd dep tree), never read .beads/issues.jsonl directly.
</integration>
When stuck:
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.