Skip to content

fix(review): failed-call coverage clause and legacy omitted count alongside summary degradations - #691

Merged
devops-thiago merged 2 commits into
mainfrom
fix/655-659-coverage-clauses
Aug 13, 2026
Merged

fix(review): failed-call coverage clause and legacy omitted count alongside summary degradations#691
devops-thiago merged 2 commits into
mainfrom
fix/655-659-coverage-clauses

Conversation

@devops-thiago

Copy link
Copy Markdown
Owner

What type of PR is this?

  • 🐛 Bug fix

Description

Two defects in ReviewResult.coverageGapClause, both about the coverage disclosure telling the reader the wrong thing (or nothing) about unreviewed files:

The pre-existing TruncationDetail shape is kept via a convenience constructor, leaving existing call sites (including #628's future patchless-reason work) untouched. #628's patchless route is deliberately out of scope here.

Related Issues

Closes #655
Closes #659

How Has This Been Tested?

  • Unit tests
  • Integration tests
  • Manual testing

New tests cover the failed-call class end-to-end from BudgetPlan.recordUncoveredFiles through VerdictBuilder to the rendered banner and check-run brief (including no-double-listing with ceiling skips and clipped files), plus the issue's A/B/C probes for the legacy count. ./mvnw verify passes locally (3133 tests) and every changed production line is covered against the merge-base diff.

Checklist

  • My code follows the project's coding standards
  • I have performed a self-review of my own code
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have updated the documentation accordingly
  • My changes generate no new warnings or errors

Screenshots / Logs

N/A

Additional Notes

CHANGELOG [Unreleased] carries Fixed entries for both issues.

…eep the legacy omitted count alongside summary degradations (#655, #659)

Files a failed batch left unreviewed were folded into the budget-omission
class, so the banner blamed the diff budget while the summary overview said
the call did not complete. They are now their own TruncationDetail class,
disclosed as 'not reviewed because the review call for them did not
complete' in the clause and the check-run brief.

On the legacy line-cap path, a detail carrying only a summary degradation
skipped the numeric fallback and nothing below it read the omitted count,
so the count vanished; it now renders as a clause alongside the
degradation.
@thrillhousebot

Copy link
Copy Markdown
Contributor

🤖 ThrillhouseBot PR Summary

What this PR does

Adds a dedicated 'review call did not complete' disclosure class for files a failed batch left unreviewed, so the coverage banner and check-run brief no longer blame the diff budget and now agree with the summary overview; it also restores the legacy numeric omitted-files count on the coverage clause when a detail carries only a summary degradation, fixing the #659 probes B/C while leaving probe A unchanged.

Description vs. Implementation

No mismatch found between the PR description and the change.

Control-Flow Diagram

🔀 Show diagram
flowchart TD
  A["Failed review batch: plan.recordUncoveredFiles(...)"] --> B["BudgetPlan merges runtime-uncovered into effectiveOmittedFiles"]
  B --> C["VerdictBuilder: callFailed = withoutNames(runtimeUncoveredFiles, ceilingSkipped)"]
  C --> D["TruncationDetail carries callFailedFileNames; omittedFileNames excludes them"]
  D --> E["coverageGapClause builds per-class clauses"]
  E --> F{"detail.hasFileGaps()?"}
  F -- "no" --> G["legacy count clause when omittedFiles > 0"]
  F -- "yes" --> H["per-class clauses render, no numeric clause"]
  D --> I["summary-degradation clause renders"]
  G --> J["banner and check-run brief disclose call-failed files, not budget"]
  H --> J
  I --> J
Loading

Changes Overview

  • Files changed: 5
  • Lines added: +290
  • Lines removed: -14

Changed Files

File Change Summary
CHANGELOG.md Modified Adds Fixed entries for #655 (call-failure disclosure class) and #659 (legacy count kept beside summary degradations).
src/main/java/dev/thiagogonzaga/thrillhousebot/review/ReviewResult.java Modified Adds callFailedFileNames as a fifth TruncationDetail class, renders it in coverageGapClause/coverageGapBrief, and restores the legacy omitted count next to summary degradations.
src/main/java/dev/thiagogonzaga/thrillhousebot/review/VerdictBuilder.java Modified Extracts runtime-uncovered files into the new call-failed class (after ceiling-skip subtraction) so the disclosure no longer blames the diff budget while approval gating is unchanged.
src/test/java/dev/thiagogonzaga/thrillhousebot/review/ReviewResultTest.java Modified Adds clause/brief/isEmpty tests for the call-failed class and the #659 legacy-count probes A/B/C, and updates the null-normalization test for the sixth field.
src/test/java/dev/thiagogonzaga/thrillhousebot/review/VerdictBuilderTest.java Modified Tracks the failed-batch disclosure end-to-end through VerdictBuilder, including no-double-listing with ceiling skips/clips and coexisting planned omissions.

Risk Assessment

Risk Count
🔴 Critical 0
🟠 High 0
🟡 Medium 1
🔵 Low 0

Things to double-check

1 lower-confidence finding
  • MEDIUM: Legacy omitted count still dropped when a per-file class coexists (e.g. call failure) (src/main/java/dev/thiagogonzaga/thrillhousebot/review/ReviewResult.java:564) (low confidence — verify before acting)

⚠️ Required CI Checks Status

Some required checks are still pending or have failed:

Check Type Status Detail
format missing ⏳ Pending -
test missing ⏳ Pending -
frontend missing ⏳ Pending -
trivy missing ⏳ Pending -
dependency-review missing ⏳ Pending -

Automated review by ThrillhouseBot. Reply with /review to re-run.

@thrillhousebot thrillhousebot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ThrillhouseBot noted 1 lower-confidence item(s) under Things to double-check in the PR summary (not posted as inline threads):

  • MEDIUM: Legacy omitted count still dropped when a per-file class coexists (e.g. call failure) (src/main/java/dev/thiagogonzaga/thrillhousebot/review/ReviewResult.java:564)
    The new #659 clause is gated on if (!detail.hasFileGaps() && omittedFiles > 0), and hasFileGaps() is true whenever ANY of the five name classes is non-empty — including the new callFailedFileNames class this same PR adds. On the legacy line-cap path the #659 issue's own reachability analysis states the precondition is "omittedFiles > 0 with no names": the count is known while the planned omissions carry no names. If such a review also has a failed batch — producer side is visible in VerdictBuilder: var callFailed = withoutNames(plan.runtimeUncoveredFiles(), ceilingSkipped); followed by callFailedFileNames: callFailed — then the count clause is suppressed (hasFileGaps true) while the named clauses cover only the failed file, and the unnamed line-cap omissions are again disclosed to nobody. That is the exact loss #659 was filed for, now arising from the combination of the PR's two fixes. The PR's tests never exercise this combination: coverageGapClauseDoesNotAddTheLegacyCountWhenFileGapsAreNamed assumes count == sum of named classes, and the detail unit tests for #659 use a detail with no name classes at all. Verify whether omittedFiles can exceed the sum of the named classes on the legacy path — check BudgetPlan.effectiveOmittedFiles and the omitted count computation in VerdictBuilder.build (just below the truncation construction, not shown in the diff). If it can, gate the numeric clause on the count exceeding the named-class sum rather than on !detail.hasFileGaps(), and add a test combining the legacy count with a call failure plus a summary degradation.

@thrillhousebot thrillhousebot Bot added bug Something isn't working java Pull requests that update java code labels Aug 13, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@thrillhousebot thrillhousebot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ThrillhouseBot found no issues in this PR, but some checks are still pending or failed:

  • Check format is pending
  • Check test is pending
  • Check frontend is pending
  • Check trivy is pending
  • Check dependency-review is pending

Additionally, No new issues in this revision, but 1 previous finding(s) remain unresolved — fix them, or reply on their review thread with why they are deferred. A finding listed only under "Things to double-check" has no thread: clear it by commenting @thrillhousebot resolved path/to/File.java:42 — <the finding's title> on this PR.

@devops-thiago

Copy link
Copy Markdown
Owner Author

@thrillhousebot resolved src/main/java/dev/thiagogonzaga/thrillhousebot/review/ReviewResult.java:564 — Legacy omitted count still dropped when a per-file class coexists (e.g. call failure)

The combination cannot be produced: coverageGapClause has exactly three producers, and none can pass a detail whose callFailedFileNames is non-empty while omittedFiles exceeds the named total.

  • On the legacy line-cap path (plan.budgeted() == false), VerdictBuilder.build assigns truncation = ReviewResult.TruncationDetail.EMPTY unconditionally — a failed batch's runtimeUncoveredFiles never reach the detail there, so hasFileGaps() is false and the numeric clause renders.
  • On the budgeted path, the count is computed as plan.effectiveOmittedFiles().size() + clipped.size() + responseCut.size(), and the detail's name classes are a partition of that exact total (omittedFileNames = effective omissions minus ceiling skips minus call failures, plus spendCeilingSkippedFileNames, callFailedFileNames, clippedFileNames, responseCutFileNames) — the count can never exceed the sum of the named classes, so the numeric clause has no residue to disclose.
  • The remaining producers (AbstractPrSuggestionGenerator.disclosure, FollowUpDeltaSummary) pass a count equal to their own name lists and never populate callFailedFileNames.

Gating on "count exceeds the named total" would guard a state no producer can construct.

🤖 Addressed by Claude Code

@thrillhousebot

Copy link
Copy Markdown
Contributor

The next review will close every previous finding this comment names by its path:line and title; anything it does not name stays open.

@codecov

codecov Bot commented Aug 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@sonarqubecloud

Copy link
Copy Markdown

@devops-thiago
devops-thiago merged commit 020019b into main Aug 13, 2026
17 checks passed
@devops-thiago
devops-thiago deleted the fix/655-659-coverage-clauses branch August 13, 2026 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working java Pull requests that update java code

Projects

None yet

1 participant