fix(exit-detection): use explicit EXIT_SIGNAL instead of confidence threshold (#132)

Replace confidence-based heuristic in update_exit_signals() with explicit
EXIT_SIGNAL checking. JSON mode always has confidence >= 70 due to
deterministic scoring, causing completion_indicators to fill after 5 loops
and triggering premature exits even when Claude sets EXIT_SIGNAL: false.

Changes:
- lib/response_analyzer.sh: Check exit_signal == "true" instead of
  confidence >= 60 when updating completion_indicators array
- ralph_loop.sh: Update safety circuit breaker comment to reflect that
  completion_indicators now only accumulates on EXIT_SIGNAL=true
- tests/unit/test_exit_detection.bats: Add 4 TDD tests (32-35) validating
  the fix for update_exit_signals() behavior
- CLAUDE.md: Document fix as v0.11.1, update test counts (420 → 424)

Test count: 424 passing (100% pass rate)

Co-authored-by: Test User <test@example.com>
This commit is contained in:
Frank Bria 2026-01-26 16:41:05 -07:00 committed by GitHub
parent c7e7a1c6a3
commit f6fde6780b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 209 additions and 10 deletions

View file

@ -384,12 +384,14 @@ should_exit_gracefully() {
return 0
fi
# 3. Safety circuit breaker - force exit after 5 consecutive completion indicators
# Bug #2 Fix: Prevents infinite loops when EXIT_SIGNAL is not explicitly set
# but completion patterns clearly indicate work is done. Threshold of 5 is higher
# than normal threshold (2) to avoid false positives while preventing API waste.
# 3. Safety circuit breaker - force exit after 5 consecutive EXIT_SIGNAL=true responses
# Note: completion_indicators only accumulates when Claude explicitly sets EXIT_SIGNAL=true
# (not based on confidence score). This safety breaker catches cases where Claude signals
# completion 5+ times but the normal exit path (completion_indicators >= 2 + EXIT_SIGNAL=true)
# didn't trigger for some reason. Threshold of 5 prevents API waste while being higher than
# the normal threshold (2) to avoid false positives.
if [[ $recent_completion_indicators -ge 5 ]]; then
log_status "WARN" "🚨 SAFETY CIRCUIT BREAKER: Force exit after 5 consecutive completion indicators ($recent_completion_indicators)" >&2
log_status "WARN" "🚨 SAFETY CIRCUIT BREAKER: Force exit after 5 consecutive EXIT_SIGNAL=true responses ($recent_completion_indicators)" >&2
echo "safety_circuit_breaker"
return 0
fi