/deep-research: rate-limited verifier abstentions reported as refutations ("all refuted / inconclusive" false negative)
Summary
The bundled /deep-research workflow misreports verifier abstentions (verifier calls that fail on transient API rate-limiting and return no votes) as evidentiary refutations. A run whose verification phase is rate-limited can return "All N claims refuted by adversarial verification. Research inconclusive" — and populate the structured refuted[] with claims that were never actually adjudicated. The claims may all be true and well-sourced; nothing was checked.
Environment
- Claude Code CLI 2.1.193, the bundled
/deep-researchworkflow. - Triggered when the adversarial verify phase hits transient server-side rate-limiting (
Server is temporarily limiting requests — not your usage limit). The limiter hits the verifier calls in a correlated burst, so the whole run is affected at once.
What happens
The 3-vote adversarial verify phase scores each claim as a notRefuted–refuted tally. Under rate-limiting, every verifier vote errors and the tally is 0–0 (zero valid votes). The survive-rule (≈ validVotes >= 2 && refuted < 2) correctly refuses to pass an unverified claim — that part is right.
The defect is in the reporting layer: the non-surviving (abstained) claims are placed into result.refuted[], and the summary renders them as "all refuted / research inconclusive." A crashed adjudicator's silence is reported as a verdict.
Expected
A claim with fewer than the quorum of valid votes is UNVERIFIED (not adjudicated) — distinct from REFUTED (a quorum of refuting votes). The structured output and the summary should keep them distinct:
refuted[]should contain only claims with a real refuting quorum.- Abstained / unverified claims belong in a separate bucket (e.g.
unverified[]). - An all-abstain run should report "verification did not complete — N claims unverified, retry," not "all refuted / research inconclusive."
Impact
A single transient, correlated outage turns an entire research run into a wall of confident false negatives. Downstream, the user discards true, well-sourced findings because the report says they were "refuted." The failure is invisible: a clean-looking "inconclusive" summary, with no indication that verification never actually ran.
Suggested fix
- Classify on valid-vote count first:
validVotes < quorum→unverified, before the refuted comparison is evaluated. - Treat a verifier call that errors / times out / returns null as an abstention → retry up to N with backoff; never count it as clean or as refuted.
- Reporting: never render "inconclusive / all-refuted" when a run is abstention-dominated; report the operational failure (verification did not complete) instead.
Workaround (for others hitting this)
Re-classify the saved run output by splitting refuted[] into genuinely-refuted (≥ quorum refuting votes) vs unverified (< quorum valid votes). Then resume the run so only the abstained verifier calls re-execute, rather than re-running the whole pipeline; a gentle sequential top-up for the tail won't re-trip the shared limiter.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗