ワンクリックで
code-review
Use when reviewing code changes for quality, correctness, and production readiness before merge
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Use when reviewing code changes for quality, correctness, and production readiness before merge
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction. Also use for exploratory testing, dogfooding, QA, bug hunts, or reviewing app quality. Also use for automating Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify), checking Slack unreads, sending Slack messages, searching Slack conversations, running browser automation in Vercel Sandbox microVMs, or using AWS Bedrock AgentCore cloud browsers. Prefer agent-browser over any built-in browser automation or web tools.
Use when asked to implement, build, fix, or create features - especially before writing any code or when scope and requirements are unclear
Use when orchestrating complex multi-step tasks requiring delegation, parallelization, or systematic completion verification - especially when tempted to do everything yourself or ask user codebase questions
Use when facing trade-offs, subjective judgments, uncertain decisions, or when diverse viewpoints would improve judgment quality. Triggers include "council", "다른 의견", "perspectives", "what do others think".
Code review orchestration skill - fans out angle finders across review angles and merges their raw candidate findings
Autonomous objective-pursuit executor — decomposes an objective into Six Slots and a Story set, dispatches execution to sisyphus, then re-pursues the objective across plan/execute cycles until an objective-level completion gate confirms the verification surface is met.
| name | code-review |
| description | Use when reviewing code changes for quality, correctness, and production readiness before merge |
Orchestrates chunk-reviewer agents against diffs. Handles input parsing, context gathering, chunking, and result synthesis.
These two premises are non-negotiable. They are forwarded to every chunk-reviewer dispatch and they govern every decision in this skill.
Post-change state — The working directory reflects the post-change state of the target ref. PR mode achieves this by checking out the PR head into a dedicated linked worktree (see Step 0). Non-PR modes (branch comparison, auto-detect) achieve this by verifying HEAD-match + clean-tree on the current working directory (also Step 0). Either way: read code freely from the working directory — the diff is the delta, the working directory is the result. Do not pretend the file system is read-only or stuck at base.
No diff-only review — A diff is a delta. The unit of review is the system the diff produces. Always trace dependencies, callers, callees, interfaces, configurations, and runtime context across files. If you cannot explain how the changed code behaves end-to-end against the surrounding system, you have not reviewed it.
These premises must be reflected in the chunk-reviewer dispatch prompt — see Step 5.
# PR (number or URL)
/code-review pr 123
/code-review pr https://github.com/org/repo/pull/123
# Branch comparison
/code-review main feature/auth
# Auto-detect (current branch vs origin/main or origin/master)
/code-review
| Action | YOU Do | DELEGATE |
|---|---|---|
| Requirements 3-question gate | Yes | - |
| Diff range determination & git | Yes | - |
| Evidence Verification (build/test/lint) | Yes | - |
| Chunking decision | Yes | - |
| Findings synthesis (rank/class verified findings) | Yes | - |
| Individual candidate judgment inline (Phase 2) | Yes | - |
| Escalation verification (candidates below confidence threshold) | - | verifier subagent (one per escalated candidate) |
| Individual chunk review | NEVER | chunk-reviewer |
| Code modification | NEVER | (forbidden entirely) |
RULE: Orchestration, synthesis, and decisions = Do directly. Per-candidate inline judgment = Do directly in Phase 2 (reasoning → confidence → verdict + enrichment). Escalated candidates (confidence below threshold) = DELEGATE to verifier subagents (one per candidate). Multi-angle finding = DELEGATE to chunk-reviewer. Code modification = FORBIDDEN.
digraph role_separation {
rankdir=LR;
"Orchestrator" [shape=box];
"chunk-reviewer" [shape=box];
"verifier" [shape=box];
"Codebase" [shape=cylinder];
"Orchestrator" -> "chunk-reviewer" [label="dispatch with {DIFF_COMMAND}"];
"chunk-reviewer" -> "Orchestrator" [label="candidate findings"];
"Orchestrator" -> "Codebase" [label="Read/Grep inline (Phase 2)"];
"Orchestrator" -> "verifier" [label="dispatch per escalated candidate"];
"verifier" -> "Codebase" [label="Read/Grep to verify"];
"verifier" -> "Orchestrator" [label="verdict (supersedes inline)"];
}
Your role as orchestrator:
NOT your role:
git diff command (chunk-reviewers execute the diff)Allowed in orchestrator context:
git diff {range} --stat outputgit diff {range} --name-only outputgit log {range} --oneline outputForbidden in orchestrator context:
git diff command (chunk-reviewers execute the diff, not you)Context management:
RULE: Inline judgment for non-escalated candidates runs in your context. Only escalated candidates are delegated to verifier subagents. You CANNOT run the raw diff command or modify files.
Environment setup runs first — resolve the range and, in PR mode, check out the post-change code into the worktree before any code-reading step (intent acquisition, the derived-context sub-step, chunk-review). Every downstream step reads the working directory, so the working directory must already hold the post-change state.
Determine range and setup for subsequent steps:
| Input | Setup | Range |
|---|---|---|
pr <number or URL> | Fetch and check out PR ref into the worktree (see below) | origin/<baseRefName>...pr-<number> |
<base> <target> | Verify HEAD is <target> via git rev-parse --abbrev-ref HEAD; verify clean tree via git status --porcelain -uno. Abort if mismatch or dirty. | <base>...<target> |
| (none) | Detect default branch (origin/main or origin/master). Verify HEAD is the target branch via git rev-parse --abbrev-ref HEAD; verify clean tree via git status --porcelain -uno. Abort if mismatch or dirty. | <default>...HEAD |
This skill assumes the orchestrator is already running inside a worktree dedicated to this review (the caller is responsible for creating the worktree). Therefore: fetch the PR ref AND check it out. The working directory must reflect the post-change state of the PR so that all subsequent code reading (Phase 2 verification, chunk-reviewer Step 2) sees the actual code under review.
PR ID 추출 규칙: 사용자가 URL(https://github.com/<org>/<repo>/pull/<N>) 형식으로 호출하면, 아래 bash로 진입하기 전에 trailing path segment에서 numeric <N>을 추출해 <number> 자리에 substitute하라. URL을 그대로 substitute하면 git fetch origin pull/<URL>/head가 invalid refspec으로 실패하고 git checkout -B pr-<URL>이 invalid 브랜치명으로 실패한다.
set -euo pipefail
# 0. Safety guards (Premise 1 enforcement) — abort BEFORE any state change
# -uno: untracked files are preserved by checkout; only check tracked modifications
if [ -n "$(git status --porcelain -uno)" ]; then
echo "Error: working directory has uncommitted changes — refusing to checkout over the user's work" >&2
exit 1
fi
# Distinguish primary repo from linked worktree.
# In a linked worktree, --git-dir points inside .git/worktrees/<wt>,
# while --git-common-dir points to the shared .git directory; they differ.
# In a primary clone they are equal — refuse so we never checkout over the user's main work tree.
if [ "$(git rev-parse --git-dir 2>/dev/null)" = "$(git rev-parse --git-common-dir 2>/dev/null)" ]; then
echo "Error: refusing to run in primary repo — create a dedicated linked worktree first (Premise 1). Hint: 'git worktree add ../review-pr-<N> -b review/pr-<N>'" >&2
exit 1
fi
# 1. Get base branch name (abort if gh fails or returns empty)
BASE_REF=$(gh pr view <number> --json baseRefName --jq '.baseRefName')
if [ -z "$BASE_REF" ]; then
echo "Error: gh pr view returned empty baseRefName — aborting before any fetch" >&2
exit 1
fi
# 2. Fetch base branch first, then PR ref last so FETCH_HEAD points to PR head
# (rerun-safe — force-push on the PR is picked up on re-review)
git fetch origin "${BASE_REF}"
git fetch origin pull/<number>/head
# 3. Reset local pr-<N> to the freshly fetched PR head (FETCH_HEAD) and check it out
# so the working directory matches the PR state
git checkout -B pr-<number> FETCH_HEAD
If the working directory is dirty (uncommitted changes) or the caller is not in a worktree, abort and report — do not silently checkout over the user's work. The worktree premise is the safety net; without it, the safety net is gone.
All range formats use three-dot syntax (A...B), which is equivalent to git diff $(git merge-base A B)..B. This shows only changes introduced by the target since the common ancestor — not changes on the base branch. This prevents false positives when origin/main has moved ahead after branching.
All subsequent steps use {range} from this table. All diff commands use git diff {range} -- <files> for path-filtered output. After checkout, code reading via Read/Grep/Glob reflects the post-change state, which is the intended behavior — diff shows the delta, the working directory shows the result.
After the range is resolved and (PR mode) the checkout is done, before proceeding to Step 1:
git diff {range} --stat (using the range determined above)Early Exit runs before intent acquisition on purpose — an empty or binary-only diff needs no interview.
Intent acquisition is non-negotiable. Either intent is confirmed (from artifacts, interview, or both), or the user explicitly defers to a code-quality-only review. There is no third option — proceeding without intent and without explicit deferral is forbidden. Reviewing without intent produces wrong severities, missed scope creep, and false positives born from misunderstanding the author's goal.
PR descriptions, commits, and comments routinely link to richer context (issue trackers, design docs, chat threads). Follow every link recursively — a linked ticket may itself link to a doc which links to a discussion thread; keep following until the trail ends.
Do not name specific tools. Use whatever fetch capability the environment provides for each link type. If a link cannot be fetched directly (no credential, no MCP for that platform, network unreachable), do not skip it — mark it for the user interview step.
Sources to consult per input mode:
| Input mode | Sources |
|---|---|
| PR | gh pr view --json title,body,labels,comments,reviews, gh pr view --comments, linked issues, gh issue view <n>, every external link found in the chain, commit messages on the PR branch |
| Branch comparison | Commit messages, branch name conventions, any linked tickets discovered in commits, related issues |
| Auto-detect | Recent commit messages on HEAD, any linked tickets found there |
After exhausting fetchable sources, ask the user about:
DO NOT interview the user about codebase facts (file locations, patterns, architecture, who calls what). Use Read/Grep/Glob and the explore agent for those — they are reachable from the working directory.
Before exiting Step 1, the state must be one of:
| State | Action |
|---|---|
| Intent confirmed — author's goal, approach, and constraints are understood from artifacts and/or interview | Proceed to Step 2 |
| User explicit deferral — user says "skip", "그냥 리뷰해줘", "없어", "code quality only", or unambiguous equivalent | Set {REQUIREMENTS} = "N/A — code-quality-only review (user deferred)" and proceed |
Non-interactive dispatch (completion-gate) — the dispatch prompt itself carries a {gate}-codereview-{sid}.json artifact path alongside a 5-slot intent payload (what_was_implemented/description/requirements/project_context/non_goals) | Treat as Intent confirmed (non-interactive, no user interview) and proceed to Step 2. Acquisition steps 1-3 (PR/branch artifacts, linked references, codebase signals) still run — they backfill any slot whose value is the (none provided) marker. Only step 4 (user interview) is replaced by the payload. |
| Neither — artifacts thin and user not yet asked, OR user gave vague answers without explicit deferral | BLOCK. Do not proceed. Continue interview until one of the two states above is reached. |
There is no "I tried hard enough, just review" path. The block IS the safety mechanism.
A fresh code-reviewer agent has no ambient session to check for an active artifact path — the non-interactive discriminator above is prompt-borne: whether the dispatch prompt includes the path, not whether a session-scoped artifact happens to exist. This is the same {gate}-codereview-{sid}.json signal Step 5 later reads as runId (Find Phase Sink, below); Step 1 is where it first enters the pipeline. When the signal is absent, the main-session interactive gate above (Neither → BLOCK) is unchanged.
When the user gives a vague answer that is not an explicit deferral, refine ONCE with a specific follow-up:
각 follow-up 메시지는 deferral 옵션을 함께 안내하여 사용자가 "skip / 그냥 리뷰해줘 / 없어" 어휘를 몰라도 escape 가능하도록 한다.
| User says | Follow-up |
|---|---|
| "대충 있어" / "뭐 좀 있긴 한데" | "어디서 찾을 수 있나요? 링크나 문서 위치를 알려주세요. (답하기 어려우면 'skip'으로 코드 품질만 리뷰 가능)" |
| "그냥 성능 개선이야" | "어떤 지표를 개선하려 했나요? (latency, throughput, memory 등 — 답하기 어려우면 'skip'으로 코드 품질만 리뷰 가능)" |
| "여러 가지 고쳤어" | "가장 중요한 1-2개만 알려주세요. 나머지는 코드에서 식별하겠습니다. (답하기 어려우면 'skip'으로 코드 품질만 리뷰 가능)" |
If refinement still yields a vague answer, surface the block explicitly to the user:
"의도를 명확히 잡기 어렵습니다. 둘 중 하나를 선택해주세요: (1) [구체적 질문]에 답하여 의도 확정, 또는 (2) 'skip / 코드 품질만 리뷰' 명시적 deferral. 둘 중 하나를 명시하기 전까지 리뷰는 시작하지 않습니다."
This is not adversarial — it is refusing to silently produce a worse review.
| Situation | Method |
|---|---|
| 2-4 structured choices (review scope, focus areas) | AskUserQuestion tool |
| Free-form / subjective (intent, alternatives, constraints, concerns) | Plain text question |
One question per message. Never bundle. Wait for the answer before the next question.
Question quality — every question must include either a specific anchor (a summary the user can correct) or a default action in parentheses (so progress is possible without an answer):
| BAD | GOOD |
|---|---|
| "요구사항이 있나요?" | "PR 본문과 연결된 이슈에서 [요약]을 추출했습니다. 보완할 부분이 있나요?" |
| "어떤 부분을 볼까요?" | "23개 파일이 변경됐습니다. 집중할 영역이 있나요? (없으면 전체 리뷰)" |
Include project context when interpolating the chunk-reviewer prompt template in Step 5. Describe what kind of software this is, who uses it, how it runs, and what depends on it — based on CLAUDE.md, README.md, and the artifacts gathered above.
If available context is insufficient to characterize the project, ask the user once: "What kind of software is this? (e.g., personal CLI tool, internal team service, public-facing API, shared library, etc.)"
Proceed to Step 2 only when the Intent Block Gate state is Intent confirmed or User explicit deferral. Any other state → continue at Step 1.
By this point {REQUIREMENTS} has settled — via interview, the deferral sentinel, or the completion-gate payload. This sub-step adds one more thing to it: bounded derived context, a codebase-grounded prediction of expected-items, kept distinct from intent acquisition above. "Intent acquisition is non-negotiable" (the Step 1 charter) means received, stated author intent is authoritative; this sub-step instead generates a hypothesis from the codebase's own "Codebase signals" (acquisition step 3) — it does not receive stated intent, it infers from what the codebase already does.
Mirror the same reasoning shape the regression and cleanup finder angles use: name a thing the codebase already establishes, then check whether the change re-establishes it. Here: name a same-role analog already in the codebase, then check whether the change wires the new addition into it the same way. Derive an expected-item only through this named-necessity gate:
| State | Condition | Action |
|---|---|---|
| Grounded + necessity-named | A citable codebase analog exists with a concrete file:line, AND a concrete runtime consequence of the item's absence can be named | Keep — emit the derived item |
| Uncertain | Only one of the two holds, or either is fuzzy | Drop |
| Neither | No citable analog, no nameable consequence | never invent |
For each kept item, emit one bullet carrying four fields — self-labeling for provenance, so the downstream requirement-gap finding needs no new field to explain where it came from:
file:line) — the existing code whose role the missing item should mirrorPhrase the bullet itself like "Codebase analog at file:line implies <wiring>; absent here" — never "a requirement you stated is absent." The label must stay honest: a same-role analog implies wiring that is absent here, not a stated requirement that is absent.
Fold kept items into {REQUIREMENTS} as a Derived Expected Items sub-block:
{REQUIREMENTS} already holds real content (caller/goal-lane requirements, or the completion-gate dispatch payload's requirements field) → append the sub-block after it; preserve what's there.{REQUIREMENTS} holds the deferral sentinel N/A — code-quality-only review (user deferred) (set at the Intent Block Gate above) AND at least one item was derived → replace the sentinel with the sub-block, so coverage never sees a self-contradictory "N/A" plus derived items.{REQUIREMENTS} exactly as it was — no empty sub-block, no sentinel change.This sub-step is unconditional on intent-source: it runs the same way regardless of whether intent came from a live interview, a caller-supplied artifact, the completion-gate dispatch payload, or explicit code-quality-only deferral. It never gates on live-interview-only or on requirements already being present — it derives wherever the codebase grounds an item, and stays silent otherwise.
When the deferral is an explicit human code-quality-only deferral (a person typed "skip" / "그냥 리뷰해줘" / "code quality only" at the Intent Block Gate) rather than the completion-gate's non-interactive payload, derived items are still surfaced — always-run holds even here — but their Runtime consequence of its absence text carries a short note such as "surfaced despite quality-only deferral," so the one mode where a person actively deferred scope stays framed honestly.
Collect in parallel (using {range} from Step 0):
git diff {range} --stat (change scale)git diff {range} --name-only (file list)git log {range} --oneline (commit history)Run build, test, and lint checks BEFORE dispatching any chunk-reviewer agents. This is a fail-fast gate — a failing check aborts the review immediately.
Do NOT assume commands. Discover per-project commands in this order:
~/.omt/{project}/project-commands.md — derive {project} with: basename -s .git $(git remote get-url origin 2>/dev/null), fallback: basename $(git rev-parse --show-toplevel 2>/dev/null || pwd)CLAUDE.md, AGENTS.md, README.md, CONTRIBUTING.mdpackage.json scripts, build.gradle / build.gradle.kts tasks, Makefile targets, pyproject.toml, Cargo.tomlDiscovery is per-command and independent — if build is found but lint is not, run build and test; skip only the undiscovered command. If no commands are discovered at all, skip this step with the unavailable message (see Output Format below).
Default timeout per command: 120 seconds.
Run in sequence — stop immediately on first failure:
Any failure → do NOT dispatch chunk-reviewer agents. See Fail-Fast Gate below for the exact exit sequence (it branches on whether this run carries the completion-gate dispatch signal from Step 1).
Produce a two-part structured table after all checks complete.
Part 1 — Automated Checks
| Check | Status | Details |
|---|---|---|
| Build | PASS / FAIL | Success: one-line summary. Failure: last 30 lines of output |
| Tests | PASS (N passed) / FAIL (N/M failed) | Success: pass count. Failure: last 30 lines of output |
| Lint | PASS / FAIL | Success: one-line summary or "No errors". Failure: last 30 lines of output |
Part 2 — Test Coverage Mapping
Identify production source files from the Step 2 file list: source code files (exclude non-code files such as config, documentation, build scripts, migrations, Markdown, YAML, JSON, images, etc.) that do NOT match test glob patterns (*Test*, *Spec*, *_test*, test_*, *.test.*, *.spec.*, *_spec*).
For each production source file, find its corresponding test file:
| Production Source File | Test File | Coverage Status |
|---|---|---|
path/to/File.kt | path/to/FileTest.kt | In diff / Exists, not in diff / No test found |
Coverage Status values:
If more than 30 production source files are in the diff, group by directory instead of listing per file.
Unavailable message (no commands discovered): "Evidence verification unavailable — no build/test/lint commands discovered"
If any check fails:
{gate}-codereview-{sid}.json artifact path — the same non-interactive discriminator Step 1 uses): before reporting, write that artifact directly — {"status": "INCONCLUSIVE", "reviewer": "<reviewer id>", "at": "<ISO timestamp>", "findings": []}. This is the exact code-review artifact schema skills/{gate}/references/completion-gate.md defines. A build/test/lint fail-fast is neither a finished review (status: "COMPLETE") nor a confirmed defect (findings stays empty — the failing command and its last 30 lines of output belong in this reviewer's own failure report surfaced to the dispatching gate, not folded into a per-finding ref) — it is the review itself failing to complete, which is exactly what INCONCLUSIVE means. Writing status: "INCONCLUSIVE" is sufficient by itself: it structurally blocks request-complete (the never-false-complete gate in {gate}-state.ts) without promoting to status: "COMPLETE" or introducing any new status value. If the artifact write itself fails, do not retry or invent a status — leave the artifact absent, which request-complete's existing absent-artifact refusal already blocks on.Determine scale from --stat summary line (N files changed, X insertions(+), Y deletions(-)):
| Condition | Strategy |
|---|---|
| Total changed lines (insertions + deletions) < 1500 AND changed files < 30 | Single review |
| Total changed lines >= 1500 OR changed files >= 30 | Group into chunks by directory/module affinity |
Chunking heuristic: group files sharing a directory prefix or import relationships.
Per-chunk size guide:
For each chunk, construct the diff command string using git's native path filtering:
git diff {range} -- <file1> <file2> ... <fileN>
The orchestrator constructs this command string but does NOT execute it. The command is passed to the chunk-reviewer via {DIFF_COMMAND}, and each reviewer CLI executes it independently.
Read dispatch template from ${CLAUDE_SKILL_DIR}/../orchestrate-review/scripts/chunk-reviewer-prompt.md
Interpolate placeholders with context from Steps 0-4:
what_was_implemented (structured-output completion-gate dispatch)description (completion-gate dispatch)requirements (completion-gate dispatch)project_context (completion-gate dispatch); if it resolves to the literal "(none provided)" backfill marker, backfill from codebase signals gathered in Step 1 acquisition steps 1-3 (CLAUDE.md/README/ADR)non_goals (completion-gate dispatch); backfilled to the literal "(none provided)" marker when blankgit diff {range} (single chunk) or git diff {range} -- <chunk-files> (multi-chunk). Orchestrator constructs this string but does NOT execute it.The five intent placeholders above ({WHAT_WAS_IMPLEMENTED}/{DESCRIPTION}/{REQUIREMENTS}/{PROJECT_CONTEXT}/{NON_GOAL}) source differently depending on mode — the same {gate}-codereview-{sid}.json dispatch signal Step 1's Intent Block Gate uses to discriminate non-interactive dispatch. In structured-output mode (completion-gate dispatch), the Step 1 payload is a JSON object with named fields what_was_implemented/description/requirements/project_context/non_goals — JSON.parse it and read each named field 1:1 into its placeholder above. This is a named-field read, not a blob split — never dump the whole payload into one placeholder. If the payload fails to parse as JSON, follow the same INCONCLUSIVE artifact bridge Step 3 uses on build failure and stop before dispatching chunk-reviewer agents — do not guess field values from malformed input.
Dispatch chunk-reviewer agent(s) via Task tool (subagent_type: "chunk-reviewer") with interpolated prompt
Dispatch rules:
| Scale | Action |
|---|---|
| Single chunk | 1 agent call |
| Multiple chunks | Parallel dispatch -- all chunks in ONE response. Each chunk gets its own interpolated template with chunk-specific {DIFF_COMMAND} and {FILE_LIST} |
Each chunk-reviewer scans its whole assigned diff through every angle and reports coverage per angle (the Angle Coverage block), not per file. A file that produced no candidates is clean, not omitted — never treat an unmentioned file as a coverage gap.
Re-dispatch a chunk-reviewer for its chunk only when its response signals an infrastructure failure: a "Partial review"/"Limited review" degradation notice, an Angle Coverage entry marked Unavailable, or a reported diff-command failure.
Cap: maximum 1 re-dispatch per original chunk; if the re-dispatch also fails, accept partial coverage.
After all re-dispatches complete, merge all chunk results (original + re-dispatched) before proceeding to the Find Phase Sink.
Establish runId before dispatching chunk-reviewers (Step 5):
{gate}-codereview-{sid}.json artifact path is active for the current session): runId = {sid}runId = crypto.randomUUID() (Tier-0 builtin — no dependency required)After all chunk-reviewers return and before Phase 2 begins, write the durable sink:
Parse the conductor's returned text for:
found — sum of per-angle counts from the Angle Coverage block (each angle's K candidates value)deduped — the N in ### Candidate Findings ({N}/from M angles) headerfindTokenUsage — raw JSON object from the ### Find Token Usage block (omit when unavailable — do not block the sink write)Compute dispatched:
dispatched = deduped — no inline cap exists; the field records verify load for the find-inclusion gate and diverges only if a later inline cap or pre-filter is addedInvoke the sink helper:
bun "${CLAUDE_SKILL_DIR}/scripts/durable-sink.ts" \
"<runId>" <found> <deduped> <dispatched> \
'<findTokenUsageJson>'
Omit the last argument when findTokenUsage is unavailable. A D=0 review (zero candidates) still invokes the sink — candidates.json is written with zeros.
Find-inclusion rule:
Read [$CLAUDE_CONFIG_DIR|~/.claude]/settings.json and ./.claude/settings.json (project overrides user):
omt.codeReview.findInclusionThreshold into <findInclusionThreshold>; if undefined, use 50000 (output tokens)After writing the sink, if findTokenUsage is available, compare findTokenUsage.usage.output_tokens directly against findInclusionThreshold as an absolute output-token count. (v1 note: verify/synthesis tokens are not measured in v1, so a true share-of-total-review-tokens ratio is not computable; this threshold is an absolute cost signal instead.) If findTokenUsage.usage.output_tokens >= findInclusionThreshold, append a note to the Phase 3 report: "Find output tokens {findTokenUsage.usage.output_tokens} >= threshold {findInclusionThreshold} tokens — find-phase redesign is in scope as a follow-up (Story 2)." This rule is measurement-only in v1 — it does not block the review or change any verdict.
After all chunk-reviewers return, produce the final findings in two phases: per-candidate inline judgment with selective escalation (Phase 2), and findings synthesis (Phase 3). The terminal deliverable is the Phase 3 findings text — no walkthrough, no diagrams, no HTML.
Finders surface candidates; they do not judge them. You judge each deduped candidate inline — reasoning through the evidence, reading the relevant code in your context, and issuing a confidence score and verdict. Inline judgment eliminates the multi-candidate batch-output parse hazard, and the orchestrator's context (already holding chunk-reviewer results and diff stat) is a clean enough frame for accurate triage: no anchoring from the authoring context, because this is already a separate review session.
Config resolution:
Read [$CLAUDE_CONFIG_DIR|~/.claude]/settings.json and ./.claude/settings.json (project overrides user):
omt.codeReview.escalationConfidenceThreshold into <threshold>; if undefined, use 0.35omt.codeReview.escalationKCap into <k>; if undefined, use 3omt.codeReview.findInclusionThreshold into <findInclusionThreshold>; if undefined, use 50000 (output tokens; also resolved in the Find Phase Sink above)Inline judgment steps:
Dedup near-duplicates first (same defect, same location, same reason → keep one, merging the found by angles and keeping the most concrete failure scenario). Deduplication reduces the judgment workload before it starts.
MANDATORY READ: references/verifier-prompt.md — read it before beginning judgment. The verdict ladder (CONFIRMED / PLAUSIBLE / REFUTED), verification method, and 9-field output contract all live there. Escalated candidates reuse this file as their dispatch prompt.
For each remaining candidate, in order:
REASONING — read the code at the issue location (Read/Grep on the candidate file), trace the call chain from the entry point, and check the execution context (threading, dispatch model, runtime configuration). Apply the verdict ladder from references/verifier-prompt.md. Reason explicitly before issuing a score.
CONFIDENCE — assign a numeric value in 0.0–1.0 reflecting certainty that the finding is real (1.0 = no doubt, 0.0 = clearly not a bug). This value is internal only: it drives the escalation comparison and candidate ranking but is never serialized into any artifact.
VERDICT — exactly one of CONFIRMED / PLAUSIBLE / REFUTED (ladder in references/verifier-prompt.md).
For CONFIRMED or PLAUSIBLE (kept findings), emit the full 9-field enrichment inline:
VERDICT: <CONFIRMED | PLAUSIBLE>
TITLE: <short finding title>
LOCATION: <file>:<line> — <section / function name>
CURRENT CODE:
<5-15 lines centered on the issue>
WHAT'S WRONG: <the problem, grounded in the quoted line>
FAILURE SCENARIO: <concrete inputs/state -> wrong output, crash, or lost effect; for a cleanup finding, the concrete cost>
FIX: <concrete diff, or design direction if structural>
BLAST RADIUS: <grep/reference evidence — what else references this, or "This location only">
FOUND BY: <angle(s)>
For REFUTED, emit a one-line note:
VERDICT: REFUTED — <one line quoting the line/guard/invariant that proves it is not a bug>
Escalation — after all inline judgments complete, collect candidates where confidence < omt.codeReview.escalationConfidenceThreshold:
omt.codeReview.escalationKCap, take the <k> lowest-confidence candidates for escalation; the overflow candidates keep their inline verdict and are surfaced in Phase 3 — never silently dropped.references/verifier-prompt.md with the candidate's fields and dispatch a general-purpose subagent via the Task tool (subagent_type: "general-purpose"). All escalated candidates in ONE response — parallel, foreground.Cap & batching: judge at most 25 candidates per batch inline. If more survive dedup, batch by file proximity, correctness candidates first, and state how many were deferred — never silently drop.
The verdict ladder, verification method, and 9-field output contract all live in references/verifier-prompt.md — that is the single source; the inline judgment mirrors this contract directly.
This is a report. You surface verified findings, ranked by what matters most. You do NOT decide whether to merge and you do NOT decide whether to fix — that is the reader's call. Removing the merge verdict is deliberate: a reviewer that labels findings and shows the failure path is more trusted than one that issues a pass/fail an author then argues with.
[Pre-existing] and listed under Out of Scope — unless the change aggravates it (increases blast radius or frequency), in which case it stays in the main list.| Situation | Handling |
|---|---|
| Finding references a deleted file | Read the file at base branch (git show {base}:{file}). Note "(deleted file)" in Context. |
| Finding spans multiple files | Primary file gets the code snippet. Other files listed in Blast Radius with brief context. |
| Fix cannot be expressed as simple diff | State design direction + "Concrete diff not possible — structural change required". |
| Zero findings after verification | Report a clean review: "No findings survived verification." |
| 50+ candidates requiring verification | Dispatch verifiers in batches per Phase 2 (≤25), correctness candidates first. |
This is a report. It does not gate. There is no Assessment / "Ready to merge" section, and there is no HTML — the deliverable is the Phase 3 findings as terminal text.
Emit the ranked findings directly: each finding carries its verdict (CONFIRMED / PLAUSIBLE), class (correctness / cleanup / requirement-gap), file:line, and enriched evidence (current code, what's wrong, failure scenario, fix, blast radius — the 9-field shape from references/verifier-prompt.md, produced inline for non-escalated findings or by the escalated verifier for superseded ones). Pre-existing findings go under Out of Scope. This findings text is also the handoff contract consumed by review-report when it dispatches a code-reviewer agent that runs this skill — do not invent a different format.
These files live in references/ alongside this skill. Each is loaded only when the workflow reaches the step that needs it — do not preload all of them.
| Reference file | What it contains | When to read |
|---|---|---|
references/verifier-prompt.md | The per-candidate verifier contract: verdict ladder (CONFIRMED / PLAUSIBLE / REFUTED), verification method, read-only constraint | Phase 2 — before dispatching verifier subagents |