Skip to content

feat(rubrics_verifier): opt-in judge timeout retries, a judge turn cap, and override points for staging and judge config - #679

Open
sarah-chitty-1 wants to merge 7 commits into
sarahchitty/fd-5840-turn-readerfrom
sarahchitty/fd-5840-verifier-hooks
Open

sarah-chitty-1 wants to merge 7 commits into
sarahchitty/fd-5840-turn-readerfrom
sarahchitty/fd-5840-verifier-hooks

Conversation

@sarah-chitty-1

@sarah-chitty-1 sarah-chitty-1 commented Nov 14, 2026 •

Copy link
Copy Markdown
Collaborator

What and why

Second of three stacked PRs for always-on grading (Linear FD-5840); it builds on #678. It makes small, opt-in additions to rubrics_verifier that the always-on verifier in #680 uses. Every one is off unless a task or subclass turns it on.

  • judge_timeout_retries (unset by default). When an agent judge call runs out of time, it is tried again. The timed-out attempt's trajectory is fetched and logged in judge_output_discrepancies (kind: judge_timeout), so there's a record of what the judge did. If the last attempt also runs out, the error (JudgeTimeoutError) carries that trajectory's link. A batch retries on its own, so the other batches keep going.
    • "Ran out of time" means the poll's own deadline, or a failed task whose error code says so (<harness>.timeout, as OpenHands and pydantic-ai send).
    • When the code doesn't say (none, or Claude Code's cli_error), it falls back to the message phrase "timed out after Ns", which Claude Code already sends.
    • A model API timeout ("The operation timed out") is not treated as the judge running out of time.
  • judge_max_turns (unset by default): sent to the judge as max_turns.
  • The Claude Code agent's peer_tools setting (default true, so every other use is unchanged). False leaves the SDK's peer_agents MCP server out of the turn, so the agent can't message or start other agents. The card lists it.
  • stage_trajectory, an override point. A subclass can stage the run in the judge's sandbox itself and say where (StagedTrajectory). Returning None, the default, loads the trajectory exactly as before.
  • judge_agent_config, an override point for extra judge settings; {} by default. It logs any setting the judge's card doesn't take.
  • Run.firings_read(): the trigger firings of every log that could be read.

Backward compatibility

  • With none of the new settings, rubrics_verifier behaves as before: a timeout still fails at once, nothing extra is fetched, and the judge config, prompt and trajectory loading are unchanged.
  • The Claude Code agent is unchanged unless a caller sets peer_tools: false. Its error codes and messages are as before.
  • One fix that applies to every verifier: if loading the trajectory into the judge's sandbox fails, a judge the verifier deployed itself is now terminated (before, it was only terminated after grading). The existing termination code moved into one helper, _terminate_auto_deployed_judge, used by both paths.

How it was tested

  • New: tst/unit/task_step/verifiers/test_rubrics_verifier_judge_timeout_retry.py. It covers:
    • the default failing at once;
    • a retry that keeps the timed-out trajectory;
    • a harness's timeout code and the message fallback (Claude Code's cli_error with "timed out after Ns");
    • three failures that are not retried;
    • round-trips and validation;
    • extra config sent only when the judge's card takes it.
  • A Claude Code agent test checks that peer_tools: false leaves the peer_agents server out of the turn.
  • New: test_rubrics_verifier_staging_cleanup.py checks that a failed staging terminates the judge the verifier deployed (it fails without the fix).
  • pytest tst/unit/agents/claude_code tst/unit/task_step/verifiers passes at this commit (771 passed), and tst/unit/task_step passes with feat(always_on_agent_verifier): with use_trajectory, the agent judge searches every wake staged as files #680 on top (3,372 passed); ruff check is clean.

🤖 Generated with Claude Code

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; no actionable issues remain.

Summary

Adds optional judge timeout retries, a turn cap, staging and config hooks, and a Claude Code peer_tools setting.

  • Agent judges can retry calls that hit their time limit.
  • Verifier subclasses can set judge turn limits and options.
  • Subclasses can stage the run where an agent judge reads it.
  • Failed trajectory staging now releases a verifier-deployed judge.
  • Claude Code turns can leave peer-agent tools out.
  • Run callers can read trigger firings from available logs.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Prepare judge] --> B[Stage trajectory]
    B -->|Staging fails| C[Terminate auto-deployed judge]
    B -->|Ready| D[Run judge]
    D -->|Timeout retries enabled| E[Capture trajectory]
    E --> F{Retries remain?}
    F -->|Yes| D
    F -->|No| G[Raise timeout with trajectory link]
    D -->|Completed| H[Check judge output]
    H --> I[Terminate auto-deployed judge]
    G --> I
Loading

Reviews (8) · Last reviewed commit: "Merge #678 into #679" · Reviewed by Greptile

…p, and override points for staging and judge config

- judge_timeout_retries (unset: a timeout fails at once, as before): an agent judge
  call that runs out of time is tried again; the timed-out attempt's trajectory is
  fetched and logged under judge_output_discrepancies (kind judge_timeout), or
  carried on JudgeTimeoutError. Running out of time is the poll's own deadline, or a
  failed task whose error code says so (`<harness>.timeout`); only a code that
  doesn't tell falls back to the message's "timed out after Ns".
- The Claude Code agent fails a turn that ran out of its timeout with error code
  claude_code.timeout (was cli_error), as other harnesses name theirs.
- The Claude Code agent's config takes peer_tools (default true): false leaves the
  SDK's peer_agents MCP server out of a turn, for an agent that must not message
  the task's other agents.
- judge_max_turns (unset: the judge's own): sent as the judge's max_turns.
- stage_trajectory: a subclass may stage the run in the judge's sandbox itself
  (StagedTrajectory); None, the default, loads the trajectory as before.
- judge_agent_config: extra judge settings, {} by default.
- Run.firings_read: the firings of every log that could be read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sarah-chitty-1
sarah-chitty-1 force-pushed the sarahchitty/fd-5840-verifier-hooks branch from a87e0b4 to 24c5385 Compare November 14, 2026 01:09
The verifier's timeout retry already recognises a Claude Code timeout from its
message ("timed out after Ns"), so the new claude_code.timeout code isn't
needed. Dropping it leaves this PR with no behaviour change for anyone who
doesn't opt in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sarah-chitty-1 added a commit that referenced this pull request Nov 14, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sarah-chitty-1 and others added 3 commits November 13, 2026 18:30
…en loading the trajectory fails

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sarah-chitty-1 added a commit that referenced this pull request Nov 14, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sarah-chitty-1 added a commit that referenced this pull request Nov 14, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sarah-chitty-1 added a commit that referenced this pull request Nov 14, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sarah-chitty-1 added a commit that referenced this pull request Nov 14, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant