This commit is contained in:
Ian Gulliver
2026-10-21 11:33:05 -07:00
parent 26a95315e6
commit 3f4e4d5e90
+1 -3
View File
@@ -86,9 +86,7 @@ Vendor setup and protocol quirks are in [Claude Code](claude-protocol.md), [Code
## Coordination
Merges to the default branch run on a coordinator: a single goroutine (`internal/agents/coordinator.go`) that every stored event wakes, and that decides only from the database's current state, never from which event woke it. Its decisions run inside one store write transaction, so no other write lands while it decides. Slow work (git, starting a turn) runs after that transaction, and shows in state while it runs (a session `running`, a task `finalizing`), so the next pass doesn't start it twice. Startup is just one more pass, with no separate recovery code. Other task progress (discards, reviews, nudges, workflow stages, lead delivery) is driven by the events themselves.
A project's merge slot is held by a task with `merging_by`, `finalizing` or `pushing_to_main` set. A Merge request takes the slot at once when it's free and nothing is queued, else queues (`merge_queued_by`). Each pass drops a merge whose turn ended without finalizing, gives a free slot to the oldest queued task, starts a claimed merge turn (`merge_after_turn`) once none of the task's agents is mid-turn, and lands each finalizing merge. A session that hands off to a fresh context stays `running` until the new session takes over, so no pass sees the task idle in between.
Merge coordination must decide from the database's current state, never from which event woke it. This lets startup use the same decisions as ordinary operation rather than maintaining separate recovery logic. Slow work must run outside the decision transaction, with its progress recorded so another pass cannot start it twice.
## git