0001
August 10, 2026 · View on GitHub
- Status: Accepted
- Date: 2025-06-09
- Deciders: quantakrypto-tools maintainers
- Supersedes / Superseded by: —
Context
quantakrypto-tools is security-positioning software: it tells users where their
quantum-vulnerable cryptography lives and it runs in privileged contexts (CI with
write tokens, AI agents with filesystem access, a potential hosted MCP service).
For such a tool, the supply chain is part of the threat model. The dominant
class of JavaScript-ecosystem risk is transitive dependencies and npm lifecycle
scripts (postinstall/prepare), as the security audit §6
records. A scanner that itself drags in a deep dependency tree would undermine
the assurance it sells.
Most of what the tools need — JSON-RPC/MCP framing, the GitHub Actions toolkit
surface (input parsing, annotations, PR comments), CLI argument parsing, SARIF
emission, NDJSON protocol handling, base64 — is small enough to hand-roll on Node
built-ins (node:fs, node:http, node:readline, node:crypto,
node:child_process, global fetch on Node ≥ 18/20).
Decision
We will ship zero runtime dependencies across every published package. The
only permitted runtime imports are Node built-ins and internal @quantakrypto/*
workspace packages. No package may declare a third-party dependencies entry.
We will also keep the dev-tooling surface minimal (typescript, tsx,
@types/node) and ship no postinstall/preinstall/prepare/install
lifecycle scripts in any package.
Any future feature that wants a runtime dependency must justify it in a new ADR against this baseline; the default answer is "hand-roll it on built-ins or do without."
Consequences
Easier: a near-nil dependency attack surface (no transitive CVEs, no
typosquats, no lifecycle-script execution vector); trivial npm ci reproducibility;
strong free wins on OpenSSF Scorecard (Pinned-Dependencies, Vulnerabilities);
a credible posture for the security claim the tools make.
Harder (costs accepted): we re-implement and maintain functionality that mature libraries provide — JSON-RPC dispatch, Actions shims, arg parsers, SARIF. These hand-rolled parsers are an input-handling risk concentrated in our own code (which is why calls for fuzz targets over the four of them: Sieve protocol/base64, manifest JSON, SARIF, qScan args). We accept this tradeoff: a small amount of audited first-party parsing code is preferable to a large unaudited dependency tree.
Enforcement: keep dependencies empty (sans @quantakrypto/*) in every
package.json; build/release with npm ci (lockfile integrity); a CI check that
fails on any non-@quantakrypto/* runtime dependency or any lifecycle script keeps the
invariant from eroding. The runtime deps: 0 README badge is a public commitment.
Alternatives considered
- Allow a small, vetted dependency set (e.g.
@actions/core, an MCP SDK, a SARIF builder). Rejected: it reintroduces transitive trust and lifecycle-script exposure for code we can write in a few hundred lines, and weakens the headline assurance property. - Bundle dependencies at build time (vendoring). Rejected for runtime code as
unnecessary given the built-ins suffice; bundling is used for the Action's
dist/for a different reason (a JavaScript action must run committed JS — see).