mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
When Desktop stops or restarts a managed-agent pair, the harness is SIGKILLed after 1s and `turn_completed` never lands. `activeAgentTurnsStore` then sees the "all turns silent at once" pattern and delays badge cleanup for up to 3 min (the pause that protects live badges during transient relay-stream gaps). This is unnecessary when Desktop itself issued the kill — there is no relay-gap ambiguity. ## What changed **`activeAgentTurnsStore.ts`** — new `clearActiveTurnsForAgent(pubkey)` - Tombstones every live turn for the agent via `recordTerminal` (blocks in-flight `turn_liveness` frames from resurrecting them via `resurrectTurn`) - Removes the agent's entry from `activeTurnsByAgent` - Preserves `lastProcessed` (watermark) — full-buffer replay after the clear is a no-op - Preserves `clockOffsetByAgent` — still valid, harmless **`managedAgentRuntimeHooks.ts`** — clearing at the successful-stop boundary - New `clearActiveTurnsForAgentOnStop(pubkey, relayUrl?)` — relay-scope gate: only clears when the stopped pair's relay matches the active community (pair-scoped), or when an active community is configured (agent-wide ops) - New `restartManagedAgentPair(pubkey, relayUrl, stop, clear, start)` — dependency-injected stop → clear → start sequence; the `restart` branch of `useManagedAgentRuntimeAction`'s `mutationFn` is a single call into it. The clear fires after a successful stop and before start begins, so the badge is gone even when start fails, a failed stop clears nothing, and no clear can run after the new process is spawned (genuinely-new turns are never wiped) - `useManagedAgentRuntimeAction.onSuccess` clears for `stop` actions, before the query-cache update **`managedAgentControlActions.ts`** — `onStopped` callback on `respawnManagedAgentWithRules`, invoked after the stop promise resolves and before start begins **`welcomeKickoff.ts`** — same `onStopped` boundary on `restartWelcomeTeammate` **Call sites covered (all stop/restart UI paths):** - `useManagedAgentRuntimeAction` — pair-scoped stop (`onSuccess`) and restart (`restartManagedAgentPair` in `mutationFn`); Members-sidebar + settings card - `useMembersSidebarActions.handleRespawnAll` — via `onStopped` - `useMembersSidebarActions.handleStopAll` — direct local-stop branch - `useMembersSidebarActions.handleLifecycleAction` — local-stop fallback branch - `useAgentLifecycleActions.handleAgentPrimaryAction` — Agents-tab stop - `useAgentLifecycleActions.handleAgentRestart` — via `onStopped` - `useManagedAgentActions.handleStop` / `handleBulkStopRunning` — Agents screen - `useAutoRestartPolicy` — inline, between stop and start - `restartWelcomeTeammate` call site — via `onStopped` Provider agents are excluded at each site: they go through `!shutdown` (relay message), not a direct harness kill. ## Tests Twelve behavior tests across three files: - `activeAgentTurnsStore.test.mjs` (6) — clear removes the agent's turns and notifies subscribers, other agents untouched; full-buffer replay after clear is a no-op (watermark preserved); late `turn_liveness` frame with timestamp ≤ clear time does not resurrect (tombstone); new `turn_started` after clear is tracked normally; badge gone when stop succeeds even if start fails; new frame during start-pending does not resurrect the cleared badge - `managedAgentControlActions.test.mjs` (3) — `onStopped` fires on stop-success/start-failure; does not fire on stop-failure; strict stop → `onStopped` → start ordering - `managedAgentRuntimeHooks.test.mjs` (3) — pair-restart seam: clear ran when start fails (rejection propagates); stop failure invokes neither clear nor start; strict stop → clear → start ordering --------- Signed-off-by: Will Pfleger <pfleger.will@gmail.com> Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>