ADR 0004: npm Is Not a Supported 1.0 Distribution Channel¶
Status: Accepted for 1.0 planning Date: 2026-08-19 Requirements: NPM-01 through NPM-15, RC-03, EXEC-06 Decision owners: Distribution, security, release
Context¶
specs/1.0.0/08-npm-distribution.md treats npm as a conditional channel: every requirement in it
begins "If npm is a supported 1.0 channel". Fifteen requirements sit behind that condition and
nobody has recorded an answer, so the ledger carries them as unmet work rather than as a decision.
The tree gives no evidence npm was ever started. There is no @blkleg/* package, no publish
workflow, and the root package.json is private: true. apps/frontend/package.json is a
workspace manifest for the bundled UI, not a publishable artifact.
The distribution channels that do exist and are tested are native systemd packages
(deb/rpm/apk/Arch/AppImage/tar for amd64 and arm64) and the mono container image
ghcr.io/blkleg/circuitbreaker. Both carry signing, checksums, SBOMs and a publication gate in
release.yml: the packages must install and uninstall cleanly on a fresh host before anything is
published, and the image is vulnerability-scanned before it is signed. Adding npm would mean a new
package identity, a registry namespace with its own MFA and access review, trusted publishing via
OIDC, cross-platform tarball smoke tests on Linux/macOS/Windows, and a compromise-and-revocation
procedure — NPM-12 through NPM-15 — for a channel with no current users.
Decision¶
npm is not a supported distribution channel for Circuit Breaker 1.0.
- The root repository manifest stays
private: true, andtests/build/test_tracked_file_policy.py::test_root_npm_manifest_stays_privateasserts it, so an accidentalnpm publishfrom the repository root is refused rather than merely discouraged. - No package is published to npmjs under any name for the 1.0 line.
- NPM-01 through NPM-15 are recorded as not applicable for 1.0 under exception
EXC-003, not as unmet requirements. - Documentation names native and mono — the two deployment modes that ship, per
the installation overview — as the only supported
installation methods, and does not present
npm/npxexamples.
docs/release/1.0.0-support-contract.md listed npm distribution as deferred "until the NPM slices
pass"; this ADR converts that open-ended deferral into a decision for the 1.0 line, and the support
contract's npm row now points here.
Rejected alternatives¶
| Alternative | Reason rejected |
|---|---|
| Publish an installer CLI now (NPM-03) | A wrapper that downloads and verifies signed artifacts duplicates install.sh, while adding a registry account, a publish credential and three new platform test matrices to the release gate. |
| Publish an API client/SDK now (NPM-04) | An SDK is a compatibility promise. RC-03 records that 1.0 makes no stable public API or SDK guarantee, so the SDK would either be unversionable or would force a promise the release contract declines to make. |
| Reserve the namespace without publishing | Insufficient on its own: NPM-12 asks for organization MFA, two maintainers and periodic access review, which is ongoing governance for an unused name. Worth doing as squatting defence, but it is not a release requirement and does not change this decision. |
| Leave the decision open | NPM-01 blocks EXEC-06, so an unanswered question is indistinguishable from an unmet requirement at the release gate. Fifteen rows would stay red for a channel nobody intends to ship. |
Consequences¶
- Fifteen release requirements close as excepted without writing a package, and the supply-chain surface stays at two governed channels — no namespace to defend, no registry access review, no publish credential to rotate.
- Users who expect an
npx @blkleg/circuitbreakerinstaller do not get one.install.shis the equivalent entry point and is documented as such. - Documentation and release notes must not show
npm installornpxas an installation path; doing so would reintroduce the promise this ADR declines. specs/1.0.0/08-npm-distribution.mdstays in the spec set as the design for a future channel, not as open 1.0 work.
Long-term reopening criteria¶
npm can be reconsidered after 1.0 when there is a reason to ship it. Reopening requires:
- answering NPM-01's first question — installer CLI or API client/SDK — before any implementation;
- for the SDK path, the API compatibility window and contract tests that RC-03 currently declines to promise;
- namespace, MFA, two maintainers and access review under NPM-12; and
- trusted publishing with provenance under NPM-13, so no long-lived token exists.
Superseding this ADR is the mechanism; the exception register row EXC-003 closes with it.