From oss
Multi-agent code review of GitHub pull requests for Python source, documentation (Markdown/RST), and CI/CD config PRs. Covers architecture, tests, performance, docs, lint, security, and API design.
How this skill is triggered — by the user, by Claude, or both
Slash command
/oss:review [PR number|path/to/report.md] [--reply] [--no-challenge] [--codemap] [--semble] [--keep "<items>"][PR number|path/to/report.md] [--reply] [--no-challenge] [--codemap] [--semble] [--keep "<items>"]sonnetThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
<objective>
Spawn specialized sub-agents in parallel. Consolidate findings into structured feedback with severity levels.
NOT for local file review or current git diff — use /develop:review (requires develop plugin). NOT for non-Python source PRs (TypeScript, Go, Rust, etc.) unless they include Python files — docs-only and CI/CD-only PRs in scope. NOT for standalone GitHub issue analysis or thread summarization — use oss:analyse. Draft PRs (GitHub isDraft=true) are work-in-progress; pass explicit PR number anyway to review draft. Note: oss:review performs inline linked-issue analysis (root-cause alignment check in Step 1) as part of PR review — within scope, no conflict.
42 or #42): review PR diff--reply: spawn oss:shepherd to draft contributor-facing PR comment. Path ending in .md → spawn oss:shepherd from that report, skip new review./develop:review (requires develop plugin) for local files or current git diff.--codemap: strict mode — stop, report if codemap not installed (on by default when installed; use --no-codemap to opt out; requires codemap plugin installed)--semble: enable semble semantic search companion (off by default; requires semble MCP server configured)/develop:plan (requires develop plugin).CHALLENGE_ENABLED=true # set to false via --no-challenge CODEMAP_ENABLED=auto # on by default if codemap installed + index found; --no-codemap = off; --codemap = strict (stop if not installed) SEMBLE_ENABLED=false # set to true via --semble
Background agent health monitoring (CLAUDE.md §6) — applies to Step 3 parallel agent spawns MONITOR_INTERVAL=300 # 5 minutes between polls HARD_CUTOFF=900 # 15 minutes of no file activity → declare timed out EXTENSION=300 # one +5 min extension if output file explains delay
Key boundary: end of Step 2 — parallel review-agent fan-out outputs collected, before Step 5 consolidation. Second boundary: end of Step 5 — consolidated report written, before Step 8 --reply. Preserve at boundary 1: RUN_DIR, REPORT_DIR, PR# (CLEAN_ARGS), per-agent finding file paths. Preserve at boundary 2: final report path, PR#, reply-mode flag.
# loads: oss-shared-resolver.md
# loads: review-section-taxonomy.md
# loads: compaction-contract.md
# cold-start fallback (sets $_OSS_SHARED) — run first:
_OSS_SHARED=$(python "${CLAUDE_PLUGIN_ROOT:-plugins/oss}/bin/resolve_shared_path.py" oss skills/_shared 2>/dev/null) # timeout: 5000
# --reply requires $_OSS_SHARED (Step 8 reads shepherd-reply-protocol.md); non-reply flows degrade gracefully
if [ ! -d "$_OSS_SHARED" ]; then
if [[ "$ARGUMENTS" == *--reply* ]]; then
echo "⛔ _OSS_SHARED resolved to '$_OSS_SHARED' but dir absent — --reply requires oss plugin shared dir; verify oss plugin installed"
exit 1
else
echo "⚠ _OSS_SHARED resolved to '$_OSS_SHARED' but dir absent — continuing with degraded functionality (oss skill-specific shared helpers unavailable; --reply mode will not work in this run)"
fi
fi
Read $_OSS_SHARED/agent-resolution.md. Agents: foundry:sw-engineer, foundry:qa-specialist, foundry:perf-optimizer, foundry:doc-scribe, foundry:linting-expert, foundry:solution-architect, foundry:challenger, oss:cicd-steward.
Resolve REVIEW_SKILL_DIR: run find ~/.claude/plugins -path "*/oss/skills/review" -type d 2>/dev/null; non-empty → use as literal value, else fall back to plugins/oss/skills/review. This resolved literal is REVIEW_SKILL_DIR — substitute into every Agent spawn prompt and every Read $REVIEW_SKILL_DIR/... call below.
Task hygiene: Call TaskList first. Each found task: completed if work done · deleted if orphaned · in_progress if genuinely continuing. TaskCreate each major phase; mark in_progress/completed throughout.
Create these tasks before starting Step 1 (in order, all at once):
Parse $ARGUMENTS flags first (applied directly — no subprocess) — this sets CLEAN_ARGS, the mode flags, and DIRECT_PATH_MODE before any step below references them (the pre-classification and Step 1 both read them):
| Flag | Variable | Present | Absent |
|---|---|---|---|
--reply | REPLY_MODE | true | false |
--no-challenge | CHALLENGE_ENABLED | false | true |
--no-codemap | CODEMAP_FORCE_OFF | true | false |
--codemap | CODEMAP_STRICT | true | false |
--semble | SEMBLE_ENABLED | true | false |
--keep "<items>" | KEEP_ITEMS | value string | "" |
CLEAN_ARGS: $ARGUMENTS with matched flags removed (including --keep "<items>" and its quoted value), leading whitespace stripped, leading # stripped.
# Extract --keep quoted value before unknown-flag scan in Step 1 (compaction-contract.md §keep: semantics)
KEEP_ITEMS=""
if [[ "$ARGUMENTS" =~ --keep[[:space:]]\"([^\"]+)\" ]]; then
KEEP_ITEMS="${BASH_REMATCH[1]}"
fi
# Clear stale contract from any prior incomplete run (compaction-contract.md §Lifecycle)
rm -f .claude/state/skill-contract.md # timeout: 5000
Then set direct-report fast-path mode (a review-report .md path passed instead of a PR number):
DIRECT_PATH_MODE=false
if [[ "$CLEAN_ARGS" == *.md ]]; then
# reject plan files — shepherd must not draft replies from plan content
if [[ "$CLEAN_ARGS" == .plans/* ]] || [[ "$CLEAN_ARGS" == *todo_*.md ]]; then
echo "Error: plan files cannot be used as review report input. Pass a review report from .reports/review/<timestamp>/review-report.md or a PR number."
exit 1
fi
# required markers: ## Summary, verdict:, or APPROVED|NEEDS_WORK|REQUEST_CHANGES
if [ -f "$CLEAN_ARGS" ] && grep -qE '(^## Summary|^verdict:|APPROVED|NEEDS_WORK|REQUEST_CHANGES)' "$CLEAN_ARGS" 2>/dev/null; then # timeout: 5000
DIRECT_PATH_MODE=true
REVIEW_FILE="$CLEAN_ARGS"
else
echo "⚠ $CLEAN_ARGS is a .md file but lacks review-report markers (## Summary | verdict: | APPROVED|NEEDS_WORK|REQUEST_CHANGES) — refusing direct-path fast-path; continuing with normal review path which expects a PR number."
fi
fi
Content-type pre-classification (PR mode only) — skip when DIRECT_PATH_MODE=true.
Classify PR from changed file patterns. Default PR_TYPE=CODE; override only when unambiguous.
PR_TYPE="CODE"
DOCS_TYPING_MODE=false; TESTS_CI_MODE=false
if [ "$DIRECT_PATH_MODE" = "false" ] && [[ "$CLEAN_ARGS" =~ ^[0-9]+$ ]]; then
_CHANGED=$(gh pr diff $CLEAN_ARGS --name-only 2>/dev/null) # timeout: 6000
_PY_LOGIC_COUNT=$(echo "$_CHANGED" | grep -E '\.py$' | grep -cvE '(test_|_test\.py|conftest\.py|\.pyi$)' 2>/dev/null || echo 0)
_ALL_COUNT=$(echo "$_CHANGED" | grep -c . 2>/dev/null || echo 0)
_DOC_COUNT=$(echo "$_CHANGED" | grep -cE '\.(md|rst|txt|ipynb)$' 2>/dev/null || echo 0)
_TEST_CI_COUNT=$(echo "$_CHANGED" | grep -cE '(test_|_test\.py|conftest\.py|\.ya?ml$|\.github/|tox\.ini|Makefile)' 2>/dev/null || echo 0)
if [ "${_PY_LOGIC_COUNT:-0}" -eq 0 ] && [ "${_ALL_COUNT:-0}" -gt 0 ]; then
if [ "$_DOC_COUNT" -ge "$_ALL_COUNT" ]; then
PR_TYPE="DOCS_TYPING"; DOCS_TYPING_MODE=true
elif [ "$(( _TEST_CI_COUNT + _DOC_COUNT ))" -ge "$_ALL_COUNT" ]; then
PR_TYPE="TESTS_CI"; TESTS_CI_MODE=true
fi
fi
echo "→ PR_TYPE=$PR_TYPE (_py_logic=$_PY_LOGIC_COUNT, _all=$_ALL_COUNT)"
fi
# Persist PR_TYPE + mode flags — fresh shell loses vars (Check 41); challenge-skip block + Steps 2/5 reload
{
echo "PR_TYPE=$PR_TYPE"
echo "DOCS_TYPING_MODE=$DOCS_TYPING_MODE"
echo "TESTS_CI_MODE=$TESTS_CI_MODE"
} > "${TMPDIR:-/tmp}/oss-review-mode-flags-${CLEAN_ARGS}"
Challenge skip — challenger adds no value for non-logic PRs:
# Reload PR_TYPE — fresh shell (Check 41)
[ -f "${TMPDIR:-/tmp}/oss-review-mode-flags-${CLEAN_ARGS}" ] && . "${TMPDIR:-/tmp}/oss-review-mode-flags-${CLEAN_ARGS}"
if [ "$PR_TYPE" = "DOCS_TYPING" ] || [ "$PR_TYPE" = "TESTS_CI" ]; then
CHALLENGE_ENABLED=false
fi
Persist PR tag for Step 2:
echo "$CLEAN_ARGS" > "${TMPDIR:-/tmp}/oss-review-pr-tag"
echo "$KEEP_ITEMS" > "${TMPDIR:-/tmp}/oss-review-keep-items" # timeout: 5000
Agent lineup — PR_TYPE != CODE overrides scope-based rules in Step 1:
PR_TYPE | Agents | Challenger | Consolidator |
|---|---|---|---|
DOCS_TYPING | foundry:linting-expert only | skip | foundry:linting-expert |
TESTS_CI | foundry:qa-specialist + foundry:linting-expert | skip | foundry:qa-specialist |
CODE | full scope-based lineup | per --no-challenge | foundry:sw-engineer |
When DOCS_TYPING_MODE=true or TESTS_CI_MODE=true: skip Step 1 file-scope detection and SCOPE classification; proceed directly to Step 2 agent launch.
Flags, CLEAN_ARGS, and DIRECT_PATH_MODE were parsed in Step 0 — reuse those values here.
# loads: detect_codemap.py — consumers: resolve/SKILL.md, review/SKILL.md
_DETECT_CODEMAP="${CLAUDE_PLUGIN_ROOT:-plugins/oss}/bin/detect_codemap.py"
[ "$CODEMAP_FORCE_OFF" = "true" ] && _DETECT_FLAGS="--force-off" || _DETECT_FLAGS=""
[ "$CODEMAP_STRICT" = "true" ] && _DETECT_FLAGS="$_DETECT_FLAGS --strict"
python "$_DETECT_CODEMAP" --prefix review $_DETECT_FLAGS 2>&1 # timeout: 5000
[ $? -ne 0 ] && { echo "! BLOCKED — codemap strict mode requested but codemap not installed or index missing"; exit 1; }
CODEMAP_ENABLED=$(cat "${TMPDIR:-/tmp}/review-codemap-enabled" 2>/dev/null || echo "false")
CODEMAP_CURRENCY=$(cat "${TMPDIR:-/tmp}/review-codemap-currency" 2>/dev/null || echo "off")
Codemap gates — when CODEMAP_FORCE_OFF=false, read $_OSS_SHARED/codemap-gates.md and run: Gate A if CODEMAP_ENABLED=false (missing index → offer to build); Gate B if CODEMAP_ENABLED=true and CODEMAP_CURRENCY=stale. On a build choice, after codemap:scan-codebase set CODEMAP_ENABLED=true. Skip both gates when CODEMAP_FORCE_OFF=true (--no-codemap).
If SEMBLE_ENABLED=true: proceed — semble MCP tool availability verified at first use. If mcp__semble__search is unavailable when called, it fails with a clear error; do not preemptively exit here.
Unsupported flag check — after all supported flags extracted, scan $ARGUMENTS for remaining --<token> tokens. Found: print ! Unknown flag(s): \--`. Supported: `--reply`, `--no-challenge`, `--codemap`, `--no-codemap`, `--semble`, `--keep`.then invokeAskUserQuestion` — (a) Abort (stop, re-invoke with correct flags) · (b) Continue ignoring (skip unknown flags, proceed). On Abort: stop.
FOUNDRY_SHARED=$(python "${CLAUDE_PLUGIN_ROOT:-plugins/foundry}/bin/resolve_shared_path.py" foundry skills/_shared 2>/dev/null) # timeout: 5000
if [ -z "$FOUNDRY_SHARED" ]; then
FOUNDRY_SHARED="plugins/foundry/skills/_shared"
echo "⚠ Could not resolve FOUNDRY_SHARED via cache lookup — using bare fallback path '$FOUNDRY_SHARED'; foundry plugin may be absent — Steps 5/7/consolidator will degrade (per-file guards still fire)"
fi
if [ "$DIRECT_PATH_MODE" = "false" ]; then
if [ -z "$CLEAN_ARGS" ] || ! [[ "$CLEAN_ARGS" =~ ^[0-9]+$ ]]; then
echo "Error: PR number required. Usage: /oss:review <PR number> [--reply] [--no-challenge]"
exit 1
fi
# Run all four in parallel:
CHANGED_FILES=$(gh pr diff $CLEAN_ARGS --name-only 2>/dev/null) # cache for reuse in codemap block # timeout: 6000
gh pr view $CLEAN_ARGS # timeout: 6000
gh pr checks $CLEAN_ARGS # timeout: 15000
gh pr view $CLEAN_ARGS --json reviews,labels,milestone # timeout: 6000
fi
CI STATUS (PR mode only): parse gh pr checks output → extract failing required check names into CI_FAILING_CHECKS. Any failing: set CI_RED=true, print ⚠ CI is red: [list failing check names] — review proceeds; status noted in report header. Continue to Steps 2–8 regardless. Expand $CI_RED and $CI_FAILING_CHECKS to literal values in the consolidator spawn prompt (Step 5).
Read $REVIEW_SKILL_DIR/modes/scope-detection.md and execute its bash blocks inside the DIRECT_PATH_MODE = "false" guard. Sets PY_FILES, DOC_FILES, CICD_FILES, CICD_ONLY_MODE, DOCS_ONLY_MODE, DOCS_CICD_MODE; persists flags to ${TMPDIR:-/tmp}/oss-review-mode-flags-${CLEAN_ARGS} for reload in Step 2.
DOCS_TYPING mode (DOCS_TYPING_MODE=true): annotation-only .py changes (no logic). Spawn: foundry:linting-expert only; challenger disabled by Step 0; skip all other agents. Proceed directly to agent launch.
TESTS_CI mode (TESTS_CI_MODE=true): test files and CI config only. Spawn: foundry:qa-specialist + foundry:linting-expert; challenger disabled by Step 0; skip all other agents. Proceed directly to agent launch.
CI/CD-only mode (CICD_ONLY_MODE=true): no .py/.md/.rst. Spawn: oss:cicd-steward + Agent 1 + Agent 7 (if CHALLENGE_ENABLED=true) + Codex; skip Agents 2–6. Proceed directly to agent launch.
Docs-only mode (DOCS_ONLY_MODE=true): no .py. foundry:doc-scribe (Agent 4) leads — Agent 1 explicitly skipped (NOT for docs clause); linked-issue spawns also skip Agent 1. Spawn: Agent 4 + Agent 7 (if CHALLENGE_ENABLED=true) + Codex; skip Agents 1, 2, 3, 5, 6. Proceed directly to agent launch.
Docs + CI/CD mode (DOCS_CICD_MODE=true): no Python. Spawn: oss:cicd-steward (Agent 8) + foundry:doc-scribe (Agent 4) + Agent 7 (if CHALLENGE_ENABLED=true); skip Agents 1, 2, 3, 5, 6. Proceed directly to agent launch.
Before spawning agents (Python mode only — all three mode flags false), classify diff:
perf, performance, optimization, refactor, architecture, cleanup OR commit message keywords refactor:, perf:, rewrite OR diff touches different modules. Detect via gh pr view --json labels,title. Small-diff perf refactors are exactly the case FIX would silently mishandle.PY_LOC_DELTA >400 → note in report headerAssign SCOPE shell variable so the EXPECTED array (Step 2 health monitor) can branch on it without comparing to an undefined value:
# for classification heuristic
PY_FILE_COUNT=$(echo "$PY_FILES" | grep -c . 2>/dev/null || echo 0)
# PY_LOC_DELTA = total churn, NOT net delta — pure renames produce >0 even with net 0; label/keyword override handles this
PY_LOC_DELTA=$(gh pr diff $CLEAN_ARGS 2>/dev/null | grep -E '^[+-][^+-]' | grep -vE '^[+-]{3}' | wc -l | tr -d ' ') # timeout: 6000
# new public API surface: added lines in src/**/__init__.py
NEW_API_LINES=$(gh pr diff $CLEAN_ARGS -- ':(glob)src/**/__init__.py' 2>/dev/null | grep -c '^+[^+]' || echo 0) # timeout: 6000
# pure config/deps changes (no .py logic changes)
NON_CONFIG_PY=$(echo "$PY_FILES" | grep -vE '(pyproject\.toml|setup\.cfg|setup\.py|requirements.*\.txt|conftest\.py)' || true)
SCOPE=$(python "${CLAUDE_PLUGIN_ROOT:-plugins/oss}/bin/classify_pr_scope.py" --py-files "$PY_FILE_COUNT" --loc-delta "$PY_LOC_DELTA" --new-api-lines "$NEW_API_LINES" --labels "$PR_LABELS" --title "$PR_TITLE" 2>/dev/null) # timeout: 10000
echo "→ SCOPE=$SCOPE (py_files=$PY_FILE_COUNT, py_loc=$PY_LOC_DELTA, new_api=$NEW_API_LINES)"
# persist — Step 2 EXPECTED_FILE is in a separate bash block
echo "$CHANGED_FILES" | grep -qE '(^|/)(requirements.*\.txt|pyproject\.toml|package.*\.json|Pipfile|poetry\.lock|setup\.cfg|.*\.lock)$' && CHORE_DEPS=true || CHORE_DEPS=false
_REVIEW_SCOPE_FILE="${TMPDIR:-/tmp}/oss-review-scope-${CLEAN_ARGS}"
{
echo "SCOPE=$SCOPE"
echo "CHORE_DEPS=$CHORE_DEPS"
} > "$_REVIEW_SCOPE_FILE"
Skip optional agents by classification:
CHALLENGE_ENABLED=true), Codex (if available); skip Agents 2, 3, 6
requirements*.txt, pyproject.toml, package*.json, Pipfile, poetry.lock, setup.cfg, *.lock → keep Agent 2 (qa-specialist) for OWASP/CVE checks. Detect via CHORE_DEPS flag above. CHORE + non-deps → skip qa-specialist.CODEMAP_ENABLED=true)Skip entire section if CODEMAP_ENABLED=false — sets codemap_available=false for downstream agent prompts; agents fall back to file reads.
loads: modes/codemap-context.md
CODEMAP_ENABLED=true: read $REVIEW_SKILL_DIR/modes/codemap-context.md and execute its contents — stages codemap_available and $CODEMAP_CONTEXT_STAGE to TMPDIR (Step 2 copies into $RUN_DIR/codemap-context.md) and defines the Step-2 spawn-prompt substitution rules + semble companion. CODEMAP_ENABLED=false: skip; agents fall back to file reads.
Parse PR body (gh pr view $CLEAN_ARGS) for issue refs (Closes #N, Fixes #N, Resolves #N, refs #N — case-insensitive). Extract to ISSUE_NUMS. Cap 3.
ISSUE_NUMS non-empty AND DOCS_CICD_MODE != true: spawn one foundry:doc-scribe per issue in Step 2 alongside Codex — all launch simultaneously. Each issue agent: fetch gh issue view <N> --json title,body,comments,state,labels + gh issue view <N> --comments; produce /oss:analyse-style output (Summary, Root Cause Hypotheses top 3, Code Evidence); write full analysis to $RUN_DIR/issue-<N>.md; return only {"status":"done","issue":N,"root_cause":"<one-line>","file":"$RUN_DIR/issue-<N>.md","confidence":0.N}.
ISSUE_NUMS empty → skip issue checks downstream.
DIRECT_PATH_MODE=true:
REPLY_MODE=false → use AskUserQuestion: "A report path was passed without --reply. Did you mean /oss:review <path.md> --reply?" Options: (a) "Yes — continue with --reply mode" → set REPLY_MODE=true; then re-check: [ ! -f "$REVIEW_FILE" ] && echo "Error: review file not found at $REVIEW_FILE" && exit 1; proceed; (b) "No — review a PR instead" → print usage hint (/oss:review <N> | path/to/dir) and stop.REPLY_MODE=true and [ ! -f "$REVIEW_FILE" ] → print Error: report not found: $REVIEW_FILE and stop.REPLY_MODE=true and file exists → print [direct] using $REVIEW_FILE → skip to Step 8. Skip Steps 2–7.Set up run directory (shared by all agents) and resolve skill paths:
TIMESTAMP=$(date -u +%Y-%m-%dT%H-%M-%SZ)
RUN_DIR=".temp/review/$TIMESTAMP"
mkdir -p "$RUN_DIR" # timeout: 5000
# persisted so agents resolve via cat; hand-typing caused leading-dot drops → stray temp/review/ dirs
echo "$RUN_DIR" > "${TMPDIR:-/tmp}/oss-review-run-dir"
REPORT_DIR=".reports/review/$TIMESTAMP"
mkdir -p "$REPORT_DIR" # timeout: 5000
echo "$REPORT_DIR" > "${TMPDIR:-/tmp}/oss-review-report-dir" # persist for contract-write
File-based handoff: read $FOUNDRY_SHARED/file-handoff-protocol.md. File absent → warn and continue without it.
IMPORTANT: Replace $REPORT_DIR, $REVIEW_SKILL_DIR, $BRANCH, and $DATE with actual literal computed values in every Agent spawn prompt. Do NOT pass as shell variables — agents receive text, not shell context. Exception — $RUN_DIR: never hand-substitute it; agents self-resolve via cat "${TMPDIR:-/tmp}/oss-review-run-dir" per the run-dir preamble in agent-prompts.md (eliminates leading-dot transcription slips).
Check Codex availability:
claude plugin list 2>/dev/null | grep -q 'codex@openai-codex' && CODEX_AVAILABLE=1 && echo "codex (openai-codex) available" || { CODEX_AVAILABLE=0; echo "⚠ codex (openai-codex) not found — skipping co-review"; } # timeout: 15000
Read $REVIEW_SKILL_DIR/templates/agent-prompts.md. Substitute <REVIEW_SKILL_DIR> → $REVIEW_SKILL_DIR before using content in spawn prompts. Leave $RUN_DIR literal in the prompt text — agents resolve it themselves via the run-dir preamble (cat "${TMPDIR:-/tmp}/oss-review-run-dir"); the orchestrator must NOT retype the run-dir path.
Codemap context propagation: rehydrate codemap_available from Step 1 persist file, copy staged context into $RUN_DIR/codemap-context.md, substitute into every dimension-agent spawn prompt per the rules in the Structural-context block above. Block omitted when codemap_available=false.
_PR_TAG=$(cat "${TMPDIR:-/tmp}/oss-review-pr-tag" 2>/dev/null || echo "$CLEAN_ARGS")
codemap_available=$(cat "${TMPDIR:-/tmp}/oss-review-codemap-available-${_PR_TAG}" 2>/dev/null || echo "false")
CODEMAP_CONTEXT_STAGE=$(cat "${TMPDIR:-/tmp}/oss-review-codemap-context-stage-${_PR_TAG}" 2>/dev/null || echo "")
if [ "$codemap_available" = "true" ] && [ -n "$CODEMAP_CONTEXT_STAGE" ] && [ -f "$CODEMAP_CONTEXT_STAGE" ]; then
cp "$CODEMAP_CONTEXT_STAGE" "$RUN_DIR/codemap-context.md"
fi
Health monitoring (CLAUDE.md §6): Create checkpoint BEFORE spawning agents:
REVIEW_CHECKPOINT="${TMPDIR:-/tmp}/review-check-$(date +%s)"
touch "$REVIEW_CHECKPOINT"
# poll block (separate bash invocation) reads it back
echo "$REVIEW_CHECKPOINT" > "${TMPDIR:-/tmp}/oss-review-checkpoint"
Launch Codex, issue agents, and all review agents in one message batch — zero hold between Codex and review agents. All Agent() calls issue in a SINGLE response turn — substitute $RUN_DIR (literal) and issue numbers before spawning. Agent lineup: codex:codex-rescue (if CODEX_AVAILABLE=1) · per-issue foundry:sw-engineer (skip if DOCS_CICD_MODE=true) · Agents 1–8 per scope/mode rules above.
Poll for expected output files per $MONITOR_INTERVAL / $HARD_CUTOFF until all present or each hits hard cutoff.
Write expected paths to file (Bash arrays don't persist across tool invocations):
# restore — each SKILL.md bash block runs in fresh shell
_PR_TAG=$(cat "${TMPDIR:-/tmp}/oss-review-pr-tag" 2>/dev/null || echo "unknown")
_REVIEW_MODE_FILE="${TMPDIR:-/tmp}/oss-review-mode-flags-${_PR_TAG}"
_REVIEW_SCOPE_FILE="${TMPDIR:-/tmp}/oss-review-scope-${_PR_TAG}"
[ -f "$_REVIEW_MODE_FILE" ] && . "$_REVIEW_MODE_FILE"
[ -f "$_REVIEW_SCOPE_FILE" ] && . "$_REVIEW_SCOPE_FILE"
POLL_START=$(date +%s)
EXPECTED_FILE="$RUN_DIR/.expected-files"
: >"$EXPECTED_FILE" # truncate / create empty
# Step 0 simplified modes — short-circuit full agent lineup
if [ "${DOCS_TYPING_MODE:-false}" = "true" ]; then
echo "$RUN_DIR/foundry--linting-expert.md" >>"$EXPECTED_FILE"
elif [ "${TESTS_CI_MODE:-false}" = "true" ]; then
echo "$RUN_DIR/foundry--qa-specialist.md" >>"$EXPECTED_FILE"
echo "$RUN_DIR/foundry--linting-expert.md" >>"$EXPECTED_FILE"
else
[ "$CODEX_AVAILABLE" = "1" ] && echo "$RUN_DIR/foundry--codex.md" >>"$EXPECTED_FILE"
[ "$DOCS_CICD_MODE" != "true" ] && for N in $ISSUE_NUMS; do echo "$RUN_DIR/issue-$N.md" >>"$EXPECTED_FILE"; done
{ [ "$CICD_ONLY_MODE" = "true" ] || [ "$DOCS_CICD_MODE" = "true" ]; } && echo "$RUN_DIR/oss--cicd-steward.md" >>"$EXPECTED_FILE"
[ "$DOCS_CICD_MODE" != "true" ] && [ "$DOCS_ONLY_MODE" != "true" ] && echo "$RUN_DIR/foundry--sw-engineer.md" >>"$EXPECTED_FILE"
{ [ "$DOCS_ONLY_MODE" = "false" ] && [ "$DOCS_CICD_MODE" = "false" ] && [ "$CICD_ONLY_MODE" != "true" ] && { [ "$SCOPE" != "CHORE" ] || [ "$CHORE_DEPS" = "true" ]; }; } && echo "$RUN_DIR/foundry--qa-specialist.md" >>"$EXPECTED_FILE"
[ "$DOCS_ONLY_MODE" = "false" ] && [ "$DOCS_CICD_MODE" = "false" ] && [ "$CICD_ONLY_MODE" != "true" ] && [ "$SCOPE" != "CHORE" ] && [ "$SCOPE" != "FIX" ] && echo "$RUN_DIR/foundry--perf-optimizer.md" >>"$EXPECTED_FILE"
[ "$CICD_ONLY_MODE" != "true" ] && echo "$RUN_DIR/foundry--doc-scribe.md" >>"$EXPECTED_FILE"
[ "$DOCS_ONLY_MODE" = "false" ] && [ "$DOCS_CICD_MODE" = "false" ] && [ "$CICD_ONLY_MODE" != "true" ] && echo "$RUN_DIR/foundry--linting-expert.md" >>"$EXPECTED_FILE"
[ "$CHALLENGE_ENABLED" = "true" ] && echo "$RUN_DIR/foundry--challenger.md" >>"$EXPECTED_FILE"
[ "$DOCS_ONLY_MODE" = "false" ] && [ "$DOCS_CICD_MODE" = "false" ] && [ "$CICD_ONLY_MODE" != "true" ] && [ "$SCOPE" != "FIX" ] && [ "$SCOPE" != "CHORE" ] && echo "$RUN_DIR/foundry--solution-architect.md" >>"$EXPECTED_FILE"
fi
Later poll blocks read paths back via while read -r path; do [ -f "$path" ] || PENDING=1; done <"$EXPECTED_FILE" — no in-memory array required.
Every $MONITOR_INTERVAL seconds, in the poll bash block, rehydrate the checkpoint path first: REVIEW_CHECKPOINT=$(cat "${TMPDIR:-/tmp}/oss-review-checkpoint" 2>/dev/null) then find $RUN_DIR -newer "$REVIEW_CHECKPOINT" -type f | wc -l — non-zero = agents alive (refresh checkpoint: touch "$REVIEW_CHECKPOINT"); zero since last refresh for $HARD_CUTOFF seconds = stalled. One $EXTENSION if tail -20 output file explains delay; second stall = cutoff. On timeout: read partial results from stalled agent's file; surface with ⏱ in report. Never omit timed-out agents.
After all outputs collected (or timed out):
ls "$RUN_DIR/"*.md 2>/dev/null || echo "⚠ No agent output files found in $RUN_DIR — check that $RUN_DIR was expanded correctly in spawn prompts"
# Compaction contract — boundary 1: after fan-out, before consolidation (compaction-contract.md §Lifecycle)
_RUN_DIR=$(cat "${TMPDIR:-/tmp}/oss-review-run-dir" 2>/dev/null || echo "")
_PR_TAG=$(cat "${TMPDIR:-/tmp}/oss-review-pr-tag" 2>/dev/null || echo "unknown")
_REPORT_DIR=$(cat "${TMPDIR:-/tmp}/oss-review-report-dir" 2>/dev/null || echo "")
_KEEP=$(cat "${TMPDIR:-/tmp}/oss-review-keep-items" 2>/dev/null || echo "")
_FINDING_FILES=$(ls "$_RUN_DIR/"*.md 2>/dev/null | tr '\n' ' ' | sed 's/ *$//')
_PRESERVE="run-dir=$_RUN_DIR, report-dir=$_REPORT_DIR, pr=$_PR_TAG, finding-files=$_FINDING_FILES"
[ -n "$_KEEP" ] && _PRESERVE="$_PRESERVE; user-keep: $_KEEP"
mkdir -p .claude/state # timeout: 5000
{
echo "## Active Skill Contract"
echo "- skill: oss:review · phase: consolidation (after parallel review-agent fan-out)"
echo "- run-dir: $_RUN_DIR"
echo "- preserve: $_PRESERVE"
echo "- next: consolidate findings → final report (→ draft --reply if reply-mode)"
} > .claude/state/skill-contract.md
Step 3a/3b may run concurrently with still-executing Step 2 agents — issue in same response turn as final Step 2 polls. Do NOT issue before PR_BASE is bound.
TRUNK=$(git remote show origin 2>/dev/null | grep 'HEAD branch' | awk '{print $NF}') # timeout: 6000
# Shallow-clone guard: git merge-base fails silently on shallow clones.
IS_SHALLOW=$(git rev-parse --is-shallow-repository 2>/dev/null || echo "unknown")
if [ "$IS_SHALLOW" = "true" ]; then
echo "⚠ Shallow clone detected — running: git fetch --unshallow to enable merge-base checks"
git fetch --unshallow 2>/dev/null || echo "⚠ git fetch --unshallow failed — Step 3 checks may be incomplete"
fi
PR_BASE=$(git merge-base HEAD "origin/${TRUNK:-main}" 2>/dev/null || echo "origin/${TRUNK:-main}")
Scope disclosure: check searches public GitHub code globally. Results may include unrelated projects using same symbol names — treat as signal, not proof. Rate-limited responses (HTTP 429, empty results) may indicate limitation, not absence of usage.
# rate-limit guard: on HTTP 429, retry once after 10s; if still limited, log and continue
CHANGED_EXPORTS=$(gh pr diff $CLEAN_ARGS -- ':(glob)src/**/__init__.py' 2>/dev/null | grep "^[-+]" | grep -v "^[-+][-+]" | grep -oP '\w+' | sort -u) # timeout: 6000
for export in $CHANGED_EXPORTS; do
echo "=== $export ==="
gh api "search/code" --field "q=$export language:python" --jq '.items[:5] | .[].repository.full_name' 2>/dev/null # timeout: 30000
done
gh pr diff $CLEAN_ARGS 2>/dev/null | grep -A2 "deprecated" # timeout: 6000
OSS_SIGNALS="${TMPDIR:-/tmp}/oss-review-signals-${CLEAN_ARGS}.json"
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || gh release list --limit 1 --json tagName --jq '.[0].tagName' 2>/dev/null || echo "") # timeout: 6000
python "${CLAUDE_PLUGIN_ROOT:-plugins/oss}/bin/check_oss_pr_signals.py" --clean-args "$CLEAN_ARGS" --latest-tag "$LATEST_TAG" --output-file "$OSS_SIGNALS" # timeout: 30000
cat "$OSS_SIGNALS" 2>/dev/null
Read $FOUNDRY_SHARED/cross-validation-protocol.md. File absent → warn: "cross-validation protocol not found — verify foundry plugin installed (claude plugin list); skipping Step 4." Then skip Step 4.
Independence requirement: cross-validation must run as separate spawned agent — same type as finding's origin. Do NOT validate in orchestrator context.
Spawn cap: max 3 verifier agents. Critical/blocking findings > 3 → group into batches of ≤2 findings per verifier; note grouped IDs in rationale.
Spawn verifier agent per critical/blocking finding (or per batch when capped). Agent reads relevant finding file from $RUN_DIR and referenced code. Each verifier must write full rationale to $RUN_DIR/verify-<finding-id>.md using the Write tool, then return ONLY: {"finding_id":"<id>","verdict":"CONFIRMED|REFUTED","rationale":"<one sentence>","file":"$RUN_DIR/verify-<finding-id>.md"}. REFUTED → downgrade finding severity or remove before consolidation.
Before output path, extract:
BRANCH=$(git branch --show-current 2>/dev/null | tr '/' '-' || echo 'main') # timeout: 3000
DATE=$(date -u +%Y-%m-%d) # timeout: 5000
IMPORTANT: expand $RUN_DIR, $REPORT_DIR, $REVIEW_SKILL_DIR, $BRANCH, $DATE, $CI_RED, and $CI_FAILING_CHECKS to literal values before inserting into the spawn prompt. Un-expanded variables create wrong paths. The ## Source Files footnote Glob(... path="<EXPANDED_RUN_DIR>") path must also be expanded to the literal $RUN_DIR value.
Select consolidator agent by PR_TYPE (lighter model for non-logic PRs):
_REVIEW_MODE_FILE="${TMPDIR:-/tmp}/oss-review-mode-flags-${CLEAN_ARGS}"
[ -f "$_REVIEW_MODE_FILE" ] && . "$_REVIEW_MODE_FILE"
case "${PR_TYPE:-CODE}" in
DOCS_TYPING) CONSOLIDATOR_AGENT="foundry:linting-expert" ;;
TESTS_CI) CONSOLIDATOR_AGENT="foundry:qa-specialist" ;;
*) CONSOLIDATOR_AGENT="claude" ;;
esac
Spawn $CONSOLIDATOR_AGENT consolidator agent with prompt:
Read $REVIEW_SKILL_DIR/templates/consolidator-prompt.md. Prepend the run-dir resolution preamble from agent-prompts.md so the consolidator self-resolves $RUN_DIR (cat "${TMPDIR:-/tmp}/oss-review-run-dir"). Substitute <REPORT_DIR>, <REVIEW_SKILL_DIR>, <_OSS_SHARED>, <DATE>, <CHANGED_FILES>, <SCOPE>, <CI_FAILING_CHECKS> with literal expanded values; leave $RUN_DIR literal (agent self-resolves). Spawn: Agent(subagent_type="$CONSOLIDATOR_AGENT", prompt=<substituted consolidator-prompt.md content>)
Main context receives only the one-liner verdict. Consolidator unavailable fallback — Agent tool deferred/not loaded:
Print: ⛔ BLOCKED — Agent tool not loaded; consolidator cannot run. Re-invoke /oss:review to retry. If persistent, run /foundry:setup (requires foundry plugin) to verify session config.
Do NOT read agent finding files inline — floods main context (~16–32K tokens per run), produces unreliable synthesis.
After parsing confidence: agent < 0.7 → prepend ⚠ LOW CONFIDENCE to findings section, state gap explicitly. Never drop uncertain findings.
Print terminal block: read the --- header from top of $REPORT_DIR/review-report.md (all fields from opening --- up to and including closing --- — Title:, Date:, PR Type:, Scope:, Focus:, Agents:, CI:, Outcome:, Summary:, Confidence:, Next steps:, Path:), append → saved to $REPORT_DIR/review-report.md, print to terminal.
This --- block IS the reply header — print/omit-box handling per quality-gates.md §Report File Format (universal rule). Review-specific rendering caveat: wrap the printed block in a ```text fence so the literal --- delimiters survive — bare, a renderer parses the leading --- as YAML frontmatter and the closing --- under Path: as a setext heading, mangling the header. Print all 12 fields verbatim; use the ·-separated one-line fallback ONLY when the $REPORT_DIR/review-report.md read genuinely fails — then state ⚠ could not read report header — verify $REPORT_DIR before the fallback line rather than silently degrading.
# Compaction contract — boundary 2: after consolidation, before --reply (compaction-contract.md §Lifecycle)
_PR_TAG=$(cat "${TMPDIR:-/tmp}/oss-review-pr-tag" 2>/dev/null || echo "unknown")
_REPORT_DIR=$(cat "${TMPDIR:-/tmp}/oss-review-report-dir" 2>/dev/null || echo "")
_RUN_DIR=$(cat "${TMPDIR:-/tmp}/oss-review-run-dir" 2>/dev/null || echo "")
{
echo "## Active Skill Contract"
echo "- skill: oss:review · phase: reply (after consolidation)"
echo "- run-dir: $_RUN_DIR"
echo "- preserve: final-report=$_REPORT_DIR/review-report.md, pr=$_PR_TAG"
echo "- next: draft contributor reply (--reply) or stop at Step 7"
} > .claude/state/skill-contract.md
Identify tasks Codex can implement — meaningful code/doc work grounded in actual implementation.
Delegate: public functions with no docstrings (read impl first, describe so Codex writes real 6-section docstring) · missing test coverage for concrete well-defined behavior · consistent rename across files. Do not delegate: architectural issues, logic errors, security vulns, or any task requiring human judgment.
Read $FOUNDRY_SHARED/codex-delegation.md. File absent → warn: "codex-delegation criteria not found — verify foundry plugin installed (claude plugin list); skipping Step 6 delegation." Then skip Step 6.
Print ### Codex Delegation only when tasks delegated — omit otherwise. Don't rewrite output file.
Confidence block ownership: REPLY_MODE=true → block in Step 8. REPLY_MODE=false → block in Step 7b.
REPLY_MODE=true: proceed to Step 8 — no Confidence block here. REPLY_MODE=false — do NOT proceed to Step 8. Execute both sub-steps below:
! IMPORTANT — invoke AskUserQuestion tool directly. Never write options as plain text. Single call — all options in one:
/oss:resolve $CLEAN_ARGS — description: fix this PR (implement review findings, resolve conflicts, push)/oss:resolve report — description: resolve from full review report only (no GitHub re-fetch)/oss:resolve $CLEAN_ARGS report — description: fix PR + resolve from full review report in one passwalk through findings — description: go through each finding interactivelyskip — description: no actionoss:resolve has disable-model-invocation: true — Skill() invocation blocked. After AskUserQuestion returns:
Run: /oss:resolve $CLEAN_ARGS); no Skill() callwalk through findings / skip: handle inline or stopEnd with ## Confidence block per CLAUDE.md output standards.
rm -f .claude/state/skill-contract.md # clear contract — skill complete (compaction-contract.md §Lifecycle) # timeout: 5000
REPLY_MODE not set → skip.
Read $_OSS_SHARED/shepherd-reply-protocol.md — apply invocation pattern and terminal summary format.
Spawn with:
gh pr view output.temp/output-reply-<PR#>-$(date -u +%Y-%m-%d).mdPart 2 compliance gate (after shepherd returns — do NOT trust the return line alone):
# only when findings reference file:line — true LGTM has none
REPLY_OUT=".temp/output-reply-<PR#>-$(date -u +%Y-%m-%d).md" # timeout: 5000
grep -qE '^\| *Importance *\| *Confidence *\| *File *\| *Line' "$REPLY_OUT" && echo "PART2_PRESENT=true" || echo "PART2_PRESENT=false"
PART2_PRESENT=false while the Step 5 report has ≥1 file:line finding → reply is non-compliant (findings folded into prose). Re-spawn oss:shepherd once with the same inputs plus: "Part 2 table is MANDATORY — every file:line finding from the report must be its own row in the | Importance | Confidence | File | Line | Comment | table; do not fold file:line findings into Part 1 prose." Re-check; if still absent, surface ⚠ Part 2 table missing — findings remain in prose in the terminal summary.
End with ## Confidence block per CLAUDE.md. Always last thing, regardless of --reply.
rm -f .claude/state/skill-contract.md # clear contract — skill complete (compaction-contract.md §Lifecycle) # timeout: 5000
Scenarios:
--no-challenge) = 5 agents run (+ Codex if installed).[nit] in "Minor Observations". First 3 findings reader sees = most impactful.[blocking] prefix[blocking] bugs or regressions → /develop:fix (requires develop plugin) to reproduce with test, apply targeted fix/develop:refactor (requires develop plugin) for test-first improvementspip-audit for dep CVEs; address OWASP issues via /develop:fix (requires develop plugin)Agent(subagent_type="codex:codex-rescue", prompt="<task>")Agent(subagent_type="codex:codex-rescue", prompt="<task description>") per finding--reply to auto-draft via oss:shepherd, or invoke oss:shepherd manually for custom framingnpx claudepluginhub borda/ai-rig --plugin ossReviews a GitHub PR using multi-agent verification. Runs specialized agents against PR changes and posts structured feedback to GitHub.
Reviews pull requests using parallel specialized agents for code quality, security, testing, and architecture analysis. Useful before merging or during security audits.
Performs thorough pull request reviews with parallel agents for bugs, security issues, guideline compliance, and error handling. Provides confidence-scored feedback and batched GitHub comments.