fix: bound bulk-scan inventory loading - #145
Open
GautamSharma99 wants to merge 1 commit into
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #132.
Add explicit resource ceilings to bulk-scan inventory loading and interactive GitHub discovery, and replace full CSV materialization with incremental parsing.
Previously, a supplied inventory was read into one complete UTF-8 string, Papa Parse retained a complete row array, and the rows were then mapped into another task array. Interactive discovery similarly accumulated every qualifying GitHub repository without a campaign limit. Both paths could consume excessive memory and create unexpectedly large checkout, scan, and model-cost scope before work began.
Limits
Bulk scan now enforces shared limits of:
The same repository ceiling applies to supplied inventories and interactive GitHub discovery.
Changes
Metadata validation before campaign state
runMultiscannow checks inventory metadata before opening or parsing the CSV.It rejects:
All inventory parsing and validation still happens before the output directory, campaign lock, manifest, checkout directory, artifact directory, or security client is created.
Incremental CSV parsing
Inventory loading now streams the file through Papa Parse in 64 KiB input chunks.
The parser:
This removes the previous simultaneous retention of the complete source string, complete Papa row array, and mapped task array.
In-stream byte enforcement
The initial metadata check rejects known oversized files before reading. A byte-counting transform independently enforces the 8 MiB ceiling while the file is read.
This second check prevents a file replacement or growth race after metadata validation from bypassing the input limit.
The source and parser streams are destroyed immediately when parsing, cancellation, byte, or repository-count validation fails.
Bounded GitHub discovery
Interactive discovery now stops and returns an actionable error as soon as the 1,001st qualifying repository is encountered.
The limit is enforced during pagination, before repository selection, output-directory creation, or inventory writing. Empty repositories and repositories older than the existing 90-day cutoff continue to be excluded before they count toward the campaign limit.
The error recommends splitting the repository list into smaller campaigns.
Shared limits and documentation
The byte and repository constants, along with the repository-limit diagnostic, are shared by CSV loading and GitHub discovery so the two entry points cannot drift.
The README now documents both limits and advises using separate inventories and output directories for larger campaigns.
Security and resource impact
This bounds:
Oversized input is rejected before persistent campaign state or checkout work begins.
Tests
Added regression coverage for:
Verification
pnpm run typespnpm run formatpnpm run buildPATH="/opt/homebrew/bin:$PATH" pnpm run testFull test result: