fix(agent): remove the todo-stall pause - #8347
Merged
Merged
Conversation
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
force-pushed
the
feat/no-chat-todo-stall-pause
branch
from
August 11, 2026 06:53
dfd15ff to
8b47fdc
Compare
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 -
progressReceiptSignaturecounts 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
todoStallPauseandmaxTodoStallRoundstodo_stallpause class and itsRunPauseInfomappingtrackTodoProgressno longer returns an error at all - it advances the streak and nudges once.Verification
TestTodoProgressGuardNeverPausesARunruns the identical stall under both ordinary chat and a Goal delivery scope, and asserts no run ends with atodo_stallpause in either. The chat case additionally asserts every scripted turn runs past the old threshold and that the reassessment nudge survived.TestTodoProgressGuardRenewsOnUniqueHostWorkunchanged - the renewal rule is untouched.TestPauseClassNamesEachGuardupdated:todo_stallis 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.mddescribes the guards that remain, which are unchanged.