From 1be9edc272620630330c1245fbdeee0135dcbe7a Mon Sep 17 00:00:00 2001 From: bullet-farmer Date: Mon, 5 Jan 2026 00:12:47 -0800 Subject: [PATCH] feat: Add debug logging for suppressed errors in session startup (gt-6d7eh) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add debugSession helper that logs non-fatal errors when GT_DEBUG_SESSION=1. Replaced all _ = error patterns with debugSession() calls for better visibility when diagnosing session startup issues. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- internal/session/manager.go | 39 +++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/internal/session/manager.go b/internal/session/manager.go index 18da39b0..c1eb5f54 100644 --- a/internal/session/manager.go +++ b/internal/session/manager.go @@ -17,6 +17,15 @@ import ( "github.com/steveyegge/gastown/internal/tmux" ) +// debugSession logs non-fatal errors during session startup when GT_DEBUG_SESSION=1. +// These errors are intentionally suppressed because they don't prevent session operation, +// but logging them helps diagnose issues when needed. +func debugSession(context string, err error) { + if os.Getenv("GT_DEBUG_SESSION") != "" && err != nil { + fmt.Fprintf(os.Stderr, "[session-debug] %s: %v\n", context, err) + } +} + // Common errors var ( ErrSessionRunning = errors.New("session already running") @@ -139,12 +148,12 @@ func (m *Manager) Start(polecat string, opts StartOptions) error { } // Set environment (non-fatal: session works without these) - _ = m.tmux.SetEnvironment(sessionID, "GT_RIG", m.rig.Name) - _ = m.tmux.SetEnvironment(sessionID, "GT_POLECAT", polecat) + debugSession("SetEnvironment GT_RIG", m.tmux.SetEnvironment(sessionID, "GT_RIG", m.rig.Name)) + debugSession("SetEnvironment GT_POLECAT", m.tmux.SetEnvironment(sessionID, "GT_POLECAT", polecat)) // Set CLAUDE_CONFIG_DIR for account selection (non-fatal) if opts.ClaudeConfigDir != "" { - _ = m.tmux.SetEnvironment(sessionID, "CLAUDE_CONFIG_DIR", opts.ClaudeConfigDir) + debugSession("SetEnvironment CLAUDE_CONFIG_DIR", m.tmux.SetEnvironment(sessionID, "CLAUDE_CONFIG_DIR", opts.ClaudeConfigDir)) } // CRITICAL: Set beads environment for worktree polecats (non-fatal: session works without) @@ -154,9 +163,9 @@ func (m *Manager) Start(polecat string, opts StartOptions) error { // Using town-level beads ensures gt prime and bd commands can find hooked work. townRoot := filepath.Dir(m.rig.Path) // Town root is parent of rig directory beadsDir := filepath.Join(townRoot, ".beads") - _ = m.tmux.SetEnvironment(sessionID, "BEADS_DIR", beadsDir) - _ = m.tmux.SetEnvironment(sessionID, "BEADS_NO_DAEMON", "1") - _ = m.tmux.SetEnvironment(sessionID, "BEADS_AGENT_NAME", fmt.Sprintf("%s/%s", m.rig.Name, polecat)) + debugSession("SetEnvironment BEADS_DIR", m.tmux.SetEnvironment(sessionID, "BEADS_DIR", beadsDir)) + debugSession("SetEnvironment BEADS_NO_DAEMON", m.tmux.SetEnvironment(sessionID, "BEADS_NO_DAEMON", "1")) + debugSession("SetEnvironment BEADS_AGENT_NAME", m.tmux.SetEnvironment(sessionID, "BEADS_AGENT_NAME", fmt.Sprintf("%s/%s", m.rig.Name, polecat))) // Hook the issue to the polecat if provided via --issue flag if opts.Issue != "" { @@ -169,11 +178,11 @@ func (m *Manager) Start(polecat string, opts StartOptions) error { // Apply theme (non-fatal: theming failure doesn't affect operation) theme := tmux.AssignTheme(m.rig.Name) - _ = m.tmux.ConfigureGasTownSession(sessionID, theme, m.rig.Name, polecat, "polecat") + debugSession("ConfigureGasTownSession", m.tmux.ConfigureGasTownSession(sessionID, theme, m.rig.Name, polecat, "polecat")) // Set pane-died hook for crash detection (non-fatal) agentID := fmt.Sprintf("%s/%s", m.rig.Name, polecat) - _ = m.tmux.SetPaneDiedHook(sessionID, agentID) + debugSession("SetPaneDiedHook", m.tmux.SetPaneDiedHook(sessionID, agentID)) // Send initial command with env vars exported inline // NOTE: tmux SetEnvironment only affects NEW panes, not the current shell. @@ -189,15 +198,13 @@ func (m *Manager) Start(polecat string, opts StartOptions) error { } // Wait for Claude to start (non-fatal: session continues even if this times out) - if err := m.tmux.WaitForCommand(sessionID, constants.SupportedShells, constants.ClaudeStartTimeout); err != nil { - // Non-fatal warning - Claude might still start - } + debugSession("WaitForCommand", m.tmux.WaitForCommand(sessionID, constants.SupportedShells, constants.ClaudeStartTimeout)) // Accept bypass permissions warning dialog if it appears. // When Claude starts with --dangerously-skip-permissions, it shows a warning that // requires pressing Down to select "Yes, I accept" and Enter to confirm. // This is needed for automated polecat startup. - _ = m.tmux.AcceptBypassPermissionsWarning(sessionID) + debugSession("AcceptBypassPermissionsWarning", m.tmux.AcceptBypassPermissionsWarning(sessionID)) // Wait for Claude to be fully ready at the prompt (not just started) // PRAGMATIC APPROACH: Use fixed delay rather than detection. @@ -209,12 +216,12 @@ func (m *Manager) Start(polecat string, opts StartOptions) error { // Inject startup nudge for predecessor discovery via /resume // This becomes the session title in Claude Code's session picker address := fmt.Sprintf("%s/polecats/%s", m.rig.Name, polecat) - _ = StartupNudge(m.tmux, sessionID, StartupNudgeConfig{ + debugSession("StartupNudge", StartupNudge(m.tmux, sessionID, StartupNudgeConfig{ Recipient: address, Sender: "witness", Topic: "assigned", MolID: opts.Issue, - }) // Non-fatal: session works without nudge + })) // GUPP: Gas Town Universal Propulsion Principle // Send the propulsion nudge to trigger autonomous work execution. @@ -222,9 +229,7 @@ func (m *Manager) Start(polecat string, opts StartOptions) error { // that triggers Claude to check the hook and begin work. // Wait for beacon to be fully processed (needs to be separate prompt) time.Sleep(2 * time.Second) - if err := m.tmux.NudgeSession(sessionID, PropulsionNudge()); err != nil { - // Non-fatal: witness can still nudge later - } + debugSession("NudgeSession PropulsionNudge", m.tmux.NudgeSession(sessionID, PropulsionNudge())) return nil }