| name | overnight-review-panel-blocked-reviewer-reads-as-clean |
| description | Overnight specialization of `code-reviewer-subagent-no-bash-blocked-on-pr-diff`
(the general tool-gap mechanism). In an UNATTENDED overnight review panel, a
reviewer that couldn't see the code reads as a CLEAN one — so a real bug ships
by morning. The usual cause: code-review subagents (feature-dev:code-reviewer,
voltagent-*, Explore) are frequently provisioned WITHOUT a Bash tool, so when
prompted to "review PR #N, fetch the diff with gh pr diff" they return a
BLOCKED report (no review performed), or silently review the current checkout
(often `main`, which predates the PR). Use when: (1) an overnight review panel
(e.g. `overnight-multi-issue-implementation` Phase C, or any
`agent-review-panel` run) dispatches reviewers against GitHub PRs or branches
not checked out in the working tree; (2) a reviewer returns "I have no
shell/gh/git tool" or "the PR sources are not in the working tree"; (3) one
reviewer in a parallel panel comes back BLOCKED while siblings succeeded. Fix:
pre-generate per-base diffs to files, materialize PR branches as worktrees,
hand each reviewer explicit paths, and in the morning synthesis treat BLOCKED
as not-clean (re-dispatch before counting the vote). Sibling to
`voltagent-reviewer-no-write-tool` (Write gap → inline output) and
`stacked-pr-review-per-base-diff-and-attach`.
|
| author | Claude Code |
| version | 1.0.0 |
| date | "2026-05-29T00:00:00.000Z" |
Overnight review panel: a BLOCKED reviewer reads as CLEAN by morning
Overnight specialization. The bare mechanism — a code-review subagent with
no Bash tool can't gh pr diff/checkout a PR, so it returns BLOCKED — is the
general skill code-reviewer-subagent-no-bash-blocked-on-pr-diff, applicable to
any PR review. This skill is the overnight-specific consequence: in an
unattended run there's no human to notice the BLOCKED report, so it silently
counts as a passing reviewer and the bug ships.
Problem
Every workflow in this repo leans on a multi-agent review panel to catch
errors before they reach the client (core pattern #1). The panel silently assumes
each reviewer can see the code under review. It can't always.
You dispatch a review subagent (e.g. feature-dev:code-reviewer, a voltagent-*
reviewer, or Explore) with a prompt like "use gh pr diff <N> to get each PR's
diff, then review." The agent returns a BLOCKED report — no findings —
explaining it has no shell/gh/git tool and the PR source isn't in the working
tree. Meanwhile a sibling reviewer in the same panel may succeed (if it happened to
find a materialized worktree on disk).
In an interactive session you'd notice. In an unattended overnight run, a BLOCKED
report that you skim at 8am reads as "no findings = clean" — and the bug it never
looked at ships to the client. This is exactly the failure class this repo exists to
prevent ("factual errors ship because a single tired reviewer missed it"), but
sourced from a tool gap rather than fatigue.
Context / Trigger Conditions
- An overnight panel (
overnight-multi-issue-implementation Phase C; any
agent-review-panel fan-out) dispatches reviewers against a GitHub PR or a
branch not checked out in the main working tree.
- A reviewer's report says any of: "No shell /
gh / git tool is exposed",
"The PR sources are not in the working tree", "WebFetch returns 404 (private
repo)", or it reviewed files on the current branch (often main, which
predates the PR) instead of the PR's changes.
- Asymmetric panel outcomes — some reviewers found the code, one came back
blocked — because the successful ones discovered an existing worktree and the
blocked one looked in the main checkout.
Root cause
These agents' toolsets exclude Bash. For example feature-dev:code-reviewer has
Glob, Grep, LS, Read, NotebookRead, WebFetch, TodoWrite, WebSearch, KillShell, BashOutput — note KillShell/BashOutput are present but Bash itself is
not, so the agent can read a background shell's output but cannot start a
command. No Bash → no gh pr diff, no git checkout <pr-branch>, no git diff.
Read hits the filesystem directly, so the agent only sees whatever branch is
checked out in the working tree it lands in (the main checkout, which predates the
PR). Private repos also defeat the WebFetch fallback (404).
Solution
Do the git/gh work in the orchestrator (which has Bash) and hand each reviewer
materialized source + pre-generated diffs — never "run gh":
- Materialize each PR branch as a worktree (or reuse existing ones):
git worktree add /tmp/pr-<N> <pr-branch>
- Pre-generate each PR's diff against its own base to a file. For a stacked PR,
diff against its own base (not main) so the diff is scoped to that PR only:
mkdir -p /tmp/diffs
git diff <base-branch>..<pr-branch> -- app/ tests/ > /tmp/diffs/pr<N>.diff
- Prompt each reviewer with explicit paths + a no-Bash preamble:
"You do NOT have a Bash/git/gh tool — only Read/Grep/Glob. The code is
materialized at /tmp/pr-<N>/; the scoped diff is at /tmp/diffs/pr<N>.diff.
Read the diff first, then read surrounding source in the worktree. Do NOT look
in the main repo checkout — it predates this work."
- For anything a reviewer wants to confirm empirically (a probe, the test
suite), have it return a
WANTS EMPIRICAL CONFIRMATION list with the exact
command; the orchestrator runs those afterward and folds results back in.
- In the morning synthesis, treat BLOCKED as not-clean. A reviewer that
couldn't see the code is not a passing vote — re-dispatch it (now with paths)
before declaring the PR reviewed. A panel's "no findings" is only valid if every
member actually read the diff.
Verification
Each reviewer returns findings citing real file:line from the worktree, not a
BLOCKED report and not a review of unrelated main code. In a panel, all reviewers
produce symmetric, source-grounded output. The morning summary distinguishes
"reviewed, clean" from "could not review."
Example
Stacked-PR tail review (#62/#63/#64) in a GA/GTM audit project: the "Correctness
Hawk" (feature-dev:code-reviewer) came back BLOCKED — it looked in the main
checkout (which predated the stack) and had no Bash to git checkout the branches.
Two siblings happened to find pre-existing worktrees and reviewed fine. Re-dispatched
the Hawk with the three per-base diffs pre-written to /tmp/s13-diffs/ plus the
worktree paths and a "you have no Bash" preamble — it then found a P0 (a
transactional version-check that broke on SDK retry, a data-loss bug 179 green tests
had missed). Had this been an unattended overnight run, the first BLOCKED report
would have read as a clean reviewer and the P0 would have shipped.
Notes
- BLOCKED ≠ CLEAN is the load-bearing rule. The cost of an unread reviewer
masquerading as a passing one is exactly what the panel exists to prevent.
- Some reviewers are also missing
Write — see voltagent-reviewer-no-write-tool
(orchestrator persists their inline output to files). A reviewer can hit both gaps
at once: no Bash to fetch the diff and no Write to save the report.
- The general-purpose / default
Agent DOES have Bash; this gap is specific to the
read-only review/search specialist agents. If you need the reviewer to run
commands, either pick a Bash-capable agent type or pre-stage everything.
- For scoping stacked-PR diffs per base and attaching reviews back to the right PR,
see
stacked-pr-review-per-base-diff-and-attach.
References
- General version:
code-reviewer-subagent-no-bash-blocked-on-pr-diff — the bare
no-Bash → BLOCKED tool-gap mechanism, applicable to any PR review (this skill is
its overnight specialization: the BLOCKED-reads-as-CLEAN consequence under autonomy)
- Sibling skill:
voltagent-reviewer-no-write-tool — Write-tool gap (inline output)
stacked-pr-review-per-base-diff-and-attach — per-base diff scoping for stacked PRs
subagent-bash-cd-wrong-worktree — Bash-capable agents landing in the wrong worktree
- Empirically observed 2026-05-29 in a GA/GTM audit project's stacked-PR review panel