From 44bbeb6c7ca5014b672ab18af01dfb8b38466c8f Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Tue, 23 Dec 2025 02:44:05 -0800 Subject: [PATCH] refactor: split builtin_molecules.go into category files (gt-nmtp) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split 1620-line file into 4 organized files: - builtin_molecules.go (77 lines) - type, registry, seeder - molecules_patrol.go (567 lines) - Deacon, Witness, Refinery patrol - molecules_work.go (446 lines) - EngineerInBox, QuickFix, Research, PolecatWork, ReadyWork - molecules_session.go (545 lines) - CrewSession, PolecatSession, Bootstrap, VersionBump, InstallGoBinary Benefits: - Easier to find/edit specific molecules - Smaller diffs on changes - Clear categorization by purpose 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- internal/beads/builtin_molecules.go | 1569 +-------------------------- internal/beads/molecules_patrol.go | 567 ++++++++++ internal/beads/molecules_session.go | 545 ++++++++++ internal/beads/molecules_work.go | 446 ++++++++ 4 files changed, 1571 insertions(+), 1556 deletions(-) create mode 100644 internal/beads/molecules_patrol.go create mode 100644 internal/beads/molecules_session.go create mode 100644 internal/beads/molecules_work.go diff --git a/internal/beads/builtin_molecules.go b/internal/beads/builtin_molecules.go index 8633e6cd..187f27a2 100644 --- a/internal/beads/builtin_molecules.go +++ b/internal/beads/builtin_molecules.go @@ -9,1573 +9,30 @@ type BuiltinMolecule struct { } // BuiltinMolecules returns all built-in molecule definitions. +// Molecules are defined in separate files by category: +// - molecules_work.go: EngineerInBox, QuickFix, Research, PolecatWork, ReadyWork +// - molecules_patrol.go: DeaconPatrol, WitnessPatrol, RefineryPatrol +// - molecules_session.go: CrewSession, PolecatSession, Bootstrap, VersionBump, InstallGoBinary func BuiltinMolecules() []BuiltinMolecule { return []BuiltinMolecule{ + // Work molecules EngineerInBoxMolecule(), QuickFixMolecule(), ResearchMolecule(), - InstallGoBinaryMolecule(), - BootstrapGasTownMolecule(), PolecatWorkMolecule(), - VersionBumpMolecule(), + ReadyWorkMolecule(), + + // Patrol molecules DeaconPatrolMolecule(), RefineryPatrolMolecule(), WitnessPatrolMolecule(), + + // Session and utility molecules CrewSessionMolecule(), PolecatSessionMolecule(), - ReadyWorkMolecule(), - } -} - -// EngineerInBoxMolecule returns the engineer-in-box molecule definition. -// This is a full workflow from design to merge. -func EngineerInBoxMolecule() BuiltinMolecule { - return BuiltinMolecule{ - ID: "mol-engineer-in-box", - Title: "Engineer in a Box", - Description: `Full workflow from design to merge. - -## Step: design -Think carefully about architecture. Consider: -- Existing patterns in the codebase -- Trade-offs between approaches -- Testability and maintainability - -Write a brief design summary before proceeding. - -## Step: implement -Write the code. Follow codebase conventions. -Needs: design - -## Step: review -Self-review the changes. Look for: -- Bugs and edge cases -- Style issues -- Missing error handling -Needs: implement - -## Step: test -Write and run tests. Cover happy path and edge cases. -Fix any failures before proceeding. -Needs: implement - -## Step: submit -Submit for merge via refinery. -Needs: review, test`, - } -} - -// QuickFixMolecule returns the quick-fix molecule definition. -// This is a fast path for small changes. -func QuickFixMolecule() BuiltinMolecule { - return BuiltinMolecule{ - ID: "mol-quick-fix", - Title: "Quick Fix", - Description: `Fast path for small changes. - -## Step: implement -Make the fix. Keep it focused. - -## Step: test -Run relevant tests. Fix any regressions. -Needs: implement - -## Step: submit -Submit for merge. -Needs: test`, - } -} - -// ResearchMolecule returns the research molecule definition. -// This is an investigation workflow. -func ResearchMolecule() BuiltinMolecule { - return BuiltinMolecule{ - ID: "mol-research", - Title: "Research", - Description: `Investigation workflow. - -## Step: investigate -Explore the question. Search code, read docs, -understand context. Take notes. - -## Step: document -Write up findings. Include: -- What you learned -- Recommendations -- Open questions -Needs: investigate`, - } -} - -// InstallGoBinaryMolecule returns the install-go-binary molecule definition. -// This is a single step to rebuild and install the gt binary after code changes. -func InstallGoBinaryMolecule() BuiltinMolecule { - return BuiltinMolecule{ - ID: "mol-install-go-binary", - Title: "Install Go Binary", - Description: `Single step to rebuild and install the gt binary after code changes. - -## Step: install -Build and install the gt binary locally. - -Run from the rig directory: -` + "```" + ` -go build -o gt ./cmd/gt -go install ./cmd/gt -` + "```" + ` - -Verify the installed binary is updated: -` + "```" + ` -which gt -gt --version # if version command exists -` + "```", - } -} - -// BootstrapGasTownMolecule returns the bootstrap molecule for new Gas Town installations. -// This walks a user through setting up Gas Town from scratch after brew install. -func BootstrapGasTownMolecule() BuiltinMolecule { - return BuiltinMolecule{ - ID: "mol-bootstrap", - Title: "Bootstrap Gas Town", - Description: `Complete setup of a new Gas Town installation. - -Run this after installing gt and bd via Homebrew. This molecule guides you through -creating an HQ, setting up rigs, and configuring your environment. - -## Step: locate-hq -Determine where to install the Gas Town HQ. - -Ask the user for their preferred location. Common choices: -- ~/gt (recommended - short, easy to type) -- ~/gastown -- ~/workspace/gt - -Validate the path: -- Must not already exist (or be empty) -- Parent directory must be writable -- Avoid paths with spaces - -Store the chosen path for subsequent steps. - -## Step: create-hq -Create the HQ directory structure. - -` + "```" + `bash -mkdir -p {{hq_path}} -cd {{hq_path}} -gt install . --name {{hq_name}} -` + "```" + ` - -If the user wants to track the HQ in git: -` + "```" + `bash -gt git-init --github={{github_repo}} --private -` + "```" + ` - -The HQ now has: -- mayor/ directory -- .beads/ for town-level tracking -- CLAUDE.md for mayor context - -Needs: locate-hq - -## Step: setup-rigs -Configure which rigs to add to the HQ. - -Default rigs for Gas Town development: -- gastown (git@github.com:steveyegge/gastown.git) -- beads (git@github.com:steveyegge/beads.git) - -For each rig, run: -` + "```" + `bash -gt rig add --prefix -` + "```" + ` - -This creates the full rig structure: -- refinery/rig/ (canonical main clone) -- mayor/rig/ (mayor's working clone) -- crew/main/ (default human workspace) -- witness/ (polecat monitor) -- polecats/ (worker directory) - -Needs: create-hq - -## Step: build-gt -Build the gt binary from source. - -` + "```" + `bash -cd {{hq_path}}/gastown/mayor/rig -go build -o gt ./cmd/gt -` + "```" + ` - -Verify the build succeeded: -` + "```" + `bash -./gt version -` + "```" + ` - -Needs: setup-rigs -Tier: haiku - -## Step: install-paths -Install gt to a location in PATH. - -Check if ~/bin or ~/.local/bin is in PATH: -` + "```" + `bash -echo $PATH | tr ':' '\n' | grep -E '(~/bin|~/.local/bin|/home/.*/bin)' -` + "```" + ` - -Copy the binary: -` + "```" + `bash -mkdir -p ~/bin -cp {{hq_path}}/gastown/mayor/rig/gt ~/bin/gt -` + "```" + ` - -If ~/bin is not in PATH, add to shell config: -` + "```" + `bash -echo 'export PATH="$HOME/bin:$PATH"' >> ~/.zshrc -# or ~/.bashrc for bash users -` + "```" + ` - -Verify: -` + "```" + `bash -which gt -gt version -` + "```" + ` - -Needs: build-gt -Tier: haiku - -## Step: init-beads -Initialize beads databases in all clones. - -For each rig's mayor clone: -` + "```" + `bash -cd {{hq_path}}//mayor/rig -bd init --prefix -` + "```" + ` - -For the town-level beads: -` + "```" + `bash -cd {{hq_path}} -bd init --prefix hq -` + "```" + ` - -Configure sync-branch for multi-clone setups: -` + "```" + `bash -echo "sync-branch: beads-sync" >> .beads/config.yaml -` + "```" + ` - -Needs: setup-rigs -Tier: haiku - -## Step: sync-beads -Sync beads from remotes and fix any issues. - -For each initialized beads database: -` + "```" + `bash -bd sync -bd doctor --fix -` + "```" + ` - -This imports existing issues from JSONL and sets up git hooks. - -Needs: init-beads -Tier: haiku - -## Step: verify -Verify the installation is complete and working. - -Run health checks: -` + "```" + `bash -gt status # Should show rigs with crew/refinery/mayor -gt doctor # Check for issues -bd list # Should show issues from synced beads -` + "```" + ` - -Test spawning capability (dry run): -` + "```" + `bash -gt spawn --help -` + "```" + ` - -Print summary: -- HQ location -- Installed rigs -- gt version -- bd version - -Needs: sync-beads, install-paths`, - } -} - -// PolecatWorkMolecule returns the polecat-work molecule definition. -// This is the full polecat lifecycle from assignment to decommission. -// It's an operational molecule that enables crash recovery and context survival. -func PolecatWorkMolecule() BuiltinMolecule { - return BuiltinMolecule{ - ID: "mol-polecat-work", - Title: "Polecat Work", - Description: `Full polecat lifecycle from assignment to decommission. - -This molecule is your contract. Follow it to one of its defined exits. -The Witness doesn't care which exit you take, only that you exit properly. - -**State Machine**: A polecat that crashes can restart, read its molecule state, -and continue from the last completed step. No work is lost. - -**Non-Linear Exits**: If blocked at any step, skip to exit-decision directly. - -## Step: load-context -Run gt prime and bd prime. Verify issue assignment. -Check inbox for any relevant messages. - -Read the assigned issue and understand the requirements. -Identify any blockers or missing information. - -**If blocked here**: Missing requirements? Unclear scope? Jump to exit-decision -with exit_type=escalate. - -## Step: implement -Implement the solution. Follow codebase conventions. -File discovered work as new issues with bd create. - -Make regular commits with clear messages. -Keep changes focused on the assigned issue. - -**Dynamic modifications allowed**: -- Add extra review or test steps if needed -- File discovered blockers as issues -- Request session refresh if context is filling up - -**If blocked here**: Dependency missing? Work too large? Jump to exit-decision. -Needs: load-context - -## Step: self-review -Review your own changes. Look for: -- Bugs and edge cases -- Style issues -- Missing error handling -- Security concerns - -Fix any issues found before proceeding. -Needs: implement - -## Step: verify-tests -Run existing tests. Add new tests for new functionality. -Ensure adequate coverage. - -` + "```" + `bash -go test ./... -` + "```" + ` - -Fix any test failures before proceeding. -Needs: implement - -## Step: rebase-main -Rebase against main to incorporate any changes. -Resolve conflicts if needed. - -` + "```" + `bash -git fetch origin main -git rebase origin/main -` + "```" + ` - -If there are conflicts, resolve them carefully and -continue the rebase. If conflicts are unresolvable, jump to exit-decision -with exit_type=escalate. -Needs: self-review, verify-tests - -## Step: submit-merge -Submit to merge queue via beads. - -**IMPORTANT**: Do NOT use gh pr create or GitHub PRs. -The Refinery processes merges via beads merge-request issues. - -1. Push your branch to origin -2. Create a beads merge-request: bd create --type=merge-request --title="Merge: " -3. Signal ready: gt done - -` + "```" + `bash -git push origin HEAD -bd create --type=merge-request --title="Merge: " -gt done # Signal work ready for merge queue -` + "```" + ` - -If there are CI failures, fix them before proceeding. -Needs: rebase-main - -## Step: exit-decision -**CONVERGENCE POINT**: All exits pass through here. - -Determine your exit type and take appropriate action: - -### Exit Type: COMPLETED (normal) -Work finished successfully. Submit-merge done. -` + "```" + `bash -# Document completion -bd update --status=closed -` + "```" + ` - -### Exit Type: BLOCKED -External dependency prevents progress. -` + "```" + `bash -# 1. File the blocker -bd create --type=task --title="Blocker: " --priority=1 - -# 2. Link dependency -bd dep add - -# 3. Defer your issue -bd update --status=deferred - -# 4. Notify witness -gt mail send /witness -s "Blocked: " -m "Blocked by . Deferring." -` + "```" + ` - -### Exit Type: REFACTOR -Work is too large for one polecat session. -` + "```" + `bash -# Option A: Self-refactor -# 1. Break into sub-issues -bd create --type=task --title="Sub: part 1" --parent= -bd create --type=task --title="Sub: part 2" --parent= - -# 2. Close what you completed, defer the rest -bd close -bd update --status=deferred - -# Option B: Request refactor -gt mail send mayor/ -s "Refactor needed: " -m " -Issue too large. Completed X, remaining Y needs breakdown. -Recommend splitting into: ... -" -bd update --status=deferred -` + "```" + ` - -### Exit Type: ESCALATE -Need human judgment or authority. -` + "```" + `bash -# 1. Document what you know -bd comment "Escalating because: . Context:
" - -# 2. Mail human -gt mail send --human -s "Escalation: " -m " -Need human decision on: -Context: -Options I see: -" - -# 3. Defer the issue -bd update --status=deferred -` + "```" + ` - -**Record your exit**: Update this step with your exit type and actions taken. -Needs: load-context - -## Step: request-shutdown -Wait for termination. - -All exit paths converge here. Your work is either: -- Merged (COMPLETED) -- Deferred with proper handoff (BLOCKED/REFACTOR/ESCALATE) - -The polecat is now ready to be cleaned up. -Do not exit directly - wait for Witness to kill the session. -Needs: exit-decision`, - } -} - -// VersionBumpMolecule returns the version-bump molecule definition. -// This is the release checklist for Gas Town versions. -func VersionBumpMolecule() BuiltinMolecule { - return BuiltinMolecule{ - ID: "mol-version-bump", - Title: "Version Bump", - Description: `Release checklist for Gas Town version {{version}}. - -This molecule ensures all release steps are completed properly. -Replace {{version}} with the target version (e.g., 0.1.0). - -## Step: update-version -Update version string in internal/cmd/version.go. - -Change the Version variable to the new version: -` + "```" + `go -var ( - Version = "{{version}}" - BuildTime = "unknown" - GitCommit = "unknown" -) -` + "```" + ` - -## Step: rebuild-binary -Rebuild the gt binary with version info. - -` + "```" + `bash -go build -ldflags="-X github.com/steveyegge/gastown/internal/cmd.Version={{version}} \ - -X github.com/steveyegge/gastown/internal/cmd.GitCommit=$(git rev-parse --short HEAD) \ - -X github.com/steveyegge/gastown/internal/cmd.BuildTime=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ - -o gt ./cmd/gt -` + "```" + ` - -Verify the version: -` + "```" + `bash -./gt version -` + "```" + ` - -Needs: update-version - -## Step: run-tests -Run the full test suite. - -` + "```" + `bash -go test ./... -` + "```" + ` - -Fix any failures before proceeding. -Needs: rebuild-binary - -## Step: update-changelog -Update CHANGELOG.md with release notes. - -Add a new section at the top: -` + "```" + `markdown -## [{{version}}] - YYYY-MM-DD - -### Added -- Feature descriptions - -### Changed -- Change descriptions - -### Fixed -- Bug fix descriptions -` + "```" + ` - -Needs: run-tests - -## Step: commit-release -Commit the release changes. - -` + "```" + `bash -git add -A -git commit -m "release: v{{version}}" -` + "```" + ` - -Needs: update-changelog - -## Step: tag-release -Create and push the release tag. - -` + "```" + `bash -git tag -a v{{version}} -m "Release v{{version}}" -git push origin main -git push origin v{{version}} -` + "```" + ` - -Needs: commit-release - -## Step: verify-release -Verify the release is complete. - -- Check that the tag exists on GitHub -- Verify CI/CD (if configured) completed successfully -- Test installation from the new tag: -` + "```" + `bash -go install github.com/steveyegge/gastown/cmd/gt@v{{version}} -gt version -` + "```" + ` - -Needs: tag-release - -## Step: update-installations -Update local installations and restart daemons. - -` + "```" + `bash -# Rebuild and install -go install ./cmd/gt - -# Restart any running daemons -pkill -f "gt daemon" || true -gt daemon start -` + "```" + ` - -Needs: verify-release`, - } -} - -// DeaconPatrolMolecule returns the deacon-patrol molecule definition. -// This is the Mayor's daemon loop for handling callbacks, health checks, and cleanup. -func DeaconPatrolMolecule() BuiltinMolecule { - return BuiltinMolecule{ - ID: "mol-deacon-patrol", - Title: "Deacon Patrol", - Description: `Mayor's daemon patrol loop. - -The Deacon is the Mayor's background process that runs continuously, -handling callbacks, monitoring rig health, and performing cleanup. -Each patrol cycle runs these steps in sequence, then loops or exits. - -## Step: inbox-check -Handle callbacks from agents. - -Check the Mayor's inbox for messages from: -- Witnesses reporting polecat status -- Refineries reporting merge results -- Polecats requesting help or escalation -- External triggers (webhooks, timers) - -Process each message: -` + "```" + `bash -gt mail inbox -# For each message: -gt mail read -# Handle based on message type -` + "```" + ` - -Callbacks may spawn new polecats, update issue state, or trigger other actions. - -## Step: trigger-pending-spawns -Nudge newly spawned polecats that are ready for input. - -When polecats are spawned, their Claude session takes 10-20 seconds to initialize. -The spawn command returns immediately without waiting. This step finds spawned -polecats that are now ready and sends them a trigger to start working. - -` + "```" + `bash -# For each rig with polecats -for rig in gastown beads; do - gt polecats $rig - # For each working polecat, check if Claude is ready - # Use tmux capture-pane to look for "> " prompt -done -` + "```" + ` - -For each ready polecat that hasn't been triggered yet: -1. Send "Begin." to trigger UserPromptSubmit hook -2. The hook injects mail, polecat sees its assignment -3. Mark polecat as triggered in state - -Use WaitForClaudeReady from tmux package (polls for "> " prompt). -Timeout: 60 seconds per polecat. If not ready, try again next cycle. -Needs: inbox-check - -## Step: health-scan -Ping Witnesses and Refineries. - -For each rig, verify: -- Witness is responsive -- Refinery is processing queue -- No stalled operations - -` + "```" + `bash -gt status --health -# Check each rig -for rig in $(gt rigs); do - gt rig status $rig -done -` + "```" + ` - -Report any issues found. Restart unresponsive components if needed. -Needs: trigger-pending-spawns - -## Step: plugin-run -Execute registered plugins. - -Scan ~/gt/plugins/ for plugin directories. Each plugin has a plugin.md with -YAML frontmatter defining its gate (when to run) and instructions (what to do). - -See docs/deacon-plugins.md for full documentation. - -Gate types: -- cooldown: Time since last run (e.g., 24h) -- cron: Schedule-based (e.g., "0 9 * * *") -- condition: Metric threshold (e.g., wisp count > 50) -- event: Trigger-based (e.g., startup, heartbeat) - -For each plugin: -1. Read plugin.md frontmatter to check gate -2. Compare against state.json (last run, etc.) -3. If gate is open, execute the plugin - -Plugins marked parallel: true can run concurrently using Task tool subagents. -Sequential plugins run one at a time in directory order. - -Skip this step if ~/gt/plugins/ does not exist or is empty. -Needs: health-scan - -## Step: orphan-check -Find abandoned work. - -Scan for orphaned state: -- Issues marked in_progress with no active polecat -- Polecats that stopped responding mid-work -- Merge queue entries with no polecat owner -- Wisp sessions that outlived their spawner - -` + "```" + `bash -bd list --status=in_progress -gt polecats --all --orphan -` + "```" + ` - -For each orphan: -- Check if polecat session still exists -- If not, mark issue for reassignment or retry -- File incident beads if data loss occurred -Needs: health-scan - -## Step: session-gc -Clean dead sessions. - -Garbage collect terminated sessions: -- Remove stale polecat directories -- Clean up wisp session artifacts -- Prune old logs and temp files -- Archive completed molecule state - -` + "```" + `bash -gt gc --sessions -gt gc --wisps --age=1h -` + "```" + ` - -Preserve audit trail. Only clean sessions confirmed dead. -Needs: orphan-check - -## Step: context-check -Check own context limit. - -The Deacon runs in a Claude session with finite context. -Check if approaching the limit: - -` + "```" + `bash -gt context --usage -` + "```" + ` - -If context is high (>80%), prepare for handoff: -- Summarize current state -- Note any pending work -- Write handoff to molecule state - -This enables the Deacon to burn and respawn cleanly. -Needs: session-gc - -## Step: loop-or-exit -Burn and let daemon respawn, or exit if context high. - -Decision point at end of patrol cycle: - -If context is LOW: -- Sleep briefly (avoid tight loop) -- Return to inbox-check step - -If context is HIGH: -- Write state to persistent storage -- Exit cleanly -- Let the daemon orchestrator respawn a fresh Deacon - -The daemon ensures Deacon is always running: -` + "```" + `bash -# Daemon respawns on exit -gt daemon status -` + "```" + ` - -This enables infinite patrol duration via context-aware respawning. -Needs: context-check`, - } -} - -// WitnessPatrolMolecule returns the witness-patrol molecule definition. -// This is the per-rig worker monitor's patrol loop with progressive nudging. -func WitnessPatrolMolecule() BuiltinMolecule { - return BuiltinMolecule{ - ID: "mol-witness-patrol", - Title: "Witness Patrol", - Description: `Per-rig worker monitor patrol loop. - -The Witness is the Pit Boss for your rig. You watch polecats, nudge them toward -completion, verify clean git state before kills, and escalate stuck workers. - -**You do NOT do implementation work.** Your job is oversight, not coding. - -This molecule uses wisp storage (.beads-wisp/) for ephemeral patrol state. -Persistent state (nudge counts, handoffs) is stored in a witness handoff bead. - -## Step: inbox-check -Process witness mail: lifecycle requests, help requests. - -` + "```" + `bash -gt mail inbox -` + "```" + ` - -Handle by message type: -- **LIFECYCLE/Shutdown**: Queue for pre-kill verification -- **Blocked/Help**: Assess if resolvable or escalate -- **HANDOFF**: Load predecessor state -- **Work complete**: Verify issue closed, proceed to pre-kill - -Record any pending actions for later steps. -Mark messages as processed when complete. - -## Step: check-refinery -Ensure the refinery is alive and processing merge requests. - -**Redundant system**: This check runs in both gt spawn and Witness patrol -to ensure the merge queue processor stays operational. - -` + "```" + `bash -# Check if refinery session is running -gt session status /refinery - -# Check for merge requests in queue -bd list --type=merge-request --status=open -` + "```" + ` - -If merge requests are waiting AND refinery is not running: -` + "```" + `bash -gt session start /refinery -gt mail send /refinery -s "PATROL: Wake up" -m "Merge requests in queue. Please process." -` + "```" + ` - -If refinery is running but queue is non-empty for >30 min, send nudge. -This ensures polecats don't wait forever for their branches to merge. -Needs: inbox-check - -## Step: load-state -Read handoff bead and get nudge counts. - -Load persistent state from the witness handoff bead: -- Active workers and their status from last cycle -- Nudge counts per worker per issue -- Last nudge timestamps -- Pending escalations - -` + "```" + `bash -bd show -` + "```" + ` - -If no handoff exists (fresh start), initialize empty state. -This state persists across wisp burns and session cycles. -Needs: check-refinery - -## Step: survey-workers -List polecats and categorize by status. - -` + "```" + `bash -gt polecat list -` + "```" + ` - -Categorize each polecat: -- **working**: Actively processing (needs inspection) -- **idle**: At prompt, not active (may need nudge) -- **pending_shutdown**: Requested termination (needs pre-kill) -- **error**: Showing errors (needs assessment) - -Build action queue for next steps. -Needs: load-state - -## Step: inspect-workers -Capture output for each 'working' polecat. - -For each polecat showing "working" status: -` + "```" + `bash -tmux capture-pane -t gt-- -p | tail -40 -` + "```" + ` - -Look for: -- Recent tool calls (good - actively working) -- Prompt waiting for input (may be stuck) -- Error messages or stack traces -- "Done" or completion indicators -- Time since last activity - -Update worker status based on inspection. -Needs: survey-workers - -## Step: decide-actions -Apply nudge matrix and queue actions. - -For each worker, apply decision rules: - -**Progressing normally**: No action needed -**Idle <10 min**: Continue monitoring -**Idle 10-15 min**: Queue first nudge (gentle) -**Idle 15-20 min with no progress since nudge 1**: Queue second nudge (direct) -**Idle 20+ min with no progress since nudge 2**: Queue third nudge (final warning) -**No response after 3 nudges**: Queue escalation to Mayor -**Requesting shutdown**: Queue pre-kill verification -**Showing errors**: Assess severity, queue nudge or escalation - -Progressive nudge text: -1. "How's progress on ? Need any help?" -2. "Please wrap up soon. What's blocking you?" -3. "Final check on . Will escalate in 5 min if no response." - -Track nudge counts in state - never exceed 3 per issue. -Needs: inspect-workers - -## Step: execute-actions -Nudge, kill, or escalate as decided. - -Process action queue in order: - -**Nudges:** -` + "```" + `bash -tmux send-keys -t gt-- "" Enter -` + "```" + ` -Update nudge count and timestamp in state. - -**Pre-kill verification:** -` + "```" + `bash -cd polecats/ && git status # Must be clean -git log origin/main..HEAD # Check for unpushed commits -bd show # Verify issue closed -` + "```" + ` - -If clean: -` + "```" + `bash -tmux kill-session -t gt-- -git worktree remove polecats/ # If transient -git branch -d polecat/ # If transient -` + "```" + ` - -If dirty: nudge worker to clean up, wait for retry. -If dirty after 3 attempts: escalate to Mayor. - -**Escalations:** -` + "```" + `bash -gt mail send mayor/ -s "Escalation: stuck on " -m " -Worker: -Issue: -Problem: - -Timeline: -- Nudge 1: