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
Agent executor silently truncates output and loses the session ID
AgentExecutor.Run (internal/executor/agent.go) called cmd.Wait() while goroutines were still reading cmd.StdoutPipe() / cmd.StderrPipe(). Per the StdoutPipe contract, Wait closes the parent pipe ends as soon as the process exits — it is incorrect to call it before all reads complete. Output the scanners had not read yet is dropped silently: no error, no log. Under load the entire output is lost, including the session_id line.
CI (go test -race): TestAgentExecutorFakeCommand failed with session="" on 2/2 runs of PR feat(llm): support the OpenAI Responses API protocol #4, while the identical code passed locally and on main's single run — the classic signature of a scheduling race, not a functional failure.
Minimal standalone repro of the same pattern (child echos 3 lines and exits, reader goroutine delayed 3 ms): old order lost the whole output in 60/100 runs; drain-first lost 0/100.
Impact
Production: under load, an agent run (claude / cursor / codex) can lose output lines and the session ID — auto-dev logs are incomplete and resume-by-session becomes impossible. No error surfaces anywhere.
CI: manifests as a flaky TestAgentExecutorFakeCommand failure that randomly blocks PRs.
Expected behavior
The scanners drain the full pipe contents before the pipes are closed — output and session ID are always captured regardless of scheduling.
A descendant process that inherits the pipe and lingers must not hang the run — bounded by a grace period, with a visible truncation note.
Acceptance criteria
Session line captured even when the child exits immediately after emitting
Grandchild output written after the parent exits is still captured
A lingering descendant returns within the grace bound and logs a truncation note
Regression tests fail against the old code and pass with the fix (go test -race ./internal/...)
Agent executor silently truncates output and loses the session ID
AgentExecutor.Run(internal/executor/agent.go) calledcmd.Wait()while goroutines were still readingcmd.StdoutPipe()/cmd.StderrPipe(). Per theStdoutPipecontract,Waitcloses the parent pipe ends as soon as the process exits — it is incorrect to call it before all reads complete. Output the scanners had not read yet is dropped silently: no error, no log. Under load the entire output is lost, including thesession_idline.中文描述
AgentExecutor.Run在扫描 goroutine 还没读完StdoutPipe/StderrPipe时就调用了cmd.Wait()。按StdoutPipe的文档约定,进程一退出Wait就会关闭父端管道——在读完成之前调用是错误的。扫描器尚未读到的输出会被静默丢弃:无报错、无日志。高负载下(如 CI 的-race)全部输出都会丢失,包括session_id行,导致 agent 日志不完整、无法按 session 恢复。Evidence
go test -race):TestAgentExecutorFakeCommandfailed withsession=""on 2/2 runs of PR feat(llm): support the OpenAI Responses API protocol #4, while the identical code passed locally and on main's single run — the classic signature of a scheduling race, not a functional failure.echos 3 lines and exits, reader goroutine delayed 3 ms): old order lost the whole output in 60/100 runs; drain-first lost 0/100.Impact
TestAgentExecutorFakeCommandfailure that randomly blocks PRs.Expected behavior
Acceptance criteria
go test -race ./internal/...)