* fix: preserve file/line info in PR review extraction recovery
When the follow-up orchestrator's structured output fails schema
validation, the Tier 2 recovery path now preserves file paths and line
numbers instead of hard-coding "unknown:0" for all recovered findings.
- Add ExtractedFindingSummary model with severity, description, file, line
- Update FollowupExtractionResponse to use structured summaries
- Add severity_override, file, line params to create_finding_from_summary()
- Update extraction prompt to request file/line in summaries
- Add tests for new model and create_finding_from_summary params
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix: update followup_reviewer.py to use ExtractedFindingSummary objects
The shared FollowupExtractionResponse.new_finding_summaries was changed
from list[str] to list[ExtractedFindingSummary] but followup_reviewer.py
was not updated, causing a runtime crash (AttributeError on .upper()).
- Destructure ExtractedFindingSummary in followup_reviewer.py loop
- Update extraction prompt to request structured summaries
- Add severity field_validator to ExtractedFindingSummary for consistency
- Deduplicate severity_map in recovery_utils.py using _EXTRACTION_SEVERITY_MAP
- Update stale docstrings in both followup reviewers
Co-Authored-By: Claude Opus 4.6 <[email protected]>
* test: tighten schema size threshold with empirical justification
Actual extraction/full schema ratio is ~50.7%. Set threshold at 55%
(was overly relaxed to 67%) to guard against future schema bloat
while providing reasonable headroom.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
---------
Co-authored-by: Claude Opus 4.6 <[email protected]>