You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
session: tasks stuck in working on restart, stopped status mapped to failed, and reader handoff #1554
Task frontier state recovery leaves queued tasks hung after restart, stopped tasks are improperly reported as failures, and chat reader subtasks do not fall back cleanly.
Items & Observed Behavior
Tasks hung in working state across restart: A task queued or waiting on machine capacity remains in working status in the database after codeaf engine --stop and restart, but is never re-admitted to the execution frontier.
Stopped tasks mapped to failure: Cancelling a task via x or /stop sets the crew line to failed and outputs /redo stronger... instead of marking it cleanly as stopped.
Chat reader subtask handoff failure: When an inline chat reader subtask fails to hand off, it prints ◆ reading for the chat · stopped and leaves a stopped card in the chat before running inline.
Expected Behavior
Engine startup must reconcile persisted task state and re-queue uncompleted tasks onto the frontier.
Explicit cancellation (x, /stop) must record status as stopped and omit retry suggestions.
Reader subtask handoff failures should fall back to inline reading without polluting the chat stream with stopped task cards.
Root Cause / Location
internal/session/cancel.go and internal/session/task_frontier.go: Startup frontier reconciliation and cancellation status mapping.
internal/session/read_handoff.go: Silent fallback handling when subtask delegation cannot be completed.
—
Drafted with CodeAF · reviewed and owned by the author
New evidence from dev 837b2b0, found by the docs lanes while writing the public docs. Replication for every item below starts from a clean install:
Build dev 837b2b0 (git checkout 837b2b0 && make build, binary bin/codeaf), or install the dev build with curl -fsSL https://agentfield.ai/get/devaf | bash.
Use an isolated profile: export HOME=$(mktemp -d), export OPENROUTER_API_KEY, and keep the default model (~deepseek/deepseek-v4-flash-latest, crew on auto).
On a busy machine set task.max_load to 0 (/settings, Tasks) so the busy-machine gate does not hold tasks.
1. Task stuck working after an engine restart (B08)
What happened: a task waiting · machine busy; codeaf engine --stop and a relaunch; the task then showed working for 10+ minutes with no worker process and no model call in codeaf logs --tail. codeaf do on the same config finished in 4 s.
Replication: force the hold with a tiny task.max_load (for example 0.01), /task add a README.md with one line, codeaf engine --stop, set task.max_load to 0, relaunch codeaf.
2. A stopped task's crew line says failed (B30, two lanes)
Screen: after x → stop it, the card reads stopped · it had changed nothing but the crew line reads task 5 crew · failed, /redo stronger runs it again on a stronger crew (a long dash written as a comma). Also for a task that /stop ended before it did anything (task 1 crew · failed …).
Replication:/task Run the shell command sleep 120, then list the files; alt+t, x, stop it. This may also teach the router wrongly.
3. Reader subtask handoff shows as a stopped task (B31)
Screen:◆ reading for the chat · stopped with stopped before it started: read handoff failed; running inline; the chats list shows 2 stopped children. The turn went on inline and answered. Seen in two conversations.
Code at 837b2b0:internal/session/readhandoff.go:192-196 (a.cancelTask(id, "read handoff failed; running inline")).
Acceptance (e2e)
After the restart above, the task is admitted and lands (or reads waiting with its reason), never working with no worker.
A stopped task's crew line says stopped, with no /redo stronger offer.
A failed read hand-off leaves no stopped card or stopped child in the chats list.
Found while writing the public docs; manual text differences are in #1545.
Independent review of automatic task recovery selected from #1619 found a related restart defect: the accepted task-specific crew was not saved in the durable run row. Pending and admitted recovery could construct a run without it, silently replacing task pins/fallback policy with conversation or profile settings.
The bounded correction now saves accepted seats, original send IDs, fallback and failed-route history, and accumulated task/checker/model spending. Restored runs use that policy without routing again. A missing legacy policy or model call interrupted before its cost was saved remains truthfully interrupted instead of executing under guessed settings or a reset budget. The manual describes this limitation.
Reproduction at a73ed558d: reopen a held task whose accepted worker/planner/checker differ from the conversation model; TestHeldRecoveryRetainsTheAcceptedCrew fails with held restart lost its accepted crew before the fix. On the candidate, the test invokes all three restored completers and checks the actual models. Admitted recovery also verifies saved fallback/failed-route state and rejection at an already-exhausted task cap. Additional checks cover missing/in-flight policy refusal and synchronous before-call/after-settlement persistence.
The targeted regression set passed three repetitions on the exact committed candidate. This correction is pending integration into #1632; final combined gate and real-workflow acceptance remain pending. It does not close every behavior described in this issue.
Follow-up during current-dev integration: the newer shared-ledger day initializes its date on first read. Restoring a saved crew spend before that initialization caused the first read to replace the saved amount with a lagging ledger value (deterministic regression: got1, expected5).
The repair refreshes the day under its existing lock before applying saved same-day floors. Checkpoint snapshots now also refresh and include observed shared spending; yesterday's values cannot be saved as today's. Real ledger-backed tests verify refusal at an exhausted restored daily cap, preserved last-call pricing, visibility of newer ledger spending, and next-day expiry.
The exact candidate passed all structural laws and ten repetitions of the targeted recovery/spending checks. The helper extraction leaves complexity limits unchanged and retains discarded-response charging. Final aggregate validation remains separate.
The remaining pending-program recovery test now records the explicit accepted unrouted crew policy, matching production admission. Missing or unsettled policy still refuses recovery. Test-only commit 1b4f35db21d00fe065b5fc955f7a5f26dffe5022 reproduces the original own-driver failure on the baseline; the corrected fixture and refusal controls pass 50 repetitions (30.631s). Independent source review approved. This is part of #1632; final combined validation remains pending.
Activity
santoshkumarradha commentedon Sep 27, 2026
New evidence from dev 837b2b0, found by the docs lanes while writing the public docs. Replication for every item below starts from a clean install:
git checkout 837b2b0 && make build, binarybin/codeaf), or install the dev build withcurl -fsSL https://agentfield.ai/get/devaf | bash.export HOME=$(mktemp -d), exportOPENROUTER_API_KEY, and keep the default model (~deepseek/deepseek-v4-flash-latest, crew on auto).task.max_loadto0(/settings, Tasks) so the busy-machine gate does not hold tasks.1. Task stuck
workingafter an engine restart (B08)waiting · machine busy;codeaf engine --stopand a relaunch; the task then showedworkingfor 10+ minutes with no worker process and no model call incodeaf logs --tail.codeaf doon the same config finished in 4 s.task.max_load(for example0.01),/task add a README.md with one line,codeaf engine --stop, settask.max_loadto0, relaunchcodeaf.2. A stopped task's crew line says failed (B30, two lanes)
x→stop it, the card readsstopped · it had changed nothingbut the crew line readstask 5 crew · failed, /redo stronger runs it again on a stronger crew(a long dash written as a comma). Also for a task that/stopended before it did anything (task 1 crew · failed …)./task Run the shell command sleep 120, then list the files;alt+t,x,stop it. This may also teach the router wrongly.3. Reader subtask handoff shows as a stopped task (B31)
◆ reading for the chat · stoppedwithstopped before it started: read handoff failed; running inline; the chats list shows2 stoppedchildren. The turn went on inline and answered. Seen in two conversations.internal/session/readhandoff.go:192-196(a.cancelTask(id, "read handoff failed; running inline")).Acceptance (e2e)
workingwith no worker.stopped, with no/redo strongeroffer.Found while writing the public docs; manual text differences are in #1545.
🤖 Generated with Claude Code
session: take back the restart reconcile of an interrupted run's plan
tasks: a held task says machine busy, stops from the main box, follow…
tasks: task.max_load changes reach the engine process, and an interru…
Consolidate verified CodeAF task, chat and runtime fixes (#1627)
santoshkumarradha commentedon Sep 28, 2026
Independent review of automatic task recovery selected from #1619 found a related restart defect: the accepted task-specific crew was not saved in the durable run row. Pending and admitted recovery could construct a run without it, silently replacing task pins/fallback policy with conversation or profile settings.
The bounded correction now saves accepted seats, original send IDs, fallback and failed-route history, and accumulated task/checker/model spending. Restored runs use that policy without routing again. A missing legacy policy or model call interrupted before its cost was saved remains truthfully interrupted instead of executing under guessed settings or a reset budget. The manual describes this limitation.
Reproduction at
a73ed558d: reopen a held task whose accepted worker/planner/checker differ from the conversation model;TestHeldRecoveryRetainsTheAcceptedCrewfails withheld restart lost its accepted crewbefore the fix. On the candidate, the test invokes all three restored completers and checks the actual models. Admitted recovery also verifies saved fallback/failed-route state and rejection at an already-exhausted task cap. Additional checks cover missing/in-flight policy refusal and synchronous before-call/after-settlement persistence.The targeted regression set passed three repetitions on the exact committed candidate. This correction is pending integration into #1632; final combined gate and real-workflow acceptance remain pending. It does not close every behavior described in this issue.
fix: recover and cancel tasks with durable admission state
santoshkumarradha commentedon Sep 28, 2026
Follow-up during current-dev integration: the newer shared-ledger day initializes its date on first read. Restoring a saved crew spend before that initialization caused the first read to replace the saved amount with a lagging ledger value (deterministic regression: got1, expected5).
The repair refreshes the day under its existing lock before applying saved same-day floors. Checkpoint snapshots now also refresh and include observed shared spending; yesterday's values cannot be saved as today's. Real ledger-backed tests verify refusal at an exhausted restored daily cap, preserved last-call pricing, visibility of newer ledger spending, and next-day expiry.
The exact candidate passed all structural laws and ten repetitions of the targeted recovery/spending checks. The helper extraction leaves complexity limits unchanged and retains discarded-response charging. Final aggregate validation remains separate.
santoshkumarradha commentedon Sep 28, 2026
The remaining pending-program recovery test now records the explicit accepted unrouted crew policy, matching production admission. Missing or unsettled policy still refuses recovery. Test-only commit
1b4f35db21d00fe065b5fc955f7a5f26dffe5022reproduces the original own-driver failure on the baseline; the corrected fixture and refusal controls pass 50 repetitions (30.631s). Independent source review approved. This is part of #1632; final combined validation remains pending.session: a read hand-off helper is read-only and leaves no stopped card