Skip to content

fix(agent): remove the todo-stall pause - #8347

Merged
esengine merged 1 commit into
main-v2from
feat/no-chat-todo-stall-pause
Aug 11, 2026
Merged

fix(agent): remove the todo-stall pause#8347
esengine merged 1 commit into
main-v2from
feat/no-chat-todo-stall-pause

Conversation

@esengine

Copy link
Copy Markdown
Owner

The last remaining way for the host to end a turn the user never asked it to end.

What it was

A stalled todo could end a run: 8 rounds without a new completion, read, command or mutation got a reassessment nudge, 16 got a resumable pause. The pause goes; the nudge stays.

It was not the mechanism that caught what it claimed

The zero-evidence ladder escalates on the same receipts and reaches its stop at 6; the storm breaker reaches its own at 3. The todo streak reached 16.

Writing the Goal test for this proved it outright: under Goal the run never got to 16 at all, because the ladder's structural pause fired first every time. So this was dead code under Goal, and in ordinary chat it was the only host-owned stop left after #8320 and #8340.

What it measured was also narrower than it reads. Any first-time successful read, command or mutation renews the streak - progressReceiptSignature counts reads, and folds the output digest into the signature, so even re-reading a file whose contents changed renews it. Sixteen rounds without renewal means sixteen rounds producing literally nothing new: exactly the state the two guards above already handle, twice over and far sooner.

What is removed

  • todoStallPause and maxTodoStallRounds
  • the todo_stall pause class and its RunPauseInfo mapping
  • the planner's non-finalization message for it
  • the Goal FSM's stop cause branch

trackTodoProgress no longer returns an error at all - it advances the streak and nudges once.

Verification

  • TestTodoProgressGuardNeverPausesARun runs the identical stall under both ordinary chat and a Goal delivery scope, and asserts no run ends with a todo_stall pause in either. The chat case additionally asserts every scripted turn runs past the old threshold and that the reassessment nudge survived.
  • TestTodoProgressGuardRenewsOnUniqueHostWork unchanged - the renewal rule is untouched.
  • TestPauseClassNamesEachGuard updated: todo_stall is no longer a class.

go test -count=1 ./internal/agent/ ./internal/control/ ./internal/boot/ green; golangci-lint run ./... 0 issues; repolint clean with no baseline change (net removal).

Where this leaves the host

After #8320, #8340 and this, an ordinary chat turn has no host-owned stop of any kind. What remains is advisory (the zero-evidence ladder, the storm breaker, the exploration decay), user-invoked (--max-steps, the opt-in spend gate), or Goal's own bounded-autonomy contract.

Cache-impact: none - removes a host-side stop and its bookkeeping. No prompt, tool schema, or provider request field changes; the reassessment nudge is unchanged in wording and trigger.
Cache-guard: existing - go test ./internal/agent/ covers the cache-hit e2e suites, green unchanged.
Documentation-impact: none - the pause was never documented as a user-facing limit; docs/GUIDE.md describes the guards that remain, which are unchanged.

@esengine
esengine requested a review from SivanCola as a code owner August 11, 2026 06:41
@github-actions github-actions Bot added v2 Go rewrite (1.x) — main-v2 branch, active development agent Core agent loop (internal/agent, internal/control) labels Aug 11, 2026
A stalled todo could end a run: 8 rounds without a new completion, read,
command or mutation got a reassessment nudge, 16 got a resumable pause. The
pause goes; the nudge stays.

It was never the mechanism that caught the stall it claimed. The
zero-evidence ladder escalates on the same receipts and reaches its stop at
6, and the storm breaker reaches its own at 3 — writing the Goal test for
this proved it, since Goal never reached 16 at all: the ladder's structural
pause always fired first. So under Goal it was dead code, and in ordinary
chat it was the last remaining way for the host to end a turn the user never
asked it to end.

What it measured was also narrower than it read. Any first-time successful
read, command or mutation renews the streak, so 16 rounds meant 16 rounds
producing literally nothing new — a state the two guards above already
handle, twice over and far sooner.

todoStallPause and maxTodoStallRounds are gone with it, along with the
todo_stall pause class, its RunPauseInfo mapping, the planner's
non-finalization message for it, and the Goal FSM's stop cause.
@esengine
esengine force-pushed the feat/no-chat-todo-stall-pause branch from dfd15ff to 8b47fdc Compare August 11, 2026 06:53
@esengine
esengine merged commit 792f5df into main-v2 Aug 11, 2026
22 checks passed
@esengine
esengine deleted the feat/no-chat-todo-stall-pause branch August 11, 2026 09:24
SivanCola added a commit to SivanCola/DeepSeek-Reasonix that referenced this pull request Aug 11, 2026
Integrate the newly landed no-Todo-stall and no-Goal-round-ceiling changes from esengine#8347 and esengine#8357 without rewriting the published PR history.

Preserve this PR's broader continuous-runtime behavior: Goal Todo stalls still trigger a second-stage replan and epoch reset, while goal_stuck finalization remains removed.

Verified with full Go tests, agent/control race tests, go vet, repolint, Desktop tests, frontend typecheck/test/build, and cache guards.
SivanCola added a commit to SivanCola/DeepSeek-Reasonix that referenced this pull request Aug 11, 2026
Problem:
- main-v2 advanced with esengine#8335, esengine#8347, and esengine#8357 while esengine#8257 was awaiting merge.
- The repository complexity baseline conflicted with the catalog branch's owner-file extractions.

Root cause:
- Both branches updated controller and frontend ownership measurements while evolving independent runtime behavior.

Fix:
- merge the latest protected main-v2 prompt-queue, todo-stall, and Goal runtime changes
- preserve the catalog session identity and hydration fences in the automatically merged frontend
- regenerate the repolint baseline from the combined tree without widening any measured budget

Verification:
- focused root/control/catalog tests
- focused race tests for control, agent, and all catalog packages
- Desktop Go test suite
- frontend test:all and production build with bundle budgets
- root and Desktop go vet
- gofmt, repolint, and staged diff checks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent Core agent loop (internal/agent, internal/control) v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant