fix(visual): filter a vision finding's model-authored path through toPublicSafe - #10101
Conversation
|
Tip ✅ LoopOver review result - approve/merge recommendedReview updated: 2026-07-31 07:07:39 UTC
Review summary Nits — 3 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
…PublicSafe
VisualVisionFinding's JSDoc says both path and body are already public-safe, but
parseVisualVisionResponse only ran body through toPublicSafe — path got a bare .trim().
path is model-authored free text off the vision response JSON, interpolated verbatim
into a public finding title ("Possible visual regression: <path>"), and visual-followup's
renderer trusts the JSDoc and does not re-scrub. So injected markdown/@mentions in a
model path reached a public comment live.
Run path through toPublicSafe exactly as body is (drop the entry when it returns null),
and bound it with a new MAX_VISUAL_PATH_CHARS constant so one finding's title cannot
flood a comment. An ordinary route path survives toPublicSafe byte-identically, so
findVisualEvidence's route.path === path lookup still matches (pinned by a test). body's
filtering, MAX_VISUAL_FINDINGS, the category parse, and the followup re-scrub are unchanged.
Closes JSONbored#10062
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #10101 +/- ##
===========================================
- Coverage 91.88% 79.59% -12.29%
===========================================
Files 930 283 -647
Lines 113827 58720 -55107
Branches 27466 8665 -18801
===========================================
- Hits 104588 46738 -57850
- Misses 7940 11694 +3754
+ Partials 1299 288 -1011
Flags with carried forward coverage won't be shown. Click here to find out more.
|
Summary
VisualVisionFinding's JSDoc (src/review/visual/visual-findings.ts:124) documents bothpathandbodyas already public-safe, butparseVisualVisionResponseonly ran body throughtoPublicSafe—pathgot a bare.trim().pathis model-authored free text off the vision response JSON (nothing validates it is a real route, andfindVisualEvidencejust returnsundefinedon no match, so an arbitrary string still produces a finding), and it is interpolated verbatim into the finding's publictitle(Possible visual regression: ${finding.path}).The two title consumers disagree:
unified-comment-bridge.tsre-scrubs it, butvisual-followup.tsdoes not — it cites the (false) JSDoc. So injected markdown /@mentionmarkup in a modelpathreached a public follow-up comment live.Fix
parseVisualVisionResponserunspaththroughtoPublicSafeexactly as it doesbody, dropping the entry when it returnsnull(the existingif (!path || !body) continue;shape).MAX_VISUAL_PATH_CHARSconstant (besideMAX_VISUAL_FINDINGS) bounds the filtered path so one finding's title cannot flood a public comment./app,/docs/getting-started) survivestoPublicSafebyte-identically, sofindVisualEvidence'sroute.path === pathlookup still matches — pinned by a test that asserts both the byte-identical round-trip and thatvisualEvidencestill attaches.body's filtering, theMAX_VISUAL_FINDINGScap, the permissivecategoryparse, the[]-on-unparseable fail-safe, the two finding codes/severity, andvisualFindingsFromFindings's defence-in-depth re-scrub are all unchanged; the JSDoc contract is now true rather than edited to match the old behaviour.Tests
visual-findings.test.ts: a path with markdown/@mentionmarkup yields a finding whosepathno longer contains the live link markup; a path longer than the constant is truncated to it; an ordinary route path round-trips byte-identically and still attachesvisualEvidencefor a captured route.visual-followup.test.ts: a follow-up comment built from a hostile modelpathdoes not contain the injected live link.The scrub/truncate/followup cases fail against the current bare-
.trim()code. Coverage of the changed file is 100% (statements/branches/lines).Closes #10062