When a developer pushes a fix after an initial review, Codehawk detects which prior findings were addressed and closes the corresponding PR threads. The summary shows a before/after score comparison.
On re-push, the agent performs a delta-only review: it reviews only the git diff between the old and new head commits, not the full PR diff. This keeps the review focused and reduces tool call usage.
The agent also runs fix verification (Step 6 of review-pr-core.md):
- Fetch the existing cr-ids from current PR threads.
- For each prior finding, classify it as:
fixed— change addressed the issuestill_present— issue remains in the new diffnot_relevant— file changed so much the finding no longer applies
- Write
fix_verifications[]intofindings.json.
When fix_verifications[] is present in findings.json, post_findings.py:
- Resolves/closes threads for "fixed" items (ADO:
PostFixReplyActivity; GitHub: reply with "Fixed" viagh api). - Generates a before/after score comparison using
ScoreComparisonService. - Includes the score comparison in the updated summary comment.
{
"pr_id": 42,
"fix_verifications": [
{"cr_id": "abc12345", "status": "fixed", "reason": "Null check added on line 17"},
{"cr_id": "def67890", "status": "still_present", "reason": "Input still not sanitized"}
],
"findings": [...]
}GitHub has no native thread resolution API (unlike ADO). Resolution is handled by:
- Replying to the comment with "Fixed" via
gh api repos/{repo}/pulls/comments/{id}/replies. - Optionally minimizing the comment via GraphQL (not yet implemented; planned for a future sprint).
Developers can reply to a CodeHawk comment thread with a reason explaining why the finding is invalid. On the next push, CodeHawk evaluates each dismissal:
- The fix verifier reads developer replies from existing PR threads.
- Each dismissal is evaluated per-file using a deterministic LLM call (not the agent loop).
- If the reasoning is valid, the finding is classified as
dismissedinfix_verifications[]. post_findings.pyposts an acceptance reply and resolves the thread withWONT_FIXstatus (notFIXED).- If the reasoning doesn't hold, the finding remains
still_presentand an explanation is posted.
PostFixReplyActivity accepts a status parameter in input_data:
- Fixed findings — thread resolved with
CommentThreadStatus.FIXED(default) - Dismissed findings — thread resolved with
CommentThreadStatus.WONT_FIX
The dismissal reply includes the accepted explanation and optionally suggests a .codereview.md rule to prevent the same pattern from being flagged in future reviews.
Fix verification matches on cr_id (8-char SHA1 hex). For matching to work across runs, the cr-id must be stable — it is computed from file:line:category and does not change unless the file is renamed or the finding's line number shifts substantially.