Files
gastown/.beads/formulas/mol-witness-patrol.formula.yaml
Steve Yegge 80d3672999 Add title fields to patrol formulas for bd cook (gt-ingm.2)
Required by bd cook command - each step needs a title field.
Cooked 4 protos: deacon(9), witness(10), refinery(11), polecat-arm(6)
2025-12-24 13:48:19 -08:00

222 lines
6.8 KiB
YAML

# Witness Patrol: Per-rig worker monitor using Christmas Ornament pattern
# 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.
formula: mol-witness-patrol
description: |
Per-rig worker monitor patrol loop using the Christmas Ornament pattern.
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 dynamic bonding to spawn mol-polecat-arm for each worker,
enabling parallel inspection with a fanout gate for aggregation.
## The Christmas Ornament Shape
```
★ mol-witness-patrol (trunk)
/|\
┌────────┘ │ └────────┐
PREFLIGHT DISCOVERY CLEANUP
│ │ │
inbox-check survey aggregate (WaitsFor: all-children)
check-refnry │ save-state
load-state │ generate-summary
↓ context-check
┌───────┼───────┐ burn-or-loop
● ● ● mol-polecat-arm (dynamic)
ace nux toast
```
version: 1
steps:
# --- PREFLIGHT PHASE ---
- id: inbox-check
title: Process witness mail
description: |
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.
- id: check-refinery
title: Ensure refinery is alive
needs: [inbox-check]
description: |
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 <rig>/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 <rig>/refinery
gt mail send <rig>/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.
- id: load-state
title: Load persisted patrol state
needs: [check-refinery]
description: |
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 <handoff-bead-id>
```
If no handoff exists (fresh start), initialize empty state.
This state persists across wisp burns and session cycles.
# --- DISCOVERY PHASE (Dynamic Bonding) ---
- id: survey-workers
title: Survey all polecats (fanout)
needs: [load-state]
description: |
List polecats and bond mol-polecat-arm for each one.
```bash
# Get list of polecats
gt polecat list <rig>
```
For each polecat discovered, dynamically bond an inspection arm:
```bash
# Bond mol-polecat-arm for each polecat
for polecat in $(gt polecat list <rig> --names); do
bd mol bond mol-polecat-arm $PATROL_WISP_ID \
--ref arm-$polecat \
--var polecat_name=$polecat \
--var rig=<rig>
done
```
This creates child wisps like:
- patrol-x7k.arm-ace (5 steps)
- patrol-x7k.arm-nux (5 steps)
- patrol-x7k.arm-toast (5 steps)
Each arm runs in PARALLEL. The aggregate step will wait for all to complete.
If no polecats are found, this step completes immediately with no children.
# --- CLEANUP PHASE (Gate + Fixed Steps) ---
- id: aggregate
title: Aggregate arm results
needs: [survey-workers]
waits_for: all-children
description: |
Collect outcomes from all polecat inspection arms.
This is a **fanout gate** - it cannot proceed until ALL dynamically-bonded
polecat arms have completed their inspection cycles.
Once all arms complete, collect their outcomes:
- Actions taken per polecat (nudge, kill, escalate, none)
- Updated nudge counts
- Any errors or issues discovered
Build the consolidated state for save-state.
- id: save-state
title: Persist patrol state
needs: [aggregate]
description: |
Update handoff bead with new states.
Persist state to the witness handoff bead:
- Updated worker statuses from all arms
- Current nudge counts per worker
- Nudge timestamps
- Actions taken this cycle
- Pending items for next cycle
```bash
bd update <handoff-bead-id> --description="<serialized state>"
```
This state survives wisp burns and session cycles.
- id: generate-summary
title: Generate handoff summary
needs: [save-state]
description: |
Summarize this patrol cycle for digest.
Include:
- Workers inspected (count, names)
- Nudges sent (count, to whom)
- Sessions killed (count, names)
- Escalations (count, issues)
- Issues found (brief descriptions)
- Actions pending for next cycle
This becomes the digest when the patrol wisp is squashed.
- id: context-check
title: Check own context limit
needs: [generate-summary]
description: |
Check own context usage.
If context is HIGH (>80%):
- Ensure state is saved to handoff bead
- Prepare for burn/respawn
If context is LOW:
- Can continue patrolling
- id: burn-or-loop
title: Burn and respawn or loop
needs: [context-check]
description: |
End of patrol cycle decision.
If context is LOW:
- Burn this wisp (no audit trail needed for patrol cycles)
- Sleep briefly to avoid tight loop (30-60 seconds)
- Return to inbox-check step
If context is HIGH:
- Burn wisp with summary digest
- Exit cleanly (daemon will respawn fresh Witness)
```bash
bd mol burn # Destroy ephemeral wisp
```
The daemon ensures Witness is always running.