You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The on-demand AI commands /describe, /changelog, and /add-docs reuse ReviewDiffFormatter (flat line cap, thrillhousebot.review.max-diff-lines) exactly like the review path, but — unlike the review path hardened in #234 and #245 — they silently drop the omitted-file count and never disclose that the output covers only a truncated slice of the diff.
Problem
All three commands run against a diff that ReviewDiffFormatter may truncate, and none of them surface it:
/describe and /changelog go through AbstractPrSuggestionGenerator.fetchDiff, which calls diffFormatter.buildDiffString(files) (AbstractPrSuggestionGenerator.java:107). buildDiffString returns only the text and throws away the FormattedDiff.omittedFiles() the formatter already computed.
/add-docs calls diffFormatter.buildDiffStringWithStats(files, reviewable).text() (DocGenerationService.java:175) — it holds the full FormattedDiff in hand but discards .omittedFiles() / .truncated().
The formatter already knows the count: FormattedDiff.truncated() / omittedFiles() (ReviewDiffFormatter.java:45-50) and it logs the omission at ReviewDiffFormatter.java:296-298. The review path threads this through to the user via ReviewResult.truncationNotice(int) (ReviewResult.java:129), consumed in VerdictBuilder.java:253 and ReviewPublisher.java:347. The three command generators have zero truncation awareness — grep -niE 'truncat|omitted|partial' over PrDescriptionGenerator.java, ChangelogEntryGenerator.java, DocGenerationService.java, AbstractPrSuggestionGenerator.java returns nothing.
Net effect: on a large PR, the bot posts a PR description / changelog entry / doc suggestions derived from a partial diff and presents them as if they were complete.
Evidence
Dogfood, native 0.3.0-SNAPSHOT, DeepSeek.
On #256 (75 changed files), the logs show the same truncation for all three commands:
None of the three commands' posted comments on #256 mentioned the 48 omitted files. The low #256 suggestion count was truncation, not an absence of documentable symbols.
Where
AbstractPrSuggestionGenerator.java:103-108 — fetchDiff calls buildDiffString, dropping the omitted count for /describe and /changelog.
PrDescriptionGenerator.java:80-93 — /describe builds the comment body (HEADER + suggestion + FOOTER).
ChangelogEntryGenerator.java:92-112 — /changelog builds the comment body.
Interim (surface what the formatter already knows):
In AbstractPrSuggestionGenerator, keep the FormattedDiff instead of the flattened string: have fetchDiff (or loadInputs) return the omittedFiles count alongside the diff text so /describe and /changelog can see it.
In DocGenerationService.generate, capture the FormattedDiff from buildDiffStringWithStats and read .omittedFiles() rather than calling .text() inline.
When omittedFiles > 0, append a disclosure line to each posted comment, reusing ReviewResult.truncationNotice(omittedFiles) (or an equivalent one-liner: "N file(s) were omitted because the diff exceeded the size limit; this covers only the reviewed portion") so the three surfaces match the review path's wording.
On a truncated diff, /describe, /changelog, and /add-docs each append a partial-coverage disclosure naming the omitted-file count to their posted comment.
The disclosure wording matches the review path (reuse ReviewResult.truncationNotice).
Non-truncated case unchanged: no disclosure line is appended when omittedFiles == 0.
/add-docs on a truncated PR still posts its suggestions/notes, now with the disclosure.
Test coverage for each command's truncated and non-truncated branches.
The on-demand AI commands
/describe,/changelog, and/add-docsreuseReviewDiffFormatter(flat line cap,thrillhousebot.review.max-diff-lines) exactly like the review path, but — unlike the review path hardened in #234 and #245 — they silently drop the omitted-file count and never disclose that the output covers only a truncated slice of the diff.Problem
All three commands run against a diff that
ReviewDiffFormattermay truncate, and none of them surface it:/describeand/changeloggo throughAbstractPrSuggestionGenerator.fetchDiff, which callsdiffFormatter.buildDiffString(files)(AbstractPrSuggestionGenerator.java:107).buildDiffStringreturns only the text and throws away theFormattedDiff.omittedFiles()the formatter already computed./add-docscallsdiffFormatter.buildDiffStringWithStats(files, reviewable).text()(DocGenerationService.java:175) — it holds the fullFormattedDiffin hand but discards.omittedFiles()/.truncated().The formatter already knows the count:
FormattedDiff.truncated()/omittedFiles()(ReviewDiffFormatter.java:45-50) and it logs the omission atReviewDiffFormatter.java:296-298. The review path threads this through to the user viaReviewResult.truncationNotice(int)(ReviewResult.java:129), consumed inVerdictBuilder.java:253andReviewPublisher.java:347. The three command generators have zero truncation awareness —grep -niE 'truncat|omitted|partial'overPrDescriptionGenerator.java,ChangelogEntryGenerator.java,DocGenerationService.java,AbstractPrSuggestionGenerator.javareturns nothing.Net effect: on a large PR, the bot posts a PR description / changelog entry / doc suggestions derived from a partial diff and presents them as if they were complete.
Evidence
Dogfood, native
0.3.0-SNAPSHOT, DeepSeek.On #256 (75 changed files), the logs show the same truncation for all three commands:
/add-docson that PR then logged:By contrast, on devops-thiago/MongOCOM#46 (27 files, not truncated),
/add-docslogged:None of the three commands' posted comments on #256 mentioned the 48 omitted files. The low #256 suggestion count was truncation, not an absence of documentable symbols.
Where
AbstractPrSuggestionGenerator.java:103-108—fetchDiffcallsbuildDiffString, dropping the omitted count for/describeand/changelog.PrDescriptionGenerator.java:80-93—/describebuilds the comment body (HEADER + suggestion + FOOTER).ChangelogEntryGenerator.java:92-112—/changelogbuilds the comment body.DocGenerationService.java:175—/add-docscallsbuildDiffStringWithStats(...).text(), dropping.omittedFiles().CommentCommandService.java:158-160— routesDESCRIBE/CHANGELOG/ADD_DOCS; handlers at:215,:245,:275.ReviewResult.truncationNotice(int)(ReviewResult.java:129).Proposed fix
Interim (surface what the formatter already knows):
AbstractPrSuggestionGenerator, keep theFormattedDiffinstead of the flattened string: havefetchDiff(orloadInputs) return theomittedFilescount alongside the diff text so/describeand/changelogcan see it.DocGenerationService.generate, capture theFormattedDifffrombuildDiffStringWithStatsand read.omittedFiles()rather than calling.text()inline.omittedFiles > 0, append a disclosure line to each posted comment, reusingReviewResult.truncationNotice(omittedFiles)(or an equivalent one-liner: "N file(s) were omitted because the diff exceeded the size limit; this covers only the reviewed portion") so the three surfaces match the review path's wording.Full (stop truncating):
Acceptance criteria
/describe,/changelog, and/add-docseach append a partial-coverage disclosure naming the omitted-file count to their posted comment.ReviewResult.truncationNotice).omittedFiles == 0./add-docson a truncated PR still posts its suggestions/notes, now with the disclosure.Related
fix(review): disclose diff truncation and don't auto-APPROVE a truncated review #234, fix(review): disclose truncation on follow-up reviews (and fix the held-back message) #245 — added truncation disclosure, but for the review path only; this issue extends the same guarantee to the three on-demand commands.
spike(review): define a better large-diff handling strategy #53 — large-diff redesign spike; the full fix routes these commands through it.
feat(review): whole-PR review via token-aware budgeting + multi-call map-reduce (#53) #256 — implements the token-aware / map-reduce path for the review path; the dogfood evidence above is from this PR.
fix(review): paginate getPullRequestFiles so large PRs (>30 files) are not silently truncated #190 — fixed >30-file pagination (so all 75 files are fetched before truncation); orthogonal but adjacent.
Sibling findings from the same v0.3.0 dogfood: fix(webhook): /summary reports "a summary already exists" from persistence state, not the live comment #297 (
/summary"already exists" wording) and fix(review): PR summary "Changes Overview" counts diverge from GitHub's file/line totals #298 (summary "Changes Overview" counts).