| 1 | # Ralph Reference |
| 2 | |
| 3 | ## Ralph — Work Monitor |
| 4 | |
| 5 | Ralph is a built-in squad member whose job is keeping tabs on work. **Ralph tracks and drives the work queue.** Always on the roster, one job: make sure the team never sits idle. |
| 6 | |
| 7 | **⚡ CRITICAL BEHAVIOR: When Ralph is active, the coordinator MUST NOT stop and wait for user input between work items. Ralph runs a continuous loop — scan for work, do the work, scan again, repeat — until the board is empty or the user explicitly says "idle" or "stop". This is not optional. If work exists, keep going. When empty, Ralph enters idle-watch (auto-recheck every {poll_interval} minutes, default: 10).** |
| 8 | |
| 9 | **Between checks:** Ralph's in-session loop runs while work exists. For persistent polling when the board is clear, use `npx @bradygaster/squad-cli watch --interval N` — a standalone local process that checks GitHub every N minutes and triggers triage/assignment. See [Watch Mode](#watch-mode-squad-watch). |
| 10 | |
| 11 | **On-demand reference:** Read `.squad/templates/ralph-reference.md` for the full work-check cycle, idle-watch mode, board format, and integration details. |
| 12 | |
| 13 | ### Roster Entry |
| 14 | |
| 15 | Ralph always appears in `team.md`: `| Ralph | Work Monitor | — | 🔄 Monitor |` |
| 16 | |
| 17 | ### Triggers |
| 18 | |
| 19 | | User says | Action | |
| 20 | |-----------|--------| |
| 21 | | "Ralph, go" / "Ralph, start monitoring" / "keep working" | Activate work-check loop | |
| 22 | | "Ralph, status" / "What's on the board?" / "How's the backlog?" | Run one work-check cycle, report results, don't loop | |
| 23 | | "Ralph, check every N minutes" | Set idle-watch polling interval | |
| 24 | | "Ralph, idle" / "Take a break" / "Stop monitoring" | Fully deactivate (stop loop + idle-watch) | |
| 25 | | "Ralph, scope: just issues" / "Ralph, skip CI" | Adjust what Ralph monitors this session | |
| 26 | | References PR feedback or changes requested | Spawn agent to address PR review feedback | |
| 27 | | "merge PR #N" / "merge it" (recent context) | Merge via `gh pr merge` | |
| 28 | |
| 29 | These are intent signals, not exact strings — match meaning, not words. |
| 30 | |
| 31 | When Ralph is active, run this check cycle after every batch of agent work completes (or immediately on activation): |
| 32 | |
| 33 | **Step 1 — Scan for work** (run these in parallel): |
| 34 | |
| 35 | ```bash |
| 36 | # Untriaged issues (labeled squad but no squad:{member} sub-label) |
| 37 | gh issue list --label "squad" --state open --json number,title,labels,assignees --limit 20 |
| 38 | |
| 39 | # Member-assigned issues (labeled squad:{member}, still open) |
| 40 | gh issue list --state open --json number,title,labels,assignees --limit 20 | # filter for squad:* labels |
| 41 | |
| 42 | # Open PRs from squad members |
| 43 | gh pr list --state open --json number,title,author,labels,isDraft,reviewDecision --limit 20 |
| 44 | |
| 45 | # Draft PRs (agent work in progress) |
| 46 | gh pr list --state open --draft --json number,title,author,labels,checks --limit 20 |
| 47 | ``` |
| 48 | |
| 49 | **Step 2 — Categorize findings:** |
| 50 | |
| 51 | | Category | Signal | Action | |
| 52 | |----------|--------|--------| |
| 53 | | **Untriaged issues** | `squad` label, no `squad:{member}` label | Lead triages: reads issue, assigns `squad:{member}` label | |
| 54 | | **Assigned but unstarted** | `squad:{member}` label, no assignee or no PR | Spawn the assigned agent to pick it up | |
| 55 | | **Draft PRs** | PR in draft from squad member | Check if agent needs to continue; if stalled, nudge | |
| 56 | | **Review feedback** | PR has `CHANGES_REQUESTED` review | Route feedback to PR author agent to address | |
| 57 | | **CI failures** | PR checks failing | Notify assigned agent to fix, or create a fix issue | |
| 58 | | **Approved PRs** | PR approved, CI green, ready to merge | Merge and close related issue | |
| 59 | | **No work found** | All clear | Report: "📋 Board is clear. Ralph is idling." Suggest `npx @bradygaster/squad-cli watch` for persistent polling. | |
| 60 | |
| 61 | **Step 3 — Act on highest-priority item:** |
| 62 | - Process one category at a time, highest priority first (untriaged > assigned > CI failures > review feedback > approved PRs) |
| 63 | - Spawn agents as needed, collect results |
| 64 | - **⚡ CRITICAL: After results are collected, DO NOT stop. DO NOT wait for user input. IMMEDIATELY go back to Step 1 and scan again.** This is a loop — Ralph keeps cycling until the board is clear or the user says "idle". Each cycle is one "round". |
| 65 | - If multiple items exist in the same category, process them in parallel (spawn multiple agents) |
| 66 | |
| 67 | **Step 4 — Periodic check-in** (every 3-5 rounds): |
| 68 | |
| 69 | After every 3-5 rounds, pause and report before continuing: |
| 70 | |
| 71 | ``` |
| 72 | 🔄 Ralph: Round {N} complete. |
| 73 | ✅ {X} issues closed, {Y} PRs merged |
| 74 | 📋 {Z} items remaining: {brief list} |
| 75 | Continuing... (say "Ralph, idle" to stop) |
| 76 | ``` |
| 77 | |
| 78 | **Do NOT ask for permission to continue.** Just report and keep going. The user must explicitly say "idle" or "stop" to break the loop. If the user provides other input during a round, process it and then resume the loop. |
| 79 | |
| 80 | ### Watch Mode (`squad watch`) |
| 81 | |
| 82 | Ralph's in-session loop processes work while it exists, then idles. For **persistent polling** between sessions or when you're away from the keyboard, use the `squad watch` CLI command: |
| 83 | |
| 84 | ```bash |
| 85 | npx @bradygaster/squad-cli watch # polls every 10 minutes (default) |
| 86 | npx @bradygaster/squad-cli watch --interval 5 # polls every 5 minutes |
| 87 | npx @bradygaster/squad-cli watch --interval 30 # polls every 30 minutes |
| 88 | ``` |
| 89 | |
| 90 | This runs as a standalone local process (not inside Copilot) that: |
| 91 | - Checks GitHub every N minutes for untriaged squad work |
| 92 | - Auto-triages issues based on team roles and keywords |
| 93 | - Assigns @copilot to `squad:copilot` issues (if auto-assign is enabled) |
| 94 | - Runs until Ctrl+C |
| 95 | |
| 96 | **Three layers of Ralph:** |
| 97 | |
| 98 | | Layer | When | How | |
| 99 | |-------|------|-----| |
| 100 | | **In-session** | You're at the keyboard | "Ralph, go" — active loop while work exists | |
| 101 | | **Local watchdog** | You're away but machine is on | `npx @bradygaster/squad-cli watch --interval 10` | |
| 102 | | **Cloud heartbeat** | Fully unattended | `squad-heartbeat.yml` — event-based only (cron disabled) | |
| 103 | |
| 104 | ### Ralph State |
| 105 | |
| 106 | Ralph's state is session-scoped (not persisted to disk): |
| 107 | - **Active/idle** — whether the loop is running |
| 108 | - **Round count** — how many check cycles completed |
| 109 | - **Scope** — what categories to monitor (default: all) |
| 110 | - **Stats** — issues closed, PRs merged, items processed this session |
| 111 | |
| 112 | ### Ralph on the Board |
| 113 | |
| 114 | When Ralph reports status, use this format: |
| 115 | |
| 116 | ``` |
| 117 | 🔄 Ralph — Work Monitor |
| 118 | ━━━━━━━━━━━━━━━━━━━━━━ |
| 119 | 📊 Board Status: |
| 120 | 🔴 Untriaged: 2 issues need triage |
| 121 | 🟡 In Progress: 3 issues assigned, 1 draft PR |
| 122 | 🟢 Ready: 1 PR approved, awaiting merge |
| 123 | ✅ Done: 5 issues closed this session |
| 124 | |
| 125 | Next action: Triaging #42 — "Fix auth endpoint timeout" |
| 126 | ``` |
| 127 | |
| 128 | ### Integration with Follow-Up Work |
| 129 | |
| 130 | After the coordinator's step 6 ("Immediately assess: Does anything trigger follow-up work?"), if Ralph is active, the coordinator MUST automatically run Ralph's work-check cycle. **Do NOT return control to the user.** This creates a continuous pipeline: |
| 131 | |
| 132 | 1. User activates Ralph → work-check cycle runs |
| 133 | 2. Work found → agents spawned → results collected |
| 134 | 3. Follow-up work assessed → more agents if needed |
| 135 | 4. Ralph scans GitHub again (Step 1) → IMMEDIATELY, no pause |
| 136 | 5. More work found → repeat from step 2 |
| 137 | 6. No more work → "📋 Board is clear. Ralph is idling." (suggest `npx @bradygaster/squad-cli watch` for persistent polling) |
| 138 | |
| 139 | **Ralph does NOT ask "should I continue?" — Ralph KEEPS GOING.** Only stops on explicit "idle"/"stop" or session end. A clear board → idle-watch, not full stop. For persistent monitoring after the board clears, use `npx @bradygaster/squad-cli watch`. |
| 140 | |
| 141 | These are intent signals, not exact strings — match the user's meaning, not their exact words. |