5.2 KiB
5.2 KiB
Bugs
- Task accepts new turns while its merge is being finalized
EndTurnclearsmerging_by(internal/agents/manager.go:899,:926–930) beforefinishMergesnapshots the live worktree, pushes and runsRemoveTask(internal/agents/mergein.go:238–318), andtransitionSessionblocks only discard (internal/store/store.go:1389). A message sent during the push can put half-done edits into the pushed squash, or be killed when the worktree is force-removed. Add a persistedfinalizingmarker set in the same EndTurn transaction; turns, discard and subtask creation refuse while it is set, and the UI shows it as Merging. - Merge finalization keeps no durable progress; cleanup runs before the task is closed
internal/agents/mergein.go:303–324runs push → notes → fast-forward →RemoveTask→MergeTask. A crash or error after the push leaves an active task with no worktree; a retried Merge fails inSnapshot, or squashes to no change and closes with an emptymerge_commit. Have thefinalizingmarker record the squash commit; on startup, a recorded commit that is an ancestor of origin/ finishes notes, fast-forward, removal and MergeTask idempotently, otherwise the marker is cleared and an error is filed. - A failed auto-commit still advances the workflow from the old HEAD
A
CommitAllerror is only logged (internal/agents/manager.go:838–841) andFinishStagestill runs (:885–889), soRecordStagestores the oldgit.Head(internal/agents/workflows.go:349–356), the next stage branches without the turn's work, anddiscardStageslater deletes the worktree that held it. On commit failure, treat the turn as unfinished: skip FinishStage, the handoff and the summary, and file the error in the task's inbox. - Codex mid-turn delivery deletes input before the steer is accepted
Queued inputs are deleted or marked delivered and recorded as
user.message(internal/agents/queue.go:119,:158;internal/agents/inbox.go:404) beforeSteer, whose error is only logged (internal/agents/codex.go:167–174). Return the consumed ids fromdeliverMidTurn; when Steer fails, re-insert the inputs in order and cleardelivered_atso the turn-end Deliver sends them. - Inbox answer validation isn't atomic with resolving the question
CheckResponsereads open state outside the write transaction andRespondupdates by id alone (internal/agents/respond.go:26–34,:93;internal/store/inbox.go:140), so two concurrent answers both land, or a withdrawal is overwritten. Condition the update onstate='open', check RowsAffected, roll back the batch on conflict and return 409. - A Codex RPC can deadlock the reader it waits on
drivecallsSteersynchronously whilereadLooppushes notifications into a 256-entry channel (internal/codex/session.go:186,:440–476,:598); if it fills before the response is read, each waits on the other. Route RPC responses separately from notification consumption and give RPCs bounded deadlines, without replacing backpressure with an unbounded queue. - Agent startup holds the manager's global lock
ensureLiveholdsm.muthrough process start and protocol init (internal/agents/manager.go:538–629), anddeliverMuserializes every session (internal/agents/queue.go:15–16), so one slow start stalls health, interrupt and event handling everywhere. Coordinate starts per session, release m.mu during process I/O and publish the result under the lock, and narrow delivery serialization to the session. - Git network operations have no deadline and run under a cross-project lock
exec.Commandhas no context (internal/git/git.go:348–364) and Merge holds the sharedmergeMuthrough fetch (internal/agents/mergein.go:68,:101), so one stalled remote blocks merges in every project. Add contextual deadlines and non-interactive git/SSH, and serialize the network phase per project while keeping same-project ordering. - A malformed file image URL breaks transcript rendering
decodeURIthrows on e.g.file:///tmp/100%.png(web/src/markdown.ts:347), andrenderAllappends events before mounting the composer (web/src/task.ts:608–609), so the rest of the transcript and the composer don't render. Catch the decode error and render the plain fallback link. - Stale reload and focus responses overwrite newer state
loadTasks,loadSessions,loadInboxandsetFocusapply every response, even a late one (web/src/state.ts:158–179,:203–215), so clicking through tabs quickly can snap the pane back. Keep a request sequence per resource key and for focus, and apply only the latest response. - operations.md describes two incompatible event-stream designs
docs/operations.md:320–324says selecting tasks opens dedicated SSE streams, which is stale againstweb/src/state.ts:309–340,:401–414, and says onlyagent.deltais transient thoughadmin.healthis too. Rewrite the Events section to match the current two-stream feed design, and qualify the transaction/event guarantee atdocs/operations.md:7for internal bookkeeping writes.