Why KISS Sorcar trails the HarnessTax agents, and how to close the gap

A post-mortem of the 1,260-attempt replication of the HarnessTax study (7 models × 2 benchmarks × 30 tasks × 3 repetitions), built from the trial trajectories, the official SWE-bench and Harbor verifier logs, and the 2.25 million events the KISS daemon recorded in ~/.kiss-harnesstax/sorcar.db. Dated 2026-09-20.

71.4%SWE-bench Lite, KISS Sorcar
Pi 71.9% · Codex 73.7% · Claude Code 73.4%
67.9%Terminal-Bench 2, KISS Sorcar
Pi 70.0% · Codex 65.7% · Claude Code 65.1%
$606total model spend
$257 of it on attempts that failed
66TB2 attempts killed by the wall clock
$102 spent, 28 min each on average

1. Which KISS Sorcar agent ran the comparison

Every attempt was a task submitted to a private KISS daemon (KISS_HOME=~/.kiss-harnesstax) and executed by the standard Sorcar agent (src/kiss/agents/sorcar/sorcar_agent.py, wrapped by relentless_agent.py and built on KISSAgent). The Sorcar agent was loaded with a Sorcar Extension Agent (SEA) generated per trial from benchmarkings/harnesstax/sea_core.py. The SEA replaces Sorcar's normal tool set and system prompt with a deliberately minimal harness modelled on the blog's Pi harness:

Harbor / SWE-bench runnertb2_runner.py, swebench_runner.pytrials.run_sea_trial()writes SEA file + configkiss.server.sorcar.run()daemon at ~/.kiss-harnesstax/sorcar.sockSorcar agentrelentless_agent → KISSAgentContainerHarness SEAbash · read · write · edit · finishdocker exectask containerOne trial = one daemon task; model, turn cap (100) and budget ($15) come from the SEA config. The Sorcar wrapper adds its own instruction block, the usage trailer and the relentless session loop.
Call chain of one attempt. The runner never talks to the model directly: it goes through the daemon so that cost, tokens and every streamed event land in sorcar.db.

What the Sorcar wrapper still contributes on top of the SEA matters for the analysis below: it appends its own "MOST IMPORTANT INSTRUCTIONS" block (~1,100 characters about finish(success=False, is_continue=True, summary_in_html=…), the work directory and the process id) to the system prompt, appends a usage trailer (Steps: N/10000, Context: …, Budget: $…/$15.00) to every tool result, requires an HTML summary and a suggested next task in finish, and runs the relentless session loop that restarts a fresh session when a session ends without success=True. The 10,000 in the trailer is Sorcar's step limit, not the SEA's 100-turn cap; the model never saw the real cap or the remaining wall-clock time.

2. How far behind is it, really

Averaged over the seven models, KISS Sorcar is 0.5 points behind Pi on SWE-bench Lite and 2.1 points behind on Terminal-Bench 2, ahead of Codex and Claude Code on Terminal-Bench 2 (67.9% vs 65.7% and 65.1%), and behind them on SWE-bench Lite (71.4% vs 73.7% and 73.4%). Per model it is within a few points of Pi on both benchmarks; on SWE-bench Lite it is cheaper than Pi with Fable, Opus, Sonnet and Kimi and 20–40% dearer with Haiku, Sol and Luna. The visible gaps are against Codex and Claude Code with the two strongest Claude models on SWE-bench Lite (Fable 5: 93.3% vs 96.7% / 97.8%; Opus 4.8: 81.1% vs 88.9% / 86.7%) and against Pi on Terminal-Bench 2 with Opus 4.8 (63.3% vs 72.2%), Sol (−4.4) and Luna (−3.4). Each of those gaps is between 3 and 8 attempts out of 90.

SWE-bench Lite

ModelKISS SorcarPiCodexClaude Code
solved$/attemptsolved$/attemptsolved$/attemptsolved$/attempt
Fable 593.3%$0.55996.7% (-3.4)$0.66696.7% (-3.4)$0.89097.8% (-4.5)$1.329
Opus 4.881.1%$0.37882.2% (-1.1)$0.47388.9% (-7.8)$0.69486.7% (-5.6)$0.976
Sonnet 4.664.4%$0.51964.4% (+0.0)$0.67968.9% (-4.5)$0.74566.7% (-2.3)$0.669
Haiku 4.560.0%$0.47160.0% (+0.0)$0.37457.8% (+2.2)$0.39252.2% (+7.8)$0.426
GPT-5.6 Sol76.7%$0.61574.4% (+2.3)$0.44173.3% (+3.4)$0.56177.8% (-1.1)$1.540
GPT-5.6 Luna53.3%$0.03653.3% (+0.0)$0.03055.6% (-2.3)$0.03555.6% (-2.3)$0.152
Kimi K371.1%$0.42572.2% (-1.1)$0.45574.4% (-3.3)$0.84576.7% (-5.6)$0.784
7-model mean71.4%$0.42971.9%$0.44573.7%$0.59573.4%$0.839

Terminal-Bench 2

ModelKISS SorcarPiCodexClaude Code
solved$/attemptsolved$/attemptsolved$/attemptsolved$/attempt
Fable 571.1%$1.12071.1% (+0.0)$1.07972.2% (-1.1)$0.97675.6% (-4.5)$1.554
Opus 4.863.3%$0.86672.2% (-8.9)$0.75872.2% (-8.9)$0.84868.9% (-5.6)$0.899
Sonnet 4.668.9%$0.59365.6% (+3.3)$0.61463.3% (+5.6)$0.55262.2% (+6.7)$0.669
Haiku 4.545.6%$0.29747.8% (-2.2)$0.25031.1% (+14.5)$0.21441.1% (+4.5)$0.263
GPT-5.6 Sol78.9%$0.55383.3% (-4.4)$0.42178.9% (-0.0)$0.76171.1% (+7.8)$1.355
GPT-5.6 Luna73.3%$0.04576.7% (-3.4)$0.04572.2% (+1.1)$0.06470.0% (+3.3)$0.098
Kimi K374.4%$0.25973.3% (+1.1)$0.38370.0% (+4.4)$0.45066.7% (+7.7)$0.521
7-model mean67.9%$0.53370.0%$0.50765.7%$0.55265.1%$0.766
Success rate — SWE-bench Lite (30 tasks × 3)0%25%50%75%100%KISS Sorcar / Fable 5: 93%93%Pi / Fable 5: 97%97%Codex / Fable 5: 97%97%Claude Code / Fable 5: 98%98%Fable 5KISS Sorcar / Opus 4.8: 81%81%Pi / Opus 4.8: 82%82%Codex / Opus 4.8: 89%89%Claude Code / Opus 4.8: 87%87%Opus 4.8KISS Sorcar / Sonnet 4.6: 64%64%Pi / Sonnet 4.6: 64%64%Codex / Sonnet 4.6: 69%69%Claude Code / Sonnet 4.6: 67%67%Sonnet 4.6KISS Sorcar / Haiku 4.5: 60%60%Pi / Haiku 4.5: 60%60%Codex / Haiku 4.5: 58%58%Claude Code / Haiku 4.5: 52%52%Haiku 4.5KISS Sorcar / GPT-5.6 Sol: 77%77%Pi / GPT-5.6 Sol: 74%74%Codex / GPT-5.6 Sol: 73%73%Claude Code / GPT-5.6 Sol: 78%78%GPT-5.6 SolKISS Sorcar / GPT-5.6 Luna: 53%53%Pi / GPT-5.6 Luna: 53%53%Codex / GPT-5.6 Luna: 56%56%Claude Code / GPT-5.6 Luna: 56%56%GPT-5.6 LunaKISS Sorcar / Kimi K3: 71%71%Pi / Kimi K3: 72%72%Codex / Kimi K3: 74%74%Claude Code / Kimi K3: 77%77%Kimi K3KISS SorcarPiCodexClaude Code
Success rate — Terminal-Bench 2 (30 tasks × 3)0%25%50%75%100%KISS Sorcar / Fable 5: 71%71%Pi / Fable 5: 71%71%Codex / Fable 5: 72%72%Claude Code / Fable 5: 76%76%Fable 5KISS Sorcar / Opus 4.8: 63%63%Pi / Opus 4.8: 72%72%Codex / Opus 4.8: 72%72%Claude Code / Opus 4.8: 69%69%Opus 4.8KISS Sorcar / Sonnet 4.6: 69%69%Pi / Sonnet 4.6: 66%66%Codex / Sonnet 4.6: 63%63%Claude Code / Sonnet 4.6: 62%62%Sonnet 4.6KISS Sorcar / Haiku 4.5: 46%46%Pi / Haiku 4.5: 48%48%Codex / Haiku 4.5: 31%31%Claude Code / Haiku 4.5: 41%41%Haiku 4.5KISS Sorcar / GPT-5.6 Sol: 79%79%Pi / GPT-5.6 Sol: 83%83%Codex / GPT-5.6 Sol: 79%79%Claude Code / GPT-5.6 Sol: 71%71%GPT-5.6 SolKISS Sorcar / GPT-5.6 Luna: 73%73%Pi / GPT-5.6 Luna: 77%77%Codex / GPT-5.6 Luna: 72%72%Claude Code / GPT-5.6 Luna: 70%70%GPT-5.6 LunaKISS Sorcar / Kimi K3: 74%74%Pi / Kimi K3: 73%73%Codex / Kimi K3: 70%70%Claude Code / Kimi K3: 67%67%Kimi K3KISS SorcarPiCodexClaude Code
Blog values are read from the HarnessTax tables; KISS values are 90 attempts per cell.

3. Where the lost attempts went

Each failed attempt was classified from its trajectory and verifier log. On SWE-bench Lite, 175 of the 180 failures are the agent calling finish(success=True) with a patch the hidden tests reject; only 5 hit the turn cap and none timed out. On Terminal-Bench 2 the picture is different: 125 wrong claims, but also 66 attempts killed by the task's wall-clock limit, 7 turn caps and 4 explicit give-ups.

How the 90 attempts per model ended — SWE-bench Lite (30 tasks × 3)022456890solved / Fable 5: 8484claimed but wrong / Fable 5: 66Fable 5solved / Opus 4.8: 7373claimed but wrong / Opus 4.8: 1717Opus 4.8solved / Sonnet 4.6: 5858claimed but wrong / Sonnet 4.6: 3232Sonnet 4.6solved / Haiku 4.5: 5454claimed but wrong / Haiku 4.5: 3131turn cap / Haiku 4.5: 55Haiku 4.5solved / GPT-5.6 Sol: 6969claimed but wrong / GPT-5.6 Sol: 2121GPT-5.6 Solsolved / GPT-5.6 Luna: 4848claimed but wrong / GPT-5.6 Luna: 4242GPT-5.6 Lunasolved / Kimi K3: 6464claimed but wrong / Kimi K3: 2626Kimi K3solvedclaimed but wrongtimeout/infraturn capgave up
How the 90 attempts per model ended — Terminal-Bench 2 (30 tasks × 3)022456890solved / Fable 5: 6464claimed but wrong / Fable 5: 1717timeout/infra / Fable 5: 99Fable 5solved / Opus 4.8: 5757claimed but wrong / Opus 4.8: 1919timeout/infra / Opus 4.8: 1414Opus 4.8solved / Sonnet 4.6: 6262claimed but wrong / Sonnet 4.6: 1111timeout/infra / Sonnet 4.6: 1717Sonnet 4.6solved / Haiku 4.5: 4141claimed but wrong / Haiku 4.5: 3333timeout/infra / Haiku 4.5: 77turn cap / Haiku 4.5: 55gave up / Haiku 4.5: 4Haiku 4.5solved / GPT-5.6 Sol: 7171claimed but wrong / GPT-5.6 Sol: 1515timeout/infra / GPT-5.6 Sol: 4GPT-5.6 Solsolved / GPT-5.6 Luna: 6666claimed but wrong / GPT-5.6 Luna: 1919timeout/infra / GPT-5.6 Luna: 3turn cap / GPT-5.6 Luna: 2GPT-5.6 Lunasolved / Kimi K3: 6767claimed but wrong / Kimi K3: 1111timeout/infra / Kimi K3: 1212Kimi K3solvedclaimed but wrongtimeout/infraturn capgave up
Timeouts: Sonnet 17, Opus 14, Kimi 12, Fable 9, Haiku 7, Sol 4, Luna 3. Haiku is the only model that gives up (4) and the main turn-cap victim (5 here, 5 more on SWE).

3.1 The tasks that make the difference

Summing solved attempts over the seven models (21 per task) and subtracting Pi's count shows that the deficit is not spread evenly; it sits in a handful of tasks. The gains are concentrated too: KISS solves scikit-learn-13241 21/21 against Pi's 12/21 and feal-linear-cryptanalysis 14/21 against 11/21.

Attempts solved: KISS minus Pi, summed over 7 models — SWE-bench Lite (30 tasks × 3)psf__requests-1963-11KISS 9/21 vs Pi 20/21 · 12 claimed but wrongdjango__django-12747-4KISS 11/21 vs Pi 15/21 · 10 claimed but wrongpytest-dev__pytest-5103-2KISS 19/21 vs Pi 21/21 · 2 claimed but wrongsympy__sympy-15345-2KISS 19/21 vs Pi 21/21 · 2 claimed but wrongdjango__django-11815-1KISS 18/21 vs Pi 19/21 · 3 claimed but wrongscikit-learn__scikit-learn-14983-1KISS 17/21 vs Pi 18/21 · 4 claimed but wrongsympy__sympy-14024-1KISS 11/21 vs Pi 12/21 · 8 claimed but wrong, 2 turn capdjango__django-11630+1KISS 9/21 vs Pi 8/21 · 11 claimed but wrong, 1 turn capdjango__django-12308+1KISS 12/21 vs Pi 11/21 · 9 claimed but wrongdjango__django-15400+1KISS 10/21 vs Pi 9/21 · 11 claimed but wrongpytest-dev__pytest-5495+1KISS 9/21 vs Pi 8/21 · 12 claimed but wrongdjango__django-11019+2KISS 5/21 vs Pi 3/21 · 16 claimed but wrongdjango__django-15819+2KISS 8/21 vs Pi 6/21 · 13 claimed but wrongmatplotlib__matplotlib-24334+2KISS 13/21 vs Pi 11/21 · 8 claimed but wrongscikit-learn__scikit-learn-13241+9KISS 21/21 vs Pi 12/21 ·
Attempts solved: KISS minus Pi, summed over 7 models — Terminal-Bench 2 (30 tasks × 3)compile-compcert-6KISS 10/21 vs Pi 16/21 · 10 timeout/infra, 1 turn capgcode-to-text-5KISS 2/21 vs Pi 7/21 · 9 claimed but wrong, 8 timeout/infrapath-tracing-4KISS 8/21 vs Pi 12/21 · 6 timeout/infra, 3 claimed but wrongmake-doom-for-mips-3KISS 0/21 vs Pi 3/21 · 12 timeout/infra, 5 turn captorch-tensor-parallelism-2KISS 4/21 vs Pi 6/21 · 14 claimed but wrongbuild-cython-ext-1KISS 13/21 vs Pi 14/21 · 5 claimed but wrongheadless-terminal-1KISS 16/21 vs Pi 17/21 · 2 claimed but wrongreshard-c4-data-1KISS 16/21 vs Pi 17/21 · 2 claimed but wrongsparql-university-1KISS 16/21 vs Pi 17/21 · 2 claimed but wrongtrain-fasttext-1KISS 1/21 vs Pi 2/21 · 19 timeout/infra, 1 claimed but wrongbuild-pmars+1KISS 16/21 vs Pi 15/21 · 2 claimed but wrongconstraints-scheduling+1KISS 18/21 vs Pi 17/21 · merge-diff-arc-agi-task+1KISS 18/21 vs Pi 17/21 · path-tracing-reverse+1KISS 12/21 vs Pi 11/21 · 4 timeout/infra, 1 turn capfinancial-document-processor+2KISS 16/21 vs Pi 14/21 · 1 claimed but wrong, 1 gave upvideo-processing+2KISS 3/21 vs Pi 1/21 · 16 claimed but wrongfeal-linear-cryptanalysis+3KISS 14/21 vs Pi 11/21 · 3 timeout/infra, 1 gave up
Green: KISS solved more attempts than Pi on that task. Red: fewer. Tasks with identical counts are omitted.

3.2 Root cause A — evaluation noise, not the agent (SWE-bench Lite, ≈7 attempts)

psf__requests-1963 accounts for the single largest gap: 9/21 for KISS against 20/21 for Pi. The official reports tell a different story than the headline number. In 7 of the 12 failed attempts every FAIL_TO_PASS test passed and the attempt was rejected only because a PASS_TO_PASS test that calls the live httpbin.org service (test_cookie_sent_on_redirect, test_unicode_multipart_post, test_BASICAUTH_TUPLE_HTTP_200_OK_GET, …) raised a JSONDecodeError on a non-JSON response. The Fable 5 attempt that "failed" contains the upstream fix verbatim:

+            # Update the request that is used for the next redirect
+            req = prepared_request
+
             resp = self.send(

With ~15 evaluations running concurrently from one IP, httpbin throttled some of them. Netting these out puts KISS on SWE-bench Lite at 72.5% against Pi's 71.9%. Over all SWE failures, 157 were genuine FAIL_TO_PASS misses, 12 were FAIL_TO_PASS plus a regression, and 9 were PASS_TO_PASS-only failures (7 of them this flake).

3.3 Root cause B — the wall clock on compute-heavy Terminal-Bench tasks (≈20 attempts)

The TB2 deficit is dominated by five tasks: compile-compcert (−6 vs Pi), gcode-to-text (−5), path-tracing (−4), make-doom-for-mips (−3) and torch-tensor-parallelism (−2). Except for the last, the failures are timeouts, and they have two distinct shapes.

Compute-bound. In compile-compcert, train-fasttext and path-tracing the tool time equals the wall time: the agent spends the whole budget waiting on opam install coq (4–8 minutes each), fastText training runs (2–14 minutes each) or a renderer. Three things compound here:

  1. Host contention. The sweep ran a mean of 15 agent tasks at once (peak 26) on a single 32-core VM, each with its own container and its own make -j. The blog's harnesses ran one task per environment. A Coq build that takes 4 minutes on an idle machine took 5–8 here, and CompCert's own build never started before the 2,400 s limit.
  2. The agent's own timeouts killed its own jobs. Across TB2, 129 bash calls were killed by the timeout the agent had passed after running for ≥ 2 minutes (8.8 hours of compute in total), and in 85 cases the next call re-ran essentially the same command from scratch. 22 of the 66 timed-out attempts contain such a kill. Nothing in the harness offered a way to run a job in the background and poll it.
  3. No deadline awareness. The model saw Steps: 12/10000 in every tool result and never the remaining time. In train-fasttext Fable 5 had a model meeting both the size and its own accuracy target after 10 turns, then spent 45 more minutes on hyper-parameter sweeps and was killed mid-experiment; the verifier measured the last model it had left behind.
compile-compcert, Fable 5, attempt 1 of the rerun: 2,355 s of a 2,355 s budgetmodel turn: 6sls /tmp/CompCert/ 2>/dev/null | head; uname -m; cat /etc/os-release | head -3; which coqc : 0smodel turn: 4sls /tmp/CompCert 2>&1; apt list --installed 2>/dev/null | grep -iE 'coq|ocaml|opam' | head: 0smodel turn: 3swhich wget git gcc make; apt-get --version | head -1; whoami: 0smodel turn: 3sapt-get update -qq 2>&1 | tail -2: 5smodel turn: 3sapt-get install -y -qq wget curl git gcc make m4 unzip bubblewrap patch rsync 2>&1 | tail : 39smodel turn: 10sapt-get install -y -qq opam 2>&1 | tail -1; opam --version; nproc: 18smodel turn: 3sopam init --disable-sandboxing -y --bare 2>&1 | tail -3: 19smodel turn: 4sopam switch create compcert 4.14.2 -y 2>&1 | tail -3: 262s262smodel turn: 3seval $(opam env --switch=compcert) && opam install -y coq.8.17.1 menhir 2>&1 | tail -5: 10smodel turn: 4sapt-get install -y -qq libgmp-dev pkg-config 2>&1 | tail -1 && eval $(opam env --switch=co: 356s356smodel turn: 7scd /tmp && wget -q https://github.com/AbsInt/CompCert/archive/refs/tags/v3.13.1.tar.gz && : 3smodel turn: 3scd /tmp/CompCert && eval $(opam env --switch=compcert) && ./configure x86_64-linux 2>&1 | : 1smodel turn: 5seval $(opam env --switch=compcert) && opam install -y coq.8.16.1 2>&1 | tail -3: 361s361smodel turn: 5seval $(opam env --switch=compcert) && coqc --version 2>&1: 0smodel turn: 4seval $(opam env --switch=compcert) && opam list 2>/dev/null | grep -iE 'coq|menhir'; opam : 266s266smodel turn: 4seval $(opam env --switch=compcert) && opam install -y coq.8.16.1 > /tmp/coq_install.log 2>: 267s267smodel turn: 6sfree -g; eval $(opam env --switch=compcert) && opam install -y coq.8.16.1 -j 4 > /tmp/coq_: 502s502smodel turn: 5scd /tmp/CompCert && eval $(opam env --switch=compcert) && ./configure x86_64-linux 2>&1 | : 0s0 min9 min18 min27 min37 minopam install / switch (3–8 min each)other shell commandsmodel thinking / generation
Reconstructed from the trajectory: purple bars are
opam installs (the model first installed Coq 8.17.1, discovered CompCert 3.13.1 needs ≤ 8.16, and re-installed 8.16.1 twice after a failed build). The CompCert build itself never ran.

Latency-bound. gcode-to-text and make-doom-for-mips have a 900 s budget. Here the tool time is 1–4 minutes and the rest is the model: Opus 4.8 took 38–56 turns at 15–21 s each on G-code interpretation, Fable 5 24 turns at 34 s each with ~52,000 prompt tokens and ~3,200 output tokens per call. Event timestamps in sorcar.db rule out API queueing: median time-to-first-token was 0.6–5 s for every model, and of the 89 model calls that took longer than 2 minutes, 88 were streaming thinking tokens the whole time (100,000–400,000 characters of reasoning in a single call on path-tracing-reverse, feal-linear-cryptanalysis and adaptive-rejection-sampler). These are reasoning marathons, and every harness in the blog runs the same models at the same effort. The difference is that a 900 s task leaves no slack for them.

3.4 Root cause C — patches that pass the agent's tests and fail the hidden ones (model-limited)

The largest failure class by count, 175 SWE and 125 TB2 attempts, is the agent declaring success on a wrong solution. It is not a failure to test: every SWE attempt ran a test command, and in 86–100% of the wrong claims the last edit was followed by a test run. Compared with the gold patches, 89% of the wrong patches touch the right file and 73% touch only the gold files. The agent finds the place and implements a different reading of the issue than the one the hidden test encodes. The tasks are the usual suspects: astropy__astropy-7746 (19 wrong claims; Pi 2/21, Codex 5/21), sympy__sympy-11400 (17), django__django-11019 (16; nobody solves it), django__django-11564 (13, twelve of them editing the wrong file), django__django-15819 (13: every agent ran the full inspectdb test module, but the hidden test fixture changes the module's expected output). These tasks are failed by all three blog harnesses at similar rates; they are a property of the models and the benchmark, not of Sorcar.

3.5 Sorcar-specific artifacts

Session-restart loops (fixed during the study, excluded from the final numbers). Before the fix, when the SEA's turn cap fired the relentless loop treated the session as unfinished and started a new one with an empty context. The database still holds the evidence: one Haiku attempt on path-tracing-reverse ran 131 sessions and 5.8 million tokens for $1.75; a Kimi attempt ran 96. Fable, Haiku, Opus and Kimi each have 3–8 such tasks. These were quarantined and re-run.

The trailer lies about the cap. Steps: N/10000 is Sorcar's limit, not the SEA's 100 turns, and there is no time-left field. Haiku hit the 100-turn cap 10 times and 7 TB2 attempts died at the cap with work in progress.

Instruction mismatch. The Sorcar block tells the model to call finish(success=False, is_continue=True) when context runs low and to return an HTML summary; the SEA prompt says to return a brief plain summary. The output cost of the HTML is negligible (final texts average about 1,400 characters), but the instruction to "pause" is what fed the restart loop.

4. Where the money goes

The per-call usage events in sorcar.db give the token split of every model call (uncached input, cache reads, output). Prompt caching works: 85–96% of prompt tokens were served from cache for every model. The cost is therefore driven by two things: output tokens (thinking plus text), which are 31–60% of spend, and the sheer volume of context re-read on every turn, which even at one tenth of the input price is 23–48% of spend for the long-running models.

Where each dollar goes (USD per attempt) — SWE-bench Lite (30 tasks × 3)$0.00$0.18$0.35$0.53$0.71uncached input / Fable 5: $0.12$0.12cache reads / Fable 5: $0.13$0.13output (thinking + text) / Fable 5: $0.31$0.31$0.56Fable 5uncached input / Opus 4.8: $0.07$0.07cache reads / Opus 4.8: $0.11$0.11output (thinking + text) / Opus 4.8: $0.19$0.19$0.38Opus 4.8uncached input / Sonnet 4.6: $0.09$0.09cache reads / Sonnet 4.6: $0.20$0.20output (thinking + text) / Sonnet 4.6: $0.23$0.23$0.52Sonnet 4.6uncached input / Haiku 4.5: $0.10$0.10cache reads / Haiku 4.5: $0.25$0.25output (thinking + text) / Haiku 4.5: $0.17$0.17$0.53Haiku 4.5uncached input / GPT-5.6 Sol: $0.14$0.14cache reads / GPT-5.6 Sol: $0.25$0.25output (thinking + text) / GPT-5.6 Sol: $0.22$0.22$0.62GPT-5.6 Soluncached input / GPT-5.6 Luna: $0.01cache reads / GPT-5.6 Luna: $0.02output (thinking + text) / GPT-5.6 Luna: $0.01$0.04GPT-5.6 Lunauncached input / Kimi K3: $0.13$0.13cache reads / Kimi K3: $0.17$0.17output (thinking + text) / Kimi K3: $0.13$0.13$0.43Kimi K3uncached inputcache readsoutput (thinking + text)
Where each dollar goes (USD per attempt) — Terminal-Bench 2 (30 tasks × 3)$0.00$0.28$0.55$0.83$1.10uncached input / Fable 5: $0.24$0.24cache reads / Fable 5: $0.14$0.14output (thinking + text) / Fable 5: $0.58$0.58$0.96Fable 5uncached input / Opus 4.8: $0.13$0.13cache reads / Opus 4.8: $0.12$0.12output (thinking + text) / Opus 4.8: $0.36$0.36$0.62Opus 4.8uncached input / Sonnet 4.6: $0.07$0.07cache reads / Sonnet 4.6: $0.08$0.08output (thinking + text) / Sonnet 4.6: $0.21$0.21$0.36Sonnet 4.6uncached input / Haiku 4.5: $0.06$0.06cache reads / Haiku 4.5: $0.12$0.12output (thinking + text) / Haiku 4.5: $0.12$0.12$0.31Haiku 4.5uncached input / GPT-5.6 Sol: $0.12$0.12cache reads / GPT-5.6 Sol: $0.20$0.20output (thinking + text) / GPT-5.6 Sol: $0.22$0.22$0.54GPT-5.6 Soluncached input / GPT-5.6 Luna: $0.01cache reads / GPT-5.6 Luna: $0.02output (thinking + text) / GPT-5.6 Luna: $0.02$0.05GPT-5.6 Lunauncached input / Kimi K3: $0.08$0.08cache reads / Kimi K3: $0.07$0.07output (thinking + text) / Kimi K3: $0.10$0.10$0.25Kimi K3uncached inputcache readsoutput (thinking + text)
Haiku's 73 turns per SWE attempt re-read a 35,000-token context 76 times; Luna's TB2 attempts average 42,000 tokens per call.
Total spend per model (USD over 90 attempts), split by outcome$0$29$58$87$116spent on solved attempts / SWE Fable: $49$49spent on failed attempts / SWE Fable: $2$50SWE Fablespent on solved attempts / SWE Opus: $24$24spent on failed attempts / SWE Opus: $10$10$34SWE Opusspent on solved attempts / SWE Sonnet: $23$23spent on failed attempts / SWE Sonnet: $24$24$47SWE Sonnetspent on solved attempts / SWE Haiku: $22$22spent on failed attempts / SWE Haiku: $20$20$42SWE Haikuspent on solved attempts / SWE GPT-5.6: $43$43spent on failed attempts / SWE GPT-5.6: $13$13$55SWE GPT-5.6spent on solved attempts / SWE GPT-5.6: $2spent on failed attempts / SWE GPT-5.6: $2$3SWE GPT-5.6spent on solved attempts / SWE Kimi: $22$22spent on failed attempts / SWE Kimi: $16$16$38SWE Kimispent on solved attempts / TB2 Fable: $54$54spent on failed attempts / TB2 Fable: $47$47$101TB2 Fablespent on solved attempts / TB2 Opus: $40$40spent on failed attempts / TB2 Opus: $38$38$78TB2 Opusspent on solved attempts / TB2 Sonnet: $20$20spent on failed attempts / TB2 Sonnet: $33$33$53TB2 Sonnetspent on solved attempts / TB2 Haiku: $6$6spent on failed attempts / TB2 Haiku: $20$20$27TB2 Haikuspent on solved attempts / TB2 GPT-5.6: $30$30spent on failed attempts / TB2 GPT-5.6: $20$20$50TB2 GPT-5.6spent on solved attempts / TB2 GPT-5.6: $2spent on failed attempts / TB2 GPT-5.6: $2$4TB2 GPT-5.6spent on solved attempts / TB2 Kimi: $12$12spent on failed attempts / TB2 Kimi: $12$12$23TB2 Kimispent on solved attemptsspent on failed attempts
Failed attempts cost 1.5–3× a solved attempt and take 42% of the total: $102 of the $336 spent on TB2 went to the 66 attempts the clock killed.
Cost driverEvidenceShare of spend it touches
Timed-out TB2 attempts66 attempts, mean $1.54 and 28 min each30% of TB2 spend
Wrong-claim attempts175 SWE ($82) + 125 TB2 ($63)24% of total spend
Output tokens (thinking)89 single calls over 2 min, up to 100k thinking tokens each31–60% per model
Context re-reads (cache hits)Haiku 2.6 M prompt tokens/attempt; GPT models 95k chars of tool output/attempt, 30k-char truncation fires 0.44×/attempt23–48% per model
Wasted tool time129 long commands killed by the agent's timeout, 85 re-run8.8 h of compute, 22 timeouts
Small-model churnHaiku: 7.4 failed calls, 3.1 duplicate calls, 99 read path errors per 90 attemptsHaiku is 26% dearer than under Pi

5. What would move the numbers

The recommendations are ordered by the size of the effect the data supports. None of them uses knowledge of the benchmark tasks; all of them are harness or wrapper changes that apply to any long-running coding job.

R1. Tell the model its real budget and let it land the plane

Replace Steps: N/10000 with the actual turn cap and add the remaining wall-clock time and dollars (Turns 37/100 · 14 min left · $2.10 of $15). Add a soft deadline hook: when less than ~15% of the time or turns remain, inject one message asking the agent to stop exploring, make sure the best artifact so far is in place, and finish. This targets the 66 TB2 timeouts ($102) and 12 turn caps directly. The train-fasttext case is the archetype: a passing model existed 45 minutes before the kill. Expected: several TB2 attempts recovered (the +2 to +3 points that separate KISS from Pi there) and a large share of the $102 not spent.

R2. Give long jobs a background lane

Add background=true to bash (start with nohup … > log 2>&1 &, return a job id) and a wait/tail primitive, and tell the model in the prompt to use it for anything expected to run longer than a minute. The trajectories contain 129 builds and training runs that the tool killed and 85 that were restarted from zero (8.8 hours). Only 50 of the 630 TB2 attempts ever used & on their own. Combined with R1, the agent can spend the waiting time reading logs or preparing verification instead of blocking.

R3. Prune the context the model re-reads every turn

Cache reads are a quarter to a half of the bill for the long-running models. Keep the last ~8 tool results verbatim and collapse older ones to their first and last 5 lines plus a one-line "use read to see it again" note; lower the tool-output cap from 30,000 to ~10,000 characters with an explicit pagination hint (GPT models triggered the cap 0.44 times per attempt). This is KISS's own context_compaction.py applied continuously rather than only at the context limit. Expected: 15–25% lower cost for Haiku, Kimi, Sonnet and the GPT models, with no change for Fable and Opus, which rarely exceed 20 turns.

R4. Put a ceiling on a single thought

Eighty-nine calls ran for more than 2 minutes, all of them generating; the longest produced ~100,000 thinking tokens ($3–5 at Fable prices) in one call. Set a per-call thinking budget (e.g. 16,000 tokens for adaptive models) and let the agent continue in the next turn with a tool call in between: the tool result usually answers the question the model was trying to reason out. This is the one recommendation with a success-rate risk, because the puzzle-style TB2 tasks (path-tracing-reverse, feal-linear-cryptanalysis) were solved precisely by those marathons; it should be A/B tested per benchmark. Expected: 10–20% lower cost on TB2 for Fable, Opus, Sonnet and Kimi.

R5. A cheap pre-finish check against the task statement

Wrong claims are the largest failure class and the agents already test; what is missing is a check that the tests they ran cover what the task text says. Before finish(success=True), run one extra model call (or a decide() question, which costs cents) with the task text and the diff: "List each behaviour the task asks for; which is not exercised by a test you ran?" and let the agent act on the answer once. The evidence for the ceiling here is honest: the same tasks defeat Pi, Codex and Claude Code at similar rates, so expect a gain of a few attempts on SWE-bench Lite (the 12 F2P-plus-regression cases are the most reachable), not a step change.

R6. Remove the wrapper's contradictions

For autonomous runs the Sorcar agent should not append the is_continue/HTML-summary block on top of a SEA prompt, and the relentless loop should treat a turn cap as terminal (it does now). Drop the mismatch, keep the usage trailer (corrected per R1). Small cost effect, but it removes the mechanism behind the 26–131-session loops.

R7. Loop and error guards for small models

Haiku averages 56 tool calls, 3.1 exact-duplicate calls and 7.4 failed calls per attempt, and made 99 read calls on paths that do not exist. Detect an identical call repeated within the last 5 turns and return a short note instead of re-running it; on a missing path, return the nearest ls. These are cheap, model-agnostic, and shave turns where turns are the cost.

R8. Fix the experiment, not just the agent

Run the compute-heavy TB2 tasks at a concurrency the host can carry (≤ 1 heavy task per 8 cores), re-grade PASS_TO_PASS-only SWE failures once (network flakes), and report the Fable/Opus SWE results with confidence intervals: a 3-attempt gap out of 90 is inside the blog's own ±5-point intervals.

Combined estimate. R1–R3 and R6–R7 are low-risk and, on the measured spend structure, cut cost by roughly 20–30% (avoided timeout spend plus context re-reads) while lifting TB2 success by 2–4 points from recovered timeouts. R4 adds another 10–20% on TB2 cost at some risk to puzzle tasks. R5 is the only lever aimed at the largest failure class, and its ceiling is set by the models: no harness in the study solves astropy-7746 or django-11019 reliably.

6. Data and reproducibility