Fix /claude review/challenge: hard timeout + merge-base diff scope#1893
Open
jackspacelb wants to merge 5 commits into
Open
Fix /claude review/challenge: hard timeout + merge-base diff scope#1893jackspacelb wants to merge 5 commits into
jackspacelb wants to merge 5 commits into
Conversation
…w/challenge hang) The `/claude` review, challenge, and consult modes piped the entire branch diff into `cat "$PROMPT_FILE" | claude -p` with no timeout and no size cap. On a large diff this can hang effectively forever — there is no timeout, so the caller waits indefinitely. The sibling `/codex` skill already wraps its review/challenge/consult calls in a `gtimeout`/`timeout` fallback with exit-124 hang handling. The `/claude` wrapper never got the same treatment (still true on main). This change wraps all four `claude -p` invocations: - Self-contained timeout per block (`gtimeout` -> `timeout` -> unwrapped, 600s). Inlined per block on purpose: each bash block in a SKILL.md runs in its own shell, so a helper defined in another block would be undefined at call time. - Prompt fed via `< "$PROMPT_FILE"` instead of `cat ... |`, so `timeout` wraps `claude` directly. Deliberately NOT `< /dev/null`, which would send an empty prompt and review nothing. - On exit 124, prints that the run did NOT finish and must not be treated as a pass/clean result, and suggests splitting the diff. Test: updates the gen-skill-docs assertion to require the new stdin-redirect shape + timeout/124 markers and to reject the old unbounded pipe, so the hang cannot silently regress. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Merging to
After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here |
…changes) The reviewer captured `git diff origin/<base>`, comparing the working tree to the base TIP. On a branch whose base moved ahead, or whose base ref is stale or un-fetched, this balloons to hundreds of unrelated files. That is the deeper reason "/claude review hangs": the timeout caps the wait, but the reviewer was still handed a giant, mostly-irrelevant diff and could never produce a useful result. - Diff from the merge base to the working tree: `git diff "$(git merge-base origin/<base> HEAD)"`. Shows only this branch's changes AND keeps uncommitted work. A plain three-dot diff would drop uncommitted changes, so merge-base -> working tree is used instead. - Harden the base fetch: warn instead of silently diffing against a stale base. Test asserts the merge-base scope and rejects the old base-tip diff. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
# Conflicts: # CHANGELOG.md # VERSION # package.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
/claudereview/challenge/consult had two compounding problems that made thenested-Claude "outside voice" unreliable:
claude -pwith no timeout and nosize cap, so a large diff could hang effectively forever.
git diff origin/<base>—the working tree against the base tip. On a branch whose base has moved
ahead, or whose base ref is stale/un-fetched, this balloons to hundreds of
unrelated files. This is the deeper cause of "the review hangs": even with a
timeout, the reviewer was handed a giant, mostly-irrelevant diff and produced
nothing useful.
The sibling
/codexskill already had timeout + exit-124 handling;/claudenever got it. (Both problems are still present on
main, v1.56.0.0.)Fix
Bound the run (commits 1–2):
claude -pinvocations (review, challenge, consult-new,consult-resume) in a hard timeout:
gtimeout→timeout, 600s. Inlinedper block on purpose — each bash block in a SKILL.md runs in its own shell, so
a helper defined in another block would be undefined at call time.
< "$PROMPT_FILE"(notcat ... |), sotimeoutwrapsclaudedirectly. Deliberately not< /dev/null(would send an emptyprompt).
coreutils" message) rather than silently running unbounded.
the first 120 lines of stderr before cleanup deletes it.
Scope the diff correctly (commit 3):
git diff "$(git merge-base origin/<base> HEAD)". Shows only this branch'schanges and keeps uncommitted work. (A plain three-dot diff would drop
uncommitted changes, so merge-base → working tree is used instead.)
Test
gen-skill-docsasserts the new stdin-redirect shape, timeout/124 + fail-closedmarkers, and the merge-base diff scope; it rejects the old unbounded pipe and the
old base-tip diff, so neither can silently regress.
Verification
timeout 2 sleep 10) → exit 124, handler fires.claude -p ... < "$PROMPT_FILE"returns the exact prompt token(confirms the redirect delivers content, not an empty prompt).
git diff origin/main= 10 files of noise; merge-base diff = exactly the 2 real files.bun test test/gen-skill-docs.test.tspasses.Left
VERSION/CHANGELOGto maintainers. Not included (deliberately, as separateconcerns): a size-preflight/split path for legitimately huge diffs, and
fail-closed on all non-zero exits (only 124/125 are special-cased today).