Premature termination

A run ends when the model decides it's done — and the same system whose effort and completion judgment are being measured is also the judge of its own success. In DeployBench, 63% of failures were agent-initiated self-stops: the agent's own smoke tests passed while the real, hidden acceptance check failed.

Task: "deploy the artifact, confirm it runs." The agent writes code, runs a smoke test it wrote itself, declares DONE. Nobody re-executes against the real target. The next session — or the human who trusts "done" — builds on a poisoned dependency.

self-assessed completion — races to "done" fast real completion — the gap nobody checked still remaining when it stops the stop decision is the highest-leverage bit an agent emits — and nothing verifies it
Watch — same task, change who checks the stop
self-assessed completion real completion self-declares "done" here real bar
Outcome
Self-assessed at stop
Real completion at stop
Stop attempts blocked
0
Mechanism — P28 inventory, not a vibe
RemedyDoesDoes notEvidence
T3 typed contractForces known_gaps[] into the done-claimBlock a vacuous or padded claimOpenAI Agents SDK output_type
T2 stop-hook gateBlocks exit on a mechanical invariant, injects a reasonJudge semantic correctness — only what its author thought to checkClaude Code Stop/TaskCompleted hooks
T6 verifier subagentIndependent fresh-context audit before done is acceptedEnforce its own verdict — advisory unless T2 wraps itCursor verifier-subagent pattern
T1 hidden executing checkerRe-runs the deliverable against a target the agent never seesAuthor itself — someone must write the target2606.05238 · 63% self-stops
T4 difficulty-trained allocationRL reward ties effort to estimated difficultyRun without weights access + an RL loop2510.01581 · +8.4% acc, −36.8% length
T5 demand-steering controllerTraining-free per-step scorer; licenses early stop only when residual demand is lowEscape being a heuristic itself — dims are math-derived2608.01319 · +21.9% vs direct

Sequencing: T3 types the done-claim, T6 generates independent evidence about it, T2 enforces the gate at the exit, T1 supplies the semantic target when one exists. T4/T5 attack the upstream cause — misallocated effort — rather than gating the symptom. No technique here removes the authorship burden of T1's target; that stays the open problem, not a missing slider.

What to try
  • Self-assessment only (default) at difficulty 60. Teal crosses the amber line fast; orange is still far below the green bar. It ships broken anyway — nothing was there to stop it.
  • Turn on Typed contract alone. Same stop, same broken ship — but now the log enumerates the gaps instead of just saying "done." Visible is not the same as blocked.
  • Turn on Stop-hook gate alone. The first attempt gets bounced back to work — but watch the outcome stat: the proxy check can still pass while orange sits under the real bar.
  • Turn on Hidden checker alone. It will not ship until orange actually clears the green line, however many attempts that takes.
  • Drag difficulty to 100 with every gate off. The gap between teal and orange widens — that's effort not scaling with difficulty, not a harder problem being solved worse.
  • Now add Adaptive effort at difficulty 100. Orange climbs faster on its own — the upstream fix needs fewer downstream rejections to reach the same outcome.
Ship the exit like you'd ship the entry point: type the done-claim (T3, cheap, everywhere), gate the exit on at least one mechanical invariant (T2), and reserve the hidden executing checker (T1) for anything money-touching or destructive where a wrong "done" is expensive. None of that fixes the upstream cause — pair it with difficulty-proportional effort (T4 if you hold weights, T5's training-free controller if you don't) or you're forever gating a budget that never scaled to the task. This is goal drift's mirror image, not a duplicate: drift completes against a different target while still running; this stops early against a weaker one. Same root cause — self-assessment is not a completion gate (2606.05238) — on opposite ends of the run.