impureBuild: build the consumer's flake attr at run time via
nix build --impure --sandbox false, instead of embedding the image
closure as an eval-time build dep — required for images that fetch
private artifacts with a token at build time (ii-agent). indexMovesLatest:
publish-index also moves :latest, for repos that publish each arch on a
separate CI agent and converge in a final index-only step. Both opt-in,
default-off; existing consumers unchanged. Verified by eval in both modes.
Lift the nix2container reproducible=false layer-chain helper (duplicated
verbatim across ii-agent, ii-researcher, temporal-based-ci, mempalace image,
ComfyUI) into parity.lib.foldImageLayers so the rationale lives in one place.
Add nixfmt-rfc-style formatter and a foldImageLayers contract probe to the
smoke check. Bump fleet-pins input to current HEAD.
Branch-deploy repos (event: push + branch:, tagging each push from
CI_COMMIT_*/pipeline-number) are a deliberate continuous-deploy guard, not
the absence of one. cms-plugins/emdash/kotkanagrilli -> 9/9; trio + self-test
unchanged; a tagless default-version publish still FAILs.
The dev-tag-guard check missed repos whose Woodpecker config is a
.woodpecker/ directory of per-arch workflows (the refs/tags/v* trigger
never entered ci_txt). Now globs .woodpecker/*.yaml|*.yml too.
commonground-legacy + csi-s3 -> 9/9; trio + self-test still 9/9.
The audit sweep wrongly FAILED ~9 converted ci-script repos on two heuristics:
- token-contract now accepts the secure indirection pass "$PASS_ENTRY" /
pass "$VAR", not only a hard-coded pass <literal-path>.
- leak scan flattens \-continuations + folds the pipe target onto the echo
line, then exempts the echo "$TOKEN" | <cmd> ... --password-stdin/--pass-stdin
stdin-feed idiom; bare echo to stdout/file and set -x still FAIL.
Adds --self-test with six inline fixtures locking in both fixes and the
three must-still-catch leaks.
Adds the attic-closure archetype builder (build closure + attic push, no
registry artifact) so caddy/overlay-xonsh/flake-hub/woodpecker-peek share one
implementation. Adds non-flake mode to pipeline-doctor so ci-script repos
(gitea-mcp, helms) pass the gate. Self-check 9/9; gitea-mcp now passes.
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.
Mirrors mkPyPiWheelPublishMulti for npm: publishes a fixed {version,file,
distTag?} list, each staged into its own dir and npm-published with its
dist-tag (idempotent). file may be a .node or a plain binary; packageJson
declares main-vs-bin. Unblocks nextjs-swc (next15 dist-tag) + sentry-cli.
Shared parity_npm_publish_dir helper added.
Single-version mkPyPiWheelPublish made consumers ship only the default
version per tag. Add a multi-version builder that loops over a fixed
{version,wheel} list (version parsed from the wheel filename, idempotent
409-skip), plus shared parity_pypi_post/parity_wheel_version helpers.
The guard read $VERSION, but app bodies set VERSION to the derived default
before calling it, so accidental local --publish without an explicit version
or v* tag still pushed. Capture PARITY_VERSION_EXPLICIT at source time and
gate on that instead.
Implements the shared parity flake-module library so the ~51 parity repos
consume one source of truth instead of hand-inlined publish shells.
- lib.mk{PyPiWheel,S390xNpm,GenericBinary,Nix2Container,GoBinary,Helm}Publish
builders returning stage-<arch>/publish-<arch>/publish-index/publish/
push-staged apps per the corrected emmett#44 standard (build-parity stages to
./.parity-stage with no registry contact; publish dry-runs by default;
publish-index is build-free + fail-closed; :latest is the last digest copy).
- Shared ci/parity-lib.sh: token resolution ($REGISTRY_TOKEN + pass fallback,
never printed), dev-tag guard, version derivation, dry-run gate, preflight.
- pipeline-doctor package/app asserting the parity contract (cluster #193).
Refs cluster #192, #193, #194, emmett#44.