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.
Follow-up to #983 / #1100, split out so the contributor PR stays tractable.
Context
--scan-timeoutlands via #1100 as a hard abort:Promise.raceagainst the scan, and on timeout the run ends with no findings. #1100 also routes that throughScanCompletenessso--incomplete-policyapplies 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
AbortSignalintoscanPackagesso a timeout stops further work and returns what completed, paired with the existingSCAN_TIMEOUTdiagnostic markingcomplete: false. The user then gets the findings that were confirmed plus an unambiguous incomplete marker, and--incomplete-policydecides whether that fails the build.Why this is in-house
scanPackagesinsrc/scanner.tsis 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
--ratchetalready 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.--scan-timeoutis unset.Sequencing
After #1100 merges. This changes what a timeout produces, not what it means, so it is additive rather than a semantic break.