Skip to main content
ClaudeWave
Skill5.8k repo starsupdated 4d ago

ralph

MCP-owned Ralph loop around background evolve_step jobs

Install in Claude Code
Copy
git clone --depth 1 https://github.com/Q00/ouroboros /tmp/ralph && cp -r /tmp/ralph/skills/ralph ~/.claude/skills/ralph
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# /ouroboros:ralph

MCP-owned Ralph loop around background `evolve_step` jobs. "The boulder never stops."

## Usage

```
ooo ralph --lineage-id <lineage_id>
/ouroboros:ralph --lineage-id <lineage_id>

# For a plain natural-language request, run `ooo interview` + `ooo seed` first,
# then call the MCP tool with a fresh lineage_id and the validated Seed YAML.
```

**Trigger keywords:** "ralph", "don't stop", "must complete", "until it works", "keep going"

## How It Works

Ralph is owned by the `ouroboros_ralph` MCP tool. In non-plugin runtimes, the
tool starts one background Ralph job, runs repeated `evolve_step` generations
inside that job, and stops only when QA passes, convergence is reached, a
terminal evolution action occurs, cancellation is requested, or
`max_generations` is reached. In OpenCode plugin mode, the MCP tool returns a
`delegated_to_plugin` envelope with `job_id=None`; the bridge plugin dispatches
a child Task session that owns the loop instead of creating a local JobManager
job.

The client skill should not reimplement the loop. Deterministic frontmatter
dispatch is limited to the router's named `--lineage-id` option so raw trailing
text is never treated as lineage identity. Raw natural-language
`ooo ralph "<request>"` input must flow through the validated Seed path before
any mutating Ralph loop starts. Until a lineage id and optional Seed YAML are
prepared, `ouroboros_ralph` returns structured input guidance instead of
starting a job. Once the inputs are prepared, start the MCP-owned Ralph surface
once, then follow either the returned job tools path or the OpenCode Task widget
path.

## Instructions

When the user invokes this skill:

### Load MCP Tools (Required first)

The Ouroboros MCP tools are often registered as deferred tools that must be
explicitly loaded before use. Do this before preparing input or calling Ralph:

1. Use the active runtime's tool-discovery capability to find and load the Ralph/job MCP tools:
   ```
   tool discovery query: "+ouroboros ralph job"
   ```
2. The loaded tools may be exposed under plugin-prefixed names such as
   `mcp__plugin_ouroboros_ouroboros__ouroboros_ralph`. Use the actual tool
   names returned by runtime tool discovery; the bare names below are the canonical MCP
   tool names for documentation.
3. Confirm that `ouroboros_ralph` and the job tools (`ouroboros_job_wait`,
   `ouroboros_job_status`, `ouroboros_job_result`, and
   `ouroboros_cancel_job`) are callable. If the tools are unavailable, stop and
   tell the user that Ralph requires the Ouroboros MCP runtime.

### Ralph Flow

1. **Prepare lineage input**:
   - If the user provides an existing `lineage_id` and explicitly wants to
     continue it, reuse that `lineage_id` and omit `seed_content` unless they
     explicitly provide an updated Seed.
   - If the user provides Seed YAML for a new Ralph run, use it as
     `seed_content` and generate a fresh `lineage_id` for this run. Keep
     `lineage_id` separate from Seed, interview, and session IDs so separate
     Ralph runs over the same Seed do not collide.
   - If the user provides only a plain natural-language request, do not treat
     it as a direct `ooo ralph "<request>"` command, do not freehand Seed YAML,
     and do not pass raw text as `seed_content`. Route through the authoritative
     Seed path first: `ooo interview` to capture requirements, then `ooo seed` /
     `ouroboros_generate_seed` to produce validated Seed YAML with the normal
     ambiguity gate. After Seed generation, call the MCP tool with a fresh
     `lineage_id` and that validated Seed YAML as `seed_content`; do not use the
     raw request text. If an interview/seed session already exists in context,
     reuse that validated Seed output instead of regenerating it.

2. **Start Ralph** by calling `ouroboros_ralph` with:
   - `lineage_id`: existing lineage id for an explicit continuation, otherwise a
     freshly generated stable id for this Ralph run, such as
     `ralph-<short-slug>-<uuid>`; do not use a Seed/interview id by itself
   - `seed_content`: valid Seed YAML for generation 1 when starting a new lineage
   - `execute`: default `true`
   - `parallel`: default `true`
   - `skip_qa`: default `false`
   - `project_dir`: explicit target project directory when known
   - `max_generations`: default `10` unless the user requests a tighter bound

3. **Handle the start response**:
   - If `response.meta.job_id` is present, report it concisely and retain the
     job cursor from `response.meta.cursor`:

     ```
     [Ralph] Started background loop: <job_id>
     Lineage: <lineage_id>
     Live view: <dashboard_url, or `ouroboros tui open`>

     A read-only observer will post meaningful progress, attention, and terminal
     events here. This conversation remains available for other safe work.
     ```

   - If `response.meta.job_observer` is unavailable, recover it from the final
     `<!-- ouroboros-job-observer-v1 base64 ... -->` content sentinel. Fail
     closed unless the bounded payload passes canonical v1 validation and its
     job identity matches the visible start receipt. Use that ID only as an
     identity anchor, never to reconstruct tools or arguments. Reject validation
     failure or any mismatch between structured and inline surfaces.

   - If the structured or recovered `job_observer` is present and the host
     supports an independent child session, spawn exactly one read-only
     observer and pass that contract unchanged. The observer exclusively owns
     job wait/result calls and the cursor. The main session retains only user
     conversation, explicit on-demand status, and cancellation when the user
     requests it. The main session must not poll the same job while the observer
     is active. It may refine requirements, perform read-only review, or work in
     an unrelated isolated worktree; check active-worker conflicts before
     writing to Ralph's workspace.
     On Codex, call `spawn_agent` exactly once w