When the agent emits no promise signal, check_output returns 1 (continue).
Under set -euo pipefail, a bare function call returning non-zero exits the
script before status=$? can capture it. Fix: use the || idiom so the
non-zero return is handled rather than triggering set -e.
Agent: human
Tests: N/A
Tests-Added: 0
TypeScript: N/A
Supersedes the simple polling version written this session. The master
harness version (from the other machine) has:
Tier 1 — Anthropic API probe via ANTHROPIC_API_KEY if available
Tier 2 — Parse reset time from agent output ("resets 11am America/New_York")
Tier 3 — Seeded --session-ends timestamp argument
Tier 4 — Fixed fallback sleep (--retry-wait, default 1800s)
Agent: human
Tests: N/A
Tests-Added: 0
TypeScript: N/A
When claude -p hits the Pro subscription usage limit, the old loop had
no detection — it would find no <promise> signal, treat it as a normal
continuation, and immediately retry, burning all --max iterations.
New behaviour:
- check_output() returns status 4 when the log contains any usage/rate
limit message (case-insensitive, multiple pattern variants)
- wait_for_session_reset() polls via a trivial probe call every
SESSION_POLL_INTERVAL seconds (default: 600s / 10 min) until claude
responds cleanly again
- When rate-limited, the same iteration is retried (i is not incremented)
so no task is skipped or double-counted
- set -e is temporarily suspended around agent calls so a non-zero claude
exit doesn't kill the bash process
Also updated the master template in docs/agent-harness/ralph-loop.sh.
Agent: human
Tests: N/A
Tests-Added: 0
TypeScript: N/A
Adds the ralph loop harness artifacts to drive autonomous implementation
of Phase 2. State lives in IMPLEMENTATION_PLAN.md so work survives
session resets — restart ralph-loop.sh after token refresh and the next
agent reads the plan to pick up where it left off.
Agent: human
Tests: N/A
Tests-Added: 0
TypeScript: N/A