From b5a3fe3e15264a5779052a45728ed8f1c86181ad Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Sun, 28 Dec 2025 15:34:35 -0800 Subject: [PATCH] fix: Polecat identity detection - template path and env export (gt-si6am, gt-y41ep, gt-9ar8x) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two bugs caused polecats to think they were mayor: 1. Template lookup path (gt-si6am): - Was looking at rig.Path/templates/ which doesn't exist - Now correctly looks at mayor/rig/templates/ - Polecats get the polecat CLAUDE.md instead of inheriting mayor's 2. Env var export (gt-y41ep): - tmux SetEnvironment only affects new panes, not current shell - Now exports GT_ROLE, GT_RIG, GT_POLECAT, BD_ACTOR inline before Claude - Matches how crew sessions work Combined effect (gt-9ar8x): Polecats now correctly identify as polecats and work from their own directory instead of mayor/rig. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- internal/polecat/manager.go | 8 +++++--- internal/session/manager.go | 9 +++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/internal/polecat/manager.go b/internal/polecat/manager.go index 11963357..1defb409 100644 --- a/internal/polecat/manager.go +++ b/internal/polecat/manager.go @@ -662,12 +662,14 @@ func (m *Manager) loadFromBeads(name string) (*Polecat, error) { // Template variables {{rig}} and {{name}} are substituted with actual values. // This provides polecats with context about their role and available commands. func (m *Manager) installCLAUDETemplate(polecatPath, name string) error { - // Read template from rig's templates directory - templatePath := filepath.Join(m.rig.Path, "templates", "polecat-CLAUDE.md") + // Read template from mayor/rig/templates directory + // Templates live in the mayor's clone, not at rig root + templatePath := filepath.Join(m.rig.Path, "mayor", "rig", "templates", "polecat-CLAUDE.md") content, err := os.ReadFile(templatePath) if err != nil { if os.IsNotExist(err) { - // Template doesn't exist - this is fine, just skip + // Template doesn't exist - warn and skip (this is a setup issue) + fmt.Printf("Warning: polecat template not found at %s\n", templatePath) return nil } return fmt.Errorf("reading template: %w", err) diff --git a/internal/session/manager.go b/internal/session/manager.go index c5ac47f2..431160aa 100644 --- a/internal/session/manager.go +++ b/internal/session/manager.go @@ -161,11 +161,16 @@ func (m *Manager) Start(polecat string, opts StartOptions) error { agentID := fmt.Sprintf("%s/%s", m.rig.Name, polecat) _ = m.tmux.SetPaneDiedHook(sessionID, agentID) - // Send initial command + // Send initial command with env vars exported inline + // NOTE: tmux SetEnvironment only affects NEW panes, not the current shell. + // We must export GT_ROLE, GT_RIG, GT_POLECAT inline for Claude to detect identity. command := opts.Command if command == "" { // Polecats run with full permissions - Gas Town is for grownups - command = "claude --dangerously-skip-permissions" + // Export env vars inline so Claude's role detection works + bdActor := fmt.Sprintf("%s/polecats/%s", m.rig.Name, polecat) + command = fmt.Sprintf("export GT_ROLE=polecat GT_RIG=%s GT_POLECAT=%s BD_ACTOR=%s && claude --dangerously-skip-permissions", + m.rig.Name, polecat, bdActor) } if err := m.tmux.SendKeys(sessionID, command); err != nil { return fmt.Errorf("sending command: %w", err)