Claude
Skills
Sign in
Back

ralph

Included with Lifetime
$97 forever

Launcher for the Ralph-style queue drain script — emits the right `node ralph-loop.mjs` invocation based on the user's filter and bounds. The actual loop runs as a Node script that spawns one `claude -p --worktree` per iteration; this skill is the configurator, not the loop. Use when a user says: drain the backlog, ralph the queue, run Ralph loop, work the queue, batch through queue items, autonomous queue worker.

Backend & APIs

What this skill does


# ralph — Queue Drain Launcher

This skill is a **launcher** for the Ralph drain script (`scripts/ralph-loop.mjs` in this plugin). It does not run a loop in the current session. It helps you configure the right invocation, previews what will be processed, and emits the exact command to run.

The actual loop runs as a separate Node process. Each iteration spawns a fresh `claude -p` in its own git worktree (via Claude Code's `-w` flag), claims one item from the TO queue, and works it to terminal per the item's schema. Outcome is signaled via a `RALPH_OUTCOME:` JSON marker that the script parses for circuit-breaker decisions.

> **Why a separate script, not a slash-command loop?** Per Geoff Huntley's canonical Ralph: the value comes from carving off small bits of work into independent context windows. Each iteration is a fresh process — fresh context, fresh worktree, isolated logs, clean exit codes. The skill-as-orchestrator pattern (one session, internal loop) accumulates context within a session and doesn't preserve fresh-context isolation. For autonomous cadence, compose with `/loop`: `/loop 30m node scripts/ralph-loop.mjs --filter "tag=bug-fix"`.

---

## Step 1 — Resolve the filter

Determine what subset of the queue to drain.

**If `$ARGUMENTS` is non-empty**, parse it as a filter expression. Supported keys:

| Key | Effect |
|---|---|
| `tag=<value>` | Items whose `tags` field contains `<value>` (substring) |
| `type=<value>` | Items with this exact `type` |
| `priority=<value>` | Items at this priority (`high`, `medium`, `low`) |
| `parentId=<uuid-or-prefix>` | Only descendants of this container |

Multiple keys combine with AND (space-separated). Examples: `tag=bug-fix priority=high`, `type=quick-fix`, `parentId=89d02e32`.

**If `$ARGUMENTS` is empty**, ask the user via `AskUserQuestion`:

```
◆ Ralph loop — what should I drain?
  1. Bug-fix backlog (tag=bug-fix)
  2. Quick fixes (type=quick-fix)
  3. Tech debt container (parentId=<lookup>)
  4. Anything in queue (no filter)
  5. Custom filter — specify
```

If the user picks "Tech debt container", search via FTS: `query_items(operation="search", query="Tech Debt", limit=5)` and use the resulting UUID. (FTS mode triggers when `query` is present; `depth` is a list-mode-only filter and is ignored in FTS mode.)

---

## Step 2 — Resolve bounds

Set sensible loop bounds. Show defaults and let the user adjust.

```
◆ Loop bounds (default in parens):
  Max iterations:           10
  Gate-failure budget:      3 consecutive
  Error budget:             2 consecutive
  Per-iteration USD cap:    $5
  Claim TTL per iteration:  1800s (30 min)
  Model:                    sonnet
  Cleanup on terminal:      smart (remove if no commits/changes; preserve otherwise)

  Adjust any?  Reply "ok" to use defaults.
```

If the user adjusts, capture the overrides. Common patterns:
- High-volume drain: `--max 30`
- Low-confidence run: `--gate-budget 1 --error-budget 1`
- Architecture-heavy items: `--model opus --budget 15`
- Preserve every worktree (debugging-heavy session): `--no-cleanup`

---

## Step 3 — Preview the queue

Show what the loop will see. Use `query_items` with the resolved filter to display the first 5 candidates and the total count:

```
query_items(operation="search", role="queue", claimStatus="unclaimed", limit=10, ...)
```

Display:

```
◆ Queue preview — filter: tag=bug-fix priority=high
  Total claimable: 7 items
  First 5 by priority:
    ◉ d4fc7b2e  Fix duplicate UUID race in claim_item            (high)
    ◉ 92da8e9a  Gate response includes stale guidance            (high)
    ◉ 0c916953  subagent-start hook double-advance               (high)
    ◉ 00769317  advance_item applied:false contradicts DB        (medium)
    ◉ 2e4c9e77  create_work_tree dependency semantics            (low)
```

If the count is zero, tell the user nothing matches and stop here. If the count exceeds the iteration cap by a lot, mention that subsequent runs would pick up the rest.

---

## Step 4 — Emit the command

Print the exact command to run. The user copies and pastes it.

```
◆ Ready to launch. Run this command:

  node claude-plugins/task-orchestrator/scripts/ralph-loop.mjs \
    --filter "tag=bug-fix priority=high" \
    --max 10 \
    --budget 5 \
    --ttl 1800 \
    --model sonnet

  → Spawns one `claude -p --worktree=ralph-...` per iteration
  → Each iteration is fresh context, isolated worktree
  → Logs print live as iterations run
  → Final summary lists outcomes and preserved worktrees

  For autonomous cadence (re-run every 30 min until empty):
    /loop 30m node claude-plugins/task-orchestrator/scripts/ralph-loop.mjs --filter "tag=bug-fix priority=high"

  Dry-run first to verify the iteration command:
    node claude-plugins/task-orchestrator/scripts/ralph-loop.mjs --dry-run --filter "tag=bug-fix priority=high"
```

Adjust the path if the user is in a different working directory — the script lives at `claude-plugins/task-orchestrator/scripts/ralph-loop.mjs` relative to the project root.

If the user wants the skill to launch the script directly (rather than emit a command), suggest using the Bash tool — but flag the tradeoff:

```
⚠ Running the script via Bash from this session means the loop output streams
   into our conversation transcript. That works for short drains but burns
   context on long ones. For drains over 5 iterations, prefer running the
   command in a separate terminal so this session stays free for other work.
```

---

## Step 5 — Post-run handoff

After the script finishes (the user reports back with the summary, or pastes the output), help interpret the outcomes:

| Final summary line | Action |
|---|---|
| `Exit reason: queue empty` | Loop succeeded — nothing to do |
| `Exit reason: iteration cap reached` | Re-run with same filter to continue, or raise `--max` |
| `Exit reason: gate failure budget exhausted` | Inspect preserved worktrees; the schema expects notes the iteration agent can't fill autonomously (often `review-checklist`) |
| `Exit reason: error budget exhausted` | Inspect last error; likely repo/build/network issue affecting all iterations |

For preserved worktrees from gate-blocked or errored iterations:

```bash
# inspect
git -C <repo-path> worktree list | grep ralph-

# resume manually with /status-progression on the item ID
# or clean up after inspection
git -C <repo-path> worktree remove ralph-<id>
```

---

## Outcomes & exit codes (script reference)

The iteration agent emits `RALPH_OUTCOME: {...}` as its final message. The loop driver maps each status to circuit-breaker behavior:

| Status | Effect on loop |
|---|---|
| `terminal` | Counter ✓; resets gate-failure and error counters; loop continues |
| `gate-blocked` | Counter ⊘; increments consecutive gate-failure counter; loop continues unless budget hit |
| `error` | Counter ✗; increments consecutive error counter; loop continues unless budget hit |
| `skip` | Counter —; no counter changes; loop continues |
| `no-item` | Loop exits cleanly (queue empty) |

The script's own exit code:
| Code | Meaning |
|---|---|
| `0` | Loop completed normally (queue empty, iteration cap, or gate-budget exit) |
| `2` | Loop stopped due to consecutive errors |
| `64` | CLI argument error |
| `70` | Could not read iteration prompt |

---

## Composition with other tools

| Want to... | Compose with |
|---|---|
| Run Ralph on a schedule | `/loop 30m node .../ralph-loop.mjs --filter ...` |
| Inspect what's claimable before running | `/work-summary` to see queue contents |
| Resume a single gate-blocked item from Ralph | `/status-progression <item-id>` |
| Clean up a preserved worktree | `git worktree remove <path>` |
| Check the iteration prompt template | Read `skills/ralph/iteration-prompt.md` in this plugin |

---

## Examples

### Example 1: Drain the bug-fix queue

User: "ralph the bug-fix backlog"

```
$ARGUMENTS = "tag=bug-fix"
```

**Step 1** parses the filter: `tag=bug-fix`.

**Step 2** uses defaults (max=10, budg

Related in Backend & APIs