Skip to content

Commit 899048c

Browse files
varunursekarclaude
andcommitted
Re-time case/verifier timeouts from baseline waits; fix officeqa optimizer loop
Audited the held-out baseline per-case wall times: the codex-probe-sized case_timeouts were too tight for the real target agents, so ~9/13/26% of gaia/officeqa/browsecomp candidate cases would be killed (scored failure) against leniently-measured baselines. Raise case_timeout to >= each benchmark's baseline max: gaia 180->900, officeqa 300->1200, tau3 900->1200, browsecomp 900->2100 (swe-atlas 1800 already fine). The pinned baselines themselves ran lenient (near-zero timeout exceptions), so they stay valid. Harbor runs the agent and verifier phases on independent clocks, and the optimizer agent phase is unbounded (governed by the gateway token budget), so verifier_timeout must cover only finalization. A verifier timeout loses the score, so size generously for n_attempts x held-out + rescore headroom: gaia 7200->10800, officeqa 14400->25200, tau3 28800->43200, browsecomp 57600->64800. Per-eval timeouts already have ample headroom; unchanged. officeqa also gets agent_env raising BASH_MAX_TIMEOUT_MS + disabling forced background tasks, so the Claude Code optimizer blocks on a whole 15-30min eval in one Bash call instead of detach/poll/end-turn (which ended the headless run after a single eval). CONFIGURATION.md updated with the new values + rationale. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent d004428 commit 899048c

5 files changed

Lines changed: 67 additions & 23 deletions

File tree

harness-engineering-bench/CONFIGURATION.md

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -68,23 +68,38 @@ benchmark can be checked against the others at a glance.
6868
| dev budget (runs / cases) | 100 / 132 | 100 / 196 | 100 / 100 | 100 / 300 | 100 / 132 |
6969
| val budget (runs / cases) | 100 / 264 | 100 / 392 | 100 / 196 | 100 / 600 | 100 / 264 |
7070
| timeout_seconds (per eval) | 3600 | 7200 | 14400 | 14400 | 28800 |
71-
| case_timeout_seconds (enforced) | 180 | 300 | 1800 | 900 † | 900 † |
71+
| case_timeout_seconds (enforced) | 900 | 1200 | 1800 | 1200 | 2100 |
7272
| task_agent_timeout_seconds (declared) | 600 | 1800 | 10800 | 3600 | 3600 |
73-
| verifier_timeout_seconds | 7200 | 14400 | 28800 | 28800 | 57600 |
73+
| verifier_timeout_seconds | 10800 | 25200 | 28800 | 43200 | 64800 |
7474
| harness_user | harness | harness | null ‡ | null ‡ | null ‡ |
7575
| task_services_use_upstream | false | false | true (rubric judge) | true (user-sim + grader) | true (answer judge) |
7676
| task-specific extras || `--no-force-build` (prebuilt corpus image) | `keepalive` --ek (ENTRYPOINT images) | `TAU2_*` model pins | pinned 2.2 GB BM25 index |
7777

7878
## Conventions
7979

80-
- **Timeouts**: `task_agent_timeout_seconds` mirrors the agent timeout the
81-
dataset's task packages declare; `case_timeout_seconds` is the per-case
82-
budget VeRO actually enforces (compiled to Harbor's agent-timeout
83-
multiplier). Set both explicitly — omitting them silently applies the
80+
- **Timeouts are per-phase, not one shared wall.** Harbor runs the optimizer
81+
agent phase and the verifier (finalization) phase with independent clocks, so
82+
a long search does not eat into finalization's budget and vice versa. The
83+
**optimizer agent phase is unbounded** (vero sets no `[agent] timeout_sec`);
84+
the search is governed by the gateway token budget, not wall time.
85+
- **`case_timeout_seconds` is the enforced per-case wall cap**;
86+
`task_agent_timeout_seconds` is the task-declared agent timeout used only as
87+
the rescale denominator (Harbor's per-case timeout = declared ×
88+
`case_timeout/task_agent_timeout`). `case_timeout` may exceed
89+
`task_agent_timeout`. Set both explicitly — omitting them silently applies the
8490
180/600 defaults regardless of what the tasks declare.
85-
- **Verifier timeout** is 2× `timeout_seconds`: finalization runs the
86-
candidate and the baseline test evaluations.
91+
- **`verifier_timeout_seconds`** bounds only finalization (the held-out
92+
evaluation of the selected candidate), sized for `n_attempts` × held-out +
93+
rescore headroom (‖). A verifier timeout yields no reward (the score is lost,
94+
only agent artifacts are salvaged), so it is sized generously.
8795
- **Case budgets** are 4× the partition size, i.e. four full passes.
96+
- **Optimizer `agent_env`** (currently on officeqa; propagate to all): inner
97+
evals take 15–30 min, but Claude Code caps a single Bash call at
98+
`BASH_MAX_TIMEOUT_MS` (default 600000=10min), which forces the agent into
99+
`--detach` + background-poll + end-turn — and in headless `--print` mode,
100+
ending the turn ends the run. Set `BASH_MAX_TIMEOUT_MS`/`BASH_DEFAULT_TIMEOUT_MS`
101+
high and `ENABLE_BACKGROUND_TASKS`/`FORCE_AUTO_BACKGROUND_TASKS=0` so the agent
102+
blocks on a whole eval in one call and stays in-loop.
88103
- **`infrastructure_max_attempts: 3`** applies only to trusted finalization
89104
re-scores. For competitive (agent) evaluations, whole-sub-run infrastructure
90105
retry is disabled and a within-trial transient-infra failure is scored at the
@@ -115,11 +130,20 @@ each agent sends `model_name.removeprefix("openai/")`, so an `openai/`-prefixed
115130
name would be allow-listed in one form and requested in another and the gateway
116131
would deny it.
117132

118-
† Sized from stock-agent probes (codex on the target model, 3 development
119-
tasks each, full declared timeouts): tau3 trials took 202-211s (900s budget
120-
≈ 4x headroom) and swe-atlas trials 379-602s (1800s ≈ 3x headroom over the
121-
slowest). BrowseComp-Plus provisionally uses the tau3 limit. Revisit against
122-
`wall_seconds` distributions from real runs.
133+
† Sized from the **held-out baseline** per-case wall-time distributions (the seed
134+
target agent on each benchmark's target model), set at or above each benchmark's
135+
observed max: gaia p99≈608/max≈609 → 900; officeqa p99≈640/max≈1076 → 1200;
136+
swe-atlas p99≈1163/max≈1278 → 1800 (unchanged); tau3 p99≈643/max≈1122 → 1200;
137+
browsecomp p99≈1479/max≈1771 → 2100. This replaces the earlier codex-probe
138+
sizing, which was too tight for the real target agents — the prior caps
139+
(180/300/900) would have killed ~9/13/26% of gaia/officeqa/browsecomp candidate
140+
cases, scoring candidates far harsher than the leniently-measured baselines.
141+
142+
`verifier_timeout_seconds` sized to ~1.5× a with-rescore finalize
143+
(`n_attempts=3` × held-out eval + `rescore_top_k=3` × validation eval), for
144+
salvage headroom even though the validation rescore does not fire in the
145+
`submit` selection path. Because phases are independent, this covers
146+
finalization only — not the search.
123147

124148
‡ Exception to the harness-isolation default: these tasks run LLM services
125149
(rubric judge, user-simulator/grader, or answer judge) inside their task

harness-engineering-bench/browsecomp-plus/baseline/build.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,13 @@ feedback_transcripts: true
5959
feedback_max_bytes: 16000
6060
expose_attempt_detail: false
6161
timeout_seconds: 28800
62-
case_timeout_seconds: 900
62+
# Raised from 900: baseline p99 ~1479s / max ~1771s exceeded 900, killing ~26% of cases.
63+
# task_agent_timeout is the task-declared denominator; case_timeout is the enforced cap.
64+
case_timeout_seconds: 2100
6365
task_agent_timeout_seconds: 3600
6466
max_concurrency: 8
6567
error_rate_threshold: 0.1
66-
verifier_timeout_seconds: 57600
68+
verifier_timeout_seconds: 64800 # sized for 3x held-out finalize + rescore headroom (~11.5h + margin)
6769
secrets:
6870
- MODAL_TOKEN_ID
6971
- MODAL_TOKEN_SECRET

harness-engineering-bench/gaia/baseline/build.yaml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,16 @@ feedback_transcripts: true
6666
feedback_max_bytes: 16000
6767
expose_attempt_detail: false
6868
timeout_seconds: 3600
69-
case_timeout_seconds: 180
69+
# case_timeout raised from 180: baseline p99 case wall ~608s (agent's own MAX_TURNS
70+
# cap) exceeded 180, killing ~9% of cases. task_agent_timeout is the task-declared
71+
# denominator; the enforced per-case cap is case_timeout_seconds.
72+
case_timeout_seconds: 900
7073
task_agent_timeout_seconds: 600
7174
max_concurrency: 8
7275
error_rate_threshold: 0.1
73-
verifier_timeout_seconds: 7200
76+
# verifier phase is separate from the (unbounded) agent phase; size for finalization
77+
# only: 3x held-out (n_attempts) + rescore headroom. A verifier timeout loses the score.
78+
verifier_timeout_seconds: 10800
7479
secrets:
7580
- MODAL_TOKEN_ID
7681
- MODAL_TOKEN_SECRET

harness-engineering-bench/officeqa/baseline/build.yaml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,11 @@ feedback_transcripts: true
7171
feedback_max_bytes: 16000
7272
expose_attempt_detail: false
7373
timeout_seconds: 7200
74-
case_timeout_seconds: 300
74+
case_timeout_seconds: 1200 # raised from 300: baseline p99 ~640s / max ~1076s exceeded 300, killing ~13% of cases
7575
task_agent_timeout_seconds: 1800
7676
max_concurrency: 8
7777
error_rate_threshold: 0.1
78-
verifier_timeout_seconds: 14400 # 2x timeout_seconds: finalization runs candidate + baseline test evals
78+
verifier_timeout_seconds: 25200 # sized for 3x held-out finalize (n_attempts=3) + rescore headroom (~4.5h + margin)
7979
secrets:
8080
- MODAL_TOKEN_ID
8181
- MODAL_TOKEN_SECRET
@@ -85,6 +85,19 @@ secrets:
8585
# candidate harness runs as an unprivileged uid, unable to read held-out state.
8686
harness_user: harness
8787

88+
# Optimizer-agent env (forwarded to the harbor claude-code agent as --ae KEY=VALUE).
89+
# Inner evals take 15-30 min; Claude Code's Bash tool caps a single call at
90+
# BASH_MAX_TIMEOUT_MS (default 600000=10min), which forced the agent into
91+
# --detach + background-poll + end-turn (it then ended its turn waiting for a
92+
# notification that never re-wakes a headless --print run). Raise the cap so the
93+
# agent can block on a whole eval in one Bash call, and disable the background
94+
# tasks harbor otherwise forces on, so it stays in-loop instead of detaching.
95+
agent_env:
96+
BASH_MAX_TIMEOUT_MS: "3600000" # 60 min: a full eval fits in one blocking call
97+
BASH_DEFAULT_TIMEOUT_MS: "1800000" # 30 min default, so un-timed eval calls still block
98+
ENABLE_BACKGROUND_TASKS: "0" # remove the detach/background temptation
99+
FORCE_AUTO_BACKGROUND_TASKS: "0" # harbor forces these on; the --ae overlay wins
100+
88101
wandb:
89102
project: harness-engineering-bench
90103
group: officeqa # keeps the benchmark distinguishable in the shared project

harness-engineering-bench/tau3/baseline/build.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,13 @@ feedback_transcripts: true
5959
feedback_max_bytes: 16000
6060
expose_attempt_detail: false
6161
timeout_seconds: 14400
62-
# Tasks declare a 3600s agent timeout; 900s is the enforced per-case budget.
63-
# Provisional - revisit against empirical wall_seconds once runs report it.
64-
case_timeout_seconds: 900
62+
# Tasks declare a 3600s agent timeout (the denominator); case_timeout is the enforced
63+
# per-case budget. Raised from 900 to 1200: baseline max case wall ~1122s exceeded 900.
64+
case_timeout_seconds: 1200
6565
task_agent_timeout_seconds: 3600
6666
max_concurrency: 8
6767
error_rate_threshold: 0.1
68-
verifier_timeout_seconds: 28800 # 2x timeout_seconds: finalization runs candidate + baseline test evals
68+
verifier_timeout_seconds: 43200 # sized for 3x held-out finalize + rescore headroom (~8h + margin)
6969
secrets:
7070
- MODAL_TOKEN_ID
7171
- MODAL_TOKEN_SECRET

0 commit comments

Comments
 (0)