From be0f77324fa0d3ba62978aa07c056d11bc8f81ba Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Sat, 20 Dec 2025 15:16:56 -0800 Subject: [PATCH] fix(refinery): avoid race condition in foreground mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In foreground mode, skip the tmux session check since we are likely running inside the session that background mode created. Only check PID to avoid self-detection. Fixes the issue where gt refinery start gastown --foreground would detect its own tmux session as already running. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- internal/refinery/manager.go | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/internal/refinery/manager.go b/internal/refinery/manager.go index fbcfdb90..c3d6bb97 100644 --- a/internal/refinery/manager.go +++ b/internal/refinery/manager.go @@ -134,22 +134,17 @@ func (m *Manager) Start(foreground bool) error { return err } - // Check if already running via tmux session t := tmux.NewTmux() sessionID := m.sessionName() - running, _ := t.HasSession(sessionID) - if running { - return ErrAlreadyRunning - } - - // Also check via PID for backwards compatibility - if ref.State == StateRunning && ref.PID > 0 && processExists(ref.PID) { - return ErrAlreadyRunning - } if foreground { + // In foreground mode, we're likely running inside the tmux session + // that background mode created. Only check PID to avoid self-detection. + if ref.State == StateRunning && ref.PID > 0 && processExists(ref.PID) { + return ErrAlreadyRunning + } + // Running in foreground - update state and run the Go-based polling loop - // This is the legacy mode, kept for backwards compatibility now := time.Now() ref.State = StateRunning ref.StartedAt = &now @@ -163,6 +158,17 @@ func (m *Manager) Start(foreground bool) error { return m.run(ref) } + // Background mode: check if session already exists + running, _ := t.HasSession(sessionID) + if running { + return ErrAlreadyRunning + } + + // Also check via PID for backwards compatibility + if ref.State == StateRunning && ref.PID > 0 && processExists(ref.PID) { + return ErrAlreadyRunning + } + // Background mode: spawn a Claude agent in a tmux session // The Claude agent handles MR processing using git commands and beads