Release
bibendi/schked
Guides through the full gem release process — bump version, update CHANGELOG, tag, push to RubyGems, and create GitHub Release.
Prepare a Rigor RubyGems release by bumping the version, consolidating changelog fragments, and running release gates.
$ npx skills add rigortype/rigor --skill rigor-release-prep -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install rigortype/rigor rigor-release-prep --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ 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-srcUse ~/.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/
Install the "rigor-release-prep" agent skill from https://github.com/rigortype/rigor/tree/master/.claude/skills/rigor-release-prep into .claude/skills/rigor-release-prep/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rigor-release-prep", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/rigortype/rigor/tree/master/.claude/skills/rigor-release-prepType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add rigortype/rigor --skill rigor-release-prep -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install rigortype/rigor rigor-release-prep --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/rigortype/rigor.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/rigor-release-prep .agents/skills/rigor-release-prep && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "rigor-release-prep" agent skill from https://github.com/rigortype/rigor/tree/master/.claude/skills/rigor-release-prep into .agents/skills/rigor-release-prep/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rigor-release-prep", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add rigortype/rigor --skill rigor-release-prep -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install rigortype/rigor rigor-release-prep --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/rigortype/rigor.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/rigor-release-prep .cursor/skills/rigor-release-prep && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "rigor-release-prep" agent skill from https://github.com/rigortype/rigor/tree/master/.claude/skills/rigor-release-prep into .cursor/skills/rigor-release-prep/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rigor-release-prep", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/rigortype/rigor.git --path .claude/skills/rigor-release-prep--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add rigortype/rigor --skill rigor-release-prep -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install rigortype/rigor rigor-release-prep --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/rigortype/rigor.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/rigor-release-prep .gemini/skills/rigor-release-prep && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "rigor-release-prep" agent skill from https://github.com/rigortype/rigor/tree/master/.claude/skills/rigor-release-prep into .gemini/skills/rigor-release-prep/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rigor-release-prep", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install rigortype/rigor rigor-release-prepInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add rigortype/rigor --skill rigor-release-prep -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/rigortype/rigor.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/rigor-release-prep .github/skills/rigor-release-prep && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "rigor-release-prep" agent skill from https://github.com/rigortype/rigor/tree/master/.claude/skills/rigor-release-prep into .github/skills/rigor-release-prep/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rigor-release-prep", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add rigortype/rigor --skill rigor-release-prep -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install rigortype/rigor rigor-release-prep --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/rigortype/rigor.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/rigor-release-prep .opencode/skills/rigor-release-prep && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "rigor-release-prep" agent skill from https://github.com/rigortype/rigor/tree/master/.claude/skills/rigor-release-prep into .opencode/skills/rigor-release-prep/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rigor-release-prep", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
rigor-release-prepPrepare 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. 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.
6 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 57a67cf. It shows what the files ask for, not the result of running them.
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.
Shell commands in SKILL.md call:
ghgitnixmakebundlerubygemFrom the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
keepachangelog.comFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
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.
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.
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.
The full file from rigortype/rigor at commit 57a67cf, republished under its MPL-2.0 licence (© rigortype). 3,876 words, ~7,792 tokens.
.claude/skills/rigor-release-prep/SKILL.md (or your agent's skills folder).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.
release/x.y.zRelease work happens on a dedicated release/x.y.z branch, not directly on
master (ADR-50).
Cut it from an up-to-date master:
git switch master && git pull
git switch -c release/x.y.zEvery 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.
Decide the next semantic version first, then update all versioned files together.
Update these files:
CHANGELOG.mdlib/rigor/version.rbGemfile.lock (regenerated by bundle install after the version bump)README.md (the ## Status line — version + date; see "Refresh the
README status" below)[Unreleased] entries — the mandatory rewrite stepDo 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:
<br> — a wrapped entry renders ragged. Same rule for any PR /
issue / comment / wiki text (docs/agents/contribution-flow.md § "Commits
and GitHub Markdown").**[rigor check]**, **[engine]**,
**[plugin contract]**, **[plugins/rigor-foo]**, etc. - …), two to three
sentences max, one topic each.[Unreleased] line may split into several.([#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.#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.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:
# ✗ 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:
- **[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:
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:
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.
Read the entire [Unreleased] block. For each top-level bullet,
explicitly classify it: release-style (leave) or commit-style (rewrite).
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.
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).
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.
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)).)
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".
[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.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.definevalue 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.
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.
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.Bump up version to x.y.z commit alongside the other
versioned files; it is release metadata, not a separate docs pass.## [x.y.z] - YYYY-MM-DD section immediately below [Unreleased].### Added / ### Changed
/ ### Fixed sections.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.Added first, Security
last). Both are gated.CHANGELOG.md.[Unreleased] compare link and add the new release link at the
bottom of CHANGELOG.md. Compare links target
https://github.com/rigortype/rigor/compare/....Rigor::VERSION in lib/rigor/version.rb to match the new release.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.Bump up version to x.y.z.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.crelease whose(a, b)pair matches the most recent release but DIFFERS from the most recent archive's prefix, move the previous-digit range out ofCHANGELOG.mdinto a newdocs/CHANGELOG-<old-prefix>.mdarchive 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:
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.## [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.CHANGELOG.md's top-of-file "Older release notes are archived"
pointer list to include the new archive file.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.
Run before committing:
nix develop --command make verify
nix develop --command git diff --checkmake 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:
nix develop --command \
bundle exec rspec spec/docs/changelog_conformance_spec.rb
nix develop --command make docs-checkThat 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:
nix develop --command gem build rigortype.gemspecThe 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.
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.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.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: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.bench-baseline-<run-id> artifact as
bench/baseline.json, with a note naming the ruling and the
attribution. The push re-runs the gate.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.Prefer a single release-prep commit containing:
lib/rigor/version.rb bumpCHANGELOG.md update for the new versionREADME.md ## Status line refreshGemfile.lock regenerated by bundle installKeep release verification cleanup and version bumps in separate commits. The final release-prep commit should be the version bump commit.
Use:
Bump up version to x.y.zIf the user asks for separate commits, keep the release version bump as the final commit.
Push the version-bump commit on the release branch:
git push -u origin release/x.y.zThe 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.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".data/oss-sweep/*-thresholds.json.Do not merge until the base gate is green and the advisory gate is reviewed.
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:
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-branchThe 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.
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.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.master; publish runs from master
afterward, so there is no separate merge-back step.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.
git switch master && git pull
nix develop --command bundle exec rake releaserake 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:
master (the merged release commit at HEAD).rigortype.gemspec sets
rubygems_mfa_required => "true", so non-MFA pushes will be rejected.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:
nix develop --command bundle exec rake release:githubThe 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:
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.gemIn 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.
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.
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.
Rigor::VERSION (lib/rigor/version.rb) and Gemfile.lock agree on the
new version.[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.)([#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.## [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.Bump up version to x.y.z.release/x.y.z branch (not directly on
master).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).master on a green ci.yml, keeping the Bump up version to x.y.z commit intact (rebase / merge, not squash).vx.y.z tag, the RubyGems push, and the GitHub Release
all exist; the release branch is deleted.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
Just SKILL.md in .claude/skills/rigor-release-prep of rigortype/rigor.
Open the folder on GitHubat commit 57a67cf
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.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Rigor Release Prep this skillrigortype/rigor | 106 | — | ~7.8k | Automated safety check: Pass | MPL-2.0 | |
| Releasebibendi/schked | 138 | — | ~670 | Automated safety check: Notes | MIT | |
| Write ChangelogDataDog/dd-trace-rb | 417 | — | ~2.9k | Automated safety check: Pass | Custom licence | |
| Release Managementruby-git/ruby-git | 1.8k | — | ~3.1k | Automated safety check: Pass | MIT | |
| Dependency Update BotVarnan-Tech/opendirectory | 674 | — | ~3k | Automated safety check: Notes | MIT | |
| Simple Englishmoeru-ai/airi | 50k | 2 repos | ~4.6k | Automated safety check: Pass | MIT |
bibendi/schked
Guides through the full gem release process — bump version, update CHANGELOG, tag, push to RubyGems, and create GitHub Release.
DataDog/dd-trace-rb
A skill your agent uses when a change in this repo needs a customer-facing changelog entry — e.g.
ruby-git/ruby-git
Prepares and publishes new releases of the ruby-git gem including version bumps, changelog updates, tagging, and gem publishing.
Varnan-Tech/opendirectory
Scans your project for outdated npm, pip, Cargo, Go, or Ruby packages.
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.
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.
rigortype/rigor
Measure Rigor's baseline drift across the tagged history of a real OSS Ruby project.
rigortype/rigor
Adjudicate a rigor unused report safely before proposing dead-code removal.
rigortype/rigor
Reduce an existing .rigor-baseline.yml rule by rule by triaging sites, fixing or intentionally suppressing them, and regenerating the baseline.
rigortype/rigor
Validate that a project's Rigor configuration, plugins, paths, and baseline are actually healthy.
rigortype/rigor
Author a new Rigor plugin, choosing plugins/ for production support or examples/ for a contract walkthrough.
rigortype/rigor
Author a Rigor plugin in an adopting project or standalone rigor- gem for a DSL, framework, or metaprogramming pattern.
Works with
Categories
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.
Rigor Release Prep fits situations like: explicitly invokes /rigor-release-prep; asks to cut a release; not for ordinary fixes; release context alone.
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.
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.
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.
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).
SKILL.md names 1 domain. As links in the text: keepachangelog.com. This is read from the text; nothing was executed.
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.
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.
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.
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.
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.