From 9308de59a9b0dee6b91201e1ea696399a71c56ad Mon Sep 17 00:00:00 2001 From: riker Date: Thu, 22 Jan 2026 11:44:45 -0800 Subject: [PATCH] fix(dog): properly set identity for dog sessions Three fixes to make dog dispatch work end-to-end: 1. Add BuildDogStartupCommand in loader.go - Similar to BuildPolecatStartupCommand/BuildCrewStartupCommand - Passes AgentName to AgentEnv so BD_ACTOR is exported in startup command 2. Use BuildDogStartupCommand in dog.go - Removes ineffective SetEnvironment calls (env vars set after shell starts don't propagate to already-running processes) 3. Add "dog" case in mail_identity.go detectSenderFromRole - Dogs now use BD_ACTOR for mail identity - Without this, dogs fell through to "overseer" and couldn't find their mail Tested: dog alpha now correctly sees inbox as deacon/dogs/alpha Co-Authored-By: Claude Opus 4.5 --- internal/cmd/dog.go | 13 ++----------- internal/cmd/mail_identity.go | 7 +++++++ internal/config/loader.go | 11 +++++++++++ 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/internal/cmd/dog.go b/internal/cmd/dog.go index dc0ad0f2..c898406c 100644 --- a/internal/cmd/dog.go +++ b/internal/cmd/dog.go @@ -852,8 +852,9 @@ func runDogDispatch(cmd *cobra.Command, args []string) error { } // Build startup command with initial prompt to check mail and execute plugin + // Use BuildDogStartupCommand to properly set BD_ACTOR=deacon/dogs/ in the startup command initialPrompt := fmt.Sprintf("I am dog %s. Check my mail inbox with 'gt mail inbox' and execute the plugin instructions I received.", targetDog.Name) - startCmd := config.BuildAgentStartupCommand("dog", "", townRoot, targetDog.Path, initialPrompt) + startCmd := config.BuildDogStartupCommand(targetDog.Name, townRoot, targetDog.Path, initialPrompt) // Create session from dog's directory if err := t.NewSessionWithCommand(dogSessionName, targetDog.Path, startCmd); err != nil { @@ -862,16 +863,6 @@ func runDogDispatch(cmd *cobra.Command, args []string) error { } // Non-fatal: mail was sent, dog is marked as working, but no session to execute // The deacon or human can manually start the session later - } else { - // Set environment for the dog session - envVars := config.AgentEnv(config.AgentEnvConfig{ - Role: "dog", - AgentName: targetDog.Name, - TownRoot: townRoot, - }) - for k, v := range envVars { - _ = t.SetEnvironment(dogSessionName, k, v) - } } // Success - output result diff --git a/internal/cmd/mail_identity.go b/internal/cmd/mail_identity.go index 4e743aa2..e446e364 100644 --- a/internal/cmd/mail_identity.go +++ b/internal/cmd/mail_identity.go @@ -129,6 +129,13 @@ func detectSenderFromRole(role string) string { return fmt.Sprintf("%s/refinery", rig) } return detectSenderFromCwd() + case "dog": + // Dogs use BD_ACTOR directly (set by BuildDogStartupCommand) + actor := os.Getenv("BD_ACTOR") + if actor != "" { + return actor + } + return detectSenderFromCwd() default: // Unknown role, try cwd detection return detectSenderFromCwd() diff --git a/internal/config/loader.go b/internal/config/loader.go index 8a4a2819..84f6e25d 100644 --- a/internal/config/loader.go +++ b/internal/config/loader.go @@ -1512,6 +1512,17 @@ func BuildPolecatStartupCommandWithAgentOverride(rigName, polecatName, rigPath, return BuildStartupCommandWithAgentOverride(envVars, rigPath, prompt, agentOverride) } +// BuildDogStartupCommand builds the startup command for a deacon dog. +// Sets GT_ROLE, BD_ACTOR, GIT_AUTHOR_NAME, and GT_ROOT. +func BuildDogStartupCommand(dogName, townRoot, dogPath, prompt string) string { + envVars := AgentEnv(AgentEnvConfig{ + Role: "dog", + AgentName: dogName, + TownRoot: townRoot, + }) + return BuildStartupCommand(envVars, dogPath, prompt) +} + // BuildCrewStartupCommand builds the startup command for a crew member. // Sets GT_ROLE, GT_RIG, GT_CREW, BD_ACTOR, GIT_AUTHOR_NAME, and GT_ROOT. func BuildCrewStartupCommand(rigName, crewName, rigPath, prompt string) string {