Release
August 12, 2026 · View on GitHub
This document is the release checklist for publishing ripr.
Release identity (read this first)
Two repositories, two different authorities (#24, #2025):
ripr-swarm = development trunk and no-publish rehearsal authority
EffortlessMetrics/ripr = public release and distribution authority
- Public tags and GitHub Releases (v0.8.0 and later) live only in
EffortlessMetrics/ripr. Do not create mirror tags in ripr-swarm for a public release; temporary mirror tags once created were removed (see the corrections on #1947 and #1959). - A swarm
CHANGELOG.mdentry may describe a published release; it must not imply the corresponding public tag lives in this repository. - Swarm rehearsal (proof packs, manifest generation, smoke) is a separate state from source publication (#1882): rehearsal artifacts are local evidence, never release proof, and "zero swarm tag-trigger runs" means rehearsal stayed read-only, not that a public release is missing.
For every public version claim, record the boundary explicitly:
rehearsal | promoted | tagged | published, with the source SHA, the public
tag/release URL in EffortlessMetrics/ripr, and the promotion evidence.
Live-history release train
Use the live-history release transaction runbook as the canonical operator sequence. This checklist remains the release-surface and packaging reference; the runbook owns exact pins, J/K expected-head guards, receipts, invalidation, publication authorization, and cleanup.
For the 0.11.0 release train, and as the standard two-repository pattern for future releases, use this authority sequence:
develop in ripr-swarm
→ select exact ripr-swarm/main at the transaction boundary
→ create an immutable swarm pin and hold ripr/main
→ qualify that exact swarm head
→ preflight the exact source/swarm pair
→ construct and prove one ordered two-parent source join
→ merge source with source parent 1 and swarm parent 2
→ establish metadata and build source artifacts
→ produce the immutable ship packet
→ explicitly authorize publication
→ publish and verify each channel
→ ancestry-preserving source-to-swarm back-sync
→ re-baseline the next release and resume swarm development
The selected swarm head includes all history reachable from that exact commit. Do not squash, rebase, cherry-pick, or reconstruct a tree-equivalent source join. The promotion PR head must itself be the reviewed join, with source as parent 1 and the selected swarm head as parent 2. The back-sync must preserve the source release ancestry through a controlled merge exception or another explicitly reviewed ancestry-preserving path, even when swarm branch settings normally disable merge commits.
After the swarm pin, later ripr-swarm/main merges are outside the release and
must not move the pin. Development may continue on branches, but no main merge
enters the release until source publication and the back-sync complete. Repin
only for an exact-candidate semantic or policy failure, or a source-preflight
failure that prevents a required survivor or release contract. Main movement
alone never repins.
The ship packet is evidence, not authorization. Only source issue #1470
authorizes tagging, publication, signing, marketplace mutation, or other
external release operations. Re-baseline 0.11.1 only after 0.11.0 publication
and closeout; merged current-head work belongs to 0.11.0 rather than 0.11.1.
The release claims must be regenerated from the selected tree. Distinguish
commands actually executed, evidence emitted, and any RepairReceiptV2
issuance. Never copy a historical blanket no-execution sentence, and never
claim correctness, test adequacy, mutation adequacy, requirement satisfaction,
or merge safety.
The two history-preserving joins have separate identities and parent order:
J = source promotion
J.parent[0] = exact SOURCE_PARENT
J.parent[1] = exact SWARM_PARENT
K = post-publication back-sync
K.parent[0] = exact swarm main before back-sync
K.parent[1] = exact released source main
The promotion head must itself be J; an appended repair commit, squash,
rebase, cherry-pick, or tree-equivalent reconstruction fails the promotion
contract. After public verification, review and transport K under an
expected-head guard. If swarm policy has merge commits disabled, use a
narrowly approved temporary exception for this one ancestry-preserving
back-sync and restore the ordinary policy immediately afterward. See
swarm-development.md for
the operator commands and the separate J/K proof boundaries.
Preparing a version bump
From a clean swarm checkout, use the gated version command instead of editing the three release manifests independently:
cargo xtask bump-version 0.11.0
The command requires the workspace version, editors/vscode/package.json, and both root version fields in editors/vscode/package-lock.json to agree before it writes. It preserves the existing JSON formatting, validates the resulting Cargo workspace with cargo metadata, and restores the original files if a write or validation step fails. It changes files only; review and commit the result as a normal release-prep PR.
Checking release state (audit contract)
Any release or status audit must name the repository it queries and fail closed on ambiguity — never silently query the current checkout for public release state:
# Public releases and tags (authoritative):
gh release list --repo EffortlessMetrics/ripr --limit 5
gh api repos/EffortlessMetrics/ripr/tags --paginate -q '.[].name'
# Swarm side (development/rehearsal only — mirror tags must not exist):
gh api repos/EffortlessMetrics/ripr-swarm/tags --paginate -q '.[].name'
- A public tag existing in the source repo but not in swarm is the expected state, not a defect.
- A swarm rehearsal without a public release is rehearsal, not a release.
- A changelog version without a source release is an unpublished draft, and is named that way (the 0.8.0/0.9.0/0.10.0 swarm drafts are working drafts, not published releases).
- The VS Code downloader and default install documentation resolve release
assets from
EffortlessMetrics/ripronly (editors/vscode/src/downloader.tsbuilds URLs against that repository).
Run the Release copy checklist before finalizing
the GitHub Release body, triggering publish-extension.yml, or running
cargo publish. It captures the public-surface rules (release body vs.
process narrative, marketplace metadata, install truth, badge freshness,
public vocabulary, asset verification) that the v0.5.0 release surfaced.
Preconditions
- The release branch has been reviewed and merged.
- The version in the root
Cargo.toml[workspace.package]is correct. This is the single release-version source;crates/ripr/Cargo.tomlinherits it withversion.workspace = trueand declares no version of its own (#2711). editors/vscode/package.jsonand itspackage-lock.jsonmatch that version.cargo xtask release-readinesschecks this asextension-version-match; a mismatch fails the marketplace publish (#1283). The check compares all four declarations —[workspace.package] version,package.json, and both placespackage-lock.jsonrecords the version — against the--versionyou pass, so running it before the bump lands is a hard fail rather than a pass.- For the defaults-first public install line, the version is newer than
0.3.0;0.3.0predatesripr pilotandripr outcome. - The root workspace uses Rust edition
2024. - The root workspace
rust-versionis1.95. repositoryandhomepagepoint athttps://github.com/EffortlessMetrics/ripr/.- The README says
ripris alpha software and does not claim mutation execution.
Local Gates
Run from the repository root:
cargo fmt --check
cargo check --workspace --all-targets
cargo test --workspace
cargo clippy --workspace --all-targets -- -D warnings
cargo doc --workspace --no-deps
cargo xtask check-product-copy
cargo xtask check-generated-clean
cargo xtask release-readiness --version 0.11.0 # the version you are cutting
cargo xtask release-negative-corpus --version 0.11.0 # readiness-chain authority negatives (#2824)
cargo package -p ripr --list
cargo publish -p ripr --dry-run
For 0.11.0, the Rust gap-repair support claim remains usable alpha.
Fixture, installed-package, packaged-editor, bounded test-only transaction, and
before/after receipt paths are proved when a valid route exists. The governed
real-repository corpus currently has zero eligible attempts, so release copy
must not imply measured route yield or ordinary-user success. Run cargo xtask rust-repair-trust-report and cargo xtask check-support-tiers; the latter
requires the unique canonical row and hard-caps it at usable alpha until one
promotion decision covers both the full governed corpus and the installed
CLI/packaged VS Code pilot (#3076 and #1702). A complete report with real
movement cannot promote the release claim by itself.
Crate tarball contents
crates/ripr/Cargo.toml intentionally includes tests/** and the tracked
example paths (examples/*/example.diff, examples/*/src/**,
examples/*/tests/**) in the published source distribution. The package list
therefore carries the checked integration corpus and sample workspace used by
release and dogfood evidence. This does not change the installed binary or
library API, but removing either surface is a release-contract change that must
be reviewed against cargo package -p ripr --list and this document.
The example paths are enumerated rather than globbed as examples/** on
purpose. ripr runs against the sample workspace during tests and writes a
fact cache into crates/ripr/examples/sample/target/. That directory is
gitignored, but a wildcard include still pulls it into the package, and
cargo package then fails its uncommitted-files check after any test run.
Widening the glob reintroduces that failure; add new example subdirectories to
the list instead.
For the defaults-first install path, also run the local install proof from Installation verification.
For 0.8.x release claims about evidence-to-repair readiness, runtime completeness, or actionability projection, also run the Lane 1 evidence reports:
cargo xtask lane1-evidence-audit
cargo xtask evidence-quality-scorecard
The release claim is supported only when the Lane 1 audit coverage section
reports zero static_unknown items without named limitations, zero actionable
canonical items without repair routes, and zero actionable canonical items
without verify commands. Raw finding counts are diagnostic context; actionable
aligned items are the user-facing work count.
Runtime Smoke
cargo run -p ripr -- --version
cargo run -p ripr -- doctor
cargo run -p ripr -- pilot --root fixtures/boundary_gap/input --out target/ripr/release-smoke/pilot
cargo run -p ripr -- outcome --before fixtures/boundary_gap/calibration/before-targeted-test.repo-exposure.json --after fixtures/boundary_gap/calibration/after-targeted-test.repo-exposure.json
cargo run -p ripr -- check --diff crates/ripr/examples/sample/example.diff
cargo run -p ripr -- check --diff crates/ripr/examples/sample/example.diff --json
cargo run -p ripr -- explain --diff crates/ripr/examples/sample/example.diff probe:crates_ripr_examples_sample_src_lib.rs:error_path:c1a03250
cargo run -p ripr -- context --diff crates/ripr/examples/sample/example.diff --at probe:crates_ripr_examples_sample_src_lib.rs:error_path:c1a03250 --json
The version smoke must print exactly ripr <CARGO_PKG_VERSION> with one
trailing newline, exit 0, and leave stderr empty. --version/-V is a
side-effect-free identity query and takes precedence over help, JSON, and
verbose-looking flags; it must not emit the help screen or write analysis
artifacts. Command-local version routes such as ripr lsp --version retain
their existing output contract.
Install And Release Proof
Before calling an install or release-path PR complete, verify the crate package, the local install path, the extension package, and the published server assets:
cargo package -p ripr --list
cargo publish -p ripr --dry-run
cargo install --path crates/ripr --locked --force --root target/ripr/install-smoke
target/ripr/install-smoke/bin/ripr --version
target/ripr/install-smoke/bin/ripr first-pr --help
target/ripr/install-smoke/bin/ripr doctor
target/ripr/install-smoke/bin/ripr pilot --root fixtures/boundary_gap/input --out target/ripr/install-smoke/pilot
target/ripr/install-smoke/bin/ripr outcome --before fixtures/boundary_gap/calibration/before-targeted-test.repo-exposure.json --after fixtures/boundary_gap/calibration/after-targeted-test.repo-exposure.json
npm --prefix editors/vscode ci
npm --prefix editors/vscode run compile
npm --prefix editors/vscode run package
For first-run adoption releases, also confirm the generated GitHub workflow
summary includes #### First-run status, the missing_start_here recovery
state, and the target/ripr/reports/start-here.md front door. Confirm
editors/vscode/package.json contributes ripr: Start Current Repair so the
installed editor path exposes the same repair loop.
For a published release, confirm that GitHub Releases contains the VSIX, server manifest, server archives, and checksums:
gh release list --repo EffortlessMetrics/ripr --limit 5
gh release view v0.8.0 --repo EffortlessMetrics/ripr --json name,tagName,publishedAt,assets,url,isDraft,isPrerelease
gh release download v0.8.0 --repo EffortlessMetrics/ripr --pattern 'ripr-server-v0.8.0-x86_64-pc-windows-msvc.zip' --pattern 'ripr-server-manifest-v0.8.0.json' --dir target/ripr/release-smoke --clobber
For the v0.8.0 release, the GitHub Release must have the VSIX, server
manifest, per-target server archives, checksums, and a server archive whose
manifest checksum matches the downloaded archive. The extracted server must run
ripr --version, ripr lsp --version, ripr pilot, ripr outcome, and
ripr agent verify. When an agent verify JSON artifact is available, also run
ripr agent receipt for the top seam.
Name Gate
Immediately before the first real publish:
cargo search ripr --limit 5
Then check the crates.io API:
curl -i https://crates.io/api/v1/crates/ripr
If ripr is taken, stop. Do not publish under a fallback name without a naming
decision.
Publish
cargo login
cargo publish -p ripr
Cargo may time out while polling the registry index after upload. If that happens, check crates.io manually before retrying.
Post-Publish
cargo install ripr --version 0.8.0 --locked --root target/ripr/install-smoke-cratesio --force
target/ripr/install-smoke-cratesio/bin/ripr --version
target/ripr/install-smoke-cratesio/bin/ripr first-pr --help
target/ripr/install-smoke-cratesio/bin/ripr doctor
target/ripr/install-smoke-cratesio/bin/ripr pilot --root fixtures/boundary_gap/input --out target/ripr/install-smoke-cratesio/pilot
target/ripr/install-smoke-cratesio/bin/ripr outcome --before fixtures/boundary_gap/calibration/before-targeted-test.repo-exposure.json --after fixtures/boundary_gap/calibration/after-targeted-test.repo-exposure.json
mkdir -p target/ripr/install-smoke-cratesio/agent
target/ripr/install-smoke-cratesio/bin/ripr agent verify --root . --before fixtures/boundary_gap/calibration/before-targeted-test.repo-exposure.json --after fixtures/boundary_gap/calibration/after-targeted-test.repo-exposure.json --json > target/ripr/install-smoke-cratesio/agent/agent-verify.json
target/ripr/install-smoke-cratesio/bin/ripr agent receipt --root . --verify-json target/ripr/install-smoke-cratesio/agent/agent-verify.json --seam-id 67fc764ba37d77bd --json --out target/ripr/install-smoke-cratesio/agent/agent-receipt.json
Tag the release — in a checkout of the source repository
(EffortlessMetrics/ripr), never in ripr-swarm (#2025):
# Run inside an EffortlessMetrics/ripr checkout; fetch AND push URLs must be that repo.
git remote get-url origin # expect github.com/EffortlessMetrics/ripr(.git)?
git remote get-url --push origin # pushurl must also resolve to EffortlessMetrics/ripr (#2193 review)
git tag v0.8.0
git push origin v0.8.0
Update docs or release notes if the install command or package metadata changed.
Public-Surface Copy
Before publishing, run the Release copy checklist. It covers the GitHub Release body, marketplace metadata, README install commands, badge freshness disclosure, public vocabulary, and asset/dependent-channel verification. For 0.8.0, also compare GitHub About and repository topics with the current release-readiness handoff before changing repository metadata. Repository metadata should describe static mutation-exposure analysis for test-gap review without implying runtime mutation execution, generated tests, provider-backed analysis, default blocking, or stable preview-language gate authority.
Recovery
If a release workflow fails after the tag has been pushed, prefer
fix-forward over retagging. Workflow reruns (gh workflow run ...) also
belong to the source repository: run them with --repo EffortlessMetrics/ripr
from anywhere else, or from a source checkout. The tag is the release-prep snapshot; the
release workflows can be rerun against main (or any commit that contains
the fix) using workflow_dispatch, and uploaded assets attach to the
existing GitHub Release rather than replacing it.
- Open a focused fix PR on
mainthat reproduces the failure as a test and fixes only the broken path. Merge it. - Rerun the failed workflow via
workflow_dispatchwith the sameversioninput as the tag, for examplegh workflow run release-server-binaries.yml -f version=0.8.0. The asset names continue to use the original version, so they overlay correctly on the existing Release. - After server assets are present and verified, rerun any downstream
workflow that was gated on them, for example
gh workflow run publish-extension.yml -f version=0.8.0. - Do not retag and do not delete the GitHub Release. Leave the tag at
the release-prep commit; the fix-forward commit is on
mainand any subsequent point release will include it. - Update the GitHub Release body to document the recovery if the failure was user-visible. crates.io publish remains a manual step and should only run once asset verification is complete.
This pattern is what the v0.5.0 release used after the initial Windows
server-archive failure; see CHANGELOG Release recovery (v0.5.0) for the
record.