e0788a4675
Bug: inferOutcome flagged `blocked` whenever errorCount > retryCount across the turn's events. But the parser emits an `error` event for ANY tool_result with is_error=true — including expected failures: TDD failing-test-first, grep returning nothing, git commands with intentional non-zero exit. On TDD-heavy turns (project's standard discipline) this systematically marked turns as blocked even when they ended on a successful tool_use. Fix: - Parser (extractProcessEvents): walk turn from end, find the LAST tool_result; if its is_error=true, emit a single `unrecovered_error` event. Distinguishes "turn ended on failure" from "errors recovered later". The original per-is_error `error` events remain (useful as raw factor signals). - Analyzer (inferOutcome): replace `errorCount > retryCount → blocked` with `events.some(kind === 'unrecovered_error') → blocked`. Same ordering preserved (interrupt > blocked > rework/success/unknown). Tests: - Parser: emits unrecovered_error when last tool_result is_error; does NOT emit when turn ended on a successful tool_result; does NOT emit for turns with no tool_results. - Analyzer: blocked iff unrecovered_error event present (not raw count); events=[error, error, retry] → success (no unrecovered_error). 142/142 vitest green (was 128). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>