All 30 public packages are released from .github/workflows/release.yaml. The
workflow is the only supported publication path. It uses the protected
npm-production environment and npm trusted publishing (OIDC); release
automation must not use a long-lived npm write token.
A release first builds and validates the workspace in an uncredentialed
prepare job. That job has read-only repository access, no npm-production
environment, no OIDC permission, and no persisted Git credentials. Package
build or lifecycle code therefore cannot mint an npm publisher token or push
repository changes.
The uncredentialed prepare job:
manifest.json;When several unpublished first-party candidates are staged together, SBOM generation resolves their complete staged runtime and peer-dependency closure from the local exact tarballs. It does not fall through to npm for a version that is present in the candidate set. Resolver-only top-level dependencies are removed from the final SBOM root relationship, so the evidence retains the package manifest's original direct dependency and peer relationships. This temporary resolution never rewrites or repacks the immutable publication tarballs. Local resolver paths are removed from the final SBOM; package purls, cryptographic hashes, licenses, and dependency relationships remain, without leaking a runner-specific filesystem location.
Staging validates the exact governed Node.js and pnpm versions, plus the minimum npm version, before creating the output directory or packing any candidate. The final candidate uses the exact governed pnpm version. Canonicalization sorts only dependency and peer-metadata maps; it preserves order-sensitive fields such as conditional exports and verifies that the publishable file set does not change. The transient workspace snapshot is deleted before evidence is generated. Together these controls prevent asynchronous workspace-version resolution from producing different bytes for equivalent package manifests.
The protected publish job downloads that immutable candidate, runs no package
build or lifecycle code, and:
.tgz files to npm publish --provenance with lifecycle
scripts disabled; andNo build, pack, code-generation, or version-rewrite step may run between attestation and publication. Published npm versions are immutable. A partial retry skips an already-published version only when its registry digest exactly matches the staged artifact.
The machine-readable contract is
governance/npm-package-supply-chain.json. Repository health tests ratchet the
workflow order, pinned actions, package count, scan gate, attestation
predicates, tokenless publication, and evidence policy.
packages/<path>/vX.Y.Z selects one governed package.release/vYYYY-MM-DD selects all governed packages.vX.Y.Z and a manual cascade release select all governed packages.main.Selection is not publication. A package is staged only when its exact
name@version is absent from npm. Package versions must therefore be updated
and reviewed on main before creating a release tag.
Download the registry tarball without installing it, then verify its GitHub attestations:
SDK_VERSION="$(npm view @bsv/sdk version)"
npm pack "@bsv/sdk@$SDK_VERSION"
gh attestation verify "bsv-sdk-$SDK_VERSION.tgz" \
--repo bsv-blockchain/ts-stack \
--signer-workflow bsv-blockchain/ts-stack/.github/workflows/release.yaml \
--predicate-type https://slsa.dev/provenance/v1
gh attestation verify "bsv-sdk-$SDK_VERSION.tgz" \
--repo bsv-blockchain/ts-stack \
--signer-workflow bsv-blockchain/ts-stack/.github/workflows/release.yaml \
--predicate-type https://cyclonedx.org/bomAfter installing dependencies with a lockfile, verify npm registry signatures and npm provenance attestations:
npm audit signaturesFor a particular release run, download the npm-release-<run>-<attempt>
workflow artifact to inspect the exact release manifest, per-package SBOMs,
aggregate SBOM, license inventory, checksums, and offline GitHub attestation
bundles.
Each public package must configure the npm trusted publisher as:
bsv-blockchain;ts-stack;release.yaml;npm-production; andnpm publish.After trusted publishing has been confirmed for a package, its npm publishing access should require 2FA and disallow traditional write tokens. Changing the repository, workflow filename, environment, or package ownership requires a coordinated update to all package settings before merging the source change.
Do not replace an immutable version after a failed release.
publish job within the
candidate artifact's one-day retention window. It reuses the original
candidate bytes; exact matching versions are verified and skipped, and
remaining packages continue in dependency order. If the candidate has
expired, review the published subset and prepare a deliberate recovery
release rather than assuming newly packed bytes are identical.