From 0cdcd0a20b2dcf07a11422001ecbff5e70ad18a0 Mon Sep 17 00:00:00 2001 From: aleiby Date: Wed, 21 Jan 2026 19:31:38 -0800 Subject: [PATCH] fix(daemon): spawn Deacon immediately after killing stuck session (#729) When checkDeaconHeartbeat detects a stuck Deacon and kills it, the code relied on ensureDeaconRunning being called on the next heartbeat. However, on the next heartbeat, checkDeaconHeartbeat exits early when it finds no session (assuming ensureDeaconRunning already ran), creating a deadlock where the Deacon is never restarted. This fix calls ensureDeaconRunning immediately after the kill attempt, regardless of success or failure, ensuring the Deacon is restarted promptly. Co-Authored-By: Claude Opus 4.5 Executed-By: mayor Role: mayor --- internal/daemon/daemon.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/daemon/daemon.go b/internal/daemon/daemon.go index 24cb021e..c8d4d74c 100755 --- a/internal/daemon/daemon.go +++ b/internal/daemon/daemon.go @@ -436,7 +436,9 @@ func (d *Daemon) checkDeaconHeartbeat() { if err := d.tmux.KillSessionWithProcesses(sessionName); err != nil { d.logger.Printf("Error killing stuck Deacon: %v", err) } - // ensureDeaconRunning will restart on next heartbeat + // Spawn new Deacon immediately instead of waiting for next heartbeat + // (kill may fail if session disappeared between check and kill) + d.ensureDeaconRunning() } else { // Stuck but not critically - nudge to wake up d.logger.Printf("Deacon stuck for %s - nudging session", age.Round(time.Minute))