description = """ Clean stale sessions and garbage collect. Dogs work through molecules (poured from this formula) to clean up dead sessions, orphaned processes, and other system cruft. This is the garbage collector for Gas Town's runtime: - Dead tmux sessions (no Claude process) - Orphaned Claude processes (no tmux parent) - Stale wisps past retention - Leftover state files ## Dog Contract This is infrastructure work. You: 1. Receive gc scope via hook_bead (aggressive or conservative) 2. Identify garbage across the system 3. Safely remove dead state 4. Report what was cleaned 5. Return to kennel ## Variables | Variable | Source | Description | |----------|--------|-------------| | mode | hook_bead | GC mode: 'conservative' (safe) or 'aggressive' (thorough) | ## Safety GC is destructive. This formula errs on the side of caution: - Conservative mode: Only obviously dead things - Aggressive mode: Includes old but possibly-recoverable state Running `gt doctor --fix` handles most of this. This formula wraps it with reporting and multi-rig scope.""" formula = "mol-session-gc" version = 1 [squash] trigger = "on_complete" template_type = "work" include_metrics = true [[steps]] id = "determine-mode" title = "Determine GC mode" description = """ Establish GC aggressiveness level. **1. Check assignment:** ```bash gt hook # Shows mode in hook_bead ``` **2. Mode definitions:** | Mode | Description | Risk | |------|-------------|------| | conservative | Only clearly dead state | Very low | | aggressive | Includes stale state | Low but non-zero | **Conservative targets:** - tmux sessions with no processes - Claude processes with no tmux parent - Wisps > 24 hours old **Aggressive additions:** - Wisps > 1 hour old - Branches with no matching polecat - State files > 7 days old **Exit criteria:** GC mode determined.""" [[steps]] id = "preview-cleanup" title = "Preview what will be cleaned" needs = ["determine-mode"] description = """ Identify garbage without removing it yet. **1. Run doctor in preview mode:** ```bash gt doctor -v # Shows what would be cleaned, doesn't do it ``` **2. Parse doctor output for:** - orphan-sessions: Tmux sessions to kill - orphan-processes: Claude processes to terminate - wisp-gc: Wisps to delete **3. Additional scans (for aggressive mode):** ```bash # Old branches git branch --list 'polecat/*' | while read branch; do last_commit=$(git log -1 --format=%ct "$branch") # If > 7 days old and no matching polecat, candidate for cleanup done # Old state files find ~/.gt/ -name "*.state" -mtime +7 ``` **4. Compile cleanup manifest:** Record each item to be cleaned with: - Type (session, process, wisp, branch, state) - Identifier - Age - Reason for cleanup **Exit criteria:** Cleanup manifest ready, nothing deleted yet.""" [[steps]] id = "execute-gc" title = "Execute garbage collection" needs = ["preview-cleanup"] description = """ Actually remove the garbage. **1. Run doctor with fix:** ```bash gt doctor --fix # This handles sessions, processes, and wisps ``` **2. For aggressive mode, additional cleanup:** ```bash # Old branches (if aggressive mode) git branch -D # Old state files (if aggressive mode) rm ``` **3. Track what was deleted:** Record each item actually removed for the report. **Safety checks:** - Never delete active sessions (tmux list-clients) - Never delete branches with uncommitted polecat work - Never delete wisps < 1 hour old **Exit criteria:** Garbage collected.""" [[steps]] id = "verify-cleanup" title = "Verify cleanup was successful" needs = ["execute-gc"] description = """ Confirm garbage was actually removed. **1. Re-run doctor to verify:** ```bash gt doctor -v # Should show no issues (or fewer issues) ``` **2. Check for stragglers:** ```bash # Tmux sessions tmux list-sessions 2>/dev/null # Claude processes pgrep -f claude # Wisps ls .beads-wisp/ 2>/dev/null | wc -l ``` **3. Compare before/after:** - Sessions before: N → after: M - Processes before: N → after: M - Wisps before: N → after: M **Exit criteria:** Cleanup verified.""" [[steps]] id = "report-gc" title = "Generate GC report" needs = ["verify-cleanup"] description = """ Create summary report of garbage collection. **1. Generate report:** ```markdown ## Session GC Report: {{timestamp}} **Mode**: {{mode}} ### Summary | Type | Before | After | Cleaned | |------|--------|-------|---------| | Sessions | X | Y | Z | | Processes | X | Y | Z | | Wisps | X | Y | Z | | Branches | X | Y | Z | | State files | X | Y | Z | ### Items Cleaned {{#each cleaned}} - {{type}}: {{identifier}} (age: {{age}}, reason: {{reason}}) {{/each}} ### Errors {{#if errors}} {{#each errors}} - {{item}}: {{error}} {{/each}} {{else}} None {{/if}} ### Space Recovered ~{{bytes_freed}} bytes ``` **2. Send to Deacon:** ```bash gt mail send deacon/ -s "GC complete: {{total_cleaned}} items" \ -m "{{report}}" ``` **Exit criteria:** Report sent.""" [[steps]] id = "return-to-kennel" title = "Signal completion and return to kennel" needs = ["report-gc"] description = """ Signal work complete and return to available pool. **1. Signal completion to Deacon:** ```bash gt mail send deacon/ -s "DOG_DONE $(hostname)" -m "Task: session-gc Mode: {{mode}} Items cleaned: {{total_cleaned}} Space recovered: {{bytes_freed}} Status: COMPLETE Ready for next assignment." ``` **2. Return to kennel:** Dog returns to available state in the pool. **Exit criteria:** Deacon notified, dog ready for next work.""" [vars] [vars.mode] description = "GC mode: 'conservative' or 'aggressive'" required = true default = "conservative"