Skip to content

feat(ralph): Simplified loop with Claude Code hooks - #11

Merged
AskTinNguyen merged 6 commits into
mainfrom
feat/simplified-ralph-loop-hooks
Jan 21, 2026
Merged

AskTinNguyen merged 6 commits into
mainfrom
feat/simplified-ralph-loop-hooks

Conversation

@AskTinNguyen

Copy link
Copy Markdown
Owner

Summary

Implements a minimal Ralph loop (~200 lines) with hook-based enforcement, achieving a 5x reduction from the original 4,244-line loop.sh.

Key changes:

  • simplified-loop.sh: Core iteration loop with signal handling, timeout, atomic checkpoints
  • lib/minimal.sh: Essential utilities (logging, atomic write, story management)
  • hooks/pre-tool.sh: PreToolUse validation (Edit requires Read, blocks git push/merge/force)
  • hooks/post-tool.sh: PostToolUse test failure detection (Jest/pytest/Go/Mocha/RSpec/Bats)
  • hooks/on-stop.sh: Stop hook for completion state and cleanup
  • hooks/pre-prompt.sh: UserPromptSubmit hook for session management

Design principles:

  • All enforcement delegated to Claude Code hooks (not inline validation)
  • Hooks ALWAYS exit 0 (never break Claude Code)
  • Atomic file operations for race-condition safety
  • Comprehensive test failure patterns for 7+ frameworks

Test plan

  • 23 unit tests passing (./tests/simplified-loop.test.sh)
  • Tests cover: hook validation, test failure detection, file operations
  • Security fixes for path traversal, log injection, sed escaping

Line count comparison

Component Original Simplified Reduction
Core loop 4,244 204 95%
Total (with hooks) 4,244+ 805 81%

Compound Engineered 🤖 Generated with Claude Code

AskTinNguyen and others added 2 commits January 21, 2026 22:09
Implements a minimal Ralph loop (~200 lines) with hook-based enforcement:

- simplified-loop.sh: Core iteration loop with signal handling, timeout
- lib/minimal.sh: Essential utilities (logging, atomic write, story mgmt)
- hooks/pre-tool.sh: PreToolUse validation (Edit requires Read, blocks git push)
- hooks/post-tool.sh: PostToolUse test failure detection (Jest/pytest/Go/etc)
- hooks/on-stop.sh: Stop hook for completion state and cleanup
- hooks/pre-prompt.sh: UserPromptSubmit hook for session management

Key improvements:
- 5x smaller than original loop.sh (805 vs 4,244 lines)
- All enforcement via hooks (not inline validation)
- Comprehensive test failure patterns for 7+ frameworks
- All hooks exit 0 (never break Claude Code)
- Atomic file operations for race-condition safety

Test coverage: 20 tests, all passing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Validate PRD_NUMBER to prevent path traversal attacks
- Escape sed special characters (& and \) in template substitution
- Sanitize session log entries to prevent log injection
- Add tests for git --force blocking and Edit/Write validation

Security improvements identified during code review.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jan 21, 2026

Copy link
Copy Markdown

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk - implements critical security fixes and comprehensive test coverage
  • Score reflects thorough security hardening (path traversal prevention, log injection fixes, sed escaping), robust error handling, comprehensive test coverage (23 passing tests), and proper platform compatibility. The hook-based architecture is well-designed with proper exit code handling to avoid breaking Claude Code.
  • No files require special attention - all core files have been security-reviewed and tested

Important Files Changed

Filename Overview
.agents/ralph/simplified-loop.sh Core loop implementation with proper error handling, signal management, and security validation (PRD number validation prevents path traversal)
.agents/ralph/lib/minimal.sh Utility functions with proper sed escaping for security; includes platform detection for macOS/Linux compatibility in mark_story_complete
.agents/ralph/hooks/pre-tool.sh PreToolUse validation hook with log injection prevention and git command blocking; uses fixed-string grep for security
.agents/ralph/hooks/post-tool.sh PostToolUse hook with comprehensive test failure detection for 7+ frameworks (Jest, pytest, Go, Mocha, RSpec, Bats, npm); includes rollback and failure logging
tests/simplified-loop.test.sh Comprehensive test suite with 23 unit tests covering hooks, utilities, and test failure detection patterns

Sequence Diagram

sequenceDiagram
    participant User
    participant SimplifiedLoop
    participant PrePromptHook
    participant PreToolHook
    participant ClaudeAgent
    participant PostToolHook
    participant StopHook
    participant GitRepo

    User->>SimplifiedLoop: Start build
    SimplifiedLoop->>SimplifiedLoop: Validate PRD
    SimplifiedLoop->>SimplifiedLoop: Select story
    SimplifiedLoop->>GitRepo: Save checkpoint
    
    SimplifiedLoop->>PrePromptHook: UserPromptSubmit
    PrePromptHook->>PrePromptHook: Clear session log
    PrePromptHook-->>SimplifiedLoop: Success
    
    SimplifiedLoop->>ClaudeAgent: Execute agent
    
    ClaudeAgent->>PreToolHook: Read file
    PreToolHook-->>ClaudeAgent: Allow
    
    ClaudeAgent->>PreToolHook: Edit file
    PreToolHook->>PreToolHook: Check session log
    PreToolHook-->>ClaudeAgent: Allow or Block
    
    ClaudeAgent->>PreToolHook: Git push
    PreToolHook-->>ClaudeAgent: Block
    
    ClaudeAgent->>PostToolHook: After tool use
    PostToolHook->>PostToolHook: Check test failures
    PostToolHook->>GitRepo: Rollback if failed
    PostToolHook-->>ClaudeAgent: Success
    
    ClaudeAgent->>StopHook: Session ends
    StopHook->>StopHook: Cleanup files
    StopHook-->>SimplifiedLoop: Complete
    
    SimplifiedLoop->>GitRepo: Commit changes
    SimplifiedLoop->>SimplifiedLoop: Mark story done
    SimplifiedLoop-->>User: Build complete
Loading

AskTinNguyen and others added 4 commits January 21, 2026 23:29
- Update README.md with simplified loop section and hooks configuration
- Update CLAUDE.md with simplified loop usage and file structure
- Update .agents/ralph/README.md with hooks reference table
- Fix post-tool.sh test failure detection patterns
- Add comprehensive test fixtures for multi-framework test detection
- All 23 tests passing

Co-Authored-By: Claude <noreply@anthropic.com>
- High-level system architecture (mermaid)
- Hook execution flow sequence diagram
- Data flow diagram
- Story lifecycle state machine
- Security considerations (10 attack vectors)
- Performance benchmarks
- Migration guide from legacy loop

Co-Authored-By: Claude <noreply@anthropic.com>
- Fix command injection via sed regex in mark_story_complete
- Enhance git command blocking to prevent bypass attempts
- Complete log injection sanitization (remove ANSI escapes)
- Add lock-based checkpoint protection against TOCTOU race
- Fix regex injection in on-stop.sh hook
- Add MAX_ITERATIONS upper bound validation

Security improvements:
- Story IDs now validated against strict US-NNN pattern
- Git push/merge detection catches subshells, scripts, base64
- All control characters stripped from log entries
- Exclusive lock prevents concurrent agent execution

Tests: All 33 tests pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The flock command is not available on macOS by default. Added fallback
support for:
- flock (Linux, GNU coreutils)
- shlock (macOS, some BSD systems)
- PID-based fallback (universal)

This ensures the TOCTOU race condition protection works across all
platforms.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@AskTinNguyen

Copy link
Copy Markdown
Owner Author

Code Review & Testing Complete ✅

Test Results

All 33 tests passing:

Tests: 33 | Passed: 33 | Failed: 0

Security Improvements Applied

Following comprehensive code review, these security enhancements were implemented:

Finding Fix Commit
sed regex injection Strict US-NNN validation 1a1f743
git command bypass Enhanced detection patterns 1a1f743
log injection (ANSI escapes) Control character stripping 1a1f743
TOCTOU race condition Cross-platform file locking ef0c192
regex injection in on-stop grep -F fixed strings 1a1f743
MAX_ITERATIONS unbounded Upper bound validation (100) 1a1f743

Cross-Platform Support

  • Linux: Uses flock for file locking
  • macOS: Uses shlock or PID-based fallback
  • All platforms: Atomic file operations via temp+mv

Demo (dry-run)

$ .agents/ralph/simplified-loop.sh --dry-run --prd=1
[23:47:34] Starting simplified loop (PRD-1, max 25 iterations)
[23:47:34] Acquired exclusive lock for agent execution
[23:47:34] === Iteration 1/25 ===
[23:47:34] ✓ All stories complete!

🤖 Reviewed and tested with Claude Code

@AskTinNguyen
AskTinNguyen merged commit d6cc5a3 into main Jan 21, 2026
3 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant