Problem
GSD's internal gsd-auto-wrapup warning can interrupt an active auto-mode turn while tools are still in flight. In the captured failure, three read calls were skipped with Skipped due to queued user message., then the provider returned Unknown error, and auto-mode paused as a provider error.
A secondary effect appears after unit completion: late async notifications still trigger extra LLM turns because GSD only clears queued follow-ups after runUnit() returns, not during pauseAuto() / stopAuto() cleanup.
Root Cause
1) gsd-auto-wrapup is injected as a turn-triggering message during active execution
In auto-timers.js, both the soft timeout warning and the context-budget warning call pi.sendMessage(..., { triggerTurn: true }) while the current unit is still active:
auto-timers.js:85-105
auto-timers.js:242-255
Relevant code:
pi.sendMessage({
customType: "gsd-auto-wrapup",
display: s.verbose,
content: [ ... ].join("\n"),
}, { triggerTurn: true });
That message is not advisory-only; it starts a new turn immediately. In the captured activity log, the agent had just emitted three read tool calls for the tablet checkout artifacts, and those tool results were then returned as:
.gsd/activity/080-execute-task-M004-S12-T03.jsonl:137-139 → Skipped due to queued user message.
.gsd/activity/080-execute-task-M004-S12-T03.jsonl:140 → queued custom_message with customType:"gsd-auto-wrapup"
.gsd/activity/080-execute-task-M004-S12-T03.jsonl:141 → assistant stopReason:"error", errorMessage:"Unknown error"
This is a race/order bug: an internal housekeeping prompt is competing with the agent's active tool-using turn.
2) Queue cleanup only happens after runUnit() completes, not when auto-mode pauses/stops
auto/run-unit.js:91-100 tries to mitigate trailing async follow-ups by calling clearQueue() once after agent_end:
const cmdCtxAny = s.cmdCtx;
if (typeof cmdCtxAny?.clearQueue === "function") {
cmdCtxAny.clearQueue();
}
But neither pauseAuto() nor stopAuto() performs equivalent queue clearing:
auto.js:360-520 (stopAuto cleanup)
auto.js:579-635 (pauseAuto cleanup)
So any follow-up notifications that arrive after unit completion / pause / stop can still trigger extra turns. That matches the observed repeated post-completion async_job_result turns where the agent kept replying Task T03 complete..
Expected Behavior
-
gsd-auto-wrapup should never interrupt an active tool-use turn.
- It should be delivered as a non-turn-triggering advisory (
triggerTurn: false), or
- queued until no tools are in flight / the unit is idle, or
- surfaced only through UI notification/status instead of a model-facing message.
-
pauseAuto() and stopAuto() should flush queued follow-up messages the same way runUnit() does.
- Reuse the existing
clearQueue() runtime check during pause/stop cleanup.
- Ideally also suppress or coalesce late informational follow-ups (
async_job_result, wrap-up warnings) once the unit has already completed.
Concrete fix suggestion
- In
auto-timers.js, change both gsd-auto-wrapup sends to avoid triggerTurn: true while a unit is active.
- In
auto.js, add the same clearQueue() cleanup used by auto/run-unit.js inside both stopAuto() and pauseAuto() before the session is marked inactive/paused.
- If GSD wants the warning in the transcript, gate it behind
getInFlightToolCount() === 0 / no active tool work before triggering a turn.
Environment
- GSD version: 2.60.0
- Model: gpt-5.4
- Unit: execute-task
M004/S12/T03
Reproduction Context
During auto-mode execution of M004/S12/T03, the agent was inspecting checkout parity screenshots after a replay failure. While the agent was still in an active browser/image-debugging turn, GSD's context-budget monitor injected gsd-auto-wrapup. That queued message caused the three pending read tool calls to be skipped, then the provider returned Unknown error, and auto-mode paused.
After task closeout, trailing async_job_result notifications still generated extra LLM turns (Task T03 complete. repeated several times), which points to missing queue flush on stop/pause.
Forensic Evidence
- Duplicate check found related but non-identical history:
- Activity log sequence:
.gsd/activity/080-execute-task-M004-S12-T03.jsonl:136 assistant emits 3 read tool calls
.gsd/activity/080-execute-task-M004-S12-T03.jsonl:137-139 each read is skipped with Skipped due to queued user message.
.gsd/activity/080-execute-task-M004-S12-T03.jsonl:140 queued gsd-auto-wrapup custom message
.gsd/activity/080-execute-task-M004-S12-T03.jsonl:141 provider returns Unknown error
- Source paths involved:
auto-timers.js:85-105
auto-timers.js:242-255
auto/run-unit.js:91-100
auto.js:360-520
auto.js:579-635
Auto-generated by /gsd forensics
Problem
GSD's internal
gsd-auto-wrapupwarning can interrupt an active auto-mode turn while tools are still in flight. In the captured failure, threereadcalls were skipped withSkipped due to queued user message., then the provider returnedUnknown error, and auto-mode paused as a provider error.A secondary effect appears after unit completion: late async notifications still trigger extra LLM turns because GSD only clears queued follow-ups after
runUnit()returns, not duringpauseAuto()/stopAuto()cleanup.Root Cause
1)
gsd-auto-wrapupis injected as a turn-triggering message during active executionIn
auto-timers.js, both the soft timeout warning and the context-budget warning callpi.sendMessage(..., { triggerTurn: true })while the current unit is still active:auto-timers.js:85-105auto-timers.js:242-255Relevant code:
That message is not advisory-only; it starts a new turn immediately. In the captured activity log, the agent had just emitted three
readtool calls for the tablet checkout artifacts, and those tool results were then returned as:.gsd/activity/080-execute-task-M004-S12-T03.jsonl:137-139→Skipped due to queued user message..gsd/activity/080-execute-task-M004-S12-T03.jsonl:140→ queuedcustom_messagewithcustomType:"gsd-auto-wrapup".gsd/activity/080-execute-task-M004-S12-T03.jsonl:141→ assistantstopReason:"error",errorMessage:"Unknown error"This is a race/order bug: an internal housekeeping prompt is competing with the agent's active tool-using turn.
2) Queue cleanup only happens after
runUnit()completes, not when auto-mode pauses/stopsauto/run-unit.js:91-100tries to mitigate trailing async follow-ups by callingclearQueue()once afteragent_end:But neither
pauseAuto()norstopAuto()performs equivalent queue clearing:auto.js:360-520(stopAutocleanup)auto.js:579-635(pauseAutocleanup)So any follow-up notifications that arrive after unit completion / pause / stop can still trigger extra turns. That matches the observed repeated post-completion
async_job_resultturns where the agent kept replyingTask T03 complete..Expected Behavior
gsd-auto-wrapupshould never interrupt an active tool-use turn.triggerTurn: false), orpauseAuto()andstopAuto()should flush queued follow-up messages the same wayrunUnit()does.clearQueue()runtime check during pause/stop cleanup.async_job_result, wrap-up warnings) once the unit has already completed.Concrete fix suggestion
auto-timers.js, change bothgsd-auto-wrapupsends to avoidtriggerTurn: truewhile a unit is active.auto.js, add the sameclearQueue()cleanup used byauto/run-unit.jsinside bothstopAuto()andpauseAuto()before the session is marked inactive/paused.getInFlightToolCount() === 0/ no active tool work before triggering a turn.Environment
M004/S12/T03Reproduction Context
During auto-mode execution of
M004/S12/T03, the agent was inspecting checkout parity screenshots after a replay failure. While the agent was still in an active browser/image-debugging turn, GSD's context-budget monitor injectedgsd-auto-wrapup. That queued message caused the three pendingreadtool calls to be skipped, then the provider returnedUnknown error, and auto-mode paused.After task closeout, trailing
async_job_resultnotifications still generated extra LLM turns (Task T03 complete.repeated several times), which points to missing queue flush on stop/pause.Forensic Evidence
None of those clearly cover the extension-side
gsd-auto-wrapupmid-turn interruption path above..gsd/activity/080-execute-task-M004-S12-T03.jsonl:136assistant emits 3readtool calls.gsd/activity/080-execute-task-M004-S12-T03.jsonl:137-139each read is skipped withSkipped due to queued user message..gsd/activity/080-execute-task-M004-S12-T03.jsonl:140queuedgsd-auto-wrapupcustom message.gsd/activity/080-execute-task-M004-S12-T03.jsonl:141provider returnsUnknown errorauto-timers.js:85-105auto-timers.js:242-255auto/run-unit.js:91-100auto.js:360-520auto.js:579-635Auto-generated by
/gsd forensics