release hardening: tested-is-shipped, pinned inputs, build-once, honest identity - #13
Merged
Merged
Conversation
…st identity Workflow slice of the release-engineering track (dplaax.spec release.* rules). Everything here is repo-local; nothing changes the published images until the next deliberate version cut. **Node 24 everywhere** (release.toolchain.tested-is-shipped): CI tested on 22 while every image stage ships node:24-alpine, which narrowed each green check to "green somewhere else". CI and release.yml now test 24, and the root package.json declares engines >=24 <25. **corepack@0.35.0** in the generated-instance Dockerfile and both scaffold templates: `npm install -g corepack --force` floated to whatever npm served that day — an unpinned build input the spec calls out by name. **release.yml explicitly disabled** (if: false): nothing is on npm and the preconditions for publishing (trusted publishing, per-ecosystem provenance) are not built. Until now it was only accidentally inert — its tag pattern never matched and the NPM_TOKEN secret does not exist. Neither accident is a gate; the if: line is. Re-enabling means building trusted publishing, not restoring a token. **build-once guard** (release.build.once): publishing a version tag now fails if that tag already resolves in GHCR — the scanned bytes and a rebuild's bytes are different artifacts sharing a name, and the exit is a new version. Plus a concurrency group so two runs on one ref cannot interleave a multi-arch push. **sha-<sha> is not "immutable"** (release.docs.match-artifacts): the header called the sha tag immutable and the quickstart called it exactly reproducible. It names the source commit but is still a registry tag — this workflow itself would move it if re-run on the same commit. The docs now say what is true: the digest is the identity, tags are locators. Each run prints its digests to the job summary (release.subject.exact-digest, the cheap half). **sbom: true**: per-platform final-stage SPDX attestations. Deliberately described as inventory, not completeness — binding evidence to the index digest is the release-evidence manifest's job and stays on the P0-7 track, alongside base-image digest pins (consciously deferred: digest-pinning bases without a scan/refresh loop freezes CVE fixes, a net loss at this maturity).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Workflow slice of the release-engineering track (dplaax.spec
release.*rules), shaped by a Codex plan review. Everything is repo-local; no image
changes until the next deliberate version cut — no cut happens here.
ci.yml(×3 jobs) +release.yml,engines: >=24 <25in root package.jsontoolchain.tested-is-shippednode:24-alpine— each green check meant "green somewhere else"corepack@0.35.0in generated-instance Dockerfile ×2 + both scaffold templatesnpm install -g corepack --forcefloated to whatever npm served that dayrelease.yml→if: falsewith the reasonprovenance.per-ecosystempreconditionNPM_TOKENdoesn't exist. Neither accident is a gatepublish-images.ymlbuild.oncedocs.match-artifacts,subject.exact-digestsha-<sha>immutable — it names the source commit but is still a mutable registry tag; the digest is the identitysbom: truesbom.subject-bound(partial)Consciously deferred (recorded, not forgotten)
freezes CVE fixes; net loss at this maturity. Comes with the P0-7 scanner
track, which also owns index-digest evidence binding, provenance
verification, and the scan/waiver state machine (the conformance ledger
already declares all
release.*unimplemented).v0.2tag — maintainerdecision: cross-repo digest choreography costs more than it buys here. The
wording fix (this PR + an oss-side follow-up) makes the claim honest instead.
Test plan
All workflows parse (yaml.safe_load ×5), package.json parses. CI on this PR
runs the Node-24 toolchain for the first time — build-and-test + both smokes
going green is the tested-is-shipped verification. The publish-images
changes are exercised at the next version cut; the build-once guard's
failure path was designed against the registry API responses verified today
(anonymous token + manifest HEAD, 200 vs 404).
🤖 Generated with Claude Code