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.
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:
finish: bash (fresh shell per call, 180 s default / 1,800 s maximum timeout, output truncated to 30,000 characters),
read (numbered lines), write, edit (exact single-occurrence replacement). Every call is a docker exec in the task container.llm_call_hook, a $15 budget per attempt, and the task's own wall-clock limit (Harbor's [agent] timeout_sec minus 45 s on TB2).decide(); the same model at the provider's default reasoning setting (adaptive thinking for Fable 5 and Opus 4.8, a 10,000-token thinking budget for Sonnet 4.6 and Haiku 4.5, reasoning: high for the GPT-5.6 models).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.
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.
| Model | KISS Sorcar | Pi | Codex | Claude Code | ||||
|---|---|---|---|---|---|---|---|---|
| solved | $/attempt | solved | $/attempt | solved | $/attempt | solved | $/attempt | |
| Fable 5 | 93.3% | $0.559 | 96.7% (-3.4) | $0.666 | 96.7% (-3.4) | $0.890 | 97.8% (-4.5) | $1.329 |
| Opus 4.8 | 81.1% | $0.378 | 82.2% (-1.1) | $0.473 | 88.9% (-7.8) | $0.694 | 86.7% (-5.6) | $0.976 |
| Sonnet 4.6 | 64.4% | $0.519 | 64.4% (+0.0) | $0.679 | 68.9% (-4.5) | $0.745 | 66.7% (-2.3) | $0.669 |
| Haiku 4.5 | 60.0% | $0.471 | 60.0% (+0.0) | $0.374 | 57.8% (+2.2) | $0.392 | 52.2% (+7.8) | $0.426 |
| GPT-5.6 Sol | 76.7% | $0.615 | 74.4% (+2.3) | $0.441 | 73.3% (+3.4) | $0.561 | 77.8% (-1.1) | $1.540 |
| GPT-5.6 Luna | 53.3% | $0.036 | 53.3% (+0.0) | $0.030 | 55.6% (-2.3) | $0.035 | 55.6% (-2.3) | $0.152 |
| Kimi K3 | 71.1% | $0.425 | 72.2% (-1.1) | $0.455 | 74.4% (-3.3) | $0.845 | 76.7% (-5.6) | $0.784 |
| 7-model mean | 71.4% | $0.429 | 71.9% | $0.445 | 73.7% | $0.595 | 73.4% | $0.839 |
| Model | KISS Sorcar | Pi | Codex | Claude Code | ||||
|---|---|---|---|---|---|---|---|---|
| solved | $/attempt | solved | $/attempt | solved | $/attempt | solved | $/attempt | |
| Fable 5 | 71.1% | $1.120 | 71.1% (+0.0) | $1.079 | 72.2% (-1.1) | $0.976 | 75.6% (-4.5) | $1.554 |
| Opus 4.8 | 63.3% | $0.866 | 72.2% (-8.9) | $0.758 | 72.2% (-8.9) | $0.848 | 68.9% (-5.6) | $0.899 |
| Sonnet 4.6 | 68.9% | $0.593 | 65.6% (+3.3) | $0.614 | 63.3% (+5.6) | $0.552 | 62.2% (+6.7) | $0.669 |
| Haiku 4.5 | 45.6% | $0.297 | 47.8% (-2.2) | $0.250 | 31.1% (+14.5) | $0.214 | 41.1% (+4.5) | $0.263 |
| GPT-5.6 Sol | 78.9% | $0.553 | 83.3% (-4.4) | $0.421 | 78.9% (-0.0) | $0.761 | 71.1% (+7.8) | $1.355 |
| GPT-5.6 Luna | 73.3% | $0.045 | 76.7% (-3.4) | $0.045 | 72.2% (+1.1) | $0.064 | 70.0% (+3.3) | $0.098 |
| Kimi K3 | 74.4% | $0.259 | 73.3% (+1.1) | $0.383 | 70.0% (+4.4) | $0.450 | 66.7% (+7.7) | $0.521 |
| 7-model mean | 67.9% | $0.533 | 70.0% | $0.507 | 65.7% | $0.552 | 65.1% | $0.766 |
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.
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.
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).
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:
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.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.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.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.
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.
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.
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.
| Cost driver | Evidence | Share of spend it touches |
|---|---|---|
| Timed-out TB2 attempts | 66 attempts, mean $1.54 and 28 min each | 30% of TB2 spend |
| Wrong-claim attempts | 175 SWE ($82) + 125 TB2 ($63) | 24% of total spend |
| Output tokens (thinking) | 89 single calls over 2 min, up to 100k thinking tokens each | 31–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×/attempt | 23–48% per model |
| Wasted tool time | 129 long commands killed by the agent's timeout, 85 re-run | 8.8 h of compute, 22 timeouts |
| Small-model churn | Haiku: 7.4 failed calls, 3.1 duplicate calls, 99 read path errors per 90 attempts | Haiku is 26% dearer than under Pi |
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.
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.
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.
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.
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.
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.
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.
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.
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.
benchmarkings/harnesstax/results/baseline/summary.json (1,260 records) and per-trial trajectory.jsonl / result.json / model.patch._eval/*/logs/run_evaluation/*/report.json; Harbor verifier/test-stdout.txt and result.json.~/.kiss-harnesstax/sorcar.db (1,518 tasks, 2,248,304 events; usage_info per call, tool_call/tool_result/thinking_delta with timestamps).tmp/analysis.py, tmp/cache_analysis.py, tmp/build_report.py (outputs in tmp/analysis_out.txt, tmp/cache_out.txt).benchmarkings/harnesstax/data/blog_tables.json, blog_per_task.json (from harnesstax.github.io).