Audit the Gym's first graded runs

a0222791cfd8 · AtlantisPleb · · parent bec1f48f1aac

Audit the Gym's first graded runs

Four agents passed fix-git by three distinct mechanics — cherry-pick,
merge with file rewrite, merge with checkout-theirs — and every one
resolved the conflict in the correct direction, which is the task's
actual trap. The task does not yet discriminate on success between
lanes; it discriminates sharply on cost shape: round count drives
metered-lane spend (gemini-3.7-flash spent 3x luna's input tokens on
15 single-command rounds of transcript replay), verbosity drives the
local lane's minutes, and cached prefix tokens — most of the spend on
exactly these workloads — are invisible to our accounting.

The levers, ranked: efficiency language inside tool declarations and a
per-model-family declaration resolver, both harvested as patterns from
Gemini CLI's own harness, which compensates for its models' habits the
same way; lane-aware economics in the system prompt; cached-token
splits end to end; and git_lost_work as the first plugin whose value
the Gym measures as a delta. Follow-ups filed as openagents#36,
openagents#37, and #220, all on the Gym board.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GoYpb8FEmdxVErsv7ABCYi
Co-Authored-By
Claude Fable 5 <noreply@anthropic.com>

Deploy story

What this commit did to the running system — joined from the forge receipt chain, the part a commit page elsewhere cannot show.

pushed
by user · WAL seq 324 · 2026-08-25T01:20:10.981038Z

Changed files

  • added docs/terminalbench/2026-08-24-fix-git-run-analysis.md

Diff

1 file changed, +186 -0

docs/terminalbench/2026-08-24-fix-git-run-analysis.md added +186

@@ -0,0 +1,186 @@

1
# Terminal-Bench analysis: fix-git, first graded runs
2
3
Date: 2026-08-24
4
5
Status: audit of the Gym's first scored trials. Companion to
6
`docs/2026-08-24-harbor-terminal-bench-plan.md`; run data lives in the
7
Gym (`/gym`, project 14) and the trial artifacts (Harbor job directories
8
with ATIF trajectories) on the machine that ran them.
9
10
## 1. The runs
11
12
Five trials of `terminal-bench@2.0` / `fix-git`, all through the real
13
`openagents coder` (working-tree build, Harbor adapter, monorepo
14
`bench/`), one task each:
15
16
| Run | Model | Lane | Verifier | Steps | Tokens in / out | Agent wall time |
17
| --- | --- | --- | --- | --- | --- | --- |
18
| luna-a | gpt-5.6-luna | proxy | **crashed** (qemu segfault; agent work correct) | 7 | not recorded | ~15 s |
19
| luna-b | gpt-5.6-luna | proxy | **pass** | 11 | 43,894 / 1,422 | ~27 s |
20
| gemini | gemini-3.7-flash | proxy | **pass** | 17 | 124,941 / 640 | ~88 s |
21
| qwen | qwen3.8:27b-mtp-q8_0 | local (Ollama) | **pass** | 19 | 110,061 / 17,160 | ~18.5 min |
22
| (aborted attempts) | — | — | install/proxy-URL failures, fixed in `bench/README.md` and `resolveProxyUrl` | — | — | — |
23
24
Every graded run passed. The task is therefore not yet discriminating on
25
*success* between these lanes; it discriminates sharply on *cost shape*,
26
which is exactly what the compute mix needs measured.
27
28
## 2. The task and its trap
29
30
The instruction: "I just made some changes to my personal site and
31
checked out master, but now I can't find those changes. Please help me
32
find them and merge them into master." The repository state: a commit
33
(`650dba4 "Move to Stanford"`) made on a detached HEAD, unreachable from
34
any branch, findable only in the reflog. Merging it into `master`
35
conflicts in `_includes/about.md`.
36
37
The conflict is the trap. Resolving toward `master`'s side (the old
38
"UW" bio) also produces a clean tree and a plausible "done" — and fails
39
both verifier tests, which check the final file contents. Passing
40
requires knowing which side is "my changes," which requires having read
41
the recovered commit's content before resolving. All four agents did.
42
43
## 3. Strategy, per agent
44
45
**luna-a — cherry-pick, minimal.** Recon in one composite command
46
(status + branches + log), inspect `650dba4`, `git cherry-pick`, hit the
47
conflict, diagnose with `diff --cc`, rewrite the file, continue. Seven
48
steps, five tool calls, no narration until the final report. The
49
tightest run of the set — and note it chose a *different strategy* from
50
every later run.
51
52
**luna-b — merge, with ancestry proof.** Broader recon (reflog `--all`,
53
stash list, unreachable objects), full inspection of `650dba4`, then two
54
`merge-base --is-ancestor` probes to establish the topology *before*
55
choosing `git merge`. Narrated twice mid-turn (found-it, then
56
conflict-diagnosis) — short, load-bearing prose. Resolved by rewriting
57
the file to the recovered content. The ancestry probes are the
58
distinguishing habit: it proved the relationship instead of assuming it.
59
60
**gemini — merge, one command at a time.** Fifteen tool rounds, almost
61
every one a single small command: `git status && git branch -a && git
62
reflog`, then `git log -p -1`, `git log --graph`, `git merge`, `git
63
diff`, `git log -p -2 master`, `git log -p 650dba4 -1`, three separate
64
diffs of the same commit, then the neat resolution `git checkout 650dba4
65
-- _includes/about.md` (take-theirs by checkout — the third distinct
66
resolution mechanic of the set), commit, verify. Output tokens were the
67
set's smallest (640 — terse to a fault), but prompt tokens the largest
68
(124,941), because **every round re-sends the growing transcript**: 15
69
rounds of an agentic conversation is quadratic-ish context replay, and
70
two full `git log -p` dumps rode along in it.
71
72
**qwen (local) — merge, exhaustive and narrated.** The most thorough
73
run: composite commands with echo section headers (good practice it
74
invented for itself), full reflog story reconstruction, `merge-base`
75
check, inspection of *both* sides' diffs before merging, a merge with
76
explicit exit-code and unmerged-file capture, resolution, then
77
verification *plus* a remotes check so its final answer could speak to
78
pushing, an enumeration of two *other* dangling commits it noticed with
79
an offer to recover them, and exact rollback commands. 17,160 output
80
tokens — 12× luna-b — and ~18.5 minutes of wall time, nearly all of it
81
local prefill on a context that had grown past 100k. On the local lane
82
the economics invert: tokens are free, latency is the cost, and this run
83
paid it in minutes.
84
85
## 4. What the numbers say
86
87
- **Round count is the cost driver on metered lanes.** Prompt tokens
88
  scale with rounds × transcript size, not with work done. luna-b did
89
  the same job as gemini in 6 model calls instead of 15 and spent a
90
  third of the input tokens. The single highest-leverage efficiency
91
  behavior is *batching independent commands into one tool call* —
92
  which the Luna and Qwen runs did unprompted and the Gemini run did
93
  not. This is a model-family habit, not a capability gap.
94
- **Full-patch dumps are the second driver.** `git log -p` twice in the
95
  gemini run put whole patches into a transcript that then got re-sent
96
  a dozen times. `--stat` first, `-p` only for the file in question, is
97
  worth teaching.
98
- **Verbosity is the local lane's cost.** qwen's 17k output tokens are
99
  free in dollars and expensive in minutes at local generation speed.
100
  The lane inverts the guidance: fewer, larger, quieter rounds.
101
- **Cached tokens are invisible.** Most of those 124,941 gemini input
102
  tokens were the same prefix re-sent — exactly the traffic shape
103
  AgentX measures — and both OpenAI and Gemini bill cached prefix
104
  tokens at a fraction of fresh ones. Our proxy's usage records do not
105
  surface `cached_tokens`, so our cost numbers overstate real cost on
106
  precisely the workloads that matter. Surfacing cache splits
107
  end-to-end (provider → proxy usage → grant → ATIF `metrics.extra`,
108
  which the ATIF spec explicitly provides for) is required before
109
  cost-per-accepted-outcome is honest.
110
- **Strategy diversity is a robustness signal.** Four passes, three
111
  distinct mechanics (cherry-pick; merge + file rewrite; merge +
112
  `checkout <commit> -- file`), and the same correct resolution
113
  direction every time. The agent is not pattern-matching one recipe.
114
115
## 5. Improvement levers
116
117
In order of expected value per unit of effort:
118
119
1. **Tool-description engineering (harvest from Gemini CLI).** Gemini's
120
   own harness compensates for its models' habits inside the tool
121
   declarations: the gemini-3 family's `read_file` description says
122
   surgical ranged reads are mandatory and that triggering truncation
123
   "is considered token-inefficient"; the shell tool carries explicit
124
   Efficiency Guidelines (quiet flags, `--no-pager`, `PAGER=cat`)
125
   behind an `enableEfficiency` flag; grep's description steers away
126
   from `shell grep` toward the bounded native tool. Our shell tool
127
   description already says to batch — the Gemini run shows saying it
128
   once in the system prompt is not enough for every family. Adopt the
129
   pattern: efficiency language *in the tool description*, including
130
   batch-independent-commands, `--no-pager`/quiet flags, and
131
   `--stat`-before-`-p` for git.
132
2. **Per-model-family declarations (the resolver pattern).** Gemini CLI
133
   resolves each tool's declaration as a base plus per-model overrides
134
   (`tools/definitions/resolver.ts`, ~30 lines, with
135
   `model-family-sets/gemini-3.ts` versus `default-legacy.ts`). The
136
   coder already knows its model from the grant; the same tiny pattern
137
   lets us ship one tool set with per-family description overrides —
138
   batching emphasis for gemini-family, brevity emphasis for local
139
   qwen — without forking the tool surface. Adapt the pattern (it is
140
   Apache-2.0 if any code is taken, with attribution), not the
141
   3,000-line manifest.
142
3. **Lane-aware guidance.** The system prompt already varies by lane
143
   (`LOCAL_LANE`, `THREAD_LANE`); add the economics to it: metered
144
   lanes say "rounds cost context replay — batch"; the local lane says
145
   "generation is slow — answer tersely, verify in one pass."
146
4. **Cached-token accounting** (section 4). Proxy usage gains the
147
   provider's cache split; grant metering and ATIF step metrics carry
148
   it; `post_gym_run.py` prices cached and fresh tokens separately.
149
5. **A git-forensics plugin as the first plugin delta.** Recon took 2–3
150
   rounds in every run (status/branches/reflog/stash/fsck). A
151
   deterministic plugin — `git_lost_work`: enumerate dangling commits
152
   and stashes with subjects, dates, and touched files as typed
153
   output — collapses that to one receipted call and is exactly the
154
   Gym's plugin-measurement methodology: same suite, with and without,
155
   delta attributable to the plugin digest. Good candidate precisely
156
   because the capability is already *possible* with shell; the plugin
157
   claims determinism and economy, and the Gym can check both.
158
6. **Output summarization, later.** Gemini CLI can summarize oversized
159
   shell output with a cheap model instead of truncating
160
   (`utils/summarizer.ts`, opt-in per tool). Heavier machinery; worth
161
   revisiting when tool outputs, not transcript replay, dominate cost.
162
163
What this does *not* recommend: benchmark-specific prompts or a
164
recovery recipe for this task. The suite measures the shipped coder;
165
every lever above is a product change that happens to be measurable
166
here.
167
168
## 6. Follow-ups filed
169
170
All three on the Gym board (project 14):
171
172
- `OpenAgentsInc/openagents#36` — per-model-family tool declarations and
173
  efficiency descriptions in the coder, with the Gym as the
174
  before/after oracle.
175
- #220 — cached-token splits through proxy usage, grants, and ATIF.
176
- `OpenAgentsInc/openagents#37` — the `git_lost_work` plugin as the
177
  first measured plugin delta, on the walking skeleton's PDK.
178
179
## 7. Method notes
180
181
Single-task, single-trial-per-lane runs: these are existence proofs and
182
cost profiles, not statistics. No pass-rate claims beyond "these trials
183
passed"; #34's suite with thresholds is where rates become claims.
184
luna-a's verifier crash (amd64 `uv` under qemu) is recorded with its
185
fix — Rosetta emulation — in `bench/README.md`; its agent-phase work
186
was verified by inspection, not counted as a pass.

This page updates live while a promote is in flight · changelog