#202

fix(scanner): exclude vendor files from scans

Openmliem2kwants to merge intofrom

Problem

The language statistics pass excludes vendor/, but the scanner's ignore list does not. A matcher that finds candidates in vendored files can therefore produce candidates greater than scannedFiles, and the CLI reports coverage above 100%.

Fixes #185.

Change

Add **/vendor/** to the scanner's default ignore list so the candidate set and the statistics denominator describe the same files. This matches the existing statistics glob and the processor prompt, which already tells agents to skip vendored code.

Tests

Added packages/scanner/src/__tests__/vendor-ignore.test.ts, which scans matching Express routes in src/api.ts and vendor/pkg/api.ts and asserts only the source file is recorded and the language match rate stays at 1.

  • pnpm exec vitest run --project scanner
  • pnpm -r build
  • pnpm lint

Activity

4
vercel[bot]2d ago

@mliem2k is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

copilot-pull-request-reviewer[bot]reviewed2d ago
copilot-pull-request-reviewer[bot]2d ago

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

auto-maintain[bot]2d ago

🤖 auto-maintain review

Automated, advisory triage for @mliem2k's PR. Facts below are read from the GitHub API.

CheckResult
Author's merged PRs (this repo)0 — ⚠️ first-time contributor
Account established✅ (age 2567d · 5 followers · 52 public repos)
Commits signed/verified✅ 1/1

Review panel: 🟡 medium highest severity

deepsec maintainer code review: 🟡 medium

The new glob fixes fresh scans, but does not exclude vendor records already persisted by earlier versions.

  • packages/scanner/src/index.ts:144 — Existing persisted vendor FileRecords are never retired by this ignore. After upgrading and rescanning, `process`, revalidation, and reports still load those stale records, so previously discovered vendored code remains in the pipeline. Filter/retire ignored records while preserving history.

General code review: 🟢 low

No actionable defects found in the complete diff.

Scanner and matcher quality: 🟡 medium

Vendor exclusion is incomplete for previously scanned projects because persisted vendor candidates remain actionable.

  • packages/scanner/src/index.ts:144 — The ignore glob prevents new vendor matches but does not remove existing vendor FileRecords. After upgrading and rescanning, pending vendor records remain on disk and `process()` still loads and investigates them; purge newly ignored records or filter them downstream.

Sandbox and credential boundaries: 🟡 medium

The one-line fix is coherent with the existing statistics glob, but it silently extends to the `process --diff` PR-review path (changed files under any `vendor/` directory are no longer reviewed) and leaves the underlying ignore-list divergence in place; both should be consciously accepted or addressed before merge.

  • packages/scanner/src/index.ts:144 — `IGNORE_DIRS` is not only the `scan()` glob filter — it is also applied to user-supplied file lists in `resolveFiles()` (`process --diff/--diff-staged/--diff-working/--files`), to `listRepositoryFiles()`/fingerprinting, and to `groundSurfaceInventory()`. Adding `/vendor/` therefore silently removes any changed file under a directory named `vendor` at any depth (including first-party code in e.g. `src/vendor/`, `app/vendor/`) from PR-mode AI review, with no warning emitted. That is a security-coverage/gating change well beyond the stated goal of aligning a statistics denominator, and it gives an author a trivial way to place code outside the review path by directory name.
  • packages/scanner/src/index.ts:552 — The duplicated ignore lists still diverge, so the reported defect (candidates > scannedFiles → coverage above 100%) is only partially fixed: the scanner ignores `/*.test.{ts,tsx,js,jsx}` while the statistics pass ignores the broader `/.test.`/`/.spec.`, so a candidate in `foo.test.mts`/`foo.cts`/`foo.spec.py` is still counted in the numerator but excluded from the denominator. Conversely `/target/`, `/testserver/`, `/.d.ts` and `**/jest-setup.` are in `IGNORE_DIRS` but absent from the stats list, under-reporting coverage for Rust repos. Deriving both lists from one constant would fix the class of bug instead of one entry.

Durability and distributed state: 🟡 medium

Vendor exclusion is incomplete for persisted state from earlier scans.

  • packages/scanner/src/index.ts:144 — Ignoring vendor paths only prevents new discovery; existing vendor FileRecords remain pending/reportable and are still loaded by process runs. A post-upgrade scan must retire or exclude stale records, otherwise previously scanned vendored code continues consuming work and producing findings.

Posted by auto-maintain. This automated code review is advisory; a human maintainer makes the call.