fix(loop): respect .ralphrc CLAUDE_CODE_CMD; add CLAUDE_MODEL/EFFORT (#228)#231
Conversation
…228) CLAUDE_CODE_CMD was hardcoded to "claude" at line 27 — before the env snapshot block at line 46. This made _env_CLAUDE_CODE_CMD always non-empty ("claude"), so the load_ralphrc() restore at line 158 unconditionally overwrote any .ralphrc value with "claude". Both .ralphrc configuration AND shell environment overrides were silently discarded. Fix: remove the unconditional assignment. CLAUDE_CODE_CMD is now set with parameter expansion (${CLAUDE_CODE_CMD:-claude}) AFTER the env snapshot block, consistent with MAX_CALLS_PER_HOUR and other tunables. The snapshot now captures "" when no env var is exported, allowing .ralphrc to take effect. Also adds CLAUDE_MODEL and CLAUDE_EFFORT config variables (requested in the issue): - Set in .ralphrc: CLAUDE_MODEL="claude-sonnet-4-6", CLAUDE_EFFORT="high" - Passed as --model / --effort flags in build_claude_command() - Env vars take precedence over .ralphrc (same pattern as other vars) Adds 8 tests covering: parameter expansion assertion, .ralphrc loading, env var precedence, and CLI flag generation for both new variables. Fixes #228
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
WalkthroughAdds Changes
Sequence Diagram(s)sequenceDiagram
participant User as User
participant Script as RalphScript
participant RC as .ralphrc
participant Claude as ClaudeCLI
User->>Script: invoke ralph_loop
Script->>Script: snapshot env (CLAUDE_CODE_CMD, CLAUDE_MODEL, CLAUDE_EFFORT)
Script->>RC: source .ralphrc (may set CLAUDE_*)
RC-->>Script: return (variables possibly set)
Script->>Script: restore env snapshots if present (preserve precedence)
Script->>Script: build_claude_command (append --model/--effort if non-empty)
Script->>Claude: execute constructed CLI command
Claude-->>Script: response
(Note: rectangle colors omitted because sequence diagram uses actors/flow only.) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Review SummaryThis PR effectively fixes issue #228 by moving the default assignment to after the environment snapshot, and adds support for and configuration variables. ✅ Code Quality & Best Practices
✅ Test CoverageEight comprehensive tests added (lines 1821-1907):
|
|
The review has been posted successfully. The comment URL is: #231 (comment) Summary: The PR is well-implemented and correctly fixes issue #228. The code is solid, follows existing patterns, and has comprehensive test coverage. The only follow-up needed is documentation updates to mention the new |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tests/unit/test_cli_modern.bats (1)
1865-1874: Consider adding a parallel test forCLAUDE_EFFORTenv precedence.There's a test verifying
CLAUDE_MODELenv var takes precedence over.ralphrc, but no equivalent test forCLAUDE_EFFORT. For completeness and to ensure parity in test coverage:📝 Suggested test to add after line 1874
+@test "CLAUDE_EFFORT env var takes precedence over .ralphrc" { + cat > "$TEST_DIR/.ralphrc" << 'EOF' +CLAUDE_EFFORT="low" +EOF + _env_CLAUDE_EFFORT="high" + CLAUDE_EFFORT="high" + + load_ralphrc + assert_equal "$CLAUDE_EFFORT" "high" +}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/unit/test_cli_modern.bats` around lines 1865 - 1874, Add a new test mirroring the CLAUDE_MODEL precedence test that verifies CLAUDE_EFFORT environment variable overrides the value in .ralphrc: create a `@test` block (e.g., "CLAUDE_EFFORT env var takes precedence over .ralphrc") that writes CLAUDE_EFFORT into "$TEST_DIR/.ralphrc", sets _env_CLAUDE_EFFORT and CLAUDE_EFFORT to a different value, calls load_ralphrc, and uses assert_equal to confirm "$CLAUDE_EFFORT" matches the environment value; follow the same structure and assertions used in the CLAUDE_MODEL test to ensure parity.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@tests/unit/test_cli_modern.bats`:
- Around line 1865-1874: Add a new test mirroring the CLAUDE_MODEL precedence
test that verifies CLAUDE_EFFORT environment variable overrides the value in
.ralphrc: create a `@test` block (e.g., "CLAUDE_EFFORT env var takes precedence
over .ralphrc") that writes CLAUDE_EFFORT into "$TEST_DIR/.ralphrc", sets
_env_CLAUDE_EFFORT and CLAUDE_EFFORT to a different value, calls load_ralphrc,
and uses assert_equal to confirm "$CLAUDE_EFFORT" matches the environment value;
follow the same structure and assertions used in the CLAUDE_MODEL test to ensure
parity.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 18fc040b-d389-48df-8dce-3e345ee7934e
📒 Files selected for processing (2)
ralph_loop.shtests/unit/test_cli_modern.bats
|
Test comment from review agent |
Contributing to Ralph for Claude CodeThank you for your interest in contributing to Ralph! This guide will help you get started and ensure your contributions follow our established patterns and quality standards. Every contribution matters - from fixing typos to implementing major features. We appreciate your help in making Ralph better! Table of Contents
Getting StartedPrerequisitesBefore contributing, ensure you have the following installed:
Clone the Repository# Fork the repository on GitHub first, then clone your fork
git clone https://github.com/YOUR_USERNAME/ralph-claude-code.git
cd ralph-claude-codeInstall Dependencies# Install BATS testing framework and dependencies
npm install
# Verify BATS is available
./node_modules/.bin/bats --version
# Optional: Install Ralph globally for testing
./install.shVerify Your Setup# Run the test suite to ensure everything works
npm test
# You should see output like:
# ✓ 276 tests passed (100% pass rate)Project StructureDevelopment WorkflowBranch Naming ConventionsAlways create a feature branch - never work directly on
# Create a new feature branch
git checkout -b feature/my-awesome-featureCommit Message FormatWe use Conventional Commits for clear, structured commit history: Types:
Examples from Recent Commits: # Feature addition
feat(import): add JSON output format support
# Bug fix with scope
fix(loop): replace non-existent --prompt-file with -p flag
# Documentation update
docs(status): update IMPLEMENTATION_STATUS.md with phased structure
# Test addition
test(cli): add 27 comprehensive CLI parsing testsWriting Good Commit Messages:
Workflow DiagramCode Style GuidelinesBash Best PracticesRalph follows consistent bash conventions across all scripts: File Structure: #!/bin/bash
# Script description
# Purpose and usage notes
# Source dependencies
source "$(dirname "${BASH_SOURCE[0]}")/lib/date_utils.sh"
# Configuration constants (UPPER_CASE)
MAX_CALLS_PER_HOUR=100
CB_NO_PROGRESS_THRESHOLD=3
STATUS_FILE="status.json"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Helper functions (snake_case)
helper_function() {
local param1=$1
local param2=$2
# Implementation
}
# Main logic
main() {
# Entry point
}
# Export functions for reuse
export -f helper_function
# Execute main if run directly
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fiNaming Conventions:
Function Documentation: # Get current circuit breaker state
# Returns the state as a string: CLOSED, HALF_OPEN, or OPEN
# Falls back to CLOSED if state file doesn't exist
get_circuit_state() {
if [[ ! -f "$CB_STATE_FILE" ]]; then
echo "$CB_STATE_CLOSED"
return
fi
jq -r '.state' "$CB_STATE_FILE" 2>/dev/null || echo "$CB_STATE_CLOSED"
}Error Handling: # Always validate inputs
if [[ -z "$1" ]]; then
echo -e "${RED}Error: Missing required argument${NC}" >&2
exit 1
fi
# Use proper exit codes
# 0 = success, 1 = general error, 2 = invalid usageCross-Platform Compatibility: # Use portable date commands
if command -v gdate &> /dev/null; then
DATE_CMD="gdate" # macOS with coreutils
else
DATE_CMD="date" # Linux
fiJSON State Management: # Always validate JSON before parsing
if ! jq '.' "$STATE_FILE" > /dev/null 2>&1; then
echo "Error: Invalid JSON in state file"
return 1
fi
# Use jq for safe parsing
local state=$(jq -r '.state' "$STATE_FILE" 2>/dev/null || echo "CLOSED")Testing RequirementsMandatory Testing StandardsAll new features must include tests. This is non-negotiable.
Test OrganizationRunning Tests
Writing TestsTest Structure: #!/usr/bin/env bats
# Unit Tests for Feature X
load '../helpers/test_helper'
# Setup runs before each test
setup() {
source "$(dirname "$BATS_TEST_FILENAME")/../helpers/test_helper.bash"
# Create isolated test environment
export TEST_TEMP_DIR="$(mktemp -d /tmp/ralph-test.XXXXXX)"
cd "$TEST_TEMP_DIR"
# Initialize test state
echo "0" > ".call_count"
}
# Teardown runs after each test
teardown() {
cd /
rm -rf "$TEST_TEMP_DIR"
}
# Test: Descriptive name explaining what's being tested
@test "can_make_call returns success when under limit" {
echo "50" > ".call_count"
export MAX_CALLS_PER_HOUR=100
run can_make_call
assert_success
}
# Test: Failure case
@test "can_make_call returns failure when at limit" {
echo "100" > ".call_count"
export MAX_CALLS_PER_HOUR=100
run can_make_call
assert_failure
}Test Best Practices:
Available Test Helpers: # From tests/helpers/test_helper.bash
assert_success # Check command succeeded (exit 0)
assert_failure # Check command failed (exit != 0)
assert_equal # Compare two values
assert_output # Check command output
assert_file_exists # Verify file exists
assert_dir_exists # Verify directory exists
strip_colors # Remove ANSI color codes
create_mock_prompt # Create test PROMPT.md
create_mock_fix_plan # Create test fix_plan.md
create_mock_status # Create test status.jsonPull Request ProcessBefore Creating a PRRun through this checklist:
Creating the PR
PR Title: Follow conventional commit format PR Description Template: ## Summary
Brief description of what this PR does (1-3 bullet points).
- Adds dry-run mode to preview loop execution
- Includes new CLI flag `--dry-run`
- Logs actions without making actual changes
## Test Plan
- [ ] Unit tests added/updated
- [ ] Integration tests added/updated
- [ ] Manual testing completed
## Related Issues
Fixes #123
Related to #456
## Screenshots (if applicable)
[Add screenshots for UI/output changes]
## Breaking Changes
[List any breaking changes, or "None"]After PR Creation
Code Review GuidelinesFor ContributorsResponding to Feedback:
If You Disagree:
For ReviewersWhat to Check:
Review Best Practices:
Quality StandardsQuality GatesAll PRs must pass these automated checks:
Documentation StandardsWhen to Update Documentation:
Keep in Sync:
Feature Completion ChecklistBefore marking any feature complete:
Community GuidelinesPriority Contribution AreasHigh Priority - Help Needed!
CommunicationBefore Major Changes:
Getting Help:
Code of Conduct
Recognition
Additional Resources
Thank you for contributing to Ralph! Your efforts help make autonomous AI development more accessible to everyone. |
|
REVIEW_PLACEHOLDER |
|
test with |
|
line1 |
|
line1 |
headingsome text |
Ralph for Claude Code
Ralph is an implementation of the Geoffrey Huntley's technique for Claude Code that enables continuous autonomous development cycles he named after Ralph Wiggum. It enables continuous autonomous development cycles where Claude Code iteratively improves your project until completion, with built-in safeguards to prevent infinite loops and API overuse. Install once, use everywhere - Ralph becomes a global command available in any directory. Project StatusVersion: v0.11.5 - Active Development What's Working Now
Recent Improvementsv0.11.5 - Community Bug Fixes (latest)
v0.11.4 - Bug Fixes & Compatibility
v0.11.3 - Live Streaming & Beads Fix
v0.11.2 - Setup Permissions Fix
v0.11.1 - Completion Indicators Fix
v0.11.0 - Ralph Enable Wizard
v0.10.1 - Bug Fixes & Monitor Path Corrections
v0.10.0 - .ralph/ Subfolder Structure (BREAKING CHANGE)
Earlier versions (v0.9.x)v0.9.9 - EXIT_SIGNAL Gate & Uninstall Script
v0.9.8 - Modern CLI for PRD Import
v0.9.7 - Session Lifecycle Management
v0.9.6 - JSON Output & Session Management
v0.9.5 - v0.9.0 - PRD import tests, project setup tests, installation tests, prompt file fix, modern CLI commands, circuit breaker enhancements In Progress
Timeline to v1.0: ~4 weeks | Full roadmap | Contributions welcome! Features
Quick StartRalph has two phases: one-time installation and per-project setup. Phase 1: Install Ralph (One Time Only)Install Ralph globally on your system: git clone https://github.com/frankbria/ralph-claude-code.git
cd ralph-claude-code
./install.shThis adds
Phase 2: Initialize Projects (Per Project)Option A: Enable Ralph in Existing Project (Recommended)cd my-existing-project
# Interactive wizard - auto-detects project type and imports tasks
ralph-enable
# Or with specific task source
ralph-enable --from beads
ralph-enable --from github --label "sprint-1"
ralph-enable --from prd ./docs/requirements.md
# Start autonomous development
ralph --monitorOption B: Import Existing PRD/Specifications# Convert existing PRD/specs to Ralph format
ralph-import my-requirements.md my-project
cd my-project
# Review and adjust the generated files:
# - .ralph/PROMPT.md (Ralph instructions)
# - .ralph/fix_plan.md (task priorities)
# - .ralph/specs/requirements.md (technical specs)
# Start autonomous development
ralph --monitorOption C: Create New Project from Scratch# Create blank Ralph project
ralph-setup my-awesome-project
cd my-awesome-project
# Configure your project requirements manually
# Edit .ralph/PROMPT.md with your project goals
# Edit .ralph/specs/ with detailed specifications
# Edit .ralph/fix_plan.md with initial priorities
# Start autonomous development
ralph --monitorOngoing Usage (After Setup)Once Ralph is installed and your project is initialized: # Navigate to any Ralph project and run:
ralph --monitor # Integrated tmux monitoring (recommended)
# Or use separate terminals:
ralph # Terminal 1: Ralph loop
ralph-monitor # Terminal 2: Live monitor dashboardUninstalling RalphTo completely remove Ralph from your system: # Run the uninstall script
./uninstall.sh
# Or if you deleted the repo, download and run:
curl -sL https://raw.githubusercontent.com/frankbria/ralph-claude-code/main/uninstall.sh | bashUnderstanding Ralph FilesAfter running
Key File RelationshipsWhen to Use specs/
See the User Guide for detailed explanations and the examples/ directory for realistic project configurations. How It WorksRalph operates on a simple but powerful cycle:
Intelligent Exit DetectionRalph uses a dual-condition check to prevent premature exits during productive iterations: Exit requires BOTH conditions:
Example behavior: Other exit conditions:
Enabling Ralph in Existing ProjectsThe cd my-existing-project
ralph-enableThe wizard:
Non-interactive mode for CI/automation: ralph-enable-ci # Sensible defaults
ralph-enable-ci --from github # Import from GitHub Issues
ralph-enable-ci --project-type typescript # Override detection
ralph-enable-ci --json # Machine-readable outputImporting Existing RequirementsRalph can convert existing PRDs, specifications, or requirement documents into the proper Ralph format using Claude Code. Supported Formats
Usage Examples# Convert a markdown PRD
ralph-import product-requirements.md my-app
# Convert a text specification
ralph-import requirements.txt webapp
# Convert a JSON API spec
ralph-import api-spec.json backend-service
# Let Ralph auto-name the project from filename
ralph-import design-doc.pdfWhat Gets GeneratedRalph-import creates a complete project with:
The conversion is intelligent and preserves your original requirements while making them actionable for autonomous development. ConfigurationProject Configuration (.ralphrc)Each Ralph project can have a # .ralphrc - Ralph project configuration
PROJECT_NAME="my-project"
PROJECT_TYPE="typescript"
# Claude Code CLI command (auto-detected, override if needed)
CLAUDE_CODE_CMD="claude"
# CLAUDE_CODE_CMD="npx @anthropic-ai/claude-code" # Alternative: use npx
# Loop settings
MAX_CALLS_PER_HOUR=100
CLAUDE_TIMEOUT_MINUTES=15
CLAUDE_OUTPUT_FORMAT="json"
# Tool permissions
ALLOWED_TOOLS="Write,Read,Edit,Bash(git *),Bash(npm *),Bash(pytest)"
# Session management
SESSION_CONTINUITY=true
SESSION_EXPIRY_HOURS=24
# Circuit breaker thresholds
CB_NO_PROGRESS_THRESHOLD=3
CB_SAME_ERROR_THRESHOLD=5Rate Limiting & Circuit BreakerRalph includes intelligent rate limiting and circuit breaker functionality: # Default: 100 calls per hour
ralph --calls 50
# With integrated monitoring
ralph --monitor --calls 50
# Check current usage
ralph --statusThe circuit breaker automatically:
Auto-recovery options: # Default: 30-minute cooldown before auto-recovery attempt
CB_COOLDOWN_MINUTES=30 # Set in .ralphrc (0 = immediate)
# Auto-reset on startup (for fully unattended operation)
ralph --auto-reset-circuit
# Or set in .ralphrc: CB_AUTO_RESET=trueClaude API 5-Hour LimitWhen Claude's 5-hour usage limit is reached, Ralph:
Custom Prompts# Use custom prompt file
ralph --prompt my_custom_instructions.md
# With integrated monitoring
ralph --monitor --prompt my_custom_instructions.mdExecution Timeouts# Set Claude Code execution timeout (default: 15 minutes)
ralph --timeout 30 # 30-minute timeout for complex tasks
# With monitoring and custom timeout
ralph --monitor --timeout 60 # 60-minute timeout
# Short timeout for quick iterations
ralph --verbose --timeout 5 # 5-minute timeout with progressVerbose Mode# Enable detailed progress updates during execution
ralph --verbose
# Combine with other options
ralph --monitor --verbose --timeout 30Live Streaming Output# Enable real-time visibility into Claude Code execution
ralph --live
# Combine with monitoring for best experience
ralph --monitor --live
# Live output is written to .ralph/live.log
tail -f .ralph/live.log # Watch in another terminalLive streaming mode shows Claude Code's output in real-time as it works, providing visibility into what's happening during each loop iteration. Session ContinuityRalph maintains session context across loop iterations for improved coherence: # Sessions are enabled by default with --continue flag
ralph --monitor # Uses session continuity
# Start fresh without session context
ralph --no-continue # Isolated iterations
# Reset session manually (clears context)
ralph --reset-session # Clears current session
# Check session status
cat .ralph/.ralph_session # View current session file
cat .ralph/.ralph_session_history # View session transition historySession Auto-Reset Triggers:
Sessions are persisted to Exit ThresholdsModify these variables in Exit Detection Thresholds: MAX_CONSECUTIVE_TEST_LOOPS=3 # Exit after 3 test-only loops
MAX_CONSECUTIVE_DONE_SIGNALS=2 # Exit after 2 "done" signals
TEST_PERCENTAGE_THRESHOLD=30 # Flag if 30%+ loops are test-onlyCircuit Breaker Thresholds: CB_NO_PROGRESS_THRESHOLD=3 # Open circuit after 3 loops with no file changes
CB_SAME_ERROR_THRESHOLD=5 # Open circuit after 5 loops with repeated errors
CB_OUTPUT_DECLINE_THRESHOLD=70 # Open circuit if output declines by >70%
CB_COOLDOWN_MINUTES=30 # Minutes before OPEN → HALF_OPEN auto-recovery
CB_AUTO_RESET=false # true = reset to CLOSED on startup (bypasses cooldown)Completion Indicators with EXIT_SIGNAL Gate:
Project StructureRalph creates a standardized structure for each project with a
Best PracticesWriting Effective Prompts
Project Specifications
Monitoring Progress
System Requirements
Testing Requirements (Development)See TESTING.md for the comprehensive testing guide. If you want to run the test suite: # Install BATS testing framework
npm install -g bats bats-support bats-assert
# Run all tests (566 tests)
npm test
# Run specific test suites
bats tests/unit/test_rate_limiting.bats
bats tests/unit/test_exit_detection.bats
bats tests/unit/test_json_parsing.bats
bats tests/unit/test_cli_modern.bats
bats tests/unit/test_cli_parsing.bats
bats tests/unit/test_session_continuity.bats
bats tests/unit/test_enable_core.bats
bats tests/unit/test_task_sources.bats
bats tests/unit/test_ralph_enable.bats
bats tests/unit/test_wizard_utils.bats
bats tests/unit/test_circuit_breaker_recovery.bats
bats tests/integration/test_loop_execution.bats
bats tests/integration/test_prd_import.bats
bats tests/integration/test_project_setup.bats
bats tests/integration/test_installation.bats
# Run error detection and circuit breaker tests
./tests/test_error_detection.sh
./tests/test_stuck_loop_detection.shCurrent test status:
Installing tmux# Ubuntu/Debian
sudo apt-get install tmux
# macOS
brew install tmux
# CentOS/RHEL
sudo yum install tmuxInstalling GNU coreutils (macOS)Ralph uses the # Install coreutils (provides gtimeout)
brew install coreutils
# Verify installation
gtimeout --versionRalph automatically detects and uses Monitoring and DebuggingLive Dashboard# Integrated tmux monitoring (recommended)
ralph --monitor
# Manual monitoring in separate terminal
ralph-monitorShows real-time:
tmux Controls:
Status Checking# JSON status output
ralph --status
# Manual log inspection
tail -f .ralph/logs/ralph.logCommon Issues
ContributingRalph is actively seeking contributors! We're working toward v1.0.0 with clear priorities and a detailed roadmap. See CONTRIBUTING.md for the complete contributor guide including:
Quick Start# Fork and clone
git clone https://github.com/YOUR_USERNAME/ralph-claude-code.git
cd ralph-claude-code
# Install dependencies and run tests
npm install
npm test # All 566 tests must passPriority Contribution Areas
Every contribution matters - from fixing typos to implementing major features! LicenseThis project is licensed under the MIT License - see the LICENSE file for details. Acknowledgments
Related Projects
Command ReferenceInstallation Commands (Run Once)./install.sh # Install Ralph globally
./uninstall.sh # Remove Ralph from system (dedicated script)
./install.sh uninstall # Alternative: Remove Ralph from system
./install.sh --help # Show installation help
ralph-migrate # Migrate existing project to .ralph/ structureRalph Loop Optionsralph [OPTIONS]
-h, --help Show help message
-c, --calls NUM Set max calls per hour (default: 100)
-p, --prompt FILE Set prompt file (default: PROMPT.md)
-s, --status Show current status and exit
-m, --monitor Start with tmux session and live monitor
-v, --verbose Show detailed progress updates during execution
-l, --live Enable live streaming output (real-time Claude Code visibility)
-t, --timeout MIN Set Claude Code execution timeout in minutes (1-120, default: 15)
--output-format FORMAT Set output format: json (default) or text
--allowed-tools TOOLS Set allowed Claude tools (default: Write,Read,Edit,Bash(git *),Bash(npm *),Bash(pytest))
--no-continue Disable session continuity (start fresh each loop)
--reset-circuit Reset the circuit breaker
--circuit-status Show circuit breaker status
--auto-reset-circuit Auto-reset circuit breaker on startup (bypasses cooldown)
--reset-session Reset session state manuallyProject Commands (Per Project)ralph-setup project-name # Create new Ralph project
ralph-enable # Enable Ralph in existing project (interactive)
ralph-enable-ci # Enable Ralph in existing project (non-interactive)
ralph-import prd.md project # Convert PRD/specs to Ralph project
ralph --monitor # Start with integrated monitoring
ralph --status # Check current loop status
ralph --verbose # Enable detailed progress updates
ralph --timeout 30 # Set 30-minute execution timeout
ralph --calls 50 # Limit to 50 API calls per hour
ralph --reset-session # Reset session state manually
ralph --live # Enable live streaming output
ralph-monitor # Manual monitoring dashboardtmux Session Managementtmux list-sessions # View active Ralph sessions
tmux attach -t <name> # Reattach to detached session
# Ctrl+B then D # Detach from session (keeps running)Development RoadmapRalph is under active development with a clear path to v1.0.0. See IMPLEMENTATION_PLAN.md for the complete roadmap. Current Status: v0.11.5What's Delivered:
Test Coverage Breakdown:
Path to v1.0.0 (~4 weeks)Enhanced Testing
Core Features
Advanced Features & Polish
See IMPLEMENTATION_STATUS.md for detailed progress tracking. How to ContributeRalph is seeking contributors! See CONTRIBUTING.md for the complete guide. Priority areas:
Ready to let AI build your project? Start with Star History |
|
Review part 1 of 4: The core bug fix is clean and correct. Removing the unconditional line-27 assignment of CLAUDE_CODE_CMD and replacing it with the default-value syntax (CLAUDE_CODE_CMD:-claude) after the env snapshot is exactly the right approach. The CLAUDE_MODEL and CLAUDE_EFFORT additions follow the established env-snapshot/default/restore pattern perfectly. Positive observations: (1) Regression test for the root bug (checking for the default-value syntax) is a smart way to guard against that class of mistake recurring. (2) All 8 new tests are targeted and meaningful -- they test behavior, not just coverage. (3) The fix is minimal and surgical -- no unrelated changes. |
|
Review part 2 of 4 -- Issues to address: (1) templates/ralphrc.template not updated: The .ralphrc template file and the generated version in lib/enable_core.sh do not include commented-out entries for the new variables. Users who run ralph enable or ralph-setup get a .ralphrc without any hint that CLAUDE_MODEL and CLAUDE_EFFORT exist. Adding them as commented-out optional settings in the Advanced Settings section would make discoverability much better (e.g. CLAUDE_MODEL="" with comment 'Model override, empty = CLI default' and CLAUDE_EFFORT="" with 'Effort level, valid values: low/medium/high'). (2) CLAUDE.md not updated: The Modern CLI Configuration section lists configuration variables but does not include CLAUDE_MODEL or CLAUDE_EFFORT. Per the project's own standards, implementation documentation must stay synchronized with the codebase. |
|
Review part 3 of 4 -- Issues (continued): (3) No validation of CLAUDE_EFFORT value: The --effort flag accepts a specific set of values (low/medium/high). If a user sets CLAUDE_EFFORT with a typo (e.g. 'meduim'), the error will come from the Claude CLI at runtime with no context about where the bad value came from. A simple warn-only guard in build_claude_command would improve UX -- a case statement matching low|medium|high, logging WARN for unexpected values, then still passing the value through. This is non-blocking, so it will not break operation if the CLI ever adds new values. |
|
Review part 4 of 4 -- Minor notes and summary: Minor notes: (a) The test 'CLAUDE_MODEL env var takes precedence over .ralphrc' pre-sets CLAUDE_MODEL before calling load_ralphrc. This works but relies on load_ralphrc not overwriting an already-set value when _env_CLAUDE_MODEL is non-empty. The logic is correct, just worth confirming the test accurately reflects the real startup sequence (env var exported -> snapshot captures it -> ralphrc cannot overwrite). (b) The build_claude_command stub in the test file now duplicates the --model/--effort block from production. This is expected for the test harness pattern used throughout this file, but it means both places need updating if the flag names change in the Claude CLI. Summary: The bug fix is solid and well-tested. The main gaps are documentation (CLAUDE.md and ralphrc.template) -- these are called out explicitly in the project's own Feature Completion Checklist. The effort validation is a nice-to-have. With those addressed this is ready to merge. |
|
Review comment test - checking if direct body posting works |
|
Deleting previous test comment — full review incoming. |
Review — Building on Prior FeedbackThe core fix is solid (covered well in previous reviews). This note focuses on what still needs to land before merge. |
CLAUDE.mdThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. Repository OverviewThis is the Ralph for Claude Code repository - an autonomous AI development loop system that enables continuous development cycles with intelligent exit detection and rate limiting. See README.md for version info, changelog, and user documentation. Core ArchitectureThe system consists of four main bash scripts and a modular library system: Main Scripts
Library Components (lib/)The system uses a modular architecture with reusable components in the
Key CommandsInstallation# Install Ralph globally (run once)
./install.sh
# Uninstall Ralph
./install.sh uninstallSetting Up a New Project# Create a new Ralph-managed project (run from anywhere)
ralph-setup my-project-name
cd my-project-nameMigrating Existing Projects# Migrate from flat structure to .ralph/ subfolder (v0.10.0+)
cd existing-project
ralph-migrateEnabling Ralph in Existing Projects# Interactive wizard (recommended for humans)
cd existing-project
ralph-enable
# With specific task source
ralph-enable --from beads
ralph-enable --from github --label "sprint-1"
ralph-enable --from prd ./docs/requirements.md
# Force overwrite existing .ralph/
ralph-enable --force
# Non-interactive for CI/scripts
ralph-enable-ci # Sensible defaults
ralph-enable-ci --from github # With task source
ralph-enable-ci --project-type typescript # Override detection
ralph-enable-ci --json # Machine-readable outputRunning the Ralph Loop# Start with integrated tmux monitoring (recommended)
ralph --monitor
# Start without monitoring
ralph
# With custom parameters and monitoring
ralph --monitor --calls 50 --prompt my_custom_prompt.md
# Check current status
ralph --status
# Circuit breaker management
ralph --reset-circuit
ralph --circuit-status
ralph --auto-reset-circuit # Auto-reset OPEN state on startup
# Session management
ralph --reset-session # Reset session state manuallyMonitoring# Integrated tmux monitoring (recommended)
ralph --monitor
# Manual monitoring in separate terminal
ralph-monitor
# tmux session management
tmux list-sessions
tmux attach -t <session-name>Running Tests# Run all tests
npm test
# Run specific test suites
npm run test:unit
npm run test:integration
# Run individual test files
bats tests/unit/test_cli_parsing.bats
bats tests/unit/test_json_parsing.bats
bats tests/unit/test_cli_modern.bats
bats tests/unit/test_enable_core.bats
bats tests/unit/test_task_sources.bats
bats tests/unit/test_ralph_enable.bats
bats tests/unit/test_circuit_breaker_recovery.bats
bats tests/unit/test_file_protection.bats
bats tests/unit/test_integrity_check.batsRalph Loop ConfigurationThe loop is controlled by several key files and environment variables within the
Rate Limiting
Modern CLI Configuration (Phase 1.1)Ralph uses modern Claude Code CLI flags for structured communication: Configuration Variables: CLAUDE_CODE_CMD="claude" # Claude Code CLI command (configurable via .ralphrc, Issue #97)
CLAUDE_OUTPUT_FORMAT="json" # Output format: json (default) or text
CLAUDE_ALLOWED_TOOLS="Write,Read,Edit,Bash(git add *),Bash(git commit *),...,Bash(npm *),Bash(pytest)" # Allowed tool permissions (see File Protection)
CLAUDE_USE_CONTINUE=true # Enable session continuity
CLAUDE_MIN_VERSION="2.0.76" # Minimum Claude CLI version
CLAUDE_AUTO_UPDATE=true # Auto-update Claude CLI at startup (set false for air-gapped environments)Auto-Update Configuration:
Claude Code CLI Command (Issue #97):
CLI Options:
Loop Context:
Session Continuity:
Intelligent Exit DetectionThe loop uses a dual-condition check to prevent premature exits during productive iterations: Exit requires BOTH conditions:
The Other exit conditions (checked before completion indicators):
Example behavior when EXIT_SIGNAL is false: Rationale: Natural language patterns like "done" or "complete" can trigger false positives during productive work (e.g., "feature done, moving to tests"). By requiring Claude's explicit EXIT_SIGNAL confirmation, Ralph avoids exiting mid-iteration when Claude is still working. CI/CD PipelineRalph uses GitHub Actions for continuous integration: Workflows (
|
| completion_indicators | EXIT_SIGNAL | .response_analysis | Result |
|---|---|---|---|
| >= 2 | true |
exists | Exit ("project_complete") |
| >= 2 | false |
exists | Continue (Claude still working) |
| >= 2 | N/A | missing | Continue (defaults to false) |
| >= 2 | N/A | malformed | Continue (defaults to false) |
| < 2 | true |
exists | Continue (threshold not met) |
Implementation (ralph_loop.sh:312-327):
local claude_exit_signal="false"
if [[ -f "$RALPH_DIR/.response_analysis" ]]; then
claude_exit_signal=$(jq -r '.analysis.exit_signal // false' "$RALPH_DIR/.response_analysis" 2>/dev/null || echo "false")
fi
if [[ $recent_completion_indicators -ge 2 ]] && [[ "$claude_exit_signal" == "true" ]]; then
echo "project_complete"
return 0
fiConflict Resolution: When STATUS: COMPLETE but EXIT_SIGNAL: false in RALPH_STATUS, the explicit EXIT_SIGNAL takes precedence. This allows Claude to mark a phase complete while indicating more phases remain.
Timeout Handling (Issues #175, #198)
When Claude Code exceeds CLAUDE_TIMEOUT_MINUTES, portable_timeout terminates the process with exit code 124. The loop handles this differently depending on the execution mode:
Live mode (--live/--monitor): The streaming pipeline captures per-command exit codes via PIPESTATUS. Timeout events are logged as a WARN:
[timestamp] [WARN] Claude Code execution timed out after 15 minutes
Background mode (default): The Claude process runs in a background subshell (&). The exit code is captured via wait $claude_pid.
Productive Timeout Detection (Issue #198):
In both modes, when exit code 124 is detected, the timeout handler checks git for actual work done during the execution (comparing HEAD to .loop_start_sha). This prevents treating productive timeouts as failures:
| Timeout + Git State | Result |
|---|---|
| Files changed (committed/staged/unstaged) | Productive timeout: runs full analysis pipeline (save_claude_session, analyze_response, update_exit_signals, record_loop_result), writes timed_out_productive status, returns 0 |
| No files changed | Idle timeout: returns 1 (generic error) |
Session ID Fallback: When the stream is truncated (missing "type":"result" message), session ID is extracted from the "type":"system" message, which is always written first and survives truncation.
API Limit Detection (Issues #183, #100)
The API limit detection uses a four-layer approach to avoid false positives. In stream-json mode, output files contain echoed file content from tool results ("type":"user" lines). If project files mention "5-hour limit", naive grep patterns match those echoed strings, incorrectly triggering the API limit recovery flow.
Layer 1 — Timeout guard:
Exit code 124 (timeout) is checked first. Productive timeouts (files changed) return 0; idle timeouts return 1 (generic error). Neither returns code 2 (API limit).
Layer 2 — Structural JSON detection (primary):
Parses rate_limit_event JSON in the output for "status":"rejected". This is the definitive signal from the Claude CLI.
Layer 3 — Filtered text fallback:
Only searches tail -30 of the output file, filtering out "type":"user", "tool_result", and "tool_use_id" lines before matching text patterns for standard 5-hour limit messages.
Layer 4 — Extra Usage quota (Issue #100):
Detects Claude Code "Extra Usage" mode exhaustion ("You're out of extra usage · resets 9pm"). Uses the same noise filtering as Layer 3.
Unattended mode: When the API limit prompt times out (no user response within 30s), Ralph auto-waits instead of exiting, supporting unattended operation.
Circuit Breaker Thresholds
CB_NO_PROGRESS_THRESHOLD=3- Open circuit after 3 loops with no file changesCB_SAME_ERROR_THRESHOLD=5- Open circuit after 5 loops with repeated errorsCB_OUTPUT_DECLINE_THRESHOLD=70%- Open circuit if output declines by >70%CB_PERMISSION_DENIAL_THRESHOLD=2- Open circuit after 2 loops with permission denials (Issue No Approval Request, silent fail #101)- Question loop suppression (Issue [BUG] Loop persistence misidentified as active session despite "completed" status in progress.json #190): When
asking_questions=true, theconsecutive_no_progresscounter is held steady (not incremented). This prevents the circuit breaker from opening prematurely when Claude asks questions in headless mode. A corrective message is injected viabuild_loop_context()in the next loop iteration.
Circuit Breaker Auto-Recovery (Issue #160)
The OPEN state is no longer terminal. Two recovery mechanisms are available:
Cooldown Timer (default): After CB_COOLDOWN_MINUTES (default: 30) in OPEN state, the circuit transitions to HALF_OPEN on next init_circuit_breaker() call. The existing HALF_OPEN logic handles recovery (progress → CLOSED) or re-trip (no progress → OPEN).
Auto-Reset: When CB_AUTO_RESET=true, the circuit resets directly to CLOSED on startup, bypassing the cooldown. Use for fully unattended operation.
Configuration:
CB_COOLDOWN_MINUTES=30 # Minutes before OPEN → HALF_OPEN (0 = immediate)
CB_AUTO_RESET=false # true = bypass cooldown, reset to CLOSED on startupCLI flag: ralph --auto-reset-circuit sets CB_AUTO_RESET=true for a single run.
State file: The opened_at field tracks when the circuit entered OPEN state. Old state files without this field fall back to last_change for backward compatibility.
Permission Denial Detection (Issue #101)
When Claude Code is denied permission to execute commands (e.g., npm install), Ralph detects this from the permission_denials array in the JSON output and halts the loop immediately:
- Detection: The
parse_json_response()function extractspermission_denialsfrom Claude Code output - Fields tracked:
has_permission_denials(boolean)permission_denial_count(integer)denied_commands(array of command strings)
- Exit behavior: When
has_permission_denials=true, Ralph exits with reason "permission_denied" - User guidance: Ralph displays instructions to update
ALLOWED_TOOLSin.ralphrc
Example .ralphrc tool patterns:
# Broad patterns (recommended for development)
ALLOWED_TOOLS="Write,Read,Edit,Bash(git *),Bash(npm *),Bash(pytest)"
# Specific patterns (more restrictive)
ALLOWED_TOOLS="Write,Read,Edit,Bash(git commit),Bash(npm install)"API Error Detection via is_error Field (Issues #134, #199)
The Claude CLI can exit with code 0 but set is_error: true in the JSON output for API-level failures (400 concurrency errors, 401 OAuth token expiry). Ralph detects this before persisting any session state:
- Detection: In
execute_claude_code(), after exit code 0,jqreads.is_errorfrom the output JSON - Session protection: If
is_erroris true, the session is NOT persisted (prevents infinite retry with bad session ID) - Session reset: The session is explicitly reset so the next loop starts fresh
- Specific handling: "tool use concurrency" errors get a targeted reset reason for logging clarity
- Defense in depth:
save_claude_session()independently checksis_erroras a guard, preventing bad sessions even if call order changes in refactors
Error Detection
Ralph uses advanced error detection with two-stage filtering to eliminate false positives:
Stage 1: JSON Field Filtering
- Filters out JSON field patterns like
"is_error": falsethat contain the word "error" but aren't actual errors - Pattern:
grep -v '"[^"]*error[^"]*":'
Stage 2: Actual Error Detection
- Detects real error messages in specific contexts:
- Error prefixes:
Error:,ERROR:,error: - Context-specific errors:
]: error,Link: error - Error occurrences:
Error occurred,failed with error - Exceptions:
Exception,Fatal,FATAL
- Error prefixes:
- Pattern:
grep -cE '(^Error:|^ERROR:|^error:|\]: error|Link: error|Error occurred|failed with error|[Ee]xception|Fatal|FATAL)'
Multi-line Error Matching
- Detects stuck loops by verifying ALL error lines appear in ALL recent history files
- Uses literal fixed-string matching (
grep -qF) to avoid regex edge cases - Prevents false negatives when multiple distinct errors occur simultaneously
File Protection (Issue #149)
Ralph uses a multi-layered strategy to prevent Claude from accidentally deleting its own configuration files:
Layer 1: ALLOWED_TOOLS Restriction
- The default
CLAUDE_ALLOWED_TOOLSuses granularBash(git add *),Bash(git commit *)etc. instead ofBash(git *), preventinggit clean,git rm, and other destructive git commands - Users can override in
.ralphrcbut the defaults are safe
Layer 2: PROMPT.md Warning
- The PROMPT.md template includes a "Protected Files (DO NOT MODIFY)" section listing
.ralph/and.ralphrc - This instructs Claude to never delete, move, rename, or overwrite these files
Layer 3: Pre-Loop Integrity Check
validate_ralph_integrity()fromlib/file_protection.shruns at startup and before every loop iteration- Checks for required paths:
.ralph/,.ralph/PROMPT.md,.ralph/fix_plan.md,.ralph/AGENT.md,.ralphrc - On failure: logs error, displays recovery report, resets session, and halts the loop
- Recovery:
ralph-enable --forcerestores missing files
Required vs Optional Files:
| Required (validation fails) | Optional (no validation) |
|---|---|
.ralph/ directory |
.ralph/logs/ |
.ralph/PROMPT.md |
.ralph/status.json |
.ralph/fix_plan.md |
.ralph/.call_count |
.ralph/AGENT.md |
.ralph/.exit_signals |
.ralphrc |
.ralph/.circuit_breaker_state |
Test Suite
Test Files (584 tests total)
| File | Tests | Description |
|---|---|---|
test_circuit_breaker_recovery.bats |
22 | Cooldown timer, auto-reset, parse_iso_to_epoch, CLI flag (Issue #160) + current_loop init/display fix (#194) |
test_cli_parsing.bats |
35 | CLI argument parsing for all flags + monitor parameter forwarding |
test_cli_modern.bats |
111 | Modern CLI commands (Phase 1.1) + build_claude_command fix + live mode text format fix (#164) + errexit pipeline guard (#175) + ALLOWED_TOOLS tightening (#149) + API limit false positive detection (#183) + Claude CLI command validation (#97) + stale call counter fix (#196) + is_error detection (#134, #199) + set-e removal (#208) + question detection + version check + semver comparison + stderr separation (#190) + productive timeout detection + session ID fallback + stale analysis cleanup (#198) + Extra Usage quota detection (#100) |
test_json_parsing.bats |
52 | JSON output format parsing + Claude CLI format + session management + array format + question detection (#190) |
test_session_continuity.bats |
26 | Session lifecycle management + expiration + circuit breaker integration + issue #91 fix |
test_exit_detection.bats |
54 | Exit signal detection + EXIT_SIGNAL-based completion indicators + progress detection + question detection integration (#190) + stale exit signal prevention (#194) |
test_rate_limiting.bats |
11 | Rate limiting behavior |
test_loop_execution.bats |
20 | Integration tests |
test_edge_cases.bats |
25 | Edge case handling |
test_installation.bats |
15 | Global installation/uninstall workflows + dotfile template copying (#174) |
test_project_setup.bats |
50 | Project setup (setup.sh) validation + .ralphrc permissions + .gitignore (#174) |
test_prd_import.bats |
33 | PRD import (ralph_import.sh) workflows + modern CLI tests |
test_enable_core.bats |
38 | Enable core library (idempotency, project detection, template generation, .gitignore #174) |
test_task_sources.bats |
23 | Task sources (beads, GitHub, PRD extraction, normalization) |
test_ralph_enable.bats |
24 | Ralph enable integration tests (wizard, CI version, JSON output, .ralphrc validation #149) |
test_wizard_utils.bats |
20 | Wizard utility functions (stdout/stderr separation, prompt functions) |
test_file_protection.bats |
15 | File integrity validation (RALPH_REQUIRED_PATHS, validate_ralph_integrity, get_integrity_report) (Issue #149) |
test_integrity_check.bats |
10 | Pre-loop integrity check in ralph_loop.sh (startup + in-loop validation) (Issue #149) |
Running Tests
# All tests
npm test
# Unit tests only
npm run test:unit
# Specific test file
bats tests/unit/test_cli_parsing.batsFeature Development Quality Standards
CRITICAL: All new features MUST meet the following mandatory requirements before being considered complete.
Testing Requirements
- Test Pass Rate: 100% - all tests must pass, no exceptions
- Test Types Required:
- Unit tests for bash script functions (if applicable)
- Integration tests for Ralph loop behavior
- End-to-end tests for full development cycles
- Test Quality: Tests must validate behavior, not just achieve coverage metrics
- Test Documentation: Complex test scenarios must include comments explaining the test strategy
Note on Coverage: The 85% coverage threshold is aspirational for bash scripts. Due to kcov subprocess limitations, test pass rate is the enforced quality gate.
E2E Testing Philosophy (v2 UI)
When Ralph introduces a web-based UI (v2), end-to-end testing is the primary quality gate for all frontend work:
- Framework: Playwright for all browser automation and E2E tests
- Real services only: E2E tests run against real backends — no mocked APIs or stubbed services
- User journey coverage: Every user-facing workflow must have at least one E2E test covering the happy path
- Visual regression: Use Playwright screenshot comparisons for layout-critical components
- Accessibility: Include automated a11y checks (e.g.,
@axe-core/playwright) in E2E runs - CI integration: E2E tests must pass in the GitHub Actions pipeline before merge
Git Workflow Requirements
Before moving to the next feature, ALL changes must be:
-
Committed with Clear Messages:
git add . git commit -m "feat(module): descriptive message following conventional commits"
- Use conventional commit format:
feat:,fix:,docs:,test:,refactor:, etc. - Include scope when applicable:
feat(loop):,fix(monitor):,test(setup): - Write descriptive messages that explain WHAT changed and WHY
- Use conventional commit format:
-
Pushed to Remote Repository:
git push origin <branch-name>
- Never leave completed features uncommitted
- Push regularly to maintain backup and enable collaboration
- Ensure CI/CD pipelines pass before considering feature complete
-
Branch Hygiene:
- Work on feature branches, never directly on
main - Branch naming convention:
feature/<feature-name>,fix/<issue-name>,docs/<doc-update> - Create pull requests for all significant changes
- Work on feature branches, never directly on
-
Ralph Integration:
- Update .ralph/fix_plan.md with new tasks before starting work
- Mark items complete in .ralph/fix_plan.md upon completion
- Update .ralph/PROMPT.md if Ralph's behavior needs modification
- Test Ralph loop with new features before completion
Documentation Requirements
ALL implementation documentation MUST remain synchronized with the codebase:
-
Script Documentation:
- Bash: Comments for all functions and complex logic
- Update inline comments when implementation changes
- Remove outdated comments immediately
-
Implementation Documentation:
- Update relevant sections in this CLAUDE.md file
- Keep template files in
templates/current - Update configuration examples when defaults change
- Document breaking changes prominently
-
README Updates:
- Keep feature lists current
- Update setup instructions when commands change
- Maintain accurate command examples
- Update version compatibility information
-
Template Maintenance:
- Update template files when new patterns are introduced
- Keep PROMPT.md template current with best practices
- Update AGENT.md template with new build patterns
- Document new Ralph configuration options
-
CLAUDE.md Maintenance:
- Add new commands to "Key Commands" section
- Update "Exit Conditions and Thresholds" when logic changes
- Keep installation instructions accurate and tested
- Document new Ralph loop behaviors or quality gates
Feature Completion Checklist
Before marking ANY feature as complete, verify:
- All tests pass (if applicable)
- Script functionality manually tested
- All changes committed with conventional commit messages
- All commits pushed to remote repository
- CI/CD pipeline passes
- .ralph/fix_plan.md task marked as complete
- Implementation documentation updated
- Inline code comments updated or added
- CLAUDE.md updated (if new patterns introduced)
- Template files updated (if applicable)
- Breaking changes documented
- Ralph loop tested with new features
- Installation process verified (if applicable)
Rationale
These standards ensure:
- Quality: Thorough testing prevents regressions in Ralph's autonomous behavior
- Traceability: Git commits and fix_plan.md provide clear history of changes
- Maintainability: Current documentation reduces onboarding time and prevents knowledge loss
- Collaboration: Pushed changes enable team visibility and code review
- Reliability: Consistent quality gates maintain Ralph loop stability
- Automation: Ralph integration ensures continuous development practices
Enforcement: AI agents should automatically apply these standards to all feature development tasks without requiring explicit instruction for each task.
|
{ |
|
Review — Building on Prior Feedback The core fix is solid (covered well in previous reviews). This note focuses on what still needs to land before merge. Blockers per project CLAUDE.md standards The Feature Completion Checklist in CLAUDE.md explicitly requires documentation to stay in sync. Two items remain open: 1. CLAUDE.md — Modern CLI Configuration section CLAUDE_MODEL and CLAUDE_EFFORT should be listed alongside the existing config variable table (around the CLAUDE_AUTO_UPDATE entry): 2. templates/ralphrc.template and lib/enable_core.sh — generated .ralphrc New users running ralph-enable or ralph-setup get a .ralphrc with no hint these options exist. Adding commented-out entries in the Advanced Settings block would make them discoverable. Example: Non-blocking: CLAUDE_EFFORT validation Previous reviews flagged this. A lightweight guard in build_claude_command() that logs a warning without blocking would be ideal. Warn-only is the right default since the CLI may add new values without notice. One test observation The CLAUDE_CODE_CMD regression test uses grep on the script file and checks output with a glob match. This would also pass if the expected string appeared inside a comment. Excluding comment lines before matching would make the test more precise. Summary: Bug fix is correct, tests are thorough. Documentation gaps (CLAUDE.md + template files) are the only items required by the project's own standards before merge. Effort validation is a nice-to-have follow-up. |
Code Review: PR #231✅ Implementation QualityThe core implementation is solid and follows established patterns correctly:
|
|
Review comment posted: #231 (comment) |
|
Follow-up review: CLAUDE.md documentation has been updated as requested. The implementation is correct and tests are solid. One optional improvement: add a combined test for --model and --effort being set simultaneously. Ready to merge. |
|
Deleting the placeholder above — full review below. |


Summary
Fixes #228 —
.ralphrcCLAUDE_CODE_CMDwas silently ignored; any custom value was always overwritten by the hardcoded"claude"default.Root cause:
CLAUDE_CODE_CMD="claude"was assigned unconditionally at line 27, before the env snapshot block at line 46. So_env_CLAUDE_CODE_CMDalways captured"claude"(never empty), and theload_ralphrc()restore at line 158 always overwrote the.ralphrcvalue with"claude".Fix: Remove the unconditional line-27 assignment.
CLAUDE_CODE_CMDis now set with${CLAUDE_CODE_CMD:-claude}after the env snapshot, consistent withMAX_CALLS_PER_HOUR,CLAUDE_OUTPUT_FORMAT, and all other tunables.Bonus (requested in issue): Adds
CLAUDE_MODELandCLAUDE_EFFORTconfig variables:These are passed as
--model/--effortflags to the Claude CLI. Env vars take precedence over.ralphrc(same pattern as all other vars).Changes
ralph_loop.sh— moveCLAUDE_CODE_CMDdefault to after env snapshot; addCLAUDE_MODEL/CLAUDE_EFFORTsnapshot, defaults,load_ralphrc()restore, andbuild_claude_command()flagstests/unit/test_cli_modern.bats— 8 new tests + update test stubsTest plan
CLAUDE_CODE_CMDdefault uses${:-}parameter expansion (not unconditional assignment).ralphrcCLAUDE_CODE_CMDis respected when no env var is exportedCLAUDE_MODELloads from.ralphrc; env var overrides itCLAUDE_EFFORTloads from.ralphrcbuild_claude_commandadds--modelflag whenCLAUDE_MODELis setbuild_claude_commandadds--effortflag whenCLAUDE_EFFORTis setSummary by CodeRabbit
New Features
Documentation
Tests