Skip to content

feat(scanner): return partial findings on scan timeout via AbortSignal #1105

Description

@sonukapoor

Note: this is an in-house item already being handled by the maintainer - not open for contribution. Filed for tracking only.

Follow-up to #983 / #1100, split out so the contributor PR stays tractable.

Context

--scan-timeout lands via #1100 as a hard abort: Promise.race against the scan, and on timeout the run ends with no findings. #1100 also routes that through ScanCompleteness so --incomplete-policy applies and a timeout is expressed as an incomplete scan rather than a bare exit.

That gets the meaning right. It does not get the outcome right.

Problem

When a scan times out at 30 seconds, everything found in the first 30 seconds is discarded. If three criticals were already detected, the user gets nothing. On the large monorepos this flag exists for, a partial answer is considerably more useful than no answer, provided it is honestly labelled as partial.

What to do

Thread an AbortSignal into scanPackages so a timeout stops further work and returns what completed, paired with the existing SCAN_TIMEOUT diagnostic marking complete: false. The user then gets the findings that were confirmed plus an unambiguous incomplete marker, and --incomplete-policy decides whether that fails the build.

Why this is in-house

scanPackages in src/scanner.ts is 641 lines and sits on the hot path. Abort plumbing has to interleave with the OSV batch fan-out, the cache, and the remediation passes without changing behaviour when no timeout is set. Per the project's conventions, scan-loop internals and performance-sensitive code are not contributor work.

Care needed

  • Partial results must never be mistakable for complete ones. The completeness diagnostic is what makes this safe; if the diagnostic is dropped or suppressed anywhere in the output path, this becomes a false-negative generator. Check terminal, JSON, SARIF and HTML.
  • --ratchet already refuses to save a baseline from an incomplete scan. Verify that still holds, because baselining a timed-out scan would silently absorb everything that was not reached.
  • Aborting mid-flight must not leave the advisory cache in a partially-written state.
  • No behaviour change and no measurable overhead when --scan-timeout is unset.

Sequencing

After #1100 merges. This changes what a timeout produces, not what it means, so it is additive rather than a semantic break.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestin-houseMaintainer-handled internal work - not open for contribution

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions