fix(review): salvage findings from nested-object fences + bare arrays + unfenced tail JSON

The canalhandia PR review lost all findings because the agent ran out of
context before emitting the closing json fence. Three failure modes hit
the old regex \{.*?\}:
  * nested objects inside the fence truncated at the first }
  * bare arrays (no {summary, findings} wrapper) returned []
  * unfenced JSON in the prose tail was never reached (first not last)

Replace the regex with a balanced-brace scanner:
  * _last_json_block walks the fence contents with a depth counter so
    nested objects survive
  * _last_balanced_json + _balanced_json_substring handle bare arrays and
    prose-tail JSON when no fence is present
  * _parse_json_tolerant returns list as well as dict; parse_findings and
    parse_review_output accept a bare array as the outer value

Agent prompt tightened: reserve the final step for emitting the JSON
block so the analysis isn't lost when context runs out.

10 new tests in tests/pilot/test_ai_review.py cover the new shapes.
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Marcos
2026-08-20 16:29:44 +00:00
parent ec26ec000a
commit 5302e8dcd7
4 changed files with 280 additions and 27 deletions
+1 -1
View File
@@ -103,7 +103,7 @@ def compress_diff(diff: str, *, context: int = 2) -> tuple[str, int, int]:
def _render_hunk_body(body: list[str], *, context: int) -> tuple[list[str], int]:
"""Trim `body` to `context` unchanged lines around the +/- lines.
r"""Trim `body` to `context` unchanged lines around the +/- lines.
Body lines are classified:
- `+` line → keep