34 lines
1.7 KiB
Markdown
34 lines
1.7 KiB
Markdown
# Scanner Runtime Evidence (Node)
|
|
|
|
## Purpose
|
|
Optional, air-gap-friendly runtime capture for Node workloads to enrich dependency graphs with observed imports/loads. Produces append-only NDJSON that the Node analyzer ingests as `node:runtime-*` records.
|
|
|
|
## Capture hooks
|
|
- **CJS**: `runtime-hooks/runtime-require-hook.js`
|
|
- Usage: `SCANNER_NODE_RUNTIME_OUT=<out.ndjson> SCANNER_NODE_ROOT=<root> node -r ./runtime-require-hook.js app.js`
|
|
- **ESM**: `runtime-hooks/runtime-esm-loader.mjs`
|
|
- Usage: `SCANNER_NODE_RUNTIME_OUT=<out.ndjson> SCANNER_NODE_ROOT=<root> node --experimental-loader=./runtime-esm-loader.mjs app.mjs`
|
|
|
|
## Output format (NDJSON)
|
|
Each line is a JSON object:
|
|
- `type`: `edge` | `component`
|
|
- `from` / `to`: module specifiers (scrubbed relative to `SCANNER_NODE_ROOT` when possible)
|
|
- `reason`: e.g., `runtime-import`, `runtime-require`, `runtime-load`
|
|
- `loaderId`: arbitrary string; hashed to SHA-256 during ingestion
|
|
- `path`: component path for `component` records
|
|
|
|
## Ingestion rules
|
|
- File name defaults to `node-runtime-evidence.ndjson` in the scan root; override with `SCANNER_NODE_RUNTIME_EVIDENCE`.
|
|
- Paths are scrubbed relative to the analyzer `rootPath`; absolute paths outside root remain absolute.
|
|
- Loader IDs are SHA-256 hashed before storage (`loaderId.sha256`).
|
|
- Evidence is tagged as `node:runtime-edge` or `node:runtime-component` with derived evidence from the reason/locators.
|
|
|
|
## Determinism & safety
|
|
- Append-only writes; no network access.
|
|
- Stable hashing, stable ordering during ingestion (sorted by `componentKey`).
|
|
- Path scrubbing prevents leakage of host-specific prefixes when root-relative.
|
|
|
|
## When to use
|
|
- Debugging dynamic imports/require resolutions.
|
|
- Environments with heavy plugin loading where static analysis is insufficient.
|