Benchmark study
Babysitter writes its own tests, and just topped Terminal-Bench 2.1
Babysitter, our open-source orchestrator, drove Claude Opus 5 to solve 77 of 89 tasks when given time to work: 86.52%, ahead of every published entry. The tasks it won back are ones other agents nearly solve and then fumble. It passed them by writing its own acceptance tests and refusing to stop until they passed.
Summary
Terminal-Bench 2.1 measures whether an AI agent can do real engineering work in a terminal: 89 containerised tasks, each graded pass or fail by a test suite the agent never sees. The strongest published entry solves 83.82% of it.
We gave the same class of model a different working style. Babysitter, an open-source orchestrator, lets an agent write its plan as executable code, run it step by step, and keep every step on record. We also lifted the benchmark's per-task time limit, because an agent that builds and runs its own checks needs longer than one that answers in a single pass. The stack solved 77 of 89 tasks, 86.52%.
Our figure is the best result per task rather than an average over five attempts, so we treat it as a ceiling, not an expected score; section 01 spells out the differences. What the run demonstrates is concrete: five tasks this model fails under a conventional agent became passes once the agent could define what “done” means and check for it before stopping.
- 01The result
- 02The benchmark
- 03Why Babysitter wins
- 04Method
- 05What still fails
- 06Limitations
- 07Takeaway
- AAll 89 tasks
01The result
The public leaderboard for
terminal-bench/terminal-bench-2-1, with our result placed by score:
| Pos* | Agent | Model | Org | Effort | Score | SE | pass@5 | Trials | Hacks | Cost |
|---|---|---|---|---|---|---|---|---|---|---|
| 1* | Babysitter + Claude Code | Opus 5 | a5c.ai | xhigh | 86.52 | n/a | n/a | 172 | n/a | ~$1,080 |
| 2 | Claude Code | Fable 5 | Anthropic | xhigh | 83.82 | ±1.16 | 93.3 | 445 | -0.2% | $553 |
| 3 | Codex | GPT-5.5 | OpenAI | xhigh | 83.15 | ±1.13 | 94.4 | 445 | -0.2% | $2,059 |
| 4 | Terminus 2 | Fable 5 | Terminal-Bench | high | 80.45 | ±1.16 | 92.1 | 445 | -0.0% | $439 |
| 5 | Cursor CLI | Grok 4.5 | Cursor | high | 79.33 | ±1.46 | 95.5 | 445 | -9.0% | $134 |
| 6 | Claude Code | Opus 4.8 | Anthropic | high | 78.88 | ±1.31 | 94.4 | 445 | -0.0% | $287 |
| 7 | Codex | GPT-5.6 Terra | OpenAI | max | 78.43 | ±1.25 | 89.9 | 445 | -0.2% | $421 |
Published entries run at the benchmark's stock time limit and report the mean of five attempts per task. We lifted the time limit, and our figure takes each task's best result. Both differences favour us. On the closest comparable published number, pass@5, the field's best reaches 95.5% and the top entry 93.3%, both above us. Read our score as a ceiling on what the stack can solve, not as a leaderboard entry.
Five of the 77 passes are tasks this model failed under a conventional single-pass agent. They passed with no task-specific hints, no access to the test suite, and no changes to the benchmark's tasks or grading.
02The benchmark
Each Terminal-Bench task is a real job in a real container: recover a corrupted database, fit spectroscopy peaks, transcribe gameplay from a video, reformat a million-row file with Vim macros, harden a web server's logging. The agent gets a shell and an instruction. When it stops, a hidden test suite grades the final state of the machine. Pass or fail; no partial credit.
The leaderboard fixes the protocol: five attempts per task, stock time limits, task text exactly as shipped. The entries at the top pair a frontier model with a loop that feeds it tool output until it declares itself done. That design is fast, and it fails in a characteristic way, which is what this study is about.
03Why Babysitter wins
Watch a strong model fail this benchmark and the pattern is rarely ignorance. On the tasks our stack initially missed, the agent understood the problem and did most of the work, then stopped one step short:
- a Vim script that transformed a million rows correctly but omitted the save-and-quit line the task asked for by name;
- a repository cleaner that removed every secret, and also edited a file it was told to leave alone;
- a log formatter that produced the right data in the wrong shape;
- a database repair that wrote the wrong value and never compared it to the one in the brief.
None of these are knowledge failures. Every requirement was stated in the task text. The missing ingredient was a check, and a conventional agent loop has nowhere to put one: the model answers, the loop ends.
Babysitter changes where the check lives. The agent writes its plan as code, runs each step as a recorded action, and can make “my tests pass” the condition for being finished, instead of “my answer looks right”. On a representative task the transcript shows what it does with that ability, unscripted:
- freezes the task text into a spec file so later reasoning cannot drift from the brief;
- checksums and backs up the input before touching it;
- writes an acceptance harness: 479 lines, nine independent checks;
- feeds that harness a deliberately broken solution and requires it to fail, proving the tests can actually catch mistakes;
- implements, and keeps iterating until every check passes.
Step 4 is the detail to remember. The agent considered the possibility that its own tests were worthless and spent effort ruling it out.
Care like this costs time, but not always. On the log-formatting task the orchestrated run passed in 13 minutes; the conventional attempt had failed in 25.
04Method
The stack
| Component | Version | Role |
|---|---|---|
| Harbor | 0.20.0 | Runs the benchmark: provisions tasks, executes the hidden tests, scores |
| Adapter (ours) | — | Connects Harbor to the agent; validates transcripts, redacts credentials |
| Babysitter | 6.0.2 | The orchestrator: process as code, recorded steps, resumable runs |
| Claude Code | 2.1.226 | The agent: tool use inside the task container |
| Claude Opus 5 | — | The model, at maximum reasoning effort |
/babysitter:yolo <task> and the agent takes it from there.The dataset and every task image are pinned by cryptographic digest, and the canonical copies are never modified; runs execute against ephemeral copies. Trials ran on dedicated Azure hosts under Docker.
Time limit
Leaderboard submissions run at the benchmark's stock per-task time limit. We raised it: three times stock for the main pass, ten times where a run had been cut off mid-process. An agent that writes a spec, builds tests and iterates does more work per task than one that answers directly, and a limit calibrated for the second truncates the first. One task shows how sharp the edge is: killed at 46.8 minutes it scored 0 of 7 checks; given 50 minutes it scored 7 of 7.
The directive
For the ten tasks the stack had missed, we appended one sentence to the instruction, after the benchmark's own text, which stays first and verbatim:
use an iterative adversarial process converging to at least 75% score in at least 3 different dimensions
It names no task, no tool and no answer, only a way of working. It appears in each trial's recorded transcript, so anyone auditing a run sees exactly what was asked. Five of the ten tasks passed with it; they are named in Table 3 and marked in the appendix, and the score without them is 80.90%. We plan to build this behaviour into Babysitter itself, so it no longer needs to be asked for.
Fixes that bought nothing
Two bugs in our own harness were found and fixed before measurement: a native library that crashed the agent on older task images before it could start, and a client fallback that turned the provider's refusals into unreadable errors. Neither fix added a single pass. They corrected the diagnosis, not the score, and we report them because a study that only mentions the changes that worked is advertising.
Scoring and cost
Harbor grades all-or-nothing and counts an unscored trial as zero. Where a task ran more than once we take its best result. Cost is read from the gateway's own spend counter; per-trial token accounting is incomplete under this adapter, and deriving cost from it understates real spend by a wide margin.
05What still fails
12 tasks remain unsolved, and they do not fail for one reason.
| Task | Baseline | Outcome | What the run established |
|---|---|---|---|
| db-wal-recovery | 5/7 | Recovered | Passed 7/7 in 50 minutes at the raised limit. At the stock-multiple limit it was killed at 46.8 minutes with 0/7. |
| large-scale-text-editing | 4/5 | Recovered | Froze the spec, wrote an acceptance harness, proved the harness could reject a broken script, then iterated. The final script had the exit line. |
| nginx-request-logging | 7/8 | Recovered | Passed 8/8, faster than the conventional attempt: 13 minutes against 25. |
| sanitize-git-repo | 2/3 | Recovered | Passed 3/3. The self-check caught the stray edit the conventional run shipped. |
| video-processing | 4/5 | Recovered | Passed 5/5. The clock killed the agent at 181 minutes, but the workspace already passed every test; the grader scores final state. |
| extract-moves-from-video | 0/2 | No effect | Killed by the kernel at 13 minutes. The approach loads the whole decoded video into memory; a streaming approach fits the task's cap. |
| gcode-to-text | 1/2 | No effect | 1/2, finishing well inside the limit. The agent decoded the correct flag but wrapped it in a report; the grader wants the bare string. |
| pytorch-model-cli | 5/6 | No effect | 5/6 in 40 minutes of a 156-minute allowance, identical to the conventional result. Time was not the constraint. |
| raman-fitting | 2/3 | Regression | 1/3, down from 2/3. Both peaks missed tolerance; a numerical accuracy gap the directive does not address. |
| filter-js-from-html | 1/2 | No verdict | Crashed 32 minutes in with no tokens spent on the failing phase, no refusal and no model fallback. No verdict either way. |
Beyond these, four tasks fail because the model refuses them outright: it classifies them as offensive security and declines before any work begins. No orchestration reaches a request the model will not make. The remainder are honest gaps: a curve fit outside tolerance, a prediction vector that must match exactly, a video decode that exceeds the task's own memory cap, and one crash we could not attribute even with full logging.
On the G-code task the agent decoded the flag correctly, then wrapped it in a thorough analysis report. The grader wanted the bare string. An instruction that rewards converging on quality from several directions is exactly wrong when the answer must be one line. A built-in version needs to read the output contract before deciding how much to write.
06Limitations
- One attempt per configuration. No variance estimate; a task that passed once might not pass again.
- Best result per task. Retries went to tasks that had already failed, which pushes a best-of figure toward its maximum. It is a ceiling, not an expectation.
- Lifted time limit. Not eligible for leaderboard submission, and comparisons at a fixed limit partly measure whether the process fits the clock.
- Appended instruction text on ten tasks, five of which passed. Without them: 80.90%.
- No per-task leader data. Published submissions do not expose per-task results, so no task-level comparison with other entries is possible.
07Takeaway
The score is the headline; the mechanism is the news. Every task recovered here failed the same way first: a capable model did the hard part, then stopped without checking a requirement the task had stated outright. A bigger model does not fix that. A place to write down what “done” means, and a way to test for it before stopping, does. That is what process as code is for.
Given that ability, the agent froze specs, wrote acceptance tests, proved those tests could catch mistakes, and iterated until they passed. Nobody showed it how. The cost is time; the fix is a time budget sized for the work. Next, we fold this working style into Babysitter itself.
AAll 89 tasks
Green solved in a conventional run; accent solved under the directive described in §04; red unsolved. Hover a failure for its cause.