CI Review
CRITICAL REQUIREMENT: This skill is an automated review submitter. Its primary deliverable is an atomic GitHub PR review submitted by calling the Bash tool to execute post-review.sh.
You MUST call the Bash tool to execute post-review.sh on EVERY run before writing any final summary text (see Step 7 for the invocation command). Ending a session without calling the Bash tool to post the review violates the contract and fails CI.
Mandatory Review Contract (Inviolable)
Every execution of /ci-review MUST complete all workflow steps through Step 8:
- Step 6 is mandatory on ALL runs: Construct the payload file
${TMPDIR:-/tmp}/ci-review-payload-<PR#>.json(using the "No Findings" template with"comments": []when clean). - Step 7 is mandatory on ALL runs: Call the
Bashtool to runsh "${CLAUDE_SKILL_DIR}/../../scripts/post-review.sh" <PR#> "${TMPDIR:-/tmp}/ci-review-payload-<PR#>.json". - Step 8 is mandatory: Output the summary including the review URL returned by
post-review.sh.
Before running, read [references/REVIEW-POSTING.md](references/REVIEW-POSTING.md) now for the review posting format and error handling chain.
Profiles
| Profile | Agents | Use When | |---------|--------|----------| | single | single-reviewer (one comprehensive agent) | Routine PRs, CI budgets, small diffs — ~6x cheaper than lean | | lean (default) | deep-reviewer, guidelines-checker, bug-detector, security-reviewer, silent-failure-hunter, code-simplifier | Every PR — balanced cost and coverage | | full | All lean agents + test-analyzer, comment-analyzer, type-analyzer | Critical PRs, large changes, pre-release | | agent | Same agents as full | PR authored by an AI agent — surfaces more findings since fixes are cheap |
Agent Profile
The --agent flag activates the agent profile, designed for reviewing AI-authored code. It uses the full agent set but with different thresholds and additional prompt context:
- Uses the full agent set (all 9 review agents)
- Lowers the default
--min-severitytolow(surface everything actionable) - Injects context into each agent prompt: "This PR was authored by an AI agent. Surface all valid findings including minor ones — the cost of fixing is negligible. Pay attention to AI-specific patterns: over-engineering, hallucinated API usage, unnecessary abstractions, verbose boilerplate, and cargo-culted patterns."
Severity Filter
Use --min-severity <level> to control which findings appear in the review:
| Level | Includes | Default For | |-------|----------|-------------| | low | All findings (low, medium, high, critical) | --agent profile | | medium | medium + high + critical | Default for --single, --lean, --full | | high | high + critical | — | | critical | critical only | — |
If not specified, --min-severity defaults to medium for normal runs and to low when --agent is used. The severity filter is applied AFTER confidence scoring — it removes real but low-priority findings, not false positives.
Review Posting Rules (Inlined for Reliability)
These rules are critical. They are also detailed in REVIEW-POSTING.md but inlined here as defense-in-depth:
- Always use event
"COMMENT"— never"APPROVE"or"REQUEST_CHANGES" lineis the line number on the new version of the file. Always useside=RIGHT- Only post actionable inline comments — no confirmations, no "looks good"
- Do not repeat correctly addressed items
- If no inline comments, write
"comments": []in the Step 6 payload file - Always post — even with zero findings. A clean review still requires a body-only review using the exact "No Findings" template from [REVIEW-POSTING.md](references/REVIEW-POSTING.md) §3 (
## CI Reviewheader, "No actionable issues found. Reviewed N files across M changed lines.", profile). - Posting is deterministic via
post-review.sh: Step 6 writes${TMPDIR:-/tmp}/ci-review-payload-<PR#>.json, and Step 7 executespost-review.shto handle payload submission, retry logic, and fallback posting automatically. Never skip Step 7.
Timing Logs
This section is reference guidance. Do not execute anything from it directly — timing markers are only emitted from within each numbered Step's own Bash invocations below. This section describes the two variants and when to apply each.
Every Step in the ## Workflow section emits a phase-start marker at its beginning and a phase-end marker at its end so the GitHub Actions log shows where time is spent. GitHub Actions renders ::group:: / ::endgroup:: as collapsible sections in the run UI; local runs see them as plain text. Track each Step's elapsed seconds and report them in the Step 8 summary as Phase timings (s): s0=... s1=... ... total=....
Single-call variant — use when the entire Step fits in one Bash invocation (Steps 0, 1, 2, 7). Capture the start epoch into a shell variable and compute elapsed inline, so no state needs to cross tool calls. Preserve the step's exit status by capturing $? immediately after <step commands> and re-emitting it at the end — otherwise the trailing echo commands would always return 0 and mask prerequisite or eligibility failures (e.g., gh auth status failing in Step 0). All echoes go to stdout — per GitHub's workflow-command spec, ::group:: / ::endgroup:: must appear on stdout to render as collapsible sections in the Actions log. For steps whose <step commands> also produces parseable output (e.g., Step 2's gh pr view --json), the output should remain parseable.
Multi-call variant — use when the Step spans multiple Bash invocations or waits on subagent tool calls (Steps 3, 3.5, 4, 5, 6). All marker echoes go to stdout (GitHub's workflow-command spec). Any value the model needs to remember for later calls (epochs, SHAs, owner/repo) must be printed to stdout as a labeled line so it survives across tool calls. In the first Bash call of the Step, print echo "::group::[ci-review] Step N: <name>" and date +%s — remember the printed epoch in your working state. In the last Bash call of the Step, substitute the remembered epoch into echo "[ci-review] Step N done elapsed=$(( $(date +%s) - <REMEMBERED_EPOCH> ))s"; echo "::endgroup::". For Steps with agent fan-out (Steps 4, 5), place the phase-end marker after all agents return.
Workflow
Step 0: Prerequisites
Verify gh CLI is available and authenticated. Single Bash invocation using the Timing Logs single-call variant:
echo "::group::[ci-review] Step 0: Prerequisites"
START=$(date +%s)
gh auth status
STATUS=$?
echo "[ci-review] Step 0 done elapsed=$(( $(date +%s) - START ))s"
echo "::endgroup::"
exit $STATUS
If gh is not found (exit 127), abort with: "gh CLI is required. Install: https://cli.github.com/" If not authenticated (non-zero exit from gh auth status), abort with: "gh is not authenticated. Run: gh auth login"
Step 1: Parse Arguments
Emit timing markers via a minimal Bash invocation even though argument parsing itself has no other shell work — s1=<parse> in the Step 8 summary must be a measured elapsed value, never a placeholder:
echo "::group::[ci-review] Step 1: Parse Arguments"
START=$(date +%s)
# Argument parsing is performed by the model from the conversation — no shell work required here.
echo "[ci-review] Step 1 done elapsed=$(( $(date +%s) - START ))s"
echo "::endgroup::"
Extract from the argument string:
- PR identifier (required): a number (e.g.,
123) or GitHub URL. If a URL, extract the PR number and store asPR_NUMBER. If the URL points to a different repository than the current one, abort with: "Cross-repo URLs are not supported. Run this skill from the target repo, or pass just the PR number." - Focus text (optional): free text describing what to focus the review on (e.g., "auth flow", "error handling")
- Profile flag (optional):
--single,--lean