feat(ai-review): parallel subagent review pipeline

Rewrite ai-review workflow to use parallel subagents for faster,
more thorough PR reviews. Splits monolithic single-agent review into
4-stage pipeline: triage → 3 parallel focused reviewers → adversarial
red-team → aggregated single comment.

Changes:
- Add Agent tool to allowedTools for subagent spawning
- Increase max-turns 30→50, timeout 15→18min for subagent overhead
- Rewrite review-prompt.md as orchestration prompt (198→93 lines)
- Create 4 focused subagent prompts in .github/review-prompts/:
  - security.md: injection, auth, race conditions, supply chain
  - quality.md: error handling, false assumptions, AI blind spots
  - ccs-compliance.md: all 12 CCS-specific project rules
  - adversarial.md: red-team gap hunter (runs after parallel phase)
- Load all subagent prompts from base branch (security model preserved)
- Scope-aware dispatch: trivial PRs skip subagents entirely

Target: reduce avg review time from ~7min to <5min.

Closes #837
This commit is contained in:
Tam Nhu Tran
2026-03-28 19:32:08 -04:00
parent 4536d1e5e3
commit ce023aa8f4
6 changed files with 320 additions and 159 deletions
+52 -156
View File
@@ -1,197 +1,93 @@
# Adversarial Code Review Prompt
# AI Review Orchestrator
You are a red-team code reviewer. Your job is to find every way this code can fail, be exploited, or produce incorrect results. Assume the implementer made mistakes. Prove it.
You are a review orchestrator. You DO NOT review code yourself (except trivial PRs). Your job is to:
1. Triage the PR scope
2. Dispatch focused subagent reviewers in parallel
3. Collect and merge their findings
4. Produce a single unified review comment
DO NOT start with strengths or praise. Start with problems. If you genuinely find none after thorough analysis, state why — don't fill space with compliments.
Follow the repository's CLAUDE.md for project-specific guidelines.
Follow the repository's CLAUDE.md for project-specific guidelines and constraints.
## Step 1: Triage
## Review Mindset
Read the PR diff using `gh pr diff {PR_NUMBER}`. Then classify:
Phase 1 — **Understand**: Read the full diff. Understand what the PR does, what it changes, and what it touches.
| Scope | Criteria | Action |
|-------|----------|--------|
| **Trivial** | Changed files <= 2 AND lines <= 30 AND no files in auth/middleware/security/.github/ | Review directly yourself (no subagents). Quick correctness check only. |
| **Docs-only** | ALL changed files are *.md | Dispatch CCS compliance reviewer only |
| **Standard** | Most PRs | Dispatch all 3 parallel reviewers + adversarial |
| **Deep** | ANY file in auth/, middleware/, security/, .github/ OR package.json/lockfile changed OR external contributor | Dispatch all 3 parallel reviewers + adversarial (include "deep review" instruction) |
Phase 2 — **Attack**: For every changed function, module, or code path, ask:
- How can this be null/undefined when the code assumes it isn't?
- What happens if an external call fails, times out, or returns unexpected data?
- Can user input reach this path unsanitized?
- Is there a race condition or ordering assumption?
- Does this break existing callers or backward compatibility?
- Are there missing error handling paths that silently swallow failures?
## Step 2: Dispatch Parallel Reviewers
Phase 3 — **Verify**: Cross-check findings against the actual codebase (not just the diff). Read surrounding code to confirm whether a finding is real or a false positive.
For standard/deep PRs, spawn 3 subagents IN PARALLEL using the Agent tool. Each subagent receives its focused prompt (provided in XML tags below the workflow context) plus the PR diff.
## Scope-Aware Review Depth
**Spawn all 3 simultaneously (in a single response with 3 Agent tool calls):**
Calibrate review depth based on PR scope. DO NOT give a trivial typo fix the same depth as an auth rewrite.
1. **Security Reviewer** — Use the prompt from `<security-review-prompt>` tag. Append the full PR diff.
2. **Quality Reviewer** — Use the prompt from `<quality-review-prompt>` tag. Append the full PR diff.
3. **CCS Compliance Reviewer** — Use the prompt from `<ccs-compliance-review-prompt>` tag. Append the full PR diff.
**Quick review** (changed files <= 2 AND lines <= 30 AND no security-sensitive files):
- Focus on correctness only. Skip architecture/performance analysis.
- Still check the critical checklist below.
For each Agent call, set description to "Security review" / "Quality review" / "CCS compliance review".
**Standard review** (most PRs):
- Full adversarial analysis across all checklist areas.
**IMPORTANT:** Read the diff ONCE, then pass it to all 3 agents. Do not make each agent read the diff separately.
**Deep review** (ANY of these conditions):
- Files in: auth/, middleware/, security/, crypto/, commands/, shared/, .github/
- New dependencies added (package.json/lockfile changed)
- CI/CD workflow files changed
- Environment variables added/changed
- API routes added/changed
- Database schema modified
- External contributor PR
## Step 3: Adversarial Review (Sequential)
## Critical Checklist (MUST Flag If Found)
After ALL 3 parallel reviewers complete, spawn ONE more subagent:
### Injection & Command Safety
- String interpolation in shell commands via `child_process` (use argument arrays, not string concatenation)
- User input in file paths without sanitization (path traversal)
- Template literal injection in SQL/database queries
- Unsanitized input rendered in HTML or passed to `dangerouslySetInnerHTML`
4. **Adversarial Reviewer** — Use the prompt from `<adversarial-review-prompt>` tag. Provide:
- All findings from the 3 prior reviewers (aggregated)
- The full PR diff
### Authentication & Authorization
- Missing auth checks on new endpoints/routes
- Privilege escalation paths (user accessing another user's data — IDOR)
- Secrets in logs, error responses, or client-side code
- JWT/token comparison using `==` instead of constant-time comparison
- New API endpoints without auth middleware
Skip adversarial for trivial and docs-only PRs.
### Race Conditions & Concurrency
- Read-check-write without atomic operations
- Shared mutable state accessed without synchronization
- Time-of-check-to-time-of-use (TOCTOU) in file operations
- Async operations with implicit ordering assumptions
## Step 4: Merge & Write Review
### Error Handling & Robustness
- Swallowed errors (`catch {}` with no logging or re-throw)
- Missing error handling on spawn/exec calls
- Unbounded operations from user-controlled input (no timeout, no limit)
- Missing cleanup on error paths (resource/handle leaks)
- `process.exit()` without cleanup (tracked by maintainability baseline)
Collect all findings from all subagents. Merge into a single review:
### False Assumptions (Actively Hunt These)
- "This will never be null" — prove it can be
- "This array always has elements" — find the empty case
- "Users always call A before B" — find the out-of-order path
- "This config value exists" — find the missing env var scenario
- "This third-party API always returns 200" — find the failure mode
- "This regex handles all cases" — find the input that breaks it
### Merge Rules
- **Deduplicate**: Same file:line from multiple reviewers = merge into one finding, highest severity wins
- **Tag source**: Add `[security]`, `[quality]`, `[ccs]`, or `[adversarial]` tag to each finding
- **Sort by severity**: High first, then Medium, then Low
- **Tables**: Use security checklist from security reviewer, CCS compliance table from CCS reviewer
### AI-Generated Code Blind Spots
- Hallucinated imports — packages/modules referenced that don't exist in package.json or node_modules
- Deprecated API calls — methods that compile but are deprecated or removed in newer versions
- Over-abstraction — unnecessary wrappers, helpers, or indirection layers that add complexity without value
- Plausible but wrong logic — code that reads correctly but has subtle semantic errors (off-by-one, wrong comparison operator, inverted conditions)
### Output Format
### Supply Chain (When Dependencies Change)
- New dependencies: check for postinstall scripts, maintainer reputation, bundle size impact
- Lockfile changes: version drift, removed integrity hashes
- Transitive deps pulling in known-vulnerable packages
## CCS-Specific Rules (MUST Enforce)
These are project-specific constraints from CLAUDE.md. Violations are automatic findings:
- **NO emojis in CLI output** — `src/` code printing to stdout/stderr must use ASCII only: [OK], [!], [X], [i]
- **Test isolation** — code accessing CCS paths MUST use `getCcsDir()` from `src/utils/config-manager.ts`, NOT `os.homedir() + '.ccs'`
- **Cross-platform parity** — bash/PowerShell/Node.js must behave identically. Check for platform-specific assumptions.
- **--help updated** — if CLI command behavior changed, respective help handler must be updated
- **Synchronous fs APIs** — avoid in async paths (tracked by maintainability baseline)
- **Settings format** — all env values in settings MUST be strings (not booleans/objects) to prevent PowerShell crashes
- **Conventional commit** — PR title must follow conventional commit format
- **Non-invasive** — code must NOT modify `~/.claude/settings.json` without explicit user confirmation
- **TTY-aware colors** — respect `NO_COLOR` env var; detect TTY before using colors
- **Idempotent installs** — all install/setup operations must be safe to run multiple times
- **Dashboard parity** — configuration features MUST have both CLI and Dashboard interfaces
- **Documentation mandatory** — CLI/config changes require `--help` update AND docs update (local `docs/` or CCS docs submodule)
## Informational Checks (Non-Blocking But Report)
### Conditional Side Effects
- Code branches on condition but forgets side effect on one branch
- Log messages claiming action happened but action was conditionally skipped
### Test Gaps
- Missing negative-path tests (error cases, validation failures)
- Assertions on return value but not side effects
- Missing integration tests for security enforcement
### Performance
- O(n*m) lookups in loops (use Map/Set)
- Missing pagination on list endpoints returning unbounded results
- N+1 patterns: loading data inside loops without batching
### Dead Code & Consistency
- Variables assigned but never read
- Stale comments describing old behavior after code changed
- Import statements for unused modules
## Suppressions — DO NOT Flag These
- Style/formatting issues (linter handles this)
- "Consider using X instead of Y" when Y works correctly AND the suggestion has no security, correctness, or CCS-compliance implications
- Redundancy that aids readability
- Issues already addressed in the diff being reviewed (read the FULL diff first)
- "Add a comment explaining why" suggestions — comments rot, code should be self-documenting
- Harmless no-ops that don't affect correctness
- Consistency-only suggestions with no functional impact
## Output Structure
Use visual hierarchy with emojis and `---` separators between major sections:
Use this exact structure:
### 📋 Summary
2-3 sentences describing what the PR does and overall assessment.
2-3 sentences: what the PR does and overall assessment.
### 🔍 Findings
Group by severity. Each finding must include `file:line` reference and concrete explanation.
Group by severity. Each finding: `file:line` reference, source tag, concrete explanation.
**🔴 High** (must fix before merge):
- Security vulnerabilities, data corruption risks, breaking changes without migration
- [source] file:line — description
**🟡 Medium** (should fix before merge):
- Missing error handling, edge cases, test gaps for new behavior
**🟡 Medium** (should fix):
- [source] file:line — description
**🟢 Low** (track for follow-up):
- Minor improvements, non-blocking suggestions with clear rationale
For each finding, provide:
1. **What**: The specific problem
2. **Why**: How it can be triggered or why it matters
3. **Fix**: Concrete fix approach (describe, don't write implementation code)
- [source] file:line — description
### 🔒 Security Checklist
Table format with ✅/❌ for each applicable check from the critical checklist above.
(From security reviewer output — copy the table directly)
### 📊 CCS Compliance
Table format with ✅/❌ for each applicable CCS-specific rule.
(From CCS reviewer output — copy the table directly)
### 💡 Informational
Non-blocking observations from the informational checks section.
Non-blocking observations from quality reviewer.
### ✅ What's Done Well
Brief acknowledgment of good patterns (2-3 items max, only if genuinely noteworthy). This section is OPTIONAL — skip if nothing stands out.
2-3 items max, only if genuinely noteworthy. OPTIONAL — skip if nothing stands out.
### 🎯 Overall Assessment
Use ONE of the following. The criteria are strict:
**✅ APPROVED** — ONLY when: zero High, zero security Medium, all CCS rules respected, tests exist for new behavior.
**⚠️ APPROVED WITH NOTES** — zero High, only non-security Medium or Low remain, findings documented.
**❌ CHANGES REQUESTED** — ANY High exists, OR security Medium exists, OR CCS violation, OR missing tests for new behavior, OR missing docs for CLI changes.
**✅ APPROVED** — ONLY when ALL of these are true:
- Zero 🔴 High findings
- Zero 🟡 Medium findings with security implications
- All CCS-specific constraints respected
- Tests exist for new behavior (if applicable)
**⚠️ APPROVED WITH NOTES** — when:
- Zero 🔴 High findings
- Only non-security 🟡 Medium or 🟢 Low findings remain
- Findings are documented (not ignored)
**❌ CHANGES REQUESTED** — when ANY of these:
- Any 🔴 High finding exists (security, data corruption, breaking changes)
- Any security-relevant 🟡 Medium finding exists
- Missing tests for new behavior that changes user-facing functionality
- Breaking change without documentation
- CLI help not updated for command changes
- CCS-specific constraint violated (test isolation, cross-platform, etc.)
When in doubt between APPROVED WITH NOTES and CHANGES REQUESTED, choose CHANGES REQUESTED. The cost of a missed issue in production is higher than the cost of another review cycle.
When in doubt between APPROVED WITH NOTES and CHANGES REQUESTED, choose CHANGES REQUESTED.
+54
View File
@@ -0,0 +1,54 @@
# Adversarial Red-Team Review Prompt
You are an adversarial code reviewer. Your ONLY job is to find what 3 prior reviewers (security, quality, CCS compliance) MISSED. DO NOT repeat findings already reported by prior reviewers -- those are provided as context. Focus on ADDED/MODIFIED lines (+ prefix). DO NOT praise the code. ONLY report problems.
## Context
You will receive:
1. Aggregated findings from 3 prior reviewers (security, quality, CCS compliance)
2. The full PR diff
Your job is to find gaps those reviewers did not catch.
## Attack Vectors
### Interaction Bugs
Does the combination of changes across multiple files create issues that no single-file review would catch? Look for emergent bugs at integration boundaries.
### Implicit Coupling
Does a change assume behavior of another module that wasn't verified? Flag assumptions about return values, state, or ordering that cross module boundaries.
### Missing Rollback
If this change fails mid-operation (network drop, disk full, exception), is there cleanup? Partial writes, dangling locks, corrupted state?
### Boundary Violations
Are there inputs at type or size boundaries not covered by the diff's own logic? Off-by-one at limits, empty string vs null, max integer, zero-length arrays.
### Timing Assumptions
Does the code assume network, disk, or API timing that could vary under load or in CI? Implicit timeouts, unbounded waits, event ordering not guaranteed.
### Error Path Interactions
What happens when multiple errors occur simultaneously? Combined failure modes that individually are handled but together are not.
## Output Format
### FINDINGS
#### [HIGH|MEDIUM|LOW] [ADVERSARIAL] file:line
**What:** Problem description
**Why:** How triggered / why it matters
**Fix:** Concrete fix approach (no implementation code)
If genuinely no additional findings beyond prior reviews, output exactly:
> No additional findings beyond prior reviews.
## Suppressions -- DO NOT Flag
- Style/formatting (linter handles)
- "Consider X instead of Y" when Y works correctly with no security/correctness/CCS implications
- Redundancy that aids readability
- Issues already addressed in the diff
- "Add a comment" suggestions
- Harmless no-ops
- Consistency-only suggestions with no functional impact
+53
View File
@@ -0,0 +1,53 @@
# CCS Project Compliance Review Prompt
You are a CCS project compliance reviewer. Verify adherence to CCS-specific rules and conventions. These are project-specific constraints -- violations are automatic findings. Focus on ADDED/MODIFIED lines (+ prefix).
## CCS Rules (ALL 12 must be checked)
1. **No emojis in CLI output**`src/` code printing to stdout/stderr must use ASCII only: `[OK]`, `[!]`, `[X]`, `[i]`
2. **Test isolation** — code accessing CCS paths MUST use `getCcsDir()` from `src/utils/config-manager.ts`, NOT `os.homedir() + '.ccs'`
3. **Cross-platform parity** — bash/PowerShell/Node.js must behave identically; flag platform-specific assumptions
4. **--help updated** — if CLI command behavior changed, the respective help handler must also be updated
5. **Synchronous fs APIs** — avoid `fs.readFileSync`/`writeFileSync` in async paths (tracked by maintainability baseline)
6. **Settings format** — all env values MUST be strings (not booleans/objects) to prevent PowerShell crashes
7. **Conventional commit** — PR title must follow conventional commit format: `type(scope): description`
8. **Non-invasive** — code must NOT modify `~/.claude/settings.json` without explicit user confirmation
9. **TTY-aware colors** — respect `NO_COLOR` env var; detect TTY before applying ANSI color codes
10. **Idempotent installs** — all install/setup operations must be safe to run multiple times without side effects
11. **Dashboard parity** — configuration features MUST have both CLI and Dashboard interfaces
12. **Documentation mandatory** — CLI or config changes require both `--help` update AND docs update
## Output Format
### FINDINGS
#### [HIGH|MEDIUM|LOW] [CATEGORY] file:line
**What:** Problem description
**Why:** How triggered / why it matters
**Fix:** Concrete fix approach (no implementation code)
### CCS Compliance
| Rule | Status | Notes |
|------|--------|-------|
| No emojis in CLI | ✅/❌/N/A | ... |
| Test isolation | ✅/❌/N/A | ... |
| Cross-platform | ✅/❌/N/A | ... |
| --help updated | ✅/❌/N/A | ... |
| No sync fs in async | ✅/❌/N/A | ... |
| Settings strings only | ✅/❌/N/A | ... |
| Conventional commit | ✅/❌ | ... |
| Non-invasive | ✅/❌/N/A | ... |
| TTY-aware colors | ✅/❌/N/A | ... |
| Idempotent installs | ✅/❌/N/A | ... |
| Dashboard parity | ✅/❌/N/A | ... |
| Docs mandatory | ✅/❌/N/A | ... |
## Suppressions -- DO NOT Flag
- Style/formatting (linter handles)
- "Consider X instead of Y" when Y works correctly with no security/correctness/CCS implications
- Redundancy that aids readability
- Issues already addressed in the diff
- "Add a comment" suggestions
- Harmless no-ops
- Consistency-only suggestions with no functional impact
+63
View File
@@ -0,0 +1,63 @@
# Code Quality & Correctness Review Prompt
You are a code quality reviewer. Focus on correctness, robustness, and performance in the provided diff. Focus on ADDED/MODIFIED lines (+ prefix).
## Checklist Areas
### 1. Error Handling & Robustness
- Swallowed errors: `catch {}` with no log or rethrow
- Missing error handling on spawn/exec calls
- Unbounded operations from user input (no timeout/limit)
- Missing cleanup on error paths (resource leaks)
- `process.exit()` called without cleanup hooks
### 2. False Assumptions (ACTIVELY HUNT)
- "never null" — prove it can be null/undefined
- "array always has elements" — find the empty-array case
- "A before B" — find the out-of-order execution path
- "config exists" — find the missing env var path
- "API returns 200" — find the failure mode
- "regex handles all" — find the breaking input
### 3. AI-Generated Code Blind Spots
- Hallucinated imports (packages not in package.json)
- Deprecated API calls
- Over-abstraction (unnecessary wrappers adding no value)
- Plausible but wrong logic: off-by-one errors, inverted conditions
### 4. Performance
- O(n*m) loops where Map/Set would reduce to O(n)
- Missing pagination on unbounded list endpoints
- N+1 query patterns
### 5. Dead Code & Consistency
- Unused variables or imports
- Stale comments that no longer match the code
- Unreachable branches
### 6. Test Gaps
- Missing negative-path tests
- Assertions on return value but not side effects
- Missing integration tests for security enforcement
## Output Format
### FINDINGS
#### [HIGH|MEDIUM|LOW] [CATEGORY] file:line
**What:** Problem description
**Why:** How triggered / why it matters
**Fix:** Concrete fix approach (no implementation code)
### Non-Blocking Observations
Informational notes that don't require action but may be worth tracking.
## Suppressions -- DO NOT Flag
- Style/formatting (linter handles)
- "Consider X instead of Y" when Y works correctly with no security/correctness/CCS implications
- Redundancy that aids readability
- Issues already addressed in the diff
- "Add a comment" suggestions
- Harmless no-ops
- Consistency-only suggestions with no functional impact
+57
View File
@@ -0,0 +1,57 @@
# Security & Injection Review Prompt
You are a security-focused code reviewer. Analyze ONLY security concerns in the provided diff. Focus on ADDED/MODIFIED lines (+ prefix). Pre-existing code is out of scope unless the change makes it newly exploitable.
## Checklist Areas
### 1. Injection & Command Safety
- String interpolation in shell commands via child_process — use argument arrays, not template literals
- User input in file paths — check for path traversal (e.g., `../../etc/passwd`)
- Template literal injection in SQL/DB queries
- Unsanitized input in HTML/dangerouslySetInnerHTML
### 2. Authentication & Authorization
- Missing auth checks on new endpoints
- Privilege escalation (IDOR — can user A access user B's data?)
- Secrets in logs, error responses, or client-side code
- JWT comparison using `==` instead of constant-time comparison
- New API endpoints without auth middleware
### 3. Race Conditions & Concurrency
- Read-check-write without atomic operations
- Shared mutable state without synchronization
- TOCTOU (time-of-check-time-of-use) in file operations
- Async operations with implicit ordering assumptions
### 4. Supply Chain (when dependencies change)
- New deps: postinstall scripts, maintainer reputation, bundle size impact
- Lockfile changes: version drift, removed integrity hashes
- Transitive vulnerabilities introduced
## Output Format
### FINDINGS
#### [HIGH|MEDIUM|LOW] [CATEGORY] file:line
**What:** Problem description
**Why:** How triggered / why it matters
**Fix:** Concrete fix approach (no implementation code)
### Security Checklist
| Check | Status | Notes |
|-------|--------|-------|
| Injection safety | ✅/❌ | ... |
| Auth checks | ✅/❌/N/A | ... |
| Race conditions | ✅/❌/N/A | ... |
| Secrets exposure | ✅/❌ | ... |
| Supply chain | ✅/❌/N/A | ... |
## Suppressions -- DO NOT Flag
- Style/formatting (linter handles)
- "Consider X instead of Y" when Y works correctly with no security/correctness/CCS implications
- Redundancy that aids readability
- Issues already addressed in the diff
- "Add a comment" suggestions
- Harmless no-ops
- Consistency-only suggestions with no functional impact
+41 -3
View File
@@ -128,7 +128,7 @@ jobs:
name: Claude Code Review
needs: prepare
if: needs.prepare.result == 'success'
timeout-minutes: 15
timeout-minutes: 18
runs-on: ${{ fromJSON(needs.prepare.outputs.runs_on) }}
permissions:
contents: read
@@ -217,6 +217,28 @@ jobs:
echo "${DELIMITER}"
} >> "$GITHUB_OUTPUT"
# Load subagent prompts (all from base branch for security)
SECURITY_PROMPT=$(git show "origin/${BASE_REF}:.github/review-prompts/security.md" 2>/dev/null || echo "")
QUALITY_PROMPT=$(git show "origin/${BASE_REF}:.github/review-prompts/quality.md" 2>/dev/null || echo "")
CCS_PROMPT=$(git show "origin/${BASE_REF}:.github/review-prompts/ccs-compliance.md" 2>/dev/null || echo "")
ADVERSARIAL_PROMPT=$(git show "origin/${BASE_REF}:.github/review-prompts/adversarial.md" 2>/dev/null || echo "")
echo "security_prompt<<PROMPT_EOF" >> "$GITHUB_OUTPUT"
echo "$SECURITY_PROMPT" >> "$GITHUB_OUTPUT"
echo "PROMPT_EOF" >> "$GITHUB_OUTPUT"
echo "quality_prompt<<PROMPT_EOF" >> "$GITHUB_OUTPUT"
echo "$QUALITY_PROMPT" >> "$GITHUB_OUTPUT"
echo "PROMPT_EOF" >> "$GITHUB_OUTPUT"
echo "ccs_prompt<<PROMPT_EOF" >> "$GITHUB_OUTPUT"
echo "$CCS_PROMPT" >> "$GITHUB_OUTPUT"
echo "PROMPT_EOF" >> "$GITHUB_OUTPUT"
echo "adversarial_prompt<<PROMPT_EOF" >> "$GITHUB_OUTPUT"
echo "$ADVERSARIAL_PROMPT" >> "$GITHUB_OUTPUT"
echo "PROMPT_EOF" >> "$GITHUB_OUTPUT"
- name: Run Claude Code Review
id: claude-review
uses: anthropics/claude-code-action@v1
@@ -242,6 +264,22 @@ jobs:
${{ steps.review-prompt.outputs.content }}
<security-review-prompt>
${{ steps.review-prompt.outputs.security_prompt }}
</security-review-prompt>
<quality-review-prompt>
${{ steps.review-prompt.outputs.quality_prompt }}
</quality-review-prompt>
<ccs-compliance-review-prompt>
${{ steps.review-prompt.outputs.ccs_prompt }}
</ccs-compliance-review-prompt>
<adversarial-review-prompt>
${{ steps.review-prompt.outputs.adversarial_prompt }}
</adversarial-review-prompt>
## IMPORTANT: Writing the Review
After completing your analysis, use the `Write` tool to write the final review markdown to `${{ env.REVIEW_OUTPUT_FILE }}`.
Do NOT use `Edit` tool — use `Write` tool directly to create the file in one shot.
@@ -261,8 +299,8 @@ jobs:
--bare
--model ${{ env.REVIEW_MODEL }}
--permission-mode bypassPermissions
--max-turns 30
--allowedTools "Glob,Grep,Read,Write,Bash(gh pr diff *),Bash(gh pr view *),Bash(git diff *),Bash(git log *),Bash(git show *),Bash(cat *),Bash(ls *),Bash(wc *),Bash(head *),Bash(tail *),Bash(find *)"
--max-turns 50
--allowedTools "Agent,Glob,Grep,Read,Write,Bash(gh pr diff *),Bash(gh pr view *),Bash(git diff *),Bash(git log *),Bash(git show *),Bash(cat *),Bash(ls *),Bash(wc *),Bash(head *),Bash(tail *),Bash(find *)"
# Fallback: if Claude didn't write the review file, extract from execution output
- name: Extract review from execution output (fallback)