Problem
When the implementer's reply is cut off mid-hunk, the harness correctly
detects it — and then fails the whole item. The model call itself returned
200, so the retry ladder never engages; validate_diff reports a fatal
patch problem and _execute returns.
One truncated response therefore costs a full item: the planner call, the
implementer call, and an attempt off the item's budget. Recovering it takes a
manual requeue, which re-plans and re-implements from scratch.
Why that is the wrong call
Truncation is the most obviously retryable failure there is. It says nothing
about the prompt and nothing about the model's suitability — the reply simply
stopped. It is not the same class of thing as "the model returned prose
instead of a diff", which is what the fatal path was built for.
Compare what happens either side of it: an HTTP 503 is retried up to six times
with backoff, and now also falls through to the next model in the chain
(#141). A reply that arrives complete but unusable fails once and stops. The
harness is most patient with the failure it can do least about, and least
patient with the one a single re-ask usually fixes.
Observed
Three times in one evening's runs, on the same item, across two different
models:
T3 patch_malformed — line 21: the patch ends mid-hunk — the reply was truncated
FAIL T3: plan -> implement -> parse
the implementer did not produce a usable diff — line 21: the patch ends mid-hunk
T2 patch_malformed — line 17: the patch ends mid-hunk — the reply was truncated
FAIL T2: plan -> implement -> parse
Each was recovered by requeue + a fresh run, i.e. by paying for the whole
item again. The second and third occurrences were on gpt-5.4 reached through
a fallback chain, so this is not one bad model.
What would fix it
Treat "the reply was truncated" as a retryable call failure rather than a
fatal item failure:
- re-ask the implementer, at the call level, so the planner's output is not
thrown away;
- with a chain configured, prefer the next route on the retry — a model that
truncated once on a given prompt is a reasonable thing to route around;
- keep the existing fatal path for replies that are malformed in ways a
re-ask will not fix (no hunk header at all, prose instead of a diff).
PatchProblem already carries fatal, and the truncation case is already
detected and named precisely — the classification simply sits on the wrong
side of the line. Worth also capping how many re-asks one item may spend, so a
model that truncates every time still terminates.
Problem
When the implementer's reply is cut off mid-hunk, the harness correctly
detects it — and then fails the whole item. The model call itself returned
200, so the retry ladder never engages;validate_diffreports a fatalpatch problem and
_executereturns.One truncated response therefore costs a full item: the planner call, the
implementer call, and an attempt off the item's budget. Recovering it takes a
manual requeue, which re-plans and re-implements from scratch.
Why that is the wrong call
Truncation is the most obviously retryable failure there is. It says nothing
about the prompt and nothing about the model's suitability — the reply simply
stopped. It is not the same class of thing as "the model returned prose
instead of a diff", which is what the fatal path was built for.
Compare what happens either side of it: an HTTP 503 is retried up to six times
with backoff, and now also falls through to the next model in the chain
(#141). A reply that arrives complete but unusable fails once and stops. The
harness is most patient with the failure it can do least about, and least
patient with the one a single re-ask usually fixes.
Observed
Three times in one evening's runs, on the same item, across two different
models:
Each was recovered by
requeue+ a fresh run, i.e. by paying for the wholeitem again. The second and third occurrences were on
gpt-5.4reached througha fallback chain, so this is not one bad model.
What would fix it
Treat "the reply was truncated" as a retryable call failure rather than a
fatal item failure:
thrown away;
truncated once on a given prompt is a reasonable thing to route around;
re-ask will not fix (no hunk header at all, prose instead of a diff).
PatchProblemalready carriesfatal, and the truncation case is alreadydetected and named precisely — the classification simply sits on the wrong
side of the line. Worth also capping how many re-asks one item may spend, so a
model that truncates every time still terminates.