Skip to content

fix(enrichment): bound dependency scans#1537

Merged
JSONbored merged 2 commits into
mainfrom
codex/fix-unbounded-osv-scans-in-rees
Jun 27, 2026
Merged

fix(enrichment): bound dependency scans#1537
JSONbored merged 2 commits into
mainfrom
codex/fix-unbounded-osv-scans-in-rees

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Motivation

  • Prevent unbounded OSV.dev queries and background work after a brief timeout by limiting how many manifest files/patch lines are scanned and ensuring analyzer fetches can be aborted.

Description

  • Add hard caps and options: MAX_MANIFEST_FILES, MAX_PATCH_LINES_PER_FILE, MAX_DEPENDENCY_QUERIES, plus ScanLimits/ScanOptions to the dependency analyzer.
  • Thread limits into extractDependencyChanges and scanDependencies so extraction and the number of OSV queries are bounded.
  • Propagate an AbortSignal into queryOsv and into outbound fetch so in-flight OSV requests can be cancelled.
  • Replace the non-cancelling timeout runner with an AbortController-backed runWithTimeout in buildBrief and pass the abort signal into the dependency analyzer registry entry so timed-out analyzers stop background work.
  • Add regression tests that exercise manifest/patch caps, OSV query capping and forwarding of abort signals, and that a timed-out buildBrief aborts dependency OSV work.
  • Modified files: review-enrichment/src/analyzers/dependency-scan.ts, review-enrichment/src/brief.ts, and review-enrichment/test/enrichment.test.ts.

Testing

  • Ran package unit tests with npm --prefix review-enrichment test, which completed successfully and the new regression tests passed.
  • Built the package with npm --prefix review-enrichment run build, which succeeded.
  • Ran the full repository CI locally with npm run test:ci, which exercised many suites but did not complete cleanly due to unrelated root-suite timeouts and a Vitest coverage remapping error (TypeError: jsTokens is not a function).
  • Ran npm audit --audit-level=moderate, which failed to contact the registry audit endpoint (returned 403), unrelated to the code changes.

Codex Task

@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Jun 26, 2026
@superagent-security

Copy link
Copy Markdown

Superagent didn't find any vulnerabilities or security issues in this PR.

@gittensory-orb

gittensory-orb Bot commented Jun 27, 2026

Copy link
Copy Markdown

Tip

🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩

✅ Gittensory review — safe to merge

3 files · 1 AI reviewers · no blockers · readiness 48/100 · CI green · unknown

✅ Approved — safe to merge

Review summary
This PR adds hard caps (MAX_MANIFEST_FILES=20, MAX_PATCH_LINES_PER_FILE=500, MAX_DEPENDENCY_QUERIES=25) to bound dependency extraction and OSV query counts, and propagates an AbortSignal from a new AbortController-backed runWithTimeout helper through scanDependencies into outbound fetch calls. The logic is correct throughout: the manifest counter only ticks after the ecosystem filter so non-manifest files don't consume budget, String.split's limit argument properly caps patch lines, .slice() before the OSV loop caps queries, and the per-iteration aborted check prevents additional OSV calls after cancellation. The three new regression tests cover manifest/patch caps, query-count caps with signal forwarding, and the end-to-end timeout-aborts-fetch integration path.

Nits (5)

  • queryOsv's JSDoc says 'Best-effort: returns [] on any error' but has no try/catch around the fetchImpl call, so an AbortError or network failure propagates instead of returning [] — the current propagating behavior is intentionally correct for the abort use case, but the docstring is now misleading after adding signal support (dependency-scan.ts, queryOsv).
  • The four non-dependency ANALYZERS entries (secret, license, installScript, actionPin) receive the AbortSignal via the updated AnalyzerFn type signature but silently ignore it and run to natural completion after a timeout fires — acceptable for the PR's stated scope, but a comment near the AnalyzerFn type noting that only the dependency analyzer is currently signal-aware would reduce confusion for future analyzer authors (brief.ts).
  • The test 'scanDependencies: caps OSV queries and forwards abort signals' creates an AbortController but never calls .abort(), so it verifies signal forwarding and query-count capping only, not actual abort-stopping behavior — renaming to 'caps OSV queries and passes signal to fetch' would better match what the test proves (enrichment.test.ts).
  • In queryOsv (dependency-scan.ts), either wrap the fetchImpl call in try/catch to honour the 'returns [] on any error' contract (mapping AbortError and network failures to []), or update the JSDoc to state that cancellation errors propagate intentionally; the current mismatch between the stated contract and the actual throw-on-abort path is a trap for future callers.
  • The 'caps OSV queries' test (enrichment.test.ts) could be extended by calling controller.abort() mid-run and asserting no subsequent fetches occur, giving a direct unit-level abort test that complements the buildBrief integration test already covering the same end-to-end signal path.
Signal Result Evidence
Code review ✅ No blockers 1 reviewers, synthesized
Linked issue ⚠️ Missing No linked issue or no-issue rationale found.
Related work ⚠️ 3 scoped overlaps Top overlaps are listed below; lower-confidence bulk is hidden.
Review load ❌ 8/20 Readiness component derived from cached public PR metadata and labels; size label size:M.
Validation evidence ❌ 5/25 Cached preflight status is hold.
Open PR queue ❌ 3/10 26 open PR(s), 9 likely reviewable, 17 unlinked.
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 81 PR(s), 297 issue(s).
Gate result ✅ Passing No configured blocker found.
Nits — 2 non-blocking
  • Repository config was not parsed
  • No linked issue detected — If this PR is intended to solve an issue, link it explicitly in the PR body.
Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository registration is not available in the local Gittensory cache.
  • Public profile languages: not available
  • Official Gittensor activity: 81 PR(s), 297 issue(s).
  • Related work: Titles/paths share 7 meaningful terms. (PR #1546)
  • Related work: Titles/paths share 6 meaningful terms. (PR #1545)
  • Related work: Titles/paths share 6 meaningful terms. (PR #1554)
  • Additional title-only matches omitted; title-only overlap does not block.
Contributor next steps
  • Treat this as maintainer-lane context rather than normal contributor-lane activity.
  • Explain no-issue PR.
  • Review top overlaps.
  • Add scope summary.
  • Fix blocker.
  • Expect slower review.
  • Refresh registry data or choose a registered active repo.
  • Link the issue being solved, or explicitly explain why this is a no-issue PR.
  • Check active issues and PRs before submitting.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Review load = cached public PR metadata such as size labels, changed paths, and preflight status.
  • Open PR queue = repo-wide review pressure; it is not a PR quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
Review details

Generated from public PR metadata and the diff. Advisory only; deterministic signals remain authoritative.

This PR adds hard caps (MAX_MANIFEST_FILES=20, MAX_PATCH_LINES_PER_FILE=500, MAX_DEPENDENCY_QUERIES=25) to bound dependency extraction and OSV query counts, and propagates an AbortSignal from a new AbortController-backed runWithTimeout helper through scanDependencies into outbound fetch calls. The logic is correct throughout: the manifest counter only ticks after the ecosystem filter so non-manifest files don't consume budget, String.split's limit argument properly caps patch lines, .slice() before the OSV loop caps queries, and the per-iteration aborted check prevents additional OSV calls after cancellation. The three new regression tests cover manifest/patch caps, query-count caps with signal forwarding, and the end-to-end timeout-aborts-fetch integration path.

Nits (5)

  • queryOsv's JSDoc says 'Best-effort: returns [] on any error' but has no try/catch around the fetchImpl call, so an AbortError or network failure propagates instead of returning [] — the current propagating behavior is intentionally correct for the abort use case, but the docstring is now misleading after adding signal support (dependency-scan.ts, queryOsv).
  • The four non-dependency ANALYZERS entries (secret, license, installScript, actionPin) receive the AbortSignal via the updated AnalyzerFn type signature but silently ignore it and run to natural completion after a timeout fires — acceptable for the PR's stated scope, but a comment near the AnalyzerFn type noting that only the dependency analyzer is currently signal-aware would reduce confusion for future analyzer authors (brief.ts).
  • The test 'scanDependencies: caps OSV queries and forwards abort signals' creates an AbortController but never calls .abort(), so it verifies signal forwarding and query-count capping only, not actual abort-stopping behavior — renaming to 'caps OSV queries and passes signal to fetch' would better match what the test proves (enrichment.test.ts).
  • In queryOsv (dependency-scan.ts), either wrap the fetchImpl call in try/catch to honour the 'returns [] on any error' contract (mapping AbortError and network failures to []), or update the JSDoc to state that cancellation errors propagate intentionally; the current mismatch between the stated contract and the actual throw-on-abort path is a trap for future callers.
  • The 'caps OSV queries' test (enrichment.test.ts) could be extended by calling controller.abort() mid-run and asserting no subsequent fetches occur, giving a direct unit-level abort test that complements the buildBrief integration test already covering the same end-to-end signal path.

🟩 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 Gittensory, a quiet PR intelligence layer for OSS maintainers.

  • Re-run Gittensory review

…sv-scans-in-rees

# Conflicts:
#	review-enrichment/test/enrichment.test.ts
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 27, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
gittensory-ui b3d4819 Commit Preview URL

Branch Preview URL
Jun 27 2026, 01:15 AM

@JSONbored JSONbored merged commit 104ac4b into main Jun 27, 2026
15 checks passed
@JSONbored JSONbored deleted the codex/fix-unbounded-osv-scans-in-rees branch June 27, 2026 01:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

aardvark codex gittensor:bug Gittensor-scored bug fix - worth 0.5x multiplier. gittensor Gittensor contributor context size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant