description = """ Full Gas Town shutdown and restart. This is an idempotent shutdown - it stops Claude sessions but preserves polecat sandboxes and hooks. Polecats can resume their work after restart. Use when you need to: - Reset all state for a fresh start - Recover from corrupted agent state - Prepare for maintenance or upgrades Sling to Mayor when ready to reboot: gt sling mol-town-shutdown mayor """ formula = "mol-town-shutdown" type = "workflow" version = 2 [[steps]] id = "preflight-check" title = "Preflight safety check" description = """ Scan for conditions that might make shutdown inadvisable. ```bash gt shutdown preflight ``` This checks for: - **Uncommitted changes**: Polecats with dirty git status - **Unpushed commits**: Work that hasn't reached remote - **Active merges**: Refinery mid-merge (could corrupt state) - **Pending CI**: PRs waiting on GitHub Actions Output is a report with warnings/blockers: | Severity | Condition | Action | |----------|-----------|--------| | BLOCKER | Active merge in progress | Abort shutdown | | WARNING | Uncommitted polecat changes | List affected polecats | | WARNING | Unpushed commits | List repos needing push | | INFO | Pending CI runs | Note for awareness | If blockers exist, STOP and resolve them first. If only warnings, decide whether to proceed (work will be preserved). """ [[steps]] id = "stop-sessions" title = "Stop Claude sessions (preserve sandboxes)" needs = ["preflight-check"] description = """ Kill Claude processes but leave polecat sandboxes intact. ```bash # Stop all polecat Claude sessions gt stop --all --preserve-sandbox # Verify sandboxes still exist gt polecats --all --status ``` What this does: - Kills tmux sessions running Claude - Leaves git clones untouched - Leaves hook files (pinned molecules) intact - Leaves uncommitted work in place What this does NOT do: - Delete polecat directories - Remove hook attachments - Lose any git state After restart, polecats can be respawned and will resume from their hooks. Note: Crew workers are NOT stopped (they're user-managed). """ [[steps]] id = "clear-inboxes" title = "Archive and clear inboxes" needs = ["stop-sessions"] description = """ Archive and clear all agent inboxes across all rigs. ```bash # For each rig for rig in $(gt rigs --names); do gt mail clear $rig/witness --archive gt mail clear $rig/refinery --archive done # Clear Mayor inbox gt mail clear mayor --archive ``` Messages are archived to `.beads/mail-archive/` before deletion. Crew inboxes are NOT cleared (user manages those). """ [[steps]] id = "stop-daemon" title = "Stop the daemon" needs = ["clear-inboxes"] description = """ Stop the Gas Town daemon gracefully. ```bash gt daemon stop ``` The daemon handles: - Heartbeat monitoring - Pending spawn triggers - Background coordination It will be restarted in the final step. """ [[steps]] id = "rotate-logs" title = "Rotate and archive logs" needs = ["stop-daemon"] description = """ Rotate logs to prevent unbounded growth. ```bash # Rotate daemon logs gt daemon rotate-logs # Clean up old session captures (but not current sandboxes) gt doctor --fix ``` Old logs are moved to `$GT_ROOT/logs/archive/` with timestamps. """ [[steps]] id = "sync-state" title = "Sync beads and push" needs = ["rotate-logs"] description = """ Ensure all beads state is persisted. ```bash bd sync ``` Note: We do NOT force-commit polecat work here. Their sandboxes are preserved with whatever state they had. They'll commit their own work when they resume. """ [[steps]] id = "handoff-mayor" title = "Send Mayor handoff" needs = ["sync-state"] description = """ Record shutdown context for the fresh Mayor session. ```bash gt mail send mayor -s "🤝 HANDOFF: Town shutdown complete" -m " Town shutdown completed. State preserved. Polecat sandboxes: PRESERVED (will resume from hooks) Inboxes: ARCHIVED and cleared Daemon: STOPPED Next steps: 1. gt daemon start 2. gt prime 3. gt status (verify health) 4. Resume operations or respawn polecats Shutdown reason: {{shutdown_reason}} " ``` """ [[steps]] id = "restart-daemon" title = "Restart daemon" needs = ["handoff-mayor"] description = """ Start the daemon with fresh state. ```bash gt daemon start ``` The daemon will: - Begin heartbeat monitoring - Watch for pending spawns - Resume background coordination Polecats are NOT auto-respawned. Use `gt sling` or let Witness restart them based on their preserved hooks. """