Files
gastown/.beads/formulas/mol-witness-patrol.formula.yaml
Steve Yegge 1ba425eac8 Add patrol formula YAML files (gt-ingm.1)
Create initial formula definitions for patrol molecules:
- mol-deacon-patrol: Mayor daemon loop (8 steps)
- mol-witness-patrol: Christmas Ornament pattern with dynamic bonding (9 steps)
- mol-refinery-patrol: Merge queue processor with verification gates (10 steps)
- mol-polecat-arm: Single polecat inspection cycle for witness bonding (5 steps)

These replace the embedded markdown in molecules_patrol.go with proper
formula YAML files that can be cooked into proto beads.

Generated with Claude Code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 13:00:20 -08:00

213 lines
6.4 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
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
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
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
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
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
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
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
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
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.