diff --git a/internal/beads/builtin_molecules.go b/internal/beads/builtin_molecules.go index 8df9c686..b031af38 100644 --- a/internal/beads/builtin_molecules.go +++ b/internal/beads/builtin_molecules.go @@ -20,6 +20,7 @@ func BuiltinMolecules() []BuiltinMolecule { VersionBumpMolecule(), DeaconPatrolMolecule(), RefineryPatrolMolecule(), + WitnessPatrolMolecule(), CrewSessionMolecule(), PolecatSessionMolecule(), } @@ -781,6 +782,221 @@ 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: 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: inbox-check + +## 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: