fix(pr-review): robustly extract JSON from codex CLI transcript output The codex reviewer (gautam-chatgpt) intermittently failed with "No valid JSON found in response" on gbharg/pi-mono PRs #28-32. Root cause: `codex exec` can frame its answer with a session transcript, a leading `codex` marker line, and a trailing token-usage epilogue, and that surrounding prose often contains stray `{`/`}` (shell snippets, file trees, JSON examples in skill docs). The old parser used a naive first-`{`/last-`}` slice, which captured the prose braces and threw — explaining why the same PR sometimes parsed and sometimes did not. parse-response.js now: - scans for balanced `{...}` spans with a string-aware stack (immune to stray/unbalanced braces in surrounding prose), and - prefers the LAST review-shaped object (codex prints the answer last), and - falls back to a quote-insensitive rescan when prose has an unmatched `"` that would otherwise hide the real object inside a phantom string. - adds parseReviewWithRepair(): one repair re-ask demanding pure JSON (faithful conversion, no fabricated findings) as a last-resort safety net for truly truncated/empty output. review-handler.js calls parseReviewWithRepair (shared by codex/gemini/ claude). gemini/claude emit clean or fenced JSON and are unaffected. Verified against the real captured codex transcript (full 19KB session log on stdout) — now extracts the correct review. Added tests for the transcript/fenced/stray-brace cases and the repair retry. 95/95 green. Co-Authored-By: Claude Opus 4.8