Repository navigation
fix(review): resolve escaped finding paths and drop findings on an excluded conventions file - #124
Merged
Merged
Conversation
The prompt writes a double quote in a path attribute as ", and the model copies that attribute into a finding's file. The unknown-file filter compared that spelling against the raw paths and dropped the finding. It now keeps a finding whose file matches only after decoding ", rewrites file to the decoded path, and logs each rewrite at debug level. A path that matches as written is never rewritten. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d-diff tests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ship-Check: pr-review · claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
umm-actually re-reviewed at 1 new finding(s) posted (8 tracked finding(s) across all runs). umm-actually · deepseek/deepseek-v4.1-flash |
…llers - Name the normalization the filter applies, state that kept findings keep the model's spelling, and give the real reason the written spelling is checked first. - State why only a double quote is escaped in path attributes, and link the file-anchoring instruction to the decode in the filter. - Destructure the dropped findings under their own name so the returned count no longer shares it, and state why drops warn while rewrites log at debug. - Make the prompt-path comment true for renamed paths and note which normalization the filter applies; restate the deadline-coverage comment. - Drop a length check that the following .some() already covers. - Rewrite the README escaped-path bullet to lead with the scenario. Ship-Check: code-quality · claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each matching-rule test now seeds a finding the rule keeps and one it drops, so a filter that keeps or drops everything fails that test on its own. - The "decodes only "" test carries an "&" in its path, so a decoder that decodes other entities fails it. - The rendered-attribute test uses a path with "&" and '"', so an encoder that starts escaping "&" without a matching decoder fails it. - The attribute regex is scoped to the one test that reads it. Ship-Check: test-audit · claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… docs Git C-quotes a path that contains a double quote, and parse-diff keeps the backslash escape, so a diff header does not print such a path unchanged. The README now says the header prints the diff's own spelling, which the filter matches as written. conventionsRenderInFull promised exactly one full copy, but a truncated conventions section with no budget left for the changed-file block sends none. It now promises no more than one. Ship-Check: bug-check · claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… for what it reports Ship-Check: triage · claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…xception The within-run overlap step also drops one of two same-severity findings, keeping the earlier line. The conventions file is read even when diff_exclude_paths or linguist rules exclude it, so findings on it are kept. Ship-Check: code-quality · claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ship-Check: triage · claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each matching-rule filter test now also seeds a finding the rule drops, so a filter that keeps everything fails it. New cases cover a leading or trailing slash on either side of the match, and an orchestrate test shows a finding filed on an escaped path is deduplicated against a prior anchor on the decoded path. The README's unknown-file filter section now says excluded files are listed by path at the end of the diff with their content withheld, and that the conventions file is sent even when excluded. Ship-Check: pr-monitor · claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The conventions path joins the unknown-file filter's accepted paths only when diff exclusion did not remove the file. The conventions section is still sent as the rubric. README states the new behaviour and uses one order phrase for both filters. Ship-Check: triage · claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ship-Check: pr-monitor · claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rops A finding on a diff-excluded file, the conventions file included, was dropped with the unknown-file warning and counted as an unknown file. That pointed an operator at context assembly, though the path is listed in the excluded-files note. The filter now returns those findings in their own bucket, logged as `dropping finding: file excluded from the review diff` and counted in a `Dropped as excluded file` job-summary row and the per-phase filter log. Which findings are dropped is unchanged. Ship-Check: pr-monitor · claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When a file path contains a double quote, the prompt writes the path attribute as
path="docs/a"b.md". The system prompt tells the model to copy that attribute into a finding'sfile, and a model that does so writesdocs/a"b.md. The unknown-file filter compared that spelling against the raw paths, which hold", and dropped the finding as "file not in prompt context". Reviewers lost valid findings on related files, related docs, priority docs, and the conventions file whenever the path contained a quote.The filter now keeps a finding whose
filematches a known path only after each"is read as", and rewritesfileto that decoded spelling. Afilethat matches as written is never rewritten, so a path that literally contains"stays as the model wrote it.A PR that changes the conventions file can also remove it from the review diff through
diff_exclude_pathsor linguist rules. The excluded-files note tells the model that file's content was not provided, and the system prompt says not to report findings on excluded paths, yet findings on the conventions file were still kept. The filter now accepts the conventions path only when diff exclusion did not remove it, so those findings are dropped like findings on any other excluded file. The conventions section is still sent unchanged as the review's rubric.A finding on any diff-excluded file, the conventions file included, is now reported apart from unknown-file drops. It was logged as
dropping finding: file not in prompt contextand counted as an unknown file, which pointed an operator at context assembly although the path is listed in the excluded-files note. It now logsdropping finding: file excluded from the review diffand has its own count. Which findings are dropped is unchanged.Changes
src/review/prompt.ts: addsunescapeAttributeValuebesideescapeAttributeValue, decoding only the one entity the encoder writes. Each function's comment names the other so they change together.src/review/filter-unknown-file-findings.ts: resolves each finding as known, unescaped, excluded, or unknown, with the written spelling checked first. Takes the diff-excluded paths, normalized like the known paths, and returns findings on them asdroppedAsExcludedFileapart fromdroppedAsUnknownFile. The known check runs first, so the set of dropped findings does not change. Returns the rewrites asunescapedFileRewrites. The JSDoc states the new contract.src/orchestrate.ts:resolved escaped finding file to a prompt path) with the phase, both spellings, and the line. The dropped count and the job summary still count only dropped findings.non-finding filter applied to model outputtoper-phase finding filters applied to model output, since it also reports unknown-file drops and cross-phase duplicates.dropping finding: file excluded from the review diffat warn with the same fields as the unknown-file warning (phase, file, line, category). The per-phase filter summary log and the job summary carrydroppedAsExcludedFile.posix.normalizeon both sides like the neighbouring priority-doc check. The conventions section of the prompt is unchanged.src/review/review-summary.ts: the findings-pipeline table gains aDropped as excluded filerow afterDropped as unknown file.action.ymland READMEfindings_count: the removed-findings list names findings on files diff exclusion removed.README.md:conventions_budget_tokensrow splits its reporting conditions into two sentences.&and"throughbuildUserPromptand feeds the attribute back asfile. Each matching-rule filter test seeds a finding the rule keeps and one it drops, and new cases cover a leading or trailing/on either side of the match. One orchestrate test asserts the posted path, the debug log, the drop warning, and the filter counts. A second shows a finding filed on the escaped spelling is deduplicated against a prior anchor on the decoded path. Two more run the real prompt builder on a PR that changes the conventions file: when the file is diff-excluded, a finding on it is dropped with the warning, nothing posts, and the prompt still carries the conventions section; the same holds whenconventions_fileis spelled./AGENTS.md; when it is not excluded, the finding posts inline. The excluded-file tests assert the excluded-file warning and no unknown-file warning; the plain excluded-file test also asserts the filter summary log and both job-summary rows. New filter cases cover the excluded bucket beside kept and unknown findings, normalized excluded paths, an excluded path reached through"(not rewritten), and a path both known and excluded. A job-summary test pins the whole findings-pipeline section with the new row.Testing
npm test: 829 passed (26 files).npm run lintandnpm run buildare clean.filefailed the orchestrate dedup test, because the finding was posted again instead of matching the prior anchor."failed the seam test and the two prompt tests that pin the escaped attribute.&as&failed the seam test, whose path holds both&and".&failed the "decodes only"" test../AGENTS.mdtest only.droppedAsUnknownFilewith the unknown-file warning.🤖 Generated with Claude Code