Agent skill

Rigor Release Prep

by rigortype in rigortype/rigor

Prepare a Rigor RubyGems release by bumping the version, consolidating changelog fragments, and running release gates.

MPL-2.0Auto-check passedDevelopment

Install Rigor Release Prep

skills CLI
$ npx skills add rigortype/rigor --skill rigor-release-prep -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install rigortype/rigor rigor-release-prep --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/rigortype/rigor.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/rigor-release-prep .claude/skills/rigor-release-prep && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
rigor-release-prep
GitHub stars
106
Token cost
~7.8k tokens
SKILL.md length
3,876 words
Files
1
Skills in repo
36
Repo updated
First seen
Licence
MPL-2.0

At a glance

Prepare a Rigor RubyGems release by bumping the version, consolidating changelog fragments, and running release gates.

  • Works in 6 steps: Pull the cycle's merged PRs up front, so… → Read the entire [Unreleased] block. For… → Rewrite every commit-style bullet — lead… → …
  • Explicitly invokes /rigor-release-prep
  • SKILL.md covers Branch: release/x.y.z, Update Release Metadata, Verify the Release and Commit the Result, plus 5 more sections
  • Calls gh, git and nix

What it does

Rigor Release Prep is an agent skill from rigortype/rigor. Prepare a Rigor RubyGems release by bumping the version, consolidating changelog fragments, and running release gates. Use only when the user explicitly invokes /rigor-release-prep or asks to cut a release; not for ordinary fixes or release context alone.

Its SKILL.md is about 7.8k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Development, covering Changelog and release notes. It works with Ruby. The repository describes itself as: Inference-first static analysis for Ruby. The licence is MPL-2.0.

When your agent uses it

  • Explicitly invokes /rigor-release-prep
  • Asks to cut a release
  • Not for ordinary fixes
  • Release context alone

Example prompts

  • “/rigor-release-prep”

Workflow steps

6 steps, taken from the first numbered list in SKILL.md.

  1. Pull the cycle's merged PRs up front, so linking is a lookup rather than
  2. Read the entire [Unreleased] block. For each top-level bullet,
  3. Rewrite every commit-style bullet — lead sentence to one clause, move the
  4. Check every bullet already carries its PR link, against the step-1 list.
  5. Watch for merge artefacts: two entries accidentally glued into one
  6. Re-read the sealed section top-to-bottom as a user would. If any top-level

What it can do on your machine

Read from SKILL.md and the folder at commit 57a67cf. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • gh
    • git
    • nix
    • make
    • bundle
    • ruby
    • gem

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • keepachangelog.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Rigor Release Prep loads about 7.8k tokens when it runs. Until then it costs about 69 tokens; SKILL.md has 3,876 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~69
When it runs · the whole SKILL.md, loaded when a task matches
~7.8k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from rigortype/rigor at commit 57a67cf, republished under its MPL-2.0 licence (© rigortype). 3,876 words, ~7,792 tokens.

Download SKILL.mdSave it as .claude/skills/rigor-release-prep/SKILL.md (or your agent's skills folder).
name
rigor-release-prep
description
Prepare a Rigor RubyGems release by bumping the version, consolidating changelog fragments, and running release gates. Use only when the user explicitly invokes `/rigor-release-prep` or asks to cut a release; not for ordinary fixes or release context alone.
metadata.internal
true

Rigor Release Prep

Follow this workflow when preparing a new rigor gem release.

All commands MUST run through the Flake per AGENTS.md. The examples below include the full nix develop --command prefix so each line is directly runnable from outside the Flake shell. Inside the Flake shell, drop the prefix.

Branch: release/x.y.z

Release work happens on a dedicated release/x.y.z branch, not directly on master (ADR-50). Cut it from an up-to-date master:

sh
git switch master && git pull
git switch -c release/x.y.z

Every step below — the metadata edits, the local verify, the version-bump commit — lands on this branch. Pushing it runs release-gate.yml (perf benchmark, gem-build validation, OSS-corpus sweep — advisory until it is promoted to a required check), the comprehensive release gate the normal master CI does not (see "Push and watch the release gate" below). The base CI gate (ci.yml) runs on the release PR you open next, via its pull_request event — ci.yml triggers on push to master only, so a release branch is not double-run (push + pull_request) the way it would be if release/** were also a push branch.

Update Release Metadata

Decide the next semantic version first, then update all versioned files together.

Update these files:

  • CHANGELOG.md
  • lib/rigor/version.rb
  • Gemfile.lock (regenerated by bundle install after the version bump)
  • README.md (the ## Status line — version + date; see "Refresh the README status" below)
Seal the [Unreleased] entries — the mandatory rewrite step

Do this first, before the mechanical version-heading move below, and treat the entries — not the version bump — as the deliverable of this skill. The intended state is that every fragment was already written release-style at landing (docs/agents/contribution-flow.md § "Release Cadence"), so this step is mostly cross-entry consolidation: fold several commits' entries into one user-recognisable change, reorder, dedupe, and split any merge artefacts — work that needs the cycle-wide context only release time has. In practice the section also accumulates commit-style drift (detailed, implementer-facing, multi-sentence, em-dash run-ons) that landing-time discipline missed, so this step is also the safety net that rewrites that drift into release-style before the version is sealed — it is not, however, a licence to skip landing-time quality and rewrite commit prose wholesale at the cut.

This is the highest-value, most-skipped step in a release. A release whose CHANGELOG still reads like commit messages is not done, even if every versioned file agrees and make verify is green — prose quality is invisible to make verify, so nothing downstream will catch a skipped rewrite. It is the one step silently lost when the mechanical steps around it get done; do not let "the entries are already there" stand in for reviewing and consolidating them.

Consolidate changelog.d/ fragments before anything else. Entries land as changelog.d/<section>/<slug>.md fragments (ADR-105), so the seal starts by moving every fragment's line(s) under the matching ### section of [Unreleased] (creating sections in Keep a Changelog order as needed) and deleting the fragment files (git rm). After this, changelog.d/ contains only its README.md, and the enumeration below runs over the consolidated [Unreleased].

CHANGELOG.md follows Keep a Changelog 1.1.0. This skill is the canonical statement of the entry rules — docs/agents/contribution-flow.md carries only the landing-time one-liner, because the full set matters to a session writing an entry, not to every session. The rules:

  • One sentence per top-level bullet. One period, no em-dash clauses, no run-ons. Self-contained enough to understand without the body.
  • One LINE per bullet, never column-wrapped. This section is extracted verbatim as the GitHub Release body, and GitHub renders a newline inside a paragraph as <br> — a wrapped entry renders ragged. Same rule for any PR / issue / comment / wiki text (docs/agents/contribution-flow.md § "Commits and GitHub Markdown").
  • Subsystem label prefix: **[rigor check]**, **[engine]**, **[plugin contract]**, **[plugins/rigor-foo]**, etc.
  • User-facing only. Cut internal implementation detail — class renames, RBS plumbing for the analyzer's own surface, test/spec additions, coverage counts, refactor-only plugin migrations. Ask of each: "would a user care if they weren't reading the source?" If no, delete it.
  • Supplementary detail goes in child items ( - …), two to three sentences max, one topic each.
  • A changelog entry is not a commit message: many commits may collapse into one entry, and one fat [Unreleased] line may split into several.
  • Link the PR that landed it, as a full markdown link at the end of the bullet: ([#170](https://github.com/rigortype/rigor/pull/170)). Put it on the child item instead when one bullet consolidates several PRs and each detail traces to a different one. Add the reporting issue too when there is one, and thank you @handle! for an outside report. The link is how a user gets from "what changed" to the detail.
    • The full form, never a bare #170. This section is extracted verbatim as the GitHub Release body (rake release:github), where GitHub autolinks a bare #170 — but the same text is also CHANGELOG.md rendered from the repo tree, where it is not autolinked and stays dead text. Only the markdown form works in both, which is why every link already in the file uses it.
    • Omit it when there is no PR. A small docs-only change can land straight on master (docs/agents/contribution-flow.md § "Branches and pull requests"), so it has a commit and no PR. Do not invent one, and do not link the commit instead — if the change is user-facing enough to have an entry, the entry is the record.

The three shapes to reject on sight:

markdown
# ✗ two sentences joined by an em-dash
- **[plugins]** All bundled plugins now ship inside the `rigortype` gem — `require "rigor-foo"` resolves without any workaround. Activate with `plugins: [rigor-foo]`.

# ✗ internal implementation detail as a child item
  - Individual gemspecs inside `plugins/` are removed; the plugin family ships as a single unit.

# ✗ commit-message prose instead of a user-meaningful description
- **[baseline]** Fix `group_for_baseline` to normalise paths to relative before building bucket keys.

Each is fixable in place — split the em-dash into a bullet plus a child item, delete the internal detail, and restate the third as what a user can now do:

markdown
- **[rigor baseline generate]** Fixed a crash when `plugins:` entries in `.rigor.yml` were plain strings.

- **[plugins]** All bundled plugins now ship inside the `rigortype` gem, so `require "rigor-foo"` works without any `RUBYLIB` or `Gemfile` workaround.
  - Activate any plugin with one line in `.rigor.yml`: `plugins: [rigor-foo]`.

Procedure — the enumeration is what makes the rewrite un-skippable, so do not shortcut it:

  1. Pull the cycle's merged PRs up front, so linking is a lookup rather than a recall. Derive the range from the previous release's tag, never from its ## [x.y.z] - DATE heading:

    sh
    git log --oneline --merges vX.Y.Z..HEAD | grep -oE '#[0-9]+'

    The heading date is a trap. It is a local-time date, and gh pr list --search "merged:>=DATE" filters in UTC, so every PR merged between the tag and local midnight falls outside the query. The tag range is exact, offline, and has no timezone to get wrong.

    Keep the list beside you for step 4. It is also a completeness check: a PR in it with no entry anywhere is either a user-facing change nobody wrote up, or correctly internal — decide which, do not skip past it.

  2. Read the entire [Unreleased] block. For each top-level bullet, explicitly classify it: release-style (leave) or commit-style (rewrite).

  3. Rewrite every commit-style bullet — lead sentence to one clause, move the "why / how it works / measured numbers" into a child item, delete internal detail outright.

  4. Check every bullet already carries its PR link, against the step-1 list. The landing rule requires the link, so this is verification, not authoring: a bullet missing one means the landing rule was skipped, and you are now paying the reconstruction cost this step exists to avoid. Match on the change, not the title wording — a bullet that consolidates several PRs links each on the child item it belongs to. Leave a bullet unlinked only when its change genuinely had no PR (a Markdown-only push to master).

  5. Watch for merge artefacts: two entries accidentally glued into one bullet (a stray second **[label]** mid-sentence, an env-var description hanging off an unrelated entry). Split them. CHANGELOG.md is merge=union (.gitattributes), which trades insertion-order conflicts for one artefact you must look for here: a duplicated ### heading, where two branches each opened the same section. Merge the two, keeping Keep a Changelog's order. spec/docs/changelog_conformance_spec.rb fails on it, so a missed one is caught rather than shipped — but catching it at the cut is cheaper.

  6. Re-read the sealed section top-to-bottom as a user would. If any top-level bullet still has two sentences or an em-dash clause, it is not done.

Worked collapse (a real shape this repo produces):

# ✗ commit-style, as it lands in [Unreleased]
- **[engine]** RBS-complete ancestor resolution — `rigor check` now resolves a
  Ruby subclass's inherited calls against an allow-listed RBS-only ancestor, so
  misuse is caught. Previously a Ruby class subclassing an RBS-only class
  resolved every inherited call to `Dynamic[Top]` because the dispatcher
  short-circuited when the subclass name is absent from the RBS environment, so
  no ancestor walk ran (the edge was recorded in `Scope#discovered_superclasses`
  but never consulted by `RbsDispatch`). The fix threads the analysis `scope`
  into `RbsDispatch.lookup_method` and resolves against the ancestor's RBS ...

# ✓ release-style, after the rewrite
- **[engine]** RBS-complete ancestor resolution: `rigor check` now resolves a
  Ruby subclass's inherited method calls against an allow-listed RBS-only
  ancestor, so a typo'd or renamed contract call such as `manifest.bogus` on a
  plugin fires `call.undefined-method` ([ADR-43](docs/adr/43-rbs-complete-ancestor-resolution.md)).
  - The allow-list is the false-positive boundary: a non-allow-listed ancestor
    (e.g. `ActionController::Base`) keeps the `Dynamic[Top]` fallback, so a
    controller calling a method an incomplete gem RBS omits is never flagged.

(ADR-43 predates public development and landed by direct commit, so it has no PR to link — the omission above is the rule working, not a lapse. A change that did go through one reads … so the scan no longer re-runs per file ([#74](https://github.com/rigortype/rigor/pull/74)).)

Write the release summary

Immediately under the new ## [x.y.z] - YYYY-MM-DD heading, before the first ### section, write a short prose summary — a few simple sentences (≈3–4), in the CHANGELOG's language (English) — that gives a reader the themes of the release before the itemised entries. It complements the bullets: the bullets are the precise "what changed", the summary is the narrative "what this release is about".

  • Lead with the dominant theme (the biggest performance thread, the headline feature, …), then name one or two secondary threads, then close with a short "other fixes" clause — mirroring the bullets' weight.
  • Keep it short. It is a lead, not a recap of every bullet — one clause per theme, no exhaustive enumeration.
  • Link sparingly, using the file's existing repo-relative convention ([ADR-46](docs/adr/46-…), [the Elixir v1.20 review](docs/notes/…)) — a pointer to the driving ADR / note for a theme, not a link per bullet.
  • It is user-facing prose: the same "would a user care?" bar as the bullets; no internal class names or measured-number dumps (those live in the bullets and their child items).

Example shape (the 0.1.17 summary):

v0.1.17 focuses on making analysis of real projects markedly faster — an incremental analysis cache, an unchanged-project fast path, and a large allocation reduction on big Rails apps. Inspired by the Elixir v1.20 type system, control-flow narrowing is strengthened for several methods. It also folds Data.define value objects to precise types and adds new clause-reachability and conformance diagnostics; fixes include a block-parameter binding crash and a pathological route-helper re-read.

Refresh the README status

Update the ## Status block in README.md to the new release as part of this release, not as a later follow-up. Because publish runs immediately after the PR merges (the next section), the README on master is never a window ahead of a published gem — updating it here means the moment the release lands, the front page already names the version RubyGems serves.

  • Change Current release: **vX.Y.Z** (YYYY-MM-DD) to the new version and date. For a patch/minor within the same leading-digit cycle that is the whole edit — the surrounding prose (the 0.x line description, the compatibility-surface and hardened-against clauses) is cycle-stable, so leave it untouched.
  • A leading-digit bump (or a release that changes the cycle's story) may also need that surrounding prose refreshed — reread the block and update any clause the release makes stale.
  • Keep this in the Bump up version to x.y.z commit alongside the other versioned files; it is release metadata, not a separate docs pass.
Release mechanics
  • Add a new ## [x.y.z] - YYYY-MM-DD section immediately below [Unreleased].
  • Open it with the release summary above, then the ### Added / ### Changed / ### Fixed sections.
  • Use Keep a Changelog section headings verbatim: Added, Changed, Deprecated, Removed, Fixed, Security. Do NOT inline a description into the heading (### Added — feature X is wrong; the heading is just ### Added). Do NOT use #### sub-headings inside a version block. There is no Performance / Internal / Documentation section — a speed-up is Changed, a docs correction is Fixed. Say what it is in the entry, not in a heading of your own invention; spec/docs/changelog_conformance_spec.rb gates this.
  • Group the same kinds of changes under the same heading — one section per type per release, in the Keep a Changelog order above (Added first, Security last). Both are gated.
  • Preserve the release date in every version heading and the Keep a Changelog / Semantic Versioning notes at the top of CHANGELOG.md.
  • Update the [Unreleased] compare link and add the new release link at the bottom of CHANGELOG.md. Compare links target https://github.com/rigortype/rigor/compare/....
  • Bump Rigor::VERSION in lib/rigor/version.rb to match the new release.
  • Run bundle install after the version bump so Gemfile.lock records the new rigortype (x.y.z) revision; commit the regenerated lockfile alongside the version bump.
  • Keep the release commit message in the form Bump up version to x.y.z.
Archival rule (mandatory check)

Before bumping the version, check whether the new release is the first release after a leading-digit bump. The archival rule:

At the first a.b.c release whose (a, b) pair matches the most recent release but DIFFERS from the most recent archive's prefix, move the previous-digit range out of CHANGELOG.md into a new docs/CHANGELOG-<old-prefix>.md archive file.

Worked example: the rule fires at 0.1.1 because (0, 1) matches 0.1.0 (the previous release) but differs from the most recent archive (none yet), so 0.0.x moves to docs/CHANGELOG-0.0.x.md. The next archival fires at the first 0.2.x post-bump release (0.2.1), which moves 0.1.x to docs/CHANGELOG-0.1.x.md.

When the rule fires:

  1. Create docs/CHANGELOG-<old-prefix>.md with a header explaining what's in the file and a back-link to CHANGELOG.md. Use the archive built at 0.1.1 as the template — the explanatory header on docs/CHANGELOG-0.0.x.md is the reference shape.
  2. Move the entire ## [a.b.c] - YYYY-MM-DD block for every version in the range, plus the matching [a.b.c]: https://... reference links from the bottom of CHANGELOG.md, into the archive.
  3. Update CHANGELOG.md's top-of-file "Older release notes are archived" pointer list to include the new archive file.
  4. Verify the active CHANGELOG.md now holds only [Unreleased] and the most recent leading-digit cycle (a.b.0 plus any later a.b.c).

The rule keeps the active CHANGELOG.md small enough to read top-to-bottom without scrolling fatigue while preserving every release note's full text and link addressability.

Verify the Release

Run before committing:

sh
nix develop --command make verify
nix develop --command git diff --check

make verify is the CI-equivalent gate (tests, lint, check, and check-plugins). git diff --check catches whitespace mistakes in the release diff.

Overlap it with the sealing rather than queueing behind it. make verify is ~170 s of wall time that the prose work does not depend on, and the release commit touches no lib/. Land the code-affecting edits first — version.rb, then bundle install — start make verify in the background, and seal the [Unreleased] entries while it runs. The gate must still see the last edit: a CHANGELOG.md tweak made after a green verify can turn CI red, and make docs-check does not cover the changelog conformance spec. So after the final edit, re-run the two cheap gates that the prose can actually break:

sh
nix develop --command \
  bundle exec rspec spec/docs/changelog_conformance_spec.rb
nix develop --command make docs-check

That preserves the after-the-last-edit invariant at a fraction of a full rerun.

Also build the gem to confirm the gemspec is still valid for the bumped version:

sh
nix develop --command gem build rigortype.gemspec

The build produces rigortype-x.y.z.gem in the working tree. Delete it before committing — built gems must not be checked in.

If make verify requires formatting fixes or other non-version cleanup, commit that work separately before creating the version-bump commit. Do not fold release verification cleanup into the Bump up version to x.y.z commit.

Show full SKILL.md (1,499 more words)Show less
Perf-gate gotchas
  • The Make target is bench-perf, not bench (the bare name collides with the bench/ data directory). release-gate.yml is advisory until it is promoted to a required check — it reports but does not block; ci.yml is the required gate. The signal is still release-quality: review it.
  • Both baselines (bench/baseline.json, data/oss-sweep/mastodon-thresholds.json) are exact-count / banded with little headroom, so a precision or allocation change flips them red by design. Any recalibration uses the CI-measured Linux values, and wall_s is a rerunnable flake — gh run rerun --failed clears it; never recalibrate for wall alone. For the OSS sweep, diff the diagnostics for FPs before blessing a higher count, and fix an FP at its root rather than blessing it in. For the perf baseline, the next bullet is the only path.
  • A red perf gate has one way through. It runs the release candidate's engine over the previous release's tree (the corpus tag in bench/baseline.json, bench/README.md), so an allocations failure is engine cost with corpus growth already out of it. The gate is planned as a required check, which makes this the only way to clear it:
    1. Attribute the rise since the baseline's calibrated_at: the "Engine allocations" summaries of the PRs merged since, gem bumps (Gemfile.lock; the rbs gem supplies the core RBS), and a Ruby change (the gate run's Ruby against the one calibrated_on names; CI's ruby-version: "4.0" floats to the latest patch with no PR). The dependency-update and Ruby-bump PRs record their own shift.
    2. Put the attribution to the user.
    3. On the user's ruling, recalibrate on the same corpus, on the release branch: commit that branch's bench-baseline-<run-id> artifact as bench/baseline.json, with a note naming the ruling and the attribution. The push re-runs the gate.
    4. Publish, then advance the corpus ("Advance the perf-gate corpus" below).
  • Perf-measurement comparability: warm numbers are only comparable within one process model (an in-process cold-then-warm chain is ~186k allocs cheaper than a fresh-process warm — a phantom regression otherwise). Self-check allocation numbers require vendor/bundle present (~8M allocs of vendored sigs); the perf gate's corpus runs without it by design (bench/README.md). A peak-RSS rise on a run over ~5s is the deadline YJIT, not a leak — A/B with RIGOR_DISABLE_YJIT=1 before diagnosing. Details: docs/notes/20260713-corpus-perf-campaign.md.

Commit the Result

Prefer a single release-prep commit containing:

  • the lib/rigor/version.rb bump
  • the CHANGELOG.md update for the new version
  • the README.md ## Status line refresh
  • the Gemfile.lock regenerated by bundle install

Keep release verification cleanup and version bumps in separate commits. The final release-prep commit should be the version bump commit.

Use:

text
Bump up version to x.y.z

If the user asks for separate commits, keep the release version bump as the final commit.

Push and watch the release gate

Push the version-bump commit on the release branch:

sh
git push -u origin release/x.y.z

The push triggers release-gate.yml; the base ci.yml gate runs on the release PR you open next (it triggers on pull_request, not on a release/** push, so the branch is not double-run):

  • ci.yml (base gate, required) — test / lint / self-check warm+cold / warm==cold diff; runs on the PR. MUST be green before the PR merge below.
  • release-gate.yml (comprehensive, advisory until promoted to a required check) — the perf benchmark (make bench-perf, ADR-50 WD4), gem-build validation, and the OSS-corpus sweep. It reports but does not block while the baselines calibrate; a regression here is still a release-quality signal worth reviewing.
    • A wall_s-only perf failure is CI wall-time noise — the deterministic allocations / peak_rss_kb bands are the real signal. Clear it with gh run rerun --failed <run-id>; never recalibrate for wall alone. An allocations failure takes the one path in "Perf-gate gotchas".
    • An OSS-sweep diagnostic-count change needs a false-positive diff before it is blessed into data/oss-sweep/*-thresholds.json.

Do not merge until the base gate is green and the advisory gate is reviewed.

Open the release PR and merge it on green

Land the release on master through a CI-gated PR — not a direct push — so the version bump, sealed CHANGELOG, and archive reach the mainline only once the required gate is green:

sh
gh pr create --draft --base master --head release/x.y.z \
  --title "Bump up version to x.y.z" --body "<short release summary>"
gh pr checks <pr> --watch        # wait for the required ci.yml gate
gh pr ready <pr>                 # only on the user's explicit word, CI green, no stop instruction
gh pr merge <pr> --rebase --delete-branch

The release PR is created --draft like every other PR, but lands by this skill's own rule, which docs/agents/contribution-flow.md § "Landing a pull request" defers to: the user reviews the sealed section on the PR, and gh pr ready is the recorded hand-off from review to landing.

  • Merge on the required gate; review the advisory one. ci.yml is the merge gate; release-gate.yml is advisory (apply the wall-noise / sweep notes above). Merge once ci.yml is green and any advisory failure is explained.
  • Rebase- or merge-commit, never squash. Keep the Bump up version to x.y.z commit intact so the tag in "Publish" lands on it. If master advanced, rebase the branch first and re-push — and re-read the sealed section afterwards. merge=union means a [Unreleased] entry that landed on master during release prep is folded in silently rather than raising a conflict, so it can arrive under the wrong heading or after the section was already sealed.
  • The PR merge is the merge-back to master; publish runs from master afterward, so there is no separate merge-back step.

Publish

After the release PR merges, publish from an up-to-date master via the bundler/gem_tasks release task wired into Rakefile. Run it only after the user explicitly authorizes publishing: it tags, pushes, and publishes to RubyGems, and none of that can be undone.

sh
git switch master && git pull
nix develop --command bundle exec rake release

rake release verifies a clean working tree, tags the release as vx.y.z, pushes the tag to origin, publishes the gem to RubyGems, AND creates the matching GitHub Release (the post-publish hook in Rakefile invokes rake release:github). It requires:

  • A clean working tree on master (the merged release commit at HEAD).
  • A RubyGems API key with MFA configured — rigortype.gemspec sets rubygems_mfa_required => "true", so non-MFA pushes will be rejected.
  • Push access to origin.
  • gh auth status clean — the GitHub Release step shells out to gh release create.

If the GitHub Release step fails after the gem is already published (transient gh / network error), the standalone task retries that step alone — the gem is not republished:

sh
nix develop --command bundle exec rake release:github

The standalone task reads Rigor::VERSION, requires the matching vx.y.z tag to exist locally, extracts the ## [x.y.z] - YYYY-MM-DD section from CHANGELOG.md verbatim as the release body, derives the previous tag via git describe --tags --abbrev=0 vx.y.z^, and appends a **Full Changelog**: compare/v(prev)...v(this) footer. The release title is the section heading without the leading ## (e.g. [0.1.12] - 2026-05-28).

If publishing must be split across people or machines, build locally and hand the artefact to the publisher:

sh
nix develop --command gem build rigortype.gemspec
# Hand off rigortype-x.y.z.gem, then on the publisher's machine:
nix develop --command gem push rigortype-x.y.z.gem

In the split-publish case, push the vx.y.z tag manually after the gem is accepted by RubyGems, then run rake release:github once the tag is on origin to create the GitHub Release.

Advance the perf-gate corpus

Once the tag exists, the perf gate's corpus moves to it, so the next cycle's engine cost is measured on this release's tree. Recalibrate from a branch cut at the tag, so the baseline measures exactly the released engine. Open no PR until the last step: the first commit sets "calibrated": false, which passes every run, so it must never sit at the head of a PR that could merge.

sh
git switch -c bench-corpus-vX.Y.Z vX.Y.Z
# bench/baseline.json: "corpus": "vX.Y.Z", "calibrated": false
git commit -am "Advance the perf-gate corpus to vX.Y.Z"
git push origin HEAD:refs/heads/bench-corpus-vX.Y.Z
gh workflow run release-gate.yml --ref bench-corpus-vX.Y.Z
gh run list --workflow release-gate.yml --branch bench-corpus-vX.Y.Z --limit 1 --json databaseId
gh run watch <run-id>
gh run view <run-id> --json status   # watch can return mid-run; wait for "completed"
gh run download <run-id> --name bench-baseline-<run-id> -D <dir>

Commit <dir>/baseline.updated.json as bench/baseline.json, adding calibrated_on (the run, and the Ruby its setup step installed) and a note with the move from the previous corpus. Push, then open the PR to master. calibrated: false in the first commit is what keeps that run from gating the new tree against the old tree's numbers, and spec/tool/bench_sampling_spec.rb fails CI if it is ever committed as the head state.

Quick Checklist

  • Working tree starts clean or every pending change is understood.
  • Rigor::VERSION (lib/rigor/version.rb) and Gemfile.lock agree on the new version.
  • Every former [Unreleased] bullet was classified and, if commit-style, rewritten per "Seal the [Unreleased] entries" — no top-level bullet in the new ## [x.y.z] section has two sentences, an em-dash clause, internal-only detail, or a merge artefact. (This is the step make verify cannot check; confirm it by eye.)
  • Every bullet whose change went through a PR carries it as a full markdown link (([#170](https://github.com/rigortype/rigor/pull/170))), and the step-1 PR list has no merged PR that is neither linked nor deliberately internal. No bare #170 anywhere — it is dead text in CHANGELOG.md.
  • The new ## [x.y.z] section opens with a short release-summary paragraph (themes, a few simple sentences) before ### Added.
  • README.md's ## Status line names the new version + date (surrounding cycle-stable prose left intact unless a leading-digit bump makes it stale).
  • [Unreleased] / [x.y.z] compare links resolve.
  • make verify passed.
  • gem build rigortype.gemspec succeeded and the produced .gem is not committed.
  • The final commit message follows Bump up version to x.y.z.
  • Release work happened on a release/x.y.z branch (not directly on master).
  • Before merge: ci.yml base gate is green; release-gate.yml (advisory) was reviewed — no unexplained perf or sweep regression (a wall_s-only perf failure is noise, rerun it).
  • The release PR merged to master on a green ci.yml, keeping the Bump up version to x.y.z commit intact (rebase / merge, not squash).
  • After publish: the vx.y.z tag, the RubyGems push, and the GitHub Release all exist; the release branch is deleted.
  • After publish: bench/baseline.json names vx.y.z as its corpus and is recalibrated on it, from a branch cut at the tag.

© rigortype, MPL-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .claude/skills/rigor-release-prep of rigortype/rigor.

Open the folder on GitHubat commit 57a67cf

Compare with similar skills

Rigor Release Prep next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Rigor Release Prep compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Rigor Release Prep this skillrigortype/rigor106—~7.8kAutomated safety check: PassMPL-2.0
Releasebibendi/schked138—~670Automated safety check: NotesMIT
Write ChangelogDataDog/dd-trace-rb417—~2.9kAutomated safety check: PassCustom licence
Release Managementruby-git/ruby-git1.8k—~3.1kAutomated safety check: PassMIT
Dependency Update BotVarnan-Tech/opendirectory674—~3kAutomated safety check: NotesMIT
Simple Englishmoeru-ai/airi50k2 repos~4.6kAutomated safety check: PassMIT

Similar skills

  • Release

    bibendi/schked

    Guides through the full gem release process — bump version, update CHANGELOG, tag, push to RubyGems, and create GitHub Release.

    138 GitHub stars~670 tokensUpdated 1 mo ago
    DevelopmentAuto-check: notes
  • Write Changelog

    DataDog/dd-trace-rb

    Official

    A skill your agent uses when a change in this repo needs a customer-facing changelog entry — e.g.

    417 GitHub stars~2.9k tokensUpdated today
    DevelopmentAuto-check passed
  • Release Management

    ruby-git/ruby-git

    Prepares and publishes new releases of the ruby-git gem including version bumps, changelog updates, tagging, and gem publishing.

    1.8k GitHub stars~3.1k tokensUpdated 6 days ago
    DevelopmentAuto-check passed
  • Dependency Update Bot

    Varnan-Tech/opendirectory

    Scans your project for outdated npm, pip, Cargo, Go, or Ruby packages.

    674 GitHub stars~3k tokensUpdated 1 mo ago
    DevelopmentAuto-check: notes
  • Simple English

    moeru-ai/airi

    Write or rewrite technical text with the rules of ASD-STE100 Simplified Technical English so it is clear, unambiguous, and free of AI slop.

    50k GitHub starsUsed in 2 repos~4.6k tokens
    DevelopmentAuto-check passed
  • StarRocks Release Notes

    StarRocks/starrocks

    Drafts English release notes for a StarRocks patch release from the PRs merged into its release branch, then opens a documentation PR and hands translation to /translate.

    12k GitHub stars~1.9k tokensUpdated today
    DevelopmentAuto-check: notes

More from rigortype/rigor

All 36 skills in this repo
  • Rigor Regression Sweep

    rigortype/rigor

    Measure Rigor's baseline drift across the tagged history of a real OSS Ruby project.

    106 GitHub stars~2.9k tokensUpdated today
    Auto-check passed
  • Adjudicate a rigor unused report safely before proposing dead-code removal.

    106 GitHub stars~1.1k tokensUpdated today
    Auto-check passed
  • Rigor Baseline Reduce

    rigortype/rigor

    Reduce an existing .rigor-baseline.yml rule by rule by triaging sites, fixing or intentionally suppressing them, and regenerating the baseline.

    106 GitHub stars~1.3k tokensUpdated today
    Auto-check passed
  • Rigor Doctor

    rigortype/rigor

    Validate that a project's Rigor configuration, plugins, paths, and baseline are actually healthy.

    106 GitHub stars~767 tokensUpdated today
    Auto-check passed
  • Rigor Plugin Author

    rigortype/rigor

    Author a new Rigor plugin, choosing plugins/ for production support or examples/ for a contract walkthrough.

    106 GitHub stars~3.3k tokensUpdated today
    Auto-check: notes
  • Rigor Plugin Author

    rigortype/rigor

    Author a Rigor plugin in an adopting project or standalone rigor- gem for a DSL, framework, or metaprogramming pattern.

    106 GitHub stars~1.9k tokensUpdated today
    Auto-check passed

Works with

Categories

Questions about Rigor Release Prep

What does Rigor Release Prep do?

Prepare a Rigor RubyGems release by bumping the version, consolidating changelog fragments, and running release gates. Rigor Release Prep is an agent skill from rigortype/rigor. Prepare a Rigor RubyGems release by bumping the version, consolidating changelog fragments, and running release gates.

When should I use Rigor Release Prep?

Rigor Release Prep fits situations like: explicitly invokes /rigor-release-prep; asks to cut a release; not for ordinary fixes; release context alone.

How do I install Rigor Release Prep in Claude Code?

Run `npx skills add rigortype/rigor --skill rigor-release-prep -a claude-code`. Or copy the skill folder (.claude/skills/rigor-release-prep in rigortype/rigor) into .claude/skills/rigor-release-prep in your project. Claude Code loads it when a task matches its description.

How do I install Rigor Release Prep in Codex?

Run `npx skills add rigortype/rigor --skill rigor-release-prep -a codex`. Or copy the skill folder (.claude/skills/rigor-release-prep in rigortype/rigor) into .agents/skills/rigor-release-prep in your project. Codex loads it when a task matches its description.

Can I use Rigor Release Prep in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add rigortype/rigor --skill rigor-release-prep -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/rigor-release-prep, .gemini/skills/rigor-release-prep, .github/skills/rigor-release-prep and .opencode/skills/rigor-release-prep in your project.

What does Rigor Release Prep need to run?

Going by SKILL.md and its folder, Rigor Release Prep needs the command-line tools its instructions call (gh, git, nix, make, bundle and ruby).

Does Rigor Release Prep access the network?

SKILL.md names 1 domain. As links in the text: keepachangelog.com. This is read from the text; nothing was executed.

Is Rigor Release Prep safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Rigor Release Prep use?

Rigor Release Prep is published under the MPL-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Rigor Release Prep use?

About 7.8k tokens (SKILL.md is roughly 31k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Rigor Release Prep?

Skills that share tags, products or a category with Rigor Release Prep: Release (bibendi/schked, 138 stars), Write Changelog (DataDog/dd-trace-rb, 417 stars), Release Management (ruby-git/ruby-git, 1.8k stars) and Dependency Update Bot (Varnan-Tech/opendirectory, 674 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Rigor Release Prep?

rigortype (a GitHub organization) maintains it in rigortype/rigor, which has 106 GitHub stars. The repository holds 36 skills in this directory. The repository was last updated on October 8, 2026.

Source: rigortype/rigor on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.