Skip to content

feat: add stateless npm declaration indexing - #43

Open
danny-avila wants to merge 2 commits into
mainfrom
danny-avila/npm-unit-sandbox
Open

feat: add stateless npm declaration indexing#43
danny-avila wants to merge 2 commits into
mainfrom
danny-avila/npm-unit-sandbox

Conversation

@danny-avila

Copy link
Copy Markdown
Collaborator

I implemented a stateless sandbox route for indexing the TypeScript declaration surface of exact npm packages without executing package code.

  • Add synchronous npm-unit dispatch without Redis jobs, persistence, or S3 round trips.
  • Restrict registry access through short-lived capabilities bound to an exact package tarball.
  • Verify SHA-512 integrity before decompression.
  • Parse tarballs in memory while rejecting unsafe paths, links, devices, excessive entries, oversized files, and decompression bombs.
  • Run parsing in a fresh network-disabled NsJail with route-specific cgroup memory, CPU, and wall-clock limits.
  • Return deterministic files, symbols, imports, rejection counters, partial-status details, and resource usage.
  • Pin web-tree-sitter@0.24.7 and tree-sitter-wasms@0.1.13.
  • Add Helm, Compose, OpenAPI, runtime-image, and operational documentation.
  • Add contract, dispatch, archive-hardening, parser-ordering, egress-policy, redirect, and capability tests.

Change Type

  • New feature (non-breaking change which adds functionality)
  • This change requires a documentation update
  • Documentation update

Testing

  • Ran the npm archive and deterministic parser tests.
  • Ran the npm contract, direct dispatch, and hardened-startup tests.
  • Built the API and service packages.
  • Validated Helm with npmUnit.enabled=true.
  • Validated Docker Compose, shell syntax, OpenAPI YAML, and Git diff formatting.

Checklist

  • My code adheres to this project's style guidelines
  • I have performed a self-review of my own code
  • I have commented in any complex areas of my code
  • I have made pertinent documentation changes
  • My changes do not introduce new warnings
  • I have written tests demonstrating that my changes are effective or that my feature works
  • Local unit tests pass with my changes

@danny-avila
danny-avila marked this pull request as ready for review August 8, 2026 11:18
Comment thread helm/codeapi/values.yaml
# Fail fast above this per-service-worker cap; npm-unit requests are never
# written to the Redis job queue.
concurrency: 8
requestTimeoutMs: 45000

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 High codeapi/values.yaml:69

npmUnit.requestTimeoutMs is only injected into the service-worker deployment, but the API forwarding path reads it via NPM_UNIT_REQUEST_TIMEOUT as well. Setting this Helm value above the API's default causes the API to abort the synchronous /internal/npm-unit request after ~46 seconds even though the worker is configured to wait longer, so longer timeouts silently don't take effect end-to-end. Inject the same value into the API container's environment (or use a separately configured forwarding timeout) so both sides honor the configured limit.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @helm/codeapi/values.yaml around line 69:

`npmUnit.requestTimeoutMs` is only injected into the service-worker deployment, but the API forwarding path reads it via `NPM_UNIT_REQUEST_TIMEOUT` as well. Setting this Helm value above the API's default causes the API to abort the synchronous `/internal/npm-unit` request after ~46 seconds even though the worker is configured to wait longer, so longer timeouts silently don't take effect end-to-end. Inject the same value into the API container's environment (or use a separately configured forwarding timeout) so both sides honor the configured limit.

Comment thread api/src/api/npm-unit.ts
timedOut ? 'Registry request timed out' : 'Registry gateway was unavailable',
true,
);
} finally {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 High api/npm-unit.ts:183

The fetch timeout is cleared in the finally block right after fetch() resolves, before readBoundedTarball() reads the response body. A registry gateway that sends headers quickly but then stalls its chunked body leaves readBoundedTarball() waiting indefinitely — SANDBOX_NPM_UNIT_FETCH_TIMEOUT no longer bounds the fetch, so connections can accumulate. Keep the abort timer active through body consumption and pass controller.signal into readBoundedTarball so a stalled stream is still aborted.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @api/src/api/npm-unit.ts around line 183:

The fetch timeout is cleared in the `finally` block right after `fetch()` resolves, before `readBoundedTarball()` reads the response body. A registry gateway that sends headers quickly but then stalls its chunked body leaves `readBoundedTarball()` waiting indefinitely — `SANDBOX_NPM_UNIT_FETCH_TIMEOUT` no longer bounds the fetch, so connections can accumulate. Keep the abort timer active through body consumption and pass `controller.signal` into `readBoundedTarball` so a stalled stream is still aborted.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant