Skip to content

Bug: completion_indicators exit check ignores Claude's explicit EXIT_SIGNAL: false #88

@amgohan

Description

@amgohan

Description

Ralph exits prematurely after 2 loops based on confidence-scoring heuristics, even when Claude explicitly reports EXIT_SIGNAL: false in the RALPH_STATUS block. This prevents projects requiring multiple iterations from running to completion.

Environment

  • Ralph Version: v0.9.8
  • OS: macOS / Linux
  • Shell: Bash

Steps to Reproduce

  1. Create a project with iterative stop conditions (e.g., quality score >= 95%)
  2. Run Ralph: ralph --timeout 30 --allowed-tools "Write,Edit,Read,Bash(*)" --verbose
  3. Observe Claude doing productive work and reporting:
    ---RALPH_STATUS---
    STATUS: IN_PROGRESS
    EXIT_SIGNAL: false
    RECOMMENDATION: Continue processing...
    ---END_RALPH_STATUS---
    
  4. Ralph exits after 2 loops with: Exit condition: Strong completion indicators (2)

Expected Behavior

Ralph should respect Claude's explicit EXIT_SIGNAL: false and continue iterating until Claude reports EXIT_SIGNAL: true (indicating project requirements are met).

Actual Behavior

Ralph exits after 2 loops regardless of Claude's EXIT_SIGNAL value. The .response_analysis file shows:

{
  "analysis": {
    "exit_signal": false,
    "has_completion_signal": false,
    "confidence_score": 70
  }
}

Despite exit_signal: false, Ralph triggers exit because confidence_score >= 60 adds the loop to completion_indicators, and 2+ indicators triggers exit.

Root Cause

In ralph_loop.sh, the should_exit_gracefully() function (~line 313) checks:

if [[ $recent_completion_indicators -ge 2 ]]; then
    log_status "WARN" "Exit condition: Strong completion indicators ($recent_completion_indicators)"
    echo "project_complete"
    return 0
fi

This check does not consult Claude's explicit exit_signal from .response_analysis. The confidence scoring triggers on natural language patterns like "Complete", "Perfect", "successfully" - even during productive IN_PROGRESS iterations.

Proposed Fix

Modify the completion indicators check to respect Claude's explicit EXIT_SIGNAL:

# 3. Strong completion indicators (only if Claude's EXIT_SIGNAL is true)
local claude_exit_signal="false"
if [[ -f ".response_analysis" ]]; then
    claude_exit_signal=$(jq -r '.analysis.exit_signal // false' ".response_analysis" 2>/dev/null || echo "false")
fi

if [[ $recent_completion_indicators -ge 2 ]] && [[ "$claude_exit_signal" == "true" ]]; then
    log_status "WARN" "Exit condition: Strong completion indicators ($recent_completion_indicators) with EXIT_SIGNAL=true" >&2
    echo "project_complete"
    return 0
elif [[ $recent_completion_indicators -ge 2 ]]; then
    log_status "INFO" "DEBUG: Completion indicators ($recent_completion_indicators) but EXIT_SIGNAL=false, continuing..." >&2
fi

Important: The >&2 is critical - without it, log_status output goes to stdout and gets captured as the function's return value (non-empty = exit reason), causing unintended exits.

Behavior After Fix

Scenario completion_indicators EXIT_SIGNAL Result
Work in progress >= 2 false Continue (fixed)
Project complete >= 2 true Exit
Early iterations < 2 false Continue

Verified Fix

I've tested this fix on a documentation refinement project:

  • Before fix: Exited after 2-3 loops at 65% quality
  • After fix: Ran 17+ loops, reached 94% quality and continuing

Related Files

  • ralph_loop.sh - should_exit_gracefully() function
  • lib/response_analyzer.sh - Parses RALPH_STATUS and populates .response_analysis
  • .response_analysis - Contains exit_signal from Claude
  • .exit_signals - Tracks completion_indicators array

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions