feat(session): Add GUPP to non-polecat roles (Mayor, Deacon, Witness, Refinery)

GUPP (Gas Town Universal Propulsion Principle) is the propulsion nudge sent
after beacon to trigger autonomous work execution. Previously only polecats
received this nudge.

Now all roles get role-specific propulsion nudges on startup:
- Polecat/Crew: "Run `gt hook` to check your hook and begin work."
- Witness: "Run `gt prime` to check patrol status and begin work."
- Refinery: "Run `gt prime` to check MQ status and begin patrol."
- Deacon: "Run `gt prime` to check patrol status and begin heartbeat cycle."
- Mayor: "Run `gt prime` to check mail and begin coordination."

Changes:
- internal/session/names.go: Add PropulsionNudgeForRole() function
- internal/cmd/witness.go: Add GUPP nudge to ensureWitnessSession
- internal/cmd/start.go: Add GUPP nudge to ensureRefinerySession (also
  converted from respawn loop to direct Claude launch like other roles)
- internal/cmd/deacon.go: Add GUPP nudge to startDeaconSession
- internal/cmd/mayor.go: Add GUPP nudge to startMayorSession

Fixes: gt-zzpmt

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
valkyrie
2026-01-01 18:46:07 -08:00
committed by Steve Yegge
parent ee1d6c12ab
commit 65c34efd4e
5 changed files with 63 additions and 4 deletions

View File

@@ -350,6 +350,12 @@ func startDeaconSession(t *tmux.Tmux) error {
Topic: "patrol",
}) // Non-fatal
// GUPP: Gas Town Universal Propulsion Principle
// Send the propulsion nudge to trigger autonomous patrol execution.
// Wait for beacon to be fully processed (needs to be separate prompt)
time.Sleep(2 * time.Second)
_ = t.NudgeSession(DeaconSessionName, session.PropulsionNudgeForRole("deacon")) // Non-fatal
return nil
}

View File

@@ -153,6 +153,12 @@ func startMayorSession(t *tmux.Tmux) error {
Topic: "cold-start",
}) // Non-fatal
// GUPP: Gas Town Universal Propulsion Principle
// Send the propulsion nudge to trigger autonomous coordination.
// Wait for beacon to be fully processed (needs to be separate prompt)
time.Sleep(2 * time.Second)
_ = t.NudgeSession(MayorSessionName, session.PropulsionNudgeForRole("mayor")) // Non-fatal
return nil
}

View File

@@ -339,14 +339,32 @@ func ensureRefinerySession(rigName string, r *rig.Rig) (bool, error) {
theme := tmux.AssignTheme(rigName)
_ = t.ConfigureGasTownSession(sessionName, theme, rigName, "refinery", "refinery")
// Launch Claude in a respawn loop
// Launch Claude directly (no respawn loop - daemon handles restart)
// Export GT_ROLE and BD_ACTOR in the command since tmux SetEnvironment only affects new panes
runtimeCmd := config.GetRuntimeCommand(r.Path)
loopCmd := `export GT_ROLE=refinery BD_ACTOR=` + bdActor + ` GIT_AUTHOR_NAME=` + bdActor + ` && while true; do echo "🛢️ Starting Refinery for ` + rigName + `..."; ` + runtimeCmd + `; echo ""; echo "Refinery exited. Restarting in 2s... (Ctrl-C to stop)"; sleep 2; done`
if err := t.SendKeysDelayed(sessionName, loopCmd, 200); err != nil {
if err := t.SendKeys(sessionName, config.BuildAgentStartupCommand("refinery", bdActor, "", "")); err != nil {
return false, fmt.Errorf("sending command: %w", err)
}
// Wait for Claude to start (non-fatal)
if err := t.WaitForCommand(sessionName, constants.SupportedShells, constants.ClaudeStartTimeout); err != nil {
// Non-fatal
}
time.Sleep(constants.ShutdownNotifyDelay)
// Inject startup nudge for predecessor discovery via /resume
address := fmt.Sprintf("%s/refinery", rigName)
_ = session.StartupNudge(t, sessionName, session.StartupNudgeConfig{
Recipient: address,
Sender: "deacon",
Topic: "patrol",
}) // Non-fatal
// GUPP: Gas Town Universal Propulsion Principle
// Send the propulsion nudge to trigger autonomous patrol execution.
// Wait for beacon to be fully processed (needs to be separate prompt)
time.Sleep(2 * time.Second)
_ = t.NudgeSession(sessionName, session.PropulsionNudgeForRole("refinery")) // Non-fatal
return true, nil
}

View File

@@ -352,6 +352,12 @@ func ensureWitnessSession(rigName string, r *rig.Rig) (bool, error) {
Topic: "patrol",
}) // Non-fatal
// GUPP: Gas Town Universal Propulsion Principle
// Send the propulsion nudge to trigger autonomous patrol execution.
// Wait for beacon to be fully processed (needs to be separate prompt)
time.Sleep(2 * time.Second)
_ = t.NudgeSession(sessionName, session.PropulsionNudgeForRole("witness")) // Non-fatal
return true, nil
}