Problem
isVisualPath (src/review/visual/paths.ts) gates whether the visual before/after screenshot-capture pipeline runs at all for a PR. Its first pattern, /^apps\/[^/]+\//i, matches ANY file under ANY apps/*/ folder regardless of extension — so a pure .ts logic/lib file (e.g. apps/ui/src/lib/metagraphed/queries.ts, JSONbored/metagraphed#6036) triggers full capture even though it touches nothing renderable.
The module's own doc comment claims "A backend change (.ts/.md/.json/.py/...) matches NONE of these, so capture never triggers for it" — that's false for any backend file that happens to live inside a frontend app's folder tree.
This wastes Browser Rendering + R2 storage on every non-visual PR under apps/*/, and produces a confusing "Visual preview" table (with a permanently-broken "after" placeholder — see #6117-style companion issues) on PRs the bot's own review text correctly calls non-visual.
Area
src/review/visual/paths.ts (isVisualPath, VISUAL_PATTERNS).
Proposal
Tighten pattern 1 so an apps/*/ path only counts as visual when it ALSO matches a front-end signal — either a route/page-style path segment (mirroring capture.ts's own DEFAULT_ROUTE_FILE = /apps\/[^/]+\/src\/routes\/(.+?)\.(?:tsx|jsx)$/i) or one of pattern 3's front-end extensions (.tsx/.jsx/.css/.scss/.sass/.less/.html/.svg/.astro/.vue/.svelte/.mdx). A pure apps/*/**/*.ts file (no route/page shape, no front-end extension) should return false.
Cross-check the result against screenshot-table-gate.ts's own (config-driven, whenPaths) visual-relevance decision for a handful of representative repos/paths — the two classifiers currently disagree, and isVisualPath should never be BROADER than what the gate itself considers in-scope for screenshot evidence.
Deliverables
Resources
Boundaries
Scope is isVisualPath only. Don't touch screenshot-table-gate.ts's own config-driven scoping, and don't change the capture pipeline itself (that's this milestone's other issues). Maintainer-only — assigned JSONbored.
Problem
isVisualPath(src/review/visual/paths.ts) gates whether the visual before/after screenshot-capture pipeline runs at all for a PR. Its first pattern,/^apps\/[^/]+\//i, matches ANY file under ANYapps/*/folder regardless of extension — so a pure.tslogic/lib file (e.g.apps/ui/src/lib/metagraphed/queries.ts, JSONbored/metagraphed#6036) triggers full capture even though it touches nothing renderable.The module's own doc comment claims "A backend change (.ts/.md/.json/.py/...) matches NONE of these, so capture never triggers for it" — that's false for any backend file that happens to live inside a frontend app's folder tree.
This wastes Browser Rendering + R2 storage on every non-visual PR under
apps/*/, and produces a confusing "Visual preview" table (with a permanently-broken "after" placeholder — see #6117-style companion issues) on PRs the bot's own review text correctly calls non-visual.Area
src/review/visual/paths.ts(isVisualPath,VISUAL_PATTERNS).Proposal
Tighten pattern 1 so an
apps/*/path only counts as visual when it ALSO matches a front-end signal — either a route/page-style path segment (mirroringcapture.ts's ownDEFAULT_ROUTE_FILE = /apps\/[^/]+\/src\/routes\/(.+?)\.(?:tsx|jsx)$/i) or one of pattern 3's front-end extensions (.tsx/.jsx/.css/.scss/.sass/.less/.html/.svg/.astro/.vue/.svelte/.mdx). A pureapps/*/**/*.tsfile (no route/page shape, no front-end extension) should returnfalse.Cross-check the result against
screenshot-table-gate.ts's own (config-driven,whenPaths) visual-relevance decision for a handful of representative repos/paths — the two classifiers currently disagree, andisVisualPathshould never be BROADER than what the gate itself considers in-scope for screenshot evidence.Deliverables
isVisualPathno longer matches a pure backend/lib.ts(or other non-front-end-extension) file just because it lives underapps/*/.tsx,public/**, etc.) remain matched — this is a narrowing, not a rewrite.tsfile underapps/ui/src/lib/**→false; a route file underapps/ui/src/routes/**→true; the existingpublic/**and front-end-extension cases stilltrueapps/ui/src/lib/metagraphed/queries.ts) →falseResources
src/review/visual/paths.ts— the classifier to fixsrc/review/visual/capture.ts'sDEFAULT_ROUTE_FILE— the stricter route-shape pattern to mirrorsrc/review/screenshot-table-gate.ts'sisScreenshotTableGateInScope— the second, correctly-scoped classifier this should agree withBoundaries
Scope is
isVisualPathonly. Don't touchscreenshot-table-gate.ts's own config-driven scoping, and don't change the capture pipeline itself (that's this milestone's other issues). Maintainer-only — assigned JSONbored.