Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 24 additions & 6 deletions .codex/skills/release-oliphaunt/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ and do not treat target/ecosystem carriers as additional products.
2. For registry/GitHub setup, identity bootstrap, or trusted-publisher work,
also read `docs/maintainers/release-setup.md`.
3. For a failed or partially public release, also read `references/recovery.md` before changing state.
4. Record the candidate commit with `git rev-parse HEAD`; keep that SHA unchanged through qualification, lock creation, and publish.
4. Record the candidate commit with `git rev-parse HEAD`; keep that SHA unchanged through qualification, lock creation, and publish. The only exception is the documented same-version control recovery: its later current-main controller receives fresh qualification, while the original release commit/tree remains the immutable publication source and retains its byte-identical approved lock.
5. Inspect `git status`, product versions, existing product tags/releases, registry identities, and the latest exact-SHA CI run. Report any public collision before attempting a mutation.
6. Run `tools/dev/bun.sh tools/release/audit-github-release-controls.mjs` with the truthful credential lifecycle before any external mutation. Use `--governance solo --bootstrap-state idle` for history repair, qualification, release-PR preparation, and dry-run while bootstrap tokens are absent. Rerun with `--bootstrap-state ready` only for an imminent first-identity bootstrap after every reviewed short-lived token required by the approved lock is installed (one registry or both; the current first release needs both); use `retired` after trusted publishers are configured and every provisioned token is revoked. Select `team` only with an independent maintainer. Treat `FAIL` as a blocker; report but do not promote `WARN` to a solo-release blocker.
6. Run `tools/dev/bun.sh tools/release/audit-github-release-controls.mjs` with the truthful credential lifecycle before any external mutation. Use `--governance solo --bootstrap-state idle` for history repair, qualification, release-PR preparation, and dry-run while bootstrap tokens are absent. Rerun with `--bootstrap-state ready` only for an imminent first-identity bootstrap after every reviewed short-lived token required by the approved lock is installed (one registry or both). If exact inventory proves that all selected Cargo/npm identities already match, keep the credential lifecycle `idle` and provision neither token. Use `retired` after trusted publishers are configured and every provisioned token is revoked. Select `team` only with an independent maintainer. Treat `FAIL` as a blocker; report but do not promote `WARN` to a solo-release blocker.
7. Generate trusted-publisher work from the approved publication lock with `tools/dev/bun.sh tools/release/trusted-publisher-config.mjs`. Its default mode is offline/read-only. Use authenticated `--audit` before considering `--apply`; mutation additionally requires the exact printed lock digest. Run npm audit and apply directly in a terminal because each classification pass starts with a discarded read-only TTY authentication warm-up before the bounded captured reads, and supply a fresh `--output` path for the atomically created mode-`0600` JSON evidence. Configure the direct workflow `release.yml` and `release-publish` environment. Keep release credentials only in their protected environments; do not add repository-level copies or a reusable-workflow secret bridge.
8. On a generated release PR, treat Release Please as the direct-candidate
authority and `sync-release-pr.mjs` as the deterministic dependent-candidate
Expand All @@ -51,7 +51,11 @@ Treat `.github/workflows/release.yml` as the sole release workflow. Its
credential-bearing jobs directly select their protected environments. Its
environment-free, secret-free continuation dispatchers consume only the typed
outputs of `publish-bootstrap` or `publish-registry` and dispatch the sealed
exact-parent pointer; never route a continuation around that DAG.
exact-parent pointer; never route a continuation around that DAG. Continuations
are available only to normal single-identity publication, where source equals
controller. Same-version dual-identity recovery rejects bootstrap and
continuation inputs and resumes only through an idempotent root `publish`
rerun.

A root `publish-bootstrap` or `publish` dispatch must run from the qualified
current `main` commit. At the mutation boundary the transport helper first
Expand All @@ -75,7 +79,16 @@ another repository mutation.
- Prepare: synchronize release-owned files, run release checks, create the generated release PR, and stop for review.
- Bootstrap: use the dedicated bootstrap environment only for identities that cannot use trusted publishing until their first package exists, including generated part identities introduced by a future lock. For npm, require a short-lived granular token with explicit `@oliphaunt` scope selection, Packages and scopes `Read and write`, and 2FA bypass, owned by a 2FA-enabled actor with scope write access; an ordinary token can authenticate yet fail the noninteractive publish with `EOTP`. Require one successful exact-SHA dry-run containing both `oliphaunt-publication-lock` and `oliphaunt-bootstrap-capsule`; select one run ID, verify the capsule's embedded lock against the separately downloaded lock, and publish only those frozen Cargo/npm bytes without rebuilding. Inventory the exact lock first. Model crates.io's documented token bucket; never accept an unverifiable numeric capacity assertion. Execute one sequential Cargo lane and one sequential npm lane, overlap only independent carriers, and preserve every lock dependency as a barrier. If one hosted job cannot finish, flush and upload the canonical hash-chained checkpoint before a separate credential-free job dispatches a bounded exact-parent continuation. Bind it to release/lock/package identity and exact artifact ID/digest/size, and permit zero-progress recursion only for explicitly typed, finite-budget rate-limit/deadline continuations. A valid `429 Retry-After` may defer; ambiguous uploads, timeouts, integrity mismatches, malformed responses, and checkpoint failures remain hard failures. After every identity has a receipt, use that exact lock with `tools/release/trusted-publisher-config.mjs`: its default plan has no network access, `--audit` is read-only, and mutation requires both `--apply` and the exact `--confirm-lock-digest`. Run npm audit/apply in a real TTY and retain each fresh `--output` JSON report, never the discarded authentication warm-up display. Require workflow `release.yml`, environment `release-publish`, and npm publish-only permission; reject extra or mismatched configurations. Revoke long-lived credentials, then resume normal publish.
- Publish: require a successful exact-SHA `Qualified` gate, complete artifact set with binary compatibility-floor evidence, current full-lifecycle WASIX evidence when selected, frozen publication lock, the exact Release Please PR markability proof, and the all-registry rate-aware admission preflight. Before crossing the mutation boundary, build and validate the complete signed Maven Central bundle locally (including sources/javadocs and the strict size ceiling), and prove the lock-derived Swift semantic tag is absent or already resolves to the exact deterministic manifest commit. At that boundary, admit the root through the immutable transport rule above before any product tag, draft, asset, or registry mutation. Normal publish remains logically ordered as stage GitHub drafts/assets/attestations, publish the exact registry topology, then verify public consumers and promote. A registry continuation may span hosted jobs but must reuse the original exact stage handoff and immutable checkpoint; finalization is disabled until receipts are exhaustive. Every normal continuation must also carry the latest root-lineage-bound GitHub content-write pacer and core-request journal, merge the child's pre-install reads monotonically, and reject reset, replay, or substitution. Transfer state only through manifest-exact artifacts downloaded by immutable ID: reuse the approved Cargo/npm capsule rather than retransferring its carriers, send only required non-capsule registry inputs in the stage handoff, and send receipts only to finalization. Reuse a complete verified bootstrap ledger rather than serially reproving its Cargo/npm identities. Execute one bounded sequential lane per registry, overlap independent lanes, honor cross-registry DAG barriers, and assemble callback-returned receipts into an exhaustive exact-lock receipt set (an empty topology is valid for source-only products). Model crates.io's version token bucket with upload work overlapping refill and treat only valid server `Retry-After` state as authoritative; never require an unverifiable capacity secret. After receipt verification, run the lock-derived anonymous public Cargo/npm/Maven/JSR and Git/Swift consumer lanes concurrently from fresh caches under one shared deadline; resolve each entry root independently, require its platform-independent resolver lock to cover the complete frozen dependency closure, retry only transient visibility/network failures in a new cache, preserve deterministic receipt-bound evidence, and then reassert Release Please markability, promote GitHub drafts, add the tagged label, and remove the pending label as the literal final step. The additive/removal label operations are idempotent and preserve unrelated labels. Distinguish resolver coverage from host-installed/fetched payloads; never relabel a missing lock dependency as receipt-only. Treat Swift as a public source-tag/manifest proof before promotion, never as a claim that draft binary-target assets are anonymously downloadable. npm's trusted credential cannot move dist-tags, so each exact npm version receives its normal tag during publication.
- Recover: inventory external state first. Resume idempotently from the publication ledger; never delete or overwrite immutable public versions.
- Recover: inventory external state first. For ordinary single-identity
recovery, resume idempotently from the publication ledger. For an authorized
same-version control recovery, keep the original commit/tree, pinned complete
payload CI inventory, approved lock/capsule, and terminal ledger as the
publication source; require fresh full CI and approved control equivalence on
the later controller; require lock replay to be byte-identical including
`source` and `lockDigest`; keep tags/releases/assets source-bound; disable
bootstrap and continuations; and rerun root `publish` to reconcile missing
state. Never delete, overwrite, or republish a matching immutable public
version.
- History repair: use only before any affected product tag/package is public. Follow `references/recovery.md` and require explicit maintainer authorization for protection changes or force-push.

## Local gates
Expand All @@ -99,8 +112,13 @@ When a shared packager, archive encoder, carrier generator, or public target
contract changes, update its exact product ownership in
`tools/release/release-semantic-inputs.toml`, run the synchronizer with
`--write`, and inspect the product-local fingerprint diff before `--check`.
Workflow, validation, registry-transport, test, and documentation-only files
must remain outside that ownership map.
Pure control-plane workflow, validation, registry-transport, test, and
documentation inputs remain outside that ownership map. Compiler, SDK, linker,
build-command, source-selection, target, and packaging choices are
product-semantic and must be owned even when a workflow or local action
currently carries them. Until such a choice has been extracted into an owned
canonical input, treat a change to it as a release blocker rather than a
zero-owner CI-only change.

For a normalized generated release PR, also run the synchronizer in write mode
and immediately in check mode. It follows only Moon production/peer edges,
Expand Down
36 changes: 32 additions & 4 deletions .codex/skills/release-oliphaunt/references/invariants.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,30 @@
member paths/checksums inside each target carrier. External extensions own
independent packaging SemVer and record their upstream version/commit
separately.
- The release commit, qualified workflow head, artifact attestations, publication lock source SHA/tree, and product tags must agree exactly.
- Normally the generated release-bump commit, qualified workflow head, artifact
attestations, publication lock source SHA/tree, and product tags agree
exactly. The sole post-publication control-recovery exception splits those
identities: the original release-bump commit/tree remains the immutable
publication source, while a later current-main commit is only the freshly
qualified workflow controller. Never rewrite the lock source or relabel
product evidence as controller output.
- Same-version recovery selects the complete original payload CI inventory,
approved lock/capsule, and terminal bootstrap ledger by exact committed
run/artifact ID, digest, and size. Its replayed publication lock must be
byte-identical to the approved original, including `source` and `lockDigest`.
The current first-release recovery requires all 73 recorded CI artifacts.
- Product tags/releases/assets, Swift source publication, registry receipts,
and consumer-facing provenance remain publication-source-bound. Workflow
code, the transport tag, OIDC claims, request journals, and pacing are
controller-bound. Dual-identity recovery evidence must bind both.
- Extension evidence runs are immutable observations. Claim regeneration never changes them, and current WASIX support is qualified only by the full lifecycle collector running against same-workflow exact-SHA artifacts and recording that commit/tree/run identity.
- The publication lock is exhaustive: reject undeclared and missing packages/assets as well as hash, size, dependency, target, or version drift.
- Every shared published-byte producer or public target contract has exactly
one declarative ownership rule and content-addressed Release Please
fingerprints under every affected product root; policy and transport-only
edits do not create product releases.
fingerprints under every affected product root. Pure control-plane policy
and transport-only edits do not create product releases; compiler, SDK,
build, source-selection, target, and packaging changes remain
product-semantic even when implemented in a workflow or local action.
- Generate the lock after artifact assembly. Freeze it before any external write. Preserve it with the release ledger.
- Publish leaves/parts before aggregators, target carriers before façades, runtime artifacts before SDKs, and packages before public GitHub release promotion.
- Every extension Cargo `*-wasix` portable carrier and each of its dynamic payload parts records the explicit canonical target `wasix-portable`; portable extension targets are never inferred from a null target.
Expand All @@ -24,4 +41,15 @@
- Before promotion, derive every applicable public consumer surface and dependency closure from the exact lock; probe each anonymous Cargo/npm/Maven/JSR entry independently plus Git/Swift in fresh caches under one deadline, require every resolver lock to contain its complete frozen closure, retry only transient visibility failures, and preserve deterministic evidence bound to both immutable receipt sets. Never hide a missing lock dependency in a receipt-only category. A macOS host install does not prove every OS carrier, and a pre-promotion Swift probe proves the public source tag/manifest rather than draft binary-target availability.
- Normal npm and JSR publication uses GitHub-hosted OIDC. Normal Cargo publication exchanges OIDC for a fresh temporary token per bounded carrier batch and revokes it in `finally`; Maven credentials remain protected environment secrets. Bootstrap credentials are short-lived, isolated, and revoked after exact trusted-publisher configuration is audited; npm bootstrap specifically requires a granular `@oliphaunt` read/write token with 2FA bypass from a 2FA-enabled actor.
- A pure version/changelog update may change the package envelope and lock, but must not change the WASIX binary-semantic input fingerprint.
- Never reuse a public version, move a public product tag, or force-push a history containing affected public releases.
- Never upload an immutable public version twice, move a public product tag, or
force-push a history containing affected public releases. A same-version
control recovery may only checksum/SRI-reconcile an already-public carrier;
one byte of drift fails closed and requires a new version.
- Same-version recovery cannot run bootstrap or any continuation. Resume only
through an idempotent root `publish` rerun that verifies the original
terminal ledger and reconciles every exact immutable identity before writes.
- With a clean release state, a pure zero-owner control-plane, workflow,
validator, registry-transport, test, or documentation change creates no
release PR and performs no publication. Semantic ownership, not a `ci:`
subject, decides; compiler, SDK, build, source-selection, target, and
packaging changes require releases.
Loading