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.
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
| Remedy | Does | Does not | Evidence |
|---|---|---|---|
| T3 typed contract | Forces known_gaps[] into the done-claim | Block a vacuous or padded claim | OpenAI Agents SDK output_type |
| T2 stop-hook gate | Blocks exit on a mechanical invariant, injects a reason | Judge semantic correctness — only what its author thought to check | Claude Code Stop/TaskCompleted hooks |
| T6 verifier subagent | Independent fresh-context audit before done is accepted | Enforce its own verdict — advisory unless T2 wraps it | Cursor verifier-subagent pattern |
| T1 hidden executing checker | Re-runs the deliverable against a target the agent never sees | Author itself — someone must write the target | 2606.05238 · 63% self-stops |
| T4 difficulty-trained allocation | RL reward ties effort to estimated difficulty | Run without weights access + an RL loop | 2510.01581 · +8.4% acc, −36.8% length |
| T5 demand-steering controller | Training-free per-step scorer; licenses early stop only when residual demand is low | Escape being a heuristic itself — dims are math-derived | 2608.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.