Skip to content

Make batch runs resumable, fault-tolerant, and shardable - #61

Merged
alanshurafa merged 3 commits into
masterfrom
claude/swebench-50task-resilience
Sep 3, 2026
Merged

Make batch runs resumable, fault-tolerant, and shardable#61
alanshurafa merged 3 commits into
masterfrom
claude/swebench-50task-resilience

Conversation

@alanshurafa

Copy link
Copy Markdown
Owner

Fifty tasks across five arms is roughly twelve hours serially. At that length an
interruption is likely, and the runner had no answer for one: a single arm that
produced no patch aborted the batch and discarded every remaining cell, and
restarting was impossible because prepare-instance refuses a directory that
already exists.

Changes

Resume. A cell holding a prediction.json is reused. A cell without one is
an abandoned clone from an interrupted attempt and gets re-prepared. Rerunning
the same command retries only what is missing.

Fault tolerance. A cell that fails is counted and reported instead of ending
the run. That is the correct reading: the subset is the denominator either way,
so an arm with no patch scores zero for that task rather than invalidating the
other 49.

Sharding. --shard N/M splits the subset across M processes on disjoint
instances. Wall clock falls by roughly M; provider concurrency rises by M, which
is the real ceiling on how far it can be pushed.

Shards write separate prediction files, because concurrent appends to one file
interleave, and each validates only its own so a sibling mid-write is not
reported as corrupt. A finished cell whose line is missing from the current
shard's file is re-linked from the cell itself, so a resume under a different
shard layout still yields complete prediction files.

Verification

test-code-bench.sh goes from 38 to 41 assertions: a cell with a prediction is
reused rather than rerun, shards partition the subset exactly once each, and a
shard index outside its count is rejected.

The partition test is functional rather than arithmetic — it seeds all five
canary cells, runs both halves of a 0/2 and 1/2 split, and asserts the two
shards between them claim all five instances with neither taking none nor all.

🤖 Generated with Claude Code

alanshurafa and others added 2 commits September 2, 2026 19:27
A fifty-task batch is hours long. One arm that produced no patch aborted the
whole run and discarded every remaining cell, and restarting was impossible
because prepare refuses a directory that already exists.

A cell holding a prediction is now reused, an abandoned clone from an
interrupted attempt is re-prepared, and a cell that fails is counted and
reported rather than ending the batch. Rerunning the same command retries only
what is missing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Fifty tasks across five arms is roughly twelve hours serially, which is long
enough that an interruption is likely and a mistake is expensive. --shard N/M
splits the subset across M processes on disjoint instances, so wall clock falls
by about M.

Shards write separate prediction files because concurrent appends to one file
interleave, and each validates only its own so a sibling mid-write is not
reported as corrupt. A finished cell whose line is missing from the current
shard's file is re-linked from the cell itself, so a resume under a different
shard layout still produces complete prediction files.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-02T23:43:14.825981Z 9eedc40 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9eedc40fcb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

input=$(bash "$CODE_DIR/scripts/prepare-swebench-instance.sh" "$instance" "$RUN_ID" "$condition")
cell="$runs_root/$instance/$condition"
if (( SHARD_COUNT > 1 )); then
pred_file="$pred_dir/$condition.s$SHARD_INDEX.jsonl"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Isolate prediction files by the complete shard layout

When a run is resumed with a different shard count, the same index reuses the old filename because M is omitted: for example, 0/2 leaves instances 0, 2, and 4 in A.s0.jsonl, then 0/3 retains those records and adds instance 3. The new s1 and s2 files subsequently duplicate instances 4 and 2, so the shards are no longer disjoint and concatenating them fails duplicate validation. Include the shard count in the filename or rebuild each projection for the current layout.

Useful? React with 👍 / 👎.

Comment on lines +86 to +89
if (( SHARD_COUNT > 1 )); then
pred_file="$pred_dir/$condition.s$SHARD_INDEX.jsonl"
else
pred_file="$pred_dir/$condition.jsonl"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Consolidate shard outputs before exposing the run

A successful sharded condition now exists only as multiple partial files, but the repository's evaluation entry point accepts one prediction file (scripts/evaluate-swebench.sh:43-50) and the site builder retains only the latest evaluator report for each condition (benchmarks/site/build-site-data.py:56-70). Evaluating shards separately therefore makes the last shard supersede the others, while evaluating any one file omits the remaining tasks; no merge path exists in the repository. Produce a consolidated condition JSONL or teach evaluation and aggregation to combine all shard files.

AGENTS.md reference: AGENTS.md:L153-L154

Useful? React with 👍 / 👎.

Comment on lines +99 to +101
if ! jq -e --arg id "$instance" 'select(.instance_id == $id)' "$pred_file" \
>/dev/null 2>&1; then
jq -c . "$cell/prediction.json" >> "$pred_file"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Repair a truncated projection instead of appending to it

If an interruption occurs while the driver is appending its potentially large JSON record, prediction.json may already be complete while the JSONL ends with a partial line. On resume, the lookup fails to parse that file and this branch appends the good record after the corrupt bytes, so final validation still aborts and the supposedly resumable run cannot recover without manual file editing. Detect parse failure separately and reconstruct the projection from completed cell records rather than appending.

Useful? React with 👍 / 👎.

A leaderboard that shows only a score answers half the question. Wall time,
reported cost, and cost per resolved task are what both reference benchmarks
lead with, and they were missing or wrong here: Codex time and tokens were never
read at all, so an arm that spent twenty minutes of Codex effort showed a blank.
Both are now taken from the log each phase already writes.

An unfinished run was the worse problem. Scoring an arm that has run 21 of 50
tasks against 50 reports it as a 42% failure when it has actually solved
everything it reached. An arm is now scored against the tasks it ran, labelled
in progress, and the page says plainly that arms which have run different
numbers of tasks cannot be compared to each other.

A cost figure that covers only an arm's Claude phases is marked, because Codex,
GLM and Kimi report no cost and rendering that as $0.00 reads as free rather
than as unmeasured.

Evaluator reports now carry a run label. Named only by timestamp, reports from
two runs of one condition were indistinguishable and a page built across them
silently mixed a 50-task subset with a 1-task one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@alanshurafa
alanshurafa merged commit ef25a75 into master Sep 3, 2026
6 checks passed
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