v0.4.2
Fixed
- A pipeline failure is no longer reported as a clean review. When the orchestrator produced no parseable findings (exit code 2),
finalizeReviewstill wrote a normal zero-findingpr-review-summary.mdand adoneprogress event — andstatustreats the summary's existence as "done, exit 0", so a detached run that failed presented as a clean PR. OnfindingsUnavailablethe run now writes the failure toerror.txtinstead of minting the summary, emits anerrorprogress event, andstatusreportsfailed(exit 22) with the message inline. Codex second-opinion findings collected before the failure are still posted, and the exit code stays 2. - Stdout salvage now recovers findings from a narrated orchestrator transcript. The JSON parser extracted exactly one value — the first fenced block or the earliest
[/{, which a prose bracket like[security]could win, defeating the whole parse.parseJsonFindingsnow merges findings from every JSON block in the blob (all fenced blocks — excised so nothing parses twice — then every balanced value, with structural recursion reaching nested payloads) and also understands the orchestrator's own{"reviewers":[{"name":…,"findings":[…]}]}file payload printed to stdout instead of written. Values found loose in prose must pass a strict finding-shape gate, so quoted log objects are not minted into findings. orchestrator-failure.lognow keeps the orchestrator's full stdout/stderr (was: last 8 KB tails). When the contract fails, stdout may hold the only copy of the reviewer findings, and a tail made even manual salvage impossible.statusno longer reportsinterrupted(with a dead-end--resumehint) when the findings file on disk is corrupt. Theinterruptedstate now requires a resumable output file — one that parses to the{reviewers:[…]}shape--resumeactually loads. A truncated/corrupt file falls through tofailedwitherror.txtsurfaced inline; a validphase1-findings.jsonfallback still readsinterruptedbecause resume genuinely recovers it. (Found by running this release's own reviewer against its PR.)
Full details: #10
🤖 Generated with Claude Code