The quota detector grepped `cat "$LOG" "$ERR"` for strings like "429" and "usage
limit". $LOG holds the worker's final JSON, including its .result prose — so a
worker whose TASK was about HTTP 429 finished successfully, wrote a report saying
so, and the runner read its own worker's words, logged "QUOTA hit", slept 600s
and was about to --resume a session that had already succeeded. That would have
burned quota redoing finished work with a fresh worker loose on a completed tree.
Two independent defences, because either alone suffices:
- the blob is now stderr plus the result text ONLY when is_error is true,
falling back to the whole log when it isn't valid JSON (a hard crash writes
no JSON, and has no prose to be confused by).
- the success check runs BEFORE the quota and session-vanished checks. A
finished worker is finished regardless of what strings its output contains.
Regression-checked against the real logs/I-gbkey.json that triggered this: the
old logic matches the quota pattern, the new logic yields SUCCESS.
Recorded as HAZARD #9 in docs/HANDOFF.md.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>