mif-docs: Cut an Attested Release
mif-docs: Cut an Attested Release
Section titled “mif-docs: Cut an Attested Release”1. Overview
Section titled “1. Overview”This runbook is the tactical procedure for cutting an attested v-release of the
mif-docs plugin from the modeled-information-format/mif-docs-plugin repo. A
release is “attested” when .github/workflows/release.yml builds a reproducible
git archive tarball, generates SLSA build provenance, and fail-closed
verifies that provenance with gh attestation verify --signer-workflow
before uploading mif-docs-plugin-<tag>.tar.gz. It covers the full path from a
green main to a marketplace pin update.
It does not cover authoring docs or changing gates — for that, see the
attested-delivery decision record (adr-0003-attested-delivery) and the
validate/author how-to (how-to-validate-and-author). This runbook assumes the
gates are already wired and you simply need to ship.
2. Prerequisites & Access
Section titled “2. Prerequisites & Access”Confirm these before you start; sorting out access mid-cut wastes a release window.
ghCLI authenticated as a user account (a PAT, not a bot) with write access tomodeled-information-format/mif-docs-plugin. The human/PAT identity is load-bearing in section 5 — a bot-created release does not fire therelease: publishedevent that triggers the workflow.- Push access to
main(for the version bump) and permission to create releases. - Local checkout of
mif-docs-pluginon an up-to-datemain. - A workstation with
gh attestation verifyavailable (gh 2.40+).
3. Pre-flight: confirm CI is green and bump the version
Section titled “3. Pre-flight: confirm CI is green and bump the version”-
Confirm CI green on
main. Do not cut from a red tree.Terminal window gh run list --repo modeled-information-format/mif-docs-plugin \--branch main --workflow ci.yml --limit 1Expected: the latest
ci.ymlrun iscompleted/success(pin-check+actionlint,validate,adr-smadrall green). If it is failing, stop and fix CI first — an attested release of a broken tree is still broken. -
Bump the plugin version. Edit
plugin.jsonsoversionis the new release (e.g.0.1.0→0.2.0), commit on a branch, and merge tomainthe normal way. The tag you cut in section 5 must match this version.Terminal window gh release list --repo modeled-information-format/mif-docs-plugin --limit 3Expected: the new version is not already an existing release tag. Re-using a tag will not re-attest a prior artifact — pick the next unused
vX.Y.Z.
4. Dry-run the release workflow
Section titled “4. Dry-run the release workflow”Before cutting anything immutable, prove the pipeline is green end to end.
workflow_dispatch runs release.yml in dry-run mode — it builds, attests,
and verifies but does not upload.
gh workflow run release.yml --repo modeled-information-format/mif-docs-plugin --ref maingh run watch --repo modeled-information-format/mif-docs-plugin \ "$(gh run list --repo modeled-information-format/mif-docs-plugin \ --workflow release.yml --limit 1 --json databaseId -q '.[0].databaseId')"Expected result: the run reaches success with the build → attest → verify
steps all green. If verify fails here, the signer-workflow identity or the
attestation is wrong — fix it now, while nothing has been published. Do not
proceed to the real cut until the dry-run is clean.
5. Cut the release (this triggers the attested upload)
Section titled “5. Cut the release (this triggers the attested upload)”Create the GitHub Release at the target commit as a user/PAT, not a bot. The
release: published event is what triggers release.yml to run for real: gate →
reproducible tarball → SLSA attest → fail-closed verify → upload
mif-docs-plugin-<tag>.tar.gz.
# Replace v0.2.0 with your bumped version; --target pins the exact commit.gh release create v0.2.0 \ --repo modeled-information-format/mif-docs-plugin \ --target main \ --title "mif-docs v0.2.0" \ --notes "Attested release. Artifact verified fail-closed before upload."Expected result: the publish triggers a release.yml run on the release
event. Watch it to completion:
gh run watch --repo modeled-information-format/mif-docs-plugin \ "$(gh run list --repo modeled-information-format/mif-docs-plugin \ --workflow release.yml --event release --limit 1 \ --json databaseId -q '.[0].databaseId')"When it is green, the release has mif-docs-plugin-v0.2.0.tar.gz attached.
6. Verify the artifact from a workstation
Section titled “6. Verify the artifact from a workstation”Independently verify the uploaded artifact’s attestation — do not trust the run’s own green check alone.
gh release download v0.2.0 \ --repo modeled-information-format/mif-docs-plugin \ --pattern 'mif-docs-plugin-v0.2.0.tar.gz'
gh attestation verify mif-docs-plugin-v0.2.0.tar.gz \ --repo modeled-information-format/mif-docs-plugin \ --signer-workflow modeled-information-format/mif-docs-plugin/.github/workflows/release.ymlExpected result: gh attestation verify prints a success line confirming the
provenance was issued by the release.yml signer workflow for this repo. A
non-zero exit means the artifact is not trustworthy — go to section 8.
7. Register the new tag in the marketplace
Section titled “7. Register the new tag in the marketplace”Update the claude-code-plugins marketplace pin so installs resolve to the new
release. Pin both the tag and its commit sha (the org enforces sha pins).
git rev-parse v0.2.0 # the sha to pin alongside the tagEdit the marketplace entry for mif-docs to point at the new tag + sha, open
the PR, and let catalog-admission run. Expected result: catalog-admission
re-verifies the release attestation fail-closed and goes green; once merged,
claude plugin install mif-docs@modeled-information-format resolves to the new
version.
8. Detection, symptoms & rollback
Section titled “8. Detection, symptoms & rollback”Symptom: a tag was published but no artifact appeared. The attestation step failed — the verify gate is fail-closed, so a failed attest/verify uploads nothing. The published tag with an empty release is the tell.
gh run list --repo modeled-information-format/mif-docs-plugin \ --workflow release.yml --event release --limit 1gh run view --repo modeled-information-format/mif-docs-plugin \ "$(gh run list --repo modeled-information-format/mif-docs-plugin \ --workflow release.yml --event release --limit 1 \ --json databaseId -q '.[0].databaseId')" --log-failedRead the failed step: a red verify step means the signer-workflow path or the attestation did not match; a red attest step means provenance generation failed.
Rollback. A published release with no verified artifact is not a usable release — retract it rather than leaving a half-cut tag:
gh release delete v0.2.0 --repo modeled-information-format/mif-docs-plugin --cleanup-tagThen fix the root cause, re-run the section 4 dry-run until green, and re-cut from section 5. Do not update the marketplace pin (section 7) until section 6 verification passes from a workstation — an unverified artifact must never be the pinned target.