ralph-loop
Ralph Loop
Use this skill with an explicit mention such as:
$ralph-loop Fix the failing tests and stop only when they pass
Optional conventions in the user message:
--max-iterations N--completion-promise TEXT--magic-word TEXT
Defaults:
- max iterations:
50 - completion promise:
DONE - continuation magic word:
RALPH_AUTO_CONTINUE - completion signal written in the assistant message:
<promise>DONE</promise> - continuation signal for non-final turns:
<ralph-continue>RALPH_AUTO_CONTINUE</ralph-continue>
What this skill does
This skill writes a workspace-local state file at .codex/ralph-loop-state.json.
A user-scope Stop-hook dispatcher in ~/.codex/hooks.json reads that state file
after each assistant response. If the completion signal is missing and the max
iteration limit has not been reached, the Stop hook blocks the turn and feeds a
continuation prompt back to Codex. The continuation prompt keeps the loop in
automatic mode, tells Codex not to ask whether it should continue, and carries
an explicit continuation signal keyed off the configured magic word.
This is a simple utility loop. It is not a replacement for higher-level orchestration systems such as cmux Autopilot.
User-scope install
Install the skill bundle and home Stop-hook helpers into ~/.codex/ with:
bash scripts/install-user-scope.sh
Optional flags:
--codex-home /absolute/path/to/.codex--mode copy|symlink
Install behavior:
- installs the skill bundle into
~/.codex/skills/ralph-loop - installs
~/.codex/hooks/ralph-loop-stop.sh - installs
~/.codex/hooks/managed-stop-dispatch.sh - enables
codex_hooks = truein~/.codex/config.toml - preserves an existing cmux-managed
~/.codex/hooks.jsonif it already points tocmux-stop-dispatch.sh
If cmux already owns the home Stop hook, Ralph Loop still works after install by letting the cmux dispatcher fall back to the home Ralph hook.
Procedure
- Parse the user request after
$ralph-loop. - Resolve:
- the task prompt
max_iterationscompletion_promisemagic_word
- Resolve the active task workspace path first.
- Run
scripts/start-loop.shfrom this skill directory and pass the workspace explicitly with--workspace. - Confirm the state file exists at
.codex/ralph-loop-state.json. - Work the task normally in the current workspace.
- While another turn is still required, keep auto-continuing and include the continuation signal in non-final assistant messages.
- When the task is actually complete, include the exact completion signal in the final assistant message.
Required command
Run this helper from the skill root:
bash scripts/start-loop.sh \
--workspace "/absolute/path/to/current/workspace" \
--max-iterations 50 \
--completion-promise DONE \
--magic-word RALPH_AUTO_CONTINUE \
--prompt "TASK GOES HERE"
If the user supplied explicit values, pass those instead of the defaults. Do not rely on the helper's current working directory; always pass the workspace path explicitly.
Continuation rules
- Stay on the same task across continuation prompts.
- Continue from the current workspace state; do not restart from scratch.
- Prefer concrete progress each iteration: inspect, edit, verify, repeat.
- Do not ask the user whether to keep going while the loop is active.
- If another turn is still required, include the exact continuation signal:
<ralph-continue>RALPH_AUTO_CONTINUE</ralph-continue>
- If the user chose a different magic word, substitute it into the tag.
- Use the loop for bounded tasks. If the user is really asking for broad orchestration, background supervision, or multi-agent management, stop and use a different workflow instead.
Conflict boundaries
$ralph-loopand$loopare not substitutes.ralph-loopowns same-session continuation through the Stop hook.loopowns recurring fresh-session scheduling and should not install or edit Stop hooks.- cmux autopilot uses the same Stop-hook channel as Ralph Loop, so only one
home dispatcher should own
~/.codex/hooks.jsonat a time. - When cmux owns the home dispatcher, Ralph Loop should install only its home stop hook and let the cmux dispatcher delegate to it.
Completion
When you are done, emit the exact completion signal:
<promise>DONE</promise>
If the user chose a different completion promise, emit that exact tag instead.
Cancel or inspect
- Cancel the loop:
bash scripts/start-loop.sh --workspace "/absolute/path/to/current/workspace" --cancel
- Show the current state:
bash scripts/start-loop.sh --workspace "/absolute/path/to/current/workspace" --show
Verification
To verify the hook logic without launching a nested Codex session:
bash scripts/test-stop-hook.sh
bash scripts/test-managed-stop-dispatch.sh
bash scripts/test-install-user-scope.sh