feat(parity): gate-ready pipeline-doctor + OCI verify-digest + stage/push-staged audit

pipeline-doctor (#191/#193): add --strict (fail on WARN) so a .woodpecker.yaml
step or pre-receive hook can gate on exit code; add documented ci/local.sh
escape-hatch (#196); fix false-negative — token/dev-tag/dry-run/meta contracts
are guaranteed by parity-lib for a consumer, so consumers PASS by delegation
instead of being penalized for not re-implementing them inline. Self-check and
numpy-s390x both pass 9/9.

mkNix2ContainerPublish (#195): add verify-digest app that builds each local arch
image and prints its OCI manifest digest (no registry contact), formalizing the
content-addressed manifest digest as the parity contract. reproducible=false is
kept deliberately (non-reproducible layer deps); digest-as-contract is the
low-risk path. Generalized from claude-plugin-registry 55f2d0b.

stage/push-staged audit (#194): verified all 8 builders expose stage-<arch> +
push-staged; all already complete, no gaps.
This commit is contained in:
Oleks
2026-06-02 21:11:49 +03:00
parent af64a8ea4c
commit 79f9a2dd62
3 changed files with 163 additions and 15 deletions
+34
View File
@@ -7,6 +7,40 @@ semantic versioning; the version is a conceptual tag (no git tag is created).
## Unreleased
- **Feature: `verify-digest` for nix2container (cluster #195).** `mkNix2ContainerPublish`
now also returns a `verify-digest` app that builds each locally-buildable arch
image and prints its OCI **manifest digest** with NO registry contact (it
`copyTo`s a throwaway local `oci:` dir and reads the digest skopeo derives).
This formalizes the manifest digest as the parity contract: the OCI layers are
built `reproducible = false` ON PURPOSE (the fix for the "Digest did not match"
caused by non-reproducible layer deps + nix2container's lazy tar regeneration),
so byte-identical-tar parity is NOT promised — but the content-addressed
manifest digest the registry stores the image under IS stable. Identical local
vs CI digest ⇒ identical registry artifact. We do NOT flip `reproducible` to
`true` (the inputs are not reproducible); the LOW-RISK digest-as-contract path
was chosen instead. Generalized from the claude-plugin-registry prototype
(`55f2d0b`) so every nix2container consumer gets it for free.
- **`pipeline-doctor` is now GATE-READY (cluster #191/#193).** It already exited
non-zero on any failing required check; added a `--strict` mode that ALSO fails
on any `WARN`, so a `.woodpecker.yaml` step or a server pre-receive hook can call
`pipeline-doctor --strict <repo>` and rely on the exit code. Added a documented
**`ci/local.sh` escape-hatch** (cluster #196): a repo that must keep a
hand-written Dockerfile/BuildKit pipeline may opt out of the archetype /
parity-lib asserts (downgraded to warnings) if it ships a `ci/local.sh`
local==CI entrypoint. Fixed a false-negative: the token / dev-tag / dry-run /
`meta.description` contracts are GUARANTEED by parity-lib for a consumer (they
live in the generated apps, not the consumer's `flake.nix` text), so a repo that
consumes parity-lib now PASSES those by delegation instead of being penalized
for not re-implementing them inline. Self-check stays green and a known-good
consumer (`numpy-s390x`) now passes 9/9.
- **Audit: stage + push-staged uniform across all 8 builders (cluster #194).**
Verified every archetype builder exposes a `stage-<arch>` (build-parity, no
registry contact, writes `./.parity-stage`) AND a `push-staged` (replay the
staged artifact): `mkPyPiWheelPublish`, `mkPyPiWheelPublishMulti`,
`mkS390xNpmPublish`, `mkS390xNpmPublishMulti`, `mkGenericBinaryPublish`,
`mkGoBinaryPublish` (alias), `mkNix2ContainerPublish` and `mkHelmPublish`
(`stage-chart`). All were already complete — no gaps to fill; the build-parity /
publish-parity split is uniform.
- **Feature: `mkS390xNpmPublishMulti` (cluster #192).** A multi-version npm
builder mirroring the PyPI multi one: publishes a fixed list of
`{ version; file; distTag? }` per tag, each staged into its own dir and