Files
git.stella-ops.org/docs/modules/scanner/design/node-bundle-phase22.md
2026-01-07 10:23:21 +02:00

51 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Scanner Node Phase 22 (22-006/007/008) · Prep deliverable
Purpose: unblock PREP tasks by freezing analyzer inputs/outputs, resolver traces, and fixtures for Node bundle/source-map coverage, native/WASM detection, and AOC-compliant observation emission.
## Output artefacts
- Sample NDJSON: `docs/modules/scanner/samples/node-phase22/node-phase22-sample.ndjson` (covers 22-006/007/008 in one run).
- Resolver trace spec and reason codes (below) are binding for workers and tests.
## 22-006 · Bundle + source-map reconstruction
- Detect bundles by `sourceMappingURL` trailers and common bundle signatures (webpack runtime, rollup intro, esbuild banners).
- Load `.map` file (inline/base64 or adjacent file); reject maps >50 MB or with missing `sourcesContent`.
- Resolver trace must include: `["bundle:<path>", "map:<path|inline>", "source:<original-path>"]`.
- Recovered module specifier shape: `{ "type": "component", "componentType": "pkg", "path": "<relative path>", "format": "esm|cjs", "fromBundle": true, "confidence": 0.8+ }`.
- Normalize paths to POSIX, strip inline `webpack://` prefixes, collapse duplicated `..` segments, and dedupe.
## 22-007 · Native addon / WASM / capability signals
- Native addons: detect `.node` files (ELF/PE/Mach-O) and `process.dlopen` calls. Emit `componentType:"native"` with `arch`, `platform`, and optional `soname`.
- WASM: detect `.wasm` files and dynamic imports (`WebAssembly.instantiate*`). Emit `componentType:"wasm"` with `exports` (function names if discoverable).
- Capability signals: AST scan for `child_process`, `vm`, `worker_threads`, `process.binding`, `fs.promises` `openFileHandle`.
- Reason codes (stable strings):
- `native-dlopen-string`, `native-dlopen-template`, `native-addon-file`,
- `wasm-import`, `wasm-file`,
- `capability-child-process`, `capability-vm`, `capability-worker`, `capability-binding`, `capability-fs-promises`.
- Hint edges: `{ "type":"edge", "edgeType":"native-addon|wasm|capability", "from":"<module>", "to":"<artifact>", "reason":"<code>", "confidence": 0.60.9 }`.
## 22-008 · AOC-compliant observation emission
- Emit NDJSON records grouped by `entrypoints`, `components`, `edges`, `resolverTrace` per record.
- Required fields: `type`, `from`, `to` (for edges), `componentType`, `format`, `reason`, `confidence`, `resolverTrace` (array, stable ordered). Optional `scopes` (`runtime|dev|optional`) when derived from package.json sections.
- Determinism:
- Sort output by `type` then `path/from/to` strings; stable sort within edges by `edgeType`.
- Timestamps forbidden; no filesystem mtime or random IDs.
- All paths POSIX, absolute paths stripped to container root.
## Validation gates
- Reject payloads if resolverTrace missing, empty, or unsorted.
- Reject entries when `confidence < 0.4` to avoid noise; keep suppressed entries in debug logs only.
- Large maps: emit `ERR_NODE_BUNDLE_MAP_TOO_LARGE` and skip map (still report bundle presence with `confidence:0.51`).
## Fixtures
- `docs/modules/scanner/samples/node-phase22/node-phase22-sample.ndjson` contains:
1) webpack bundle w/ source map mapping to `/src/app.js` (22-006)
2) native addon load via `process.dlopen('./native/addon.node')` (22-007)
3) WASM module import via `WebAssembly.instantiateStreaming(fetch('./pkg.wasm'))` (22-007)
4) capability signal for `child_process.execFile` (22-007)
5) consolidated edges + components emitted per AOC rules (22-008)
## Implementation notes
- Keep analyser pure: no execution of JS; rely on parse + static string matching. Use cached sourcemap parser in `StellaOps.Scanner.Analyzers.Lang.Node`.
- Resolver trace must be included verbatim in tests; any change requires fixture update and sprint note.
- Workers must mark node phase 22 outputs as experimental behind feature flag `scanner:node:phase22=true` defaulting true for CI only until stabilized.