feat(review): drop the default reviewer timeout — reviewers run until done - #1664
Merged
Conversation
… done Reviewers were killed at a wall-clock default (10m, later 20m) that conflated 'slow because working' with 'hung'. Measured: a reviewer at ~90% completion was killed with all work discarded, and legitimate review subagents run 12+ minutes with zero parent output — so no inactivity watchdog can save this either (a headless child offers no liveness signal that distinguishes a quiet working subagent from a hang). A controlled A/B also showed entire review is not slower than the same skills invoked directly in a session (9m57s plain vs 9m08s through entire, same branch, same skills) — the duration is the task, and killing it at an arbitrary ceiling only discards paid-for work. Reviewers now run until they finish, exactly like a directly-invoked skill. --timeout remains as an explicit opt-in hard cap (CI, cost bounds); its default is 0/none. The judge keeps its own 5m default regardless — it is a single text-generation call, and the reviewer no-cap sentinel must not leak into its bound (judgeTimeoutArg). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Entire-Checkpoint: 01KWY3M0FWWCV0SVB84CPG040G
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the entire review command’s timeout semantics so reviewers no longer have a default wall-clock cap. The reviewer timeout flag remains available as an explicit hard limit, while the consolidating judge keeps its own bounded default unless a positive --timeout is provided.
Changes:
- Remove the default per-reviewer timeout so reviewers run until completion unless explicitly capped via
--timeout. - Add a
judgeTimeoutArgmapping so the reviewer “no-cap” sentinel does not disable the judge timeout (judge keeps its default unless explicitly bounded). - Update tests and flag-resolution expectations to pin the new contract.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| cmd/entire/cli/review/run.go | Drops the default reviewer timeout and treats non-positive values as “no cap”. |
| cmd/entire/cli/review/run_test.go | Updates and adds tests to lock in the new reviewer/judge timeout contract and flag resolution. |
| cmd/entire/cli/review/cmd.go | Changes --timeout default to 0, introduces judgeTimeoutArg, and wires judge timeout behavior accordingly. |
Soph
previously approved these changes
Jul 7, 2026
pfleidi
reviewed
Jul 7, 2026
pfleidi
reviewed
Jul 7, 2026
…ack)
Review feedback asked whether the two timeout helpers could collapse to
max(). Tracing every ReviewerTimeout reader shows the truth is stronger
on one side and subtler on the other:
- resolveReviewerTimeoutArg is deleted outright, not simplified. Its -1
'disabled' sentinel was load-bearing in the old three-state world
(positive/default-20m/disabled); with the default gone, both remaining
consumers (reviewerTimeout, judgeTimeoutArg) use a plain > 0 check, so
-1 and 0 were indistinguishable everywhere and the mapping did
nothing. The --timeout flag value now flows into RunConfig unmapped.
This also removes the stale doc comment Copilot flagged ('the flag's
default is nonzero').
- judgeTimeoutArg stays as a named function — the point is its contract
(the judge is one bounded call and must never be uncapped, whatever
the reviewer setting says), not the arithmetic — but its body is now
max(reviewerArg, 0) as suggested (builtin max; math.Max is float64).
A negative can still arrive via an explicit '--timeout -5m'.
- types/reviewer.go's ReviewerTimeout doc still described the deleted
defaultReviewerTimeout three-state; rewritten to the two-state
contract.
Tests updated to pin the flag->RunConfig two-state flow directly.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Entire-Checkpoint: 01KX0NQY37TYQ2B8DF5CGBA8FJ
…ack) Same shape as judgeTimeoutArg one commit earlier: the named function stays (its doc comment carries the no-default-timeout rationale), the two-state arithmetic becomes builtin max. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Entire-Checkpoint: 01KX0P0XW5TXCPJY4G65B8N82V
…ail findings) Trail findings on this branch caught two regressions the reviews missed: - The judge's effective no-flag bound silently dropped 20m -> 5m: on main the --timeout flag default (20m) always flowed into SynthesisSink.ProviderTimeout, so the 5m defaultSynthesisProviderTimeout was nearly dead code on this path; with the flag default now 0, the 5m fallback became live and tightened the judge 4x — against this PR's own thesis, and a judge timeout discards the whole multi-reviewer run with no verdict. The synthesis default is now 20m, preserving the prior effective bound while keeping the judge always bounded. - The command's Long help still promised 'default 20m; 0 disables both bounds' — both claims stale. Rewritten to the new contract: no reviewer default, judge separately bounded and never uncapped. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Entire-Checkpoint: 01KX0PWPRKDPWNYPN3PWMT2YQB
The 'restore 20m' commit updated the constant and the Long usage block but missed three references, leaving --help contradicting itself (flag string said 5m, usage block said 20m) — a user bounding CI cost would mis-estimate the judge's ceiling by 4x. Fixed the --timeout flag registration string, the judgeTimeoutArg doc comment, and the stale test comment. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Entire-Checkpoint: 01KX0QK2EKA17HTM2NK5Q1GYSV
Soph
approved these changes
Jul 8, 2026
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.
https://entire.io/gh/entireio/cli/trails/784
Problem
Reviewers were killed at a wall-clock default (10m, later raised to 20m) that conflates "slow because working" with "hung". Observed live: a reviewer at ~90% completion killed with everything discarded. Plain agent invocation has no such cliff — the user is the liveness check.
Two findings shaped the fix:
claudesession 9m57s vsentire review9m08s. Reviews take as long as they take, wherever they run.Change
--timeoutdefault:20m→0(none). Reviewers run until they finish, exactly like a directly-invoked skill. The flag remains as an explicit opt-in hard cap for CI/cost-bounded runs.judgeTimeoutArgmapping prevents the reviewer's no-cap sentinel leaking through as "judge unbounded".Testing
TestReviewerTimeout_NoDefaultCap,TestJudgeTimeoutArg, and the flag-resolution test updated to pin the new contractmise run test(7,604) green, lint clean🤖 Generated with Claude Code
Note
Medium Risk
Default behavior change means long or stuck reviewer processes are no longer auto-cancelled unless users pass
--timeout; multi-agent reviews may run much longer, though the judge consolidation step remains bounded.Overview
entire reviewno longer applies a wall-clock cap to reviewers by default (previously ~20m). Reviewers run until they finish, matching a skill invoked in a normal session;--timeoutstays an opt-in hard cap for CI or cost limits, with updated flag help (default0).reviewerTimeoutdrops the implicit default: only a positiveReviewerTimeoutenablescontext.WithTimeout; unset, zero, or the no-cap sentinel means no reviewer deadline.The consolidating judge is handled separately via
judgeTimeoutArg: an explicit positive--timeoutstill bounds the judge; when reviewers are uncapped, the reviewer sentinel must not disable the judge—the judge keeps its existing ~5m synthesis default.Tests pin the no-default-cap contract, judge mapping, and flag → resolver behavior.
Reviewed by Cursor Bugbot for commit fbe6fe6. Configure here.