When the codex-reviewer and ralph-reviewed Stop hooks invoke `codex exec`, they pass `-o <outputFile>` so the verdict can be parsed back from a known path, then append the user's `extra_args`. Two latent bugs surfaced after the docs commit started promoting the shared ~/.claude/codex.json knobs to standalone users: 1. The previous filter dropped `-o` / `--output*` tokens individually but not the value that followed a bare flag. With extra_args: ["-o", "/tmp/other"], the filter left "/tmp/other" as a stray positional that Codex treated as an extra prompt argument. The new index-walk filter consumes both halves of paired flags (-o, --output, --output-last-message) and drops the inline --flag=value variants. Applied to both hooks. 2. ralph-reviewed honored `timeout_seconds` raw. A configured value at or above the 1800s Stop hook timeout let Claude kill the hook before it could parse Codex's output and surface a verdict. Now clamped to [60, 1680] (matching the existing codex-reviewer clamp), leaving a 120s buffer below the hook ceiling. Bumps ralph-reviewed to 3.0.2 and codex-reviewer to 1.6.10 in lockstep across each plugin.json and the root marketplace.json. The ralph-reviewed troubleshooting README is updated to describe the new clamp range rather than telling users to "increase to 1800".
Ralph Reviewed
An iterative development loop with Codex review gates. Fork of ralph-wiggum with added code review at completion.
How It Works
┌─────────────────────────────────────────────────────────────┐
│ │
│ Claude works ──► Claims done ──► Codex reviews │
│ ▲ │ │
│ │ ┌────┴────┐ │
│ │ ▼ ▼ │
│ │ APPROVE REJECT │
│ │ │ │ │
│ │ EXIT feedback │
│ │ │ │
│ └────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
- Start a loop with a task description
- Claude works iteratively until it believes the task is complete
- When Claude outputs the completion promise, Codex reviews the work
- If approved: loop ends successfully
- If rejected: Claude receives feedback and continues working
- After max review cycles, loop ends with final feedback
Installation
From Marketplace (Recommended)
# 1. Add the marketplace
/plugin marketplace add 0xbigboss/plugins
# 2. Install the plugin
/plugin install ralph-reviewed@0xbigboss-plugins
Or use the interactive plugin manager:
/plugin
Navigate to the Discover tab to browse and install.
From Local Development
If developing locally or using dotfiles:
# Add local path as marketplace
/plugin marketplace add ~/code/dotfiles/claude-code/plugins
# Install from local
/plugin install ralph-reviewed@local
Commands
/ralph-reviewed:ralph-loop
Start an iterative loop with review gates.
/ralph-reviewed:ralph-loop "Your task description" [options]
Options:
| Flag | Default | Description |
|---|---|---|
--max-iterations |
30 | Max work iterations before auto-stop |
--max-reviews |
max-iterations | Max review cycles before force-complete |
--no-review |
false | Disable Codex review gate |
--debug |
false | Write debug logs |
Completion: The agent runs .rl/rl done when finished, or .rl/rl done --blocked if stuck.
Examples:
# Basic usage
/ralph-reviewed:ralph-loop "Build a REST API with CRUD for todos. Include tests."
# With options
/ralph-reviewed:ralph-loop "Fix the auth bug in src/auth.ts" \
--max-iterations 20 \
--max-reviews 2
# Without review (original ralph behavior)
/ralph-reviewed:ralph-loop "Refactor the utils module" --no-review
/ralph-reviewed:cancel-ralph
Cancel the active loop immediately.
/ralph-reviewed:help
Show help and usage information.
Writing Good Prompts
Include Clear Success Criteria
Build a user registration API.
Requirements:
- POST /register accepting email and password
- Password hashing with bcrypt
- Email validation (valid format)
- Return 201 with user ID on success
- Return 400 with error message on invalid input
- Tests for all cases
When all tests pass, run `.rl/rl done`
Include Verification Steps
Fix the authentication middleware bug.
Verification:
1. Run `npm test src/auth.test.ts` - all tests pass
2. Run `npm run lint` - no errors
3. Manual check: login flow works in dev
When verified, run `.rl/rl done`
Set Escape Conditions
.rl/rl done --blocked is the escape hatch — terminates the loop immediately without triggering a Codex review. Use it when genuinely stuck:
Implement the search feature.
If blocked by external issues (missing deps, pre-existing bugs, etc.):
- Document what's blocking and what you tried
- Run `.rl/rl done --blocked`
Review Gate
When Claude outputs the completion promise, Codex CLI is invoked to review:
- Original task - What was requested
- Work summary - Recent Claude output
- Git diff - Code changes made
Codex responds with:
<review>APPROVE</review>- Work meets requirements<review>REJECT</review>with<issues>block - Needs changes
On rejection, Claude receives structured feedback with tagged issues (e.g., [ISSUE-1] major: description) and continues working. After --max-reviews cycles, the loop ends regardless (to prevent infinite ping-pong).
Requirements
- Git repository - State file is stored at repo root to survive directory changes
- Bun - For TypeScript hook execution
- codex - Codex CLI for reviews (optional - degrades gracefully if missing)
- git - For diff generation and repo root detection
Configuration
User Preferences
Configure Codex reviewer behavior via ~/.claude/codex.json:
{
"codex": {
"sandbox": "read-only",
"approval_policy": "never",
"bypass_sandbox": false,
"extra_args": [],
"timeout_seconds": 1200
}
}
Options:
| Key | Values | Default | Description |
|---|---|---|---|
sandbox |
read-only, workspace-write, danger-full-access |
read-only |
Codex sandbox mode |
approval_policy |
untrusted, on-failure, on-request, never |
never |
When Codex asks for approval |
bypass_sandbox |
true, false |
false |
Bypass sandbox entirely (overrides sandbox/approval_policy) |
extra_args |
string array | [] |
Additional CLI args passed to Codex (appended last, can override earlier flags) |
timeout_seconds |
number | 1200 |
Timeout for Codex review call (20 minutes default) |
Example: Full permissions for tooling (tsc, linters, tests):
{
"codex": {
"bypass_sandbox": true
}
}
This allows Codex to run build tools, linters, and tests during review. Without this, Codex runs in read-only mode and cannot verify tooling-based success criteria.
Example: Write access without full bypass:
{
"codex": {
"sandbox": "workspace-write",
"approval_policy": "never"
}
}
Loop State
State is stored in .rl/state.json at the git repository root. This ensures the loop survives directory changes within the repo. A structured log is appended to .rl/log.jsonl for progression tracking. The state file tracks:
- Current iteration count
- Max iterations
- Completion promise
- Original prompt
- Review count
- Pending feedback
Do not edit this file manually. Use /ralph-reviewed:cancel-ralph to stop.
Differences from ralph-wiggum
| Feature | ralph-wiggum | ralph-reviewed |
|---|---|---|
| Review gate | No | Yes (Codex CLI) |
| Max review cycles | N/A | Configurable |
| Feedback injection | No | Yes |
| Graceful degradation | N/A | Yes (if Codex unavailable) |
| Hook language | Bash | TypeScript (Bun) |
| Directory change handling | Breaks | Survives (uses git root) |
| Debug logging | No | Yes (--debug flag) |
| BLOCKED escape | No | Yes (terminates without review) |
Troubleshooting
Loop won't stop:
- Use
/ralph-reviewed:cancel-ralphto force stop - Verify completion promise matches exactly (case-insensitive)
State file not found after directory change:
- Ensure you're in a git repository (
git rev-parse --show-toplevel) - State file is at repo root:
{GIT_ROOT}/.rl/state.json - Outside git repos, directory changes will break the loop
Reviews not happening:
- Check
codexCLI is installed:which codex - Check
--no-reviewis not set - Check
.rl/state.jsonhas"review_enabled": true
Codex can't run tooling (EPERM errors, tsc/lint/test fails):
- By default, Codex runs in read-only sandbox mode
- Set
"bypass_sandbox": truein~/.claude/codex.json - See User Preferences for full config options
Too slow:
- Reduce
--max-iterationsfor faster feedback - Reduce
--max-reviewsif reviews are redundant
Review timing out:
- Default timeout is 1200 seconds (20 minutes)
- Increase via
~/.claude/codex.json:"timeout_seconds": 1500 - The hook clamps
timeout_secondsto[60, 1680]so it always finishes before the 1800sStophook timeout. Values outside that range are silently clamped (look forWARNING: Clamping timeoutin the debug log).
Debugging:
- Use
--debugflag to enable logging - Session logs:
~/.claude/ralphs/{session_id}/debug.log - Crash logs:
~/.claude/ralphs/{session_id}/crash.log - Pre-session startup log:
~/.claude/ralphs/startup.log
Credits
Based on the Ralph Wiggum technique by Geoffrey Huntley and the official Claude plugin.