Cut a prospec GitHub release — bump version strings, tag, and publish release notes in the established format so the Release Binaries workflow attaches multi-platform binaries. Triggers: release, publish release, cut a release, ship a version, 發布, 發佈, 出版本, 發版, 版本發布, 發布 release
Scanned 9/2/2026
Install to Claude Code
npx -y skills add benwu95/prospec --skill release --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Release?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/benwu95-release)More formats (shields.io, HTML) on the badges page.
---
name: release
description: "Cut a prospec GitHub release — bump version strings, tag, and publish release notes in the established format so the Release Binaries workflow attaches multi-platform binaries. Triggers: release, publish release, cut a release, ship a version, 發布, 發佈, 出版本, 發版, 版本發布, 發布 release"
---
# Release Skill
Cut a new prospec release from `main`: bump the version strings, create the tag, and publish
GitHub release notes in the house format. Publishing the release (`published` event) triggers
`.github/workflows/release.yml`, which compiles the multi-platform standalone binaries and attaches
them as compressed assets — so this skill's job is the version bump + notes, not the build.
## Language
The release notes, commit message, and everything this skill writes are in **English** — a release
is trust-zone / public-facing technical output, exempt from the Traditional Chinese change-artifact
rule (see `prospec/CONSTITUTION.md` → Language Policy, mirrored in `AGENTS.md`). Talk to the user in
their language; write the artifacts in English.
## Preconditions — do not release until all hold
1. **All PRs for this version are merged to `main`** and `main` is checked out with a clean tree
(`git status`). `gh pr list --state open --base main` is empty. A release is cut from `main`,
never a feature branch.
2. **Each change is archived** (`/prospec-archive`) — REQs graduated, Knowledge synced, summary
written. `prospec status` reports no in-progress changes. The release notes' Dogfood section
reports this; it must already be true.
3. **Counts are already synced.** `pnpm counts` runs as the last step of each *feature* commit, not
here — READMEs / `index.md` / module READMEs already carry the right test/skill counts. Do not
run `pnpm counts` during the bump. (See memory: counts are generated by `sync-counts.ts`.)
4. **Green locally with the current CI/release gates.** Run the coverage suite once, then reuse its
explicit JSON report for the factual-count check so the suite is not run twice:
```bash
pnpm test:coverage
pnpm typecheck
pnpm lint
pnpm counts:check --from vitest-report.json
pnpm agents:check
pnpm knowledge:check
prospec check --strict
pnpm bundle
```
`coverage/` and `vitest-report.json` on disk may be stale; only figures from this invocation are
release evidence. `knowledge:check` may honestly skip when the release-only diff touches no
module-owned source — report that result rather than manufacturing work. Capture the numbers for
the "Quality & tests" section. Read `prospec check` WARNs by type, not as one bucket:
- **`knowledge-health` (stale module README)** — almost always a prior change's archive that
changed a module's source but never touched its README (drift compares git commit times).
**Fix it before releasing**: sync + commit that module README so the notes can honestly claim
a green check. Then confirm the fix didn't tip **`knowledge-size`** over the L2 per-module
budget (this project overrides it to 2000 tokens in `.prospec.yaml`; the shipped default is
1000) — if it did, trim the README back under budget (net-neutral) rather than accept a new
WARN.
- **`knowledge-size` budget WARN** that pre-exists and is deliberate (the SC-002 signal) may be
reported as such, mirroring how 0.5.2 framed it — do not thrash the README to chase it away.
5. **`gh` is authenticated as an account with write access to this repo.** When more than one account
is logged in (`gh auth status` lists them), the active one can silently be the wrong one — and then
`gh release create` fails with a **misleading** `"workflow" scope may be required`. The cause is the
account, not the scope. Check, and switch if needed, before publishing:
```bash
gh api user -q .login # must be an account that can write here
gh auth switch --hostname github.com --user <account> # only if it is not
```
`git push` may travel over a different credential path (an SSH host alias, say) and be unaffected —
only `gh` API operations follow the active account, so a successful push proves nothing about this.
If a check FAILs, stop and resolve it — never paper over it in the notes.
## Version & tag conventions
- **SemVer.** Pick `X.Y.Z` from the scope since the last tag: incompatible/breaking behavior → major;
backward-compatible user-visible capability → minor; bug-fix / hardening / CI-only → patch.
Confirm the number with the user before tagging.
- **Tag = bare `X.Y.Z`** (no `v` prefix — the `v` was dropped at 0.5.0). Lightweight tag, created
by `gh release create` at `main` HEAD (the bump commit).
- **Release title** carries no `v` either (also dropped at 0.5.0): `X.Y.Z — Headline: subtitle`.
## Step-by-step
### 1. Gather the source material
```bash
LAST=$(git describe --tags --abbrev=0) # previous release tag, e.g. 1.3.0
git log --first-parent --merges --oneline "$LAST"..HEAD # merged PRs in release ancestry
git log --first-parent --no-merges --oneline "$LAST"..HEAD # direct commits also shipping
git diff --shortstat "$LAST"..HEAD # provisional; re-run after the bump
gh pr list --state merged --base main --limit 100 # titles + URLs to cross-check
gh release view "$LAST" --json body # the canonical format to mirror
```
Use the first-parent ancestry, not a date cutoff or the `gh pr list` result by itself, as the
authoritative merged-PR set: a busy release may exceed the list limit, and merge time is not tag
ancestry. Note the direct commits too so the notes do not silently omit work. Record the previous
version's test count from that release's notes or the current `README.md`; the notes report the delta.
### 2. Audit and update the release-owned surfaces (manual, no script exists)
> If a `chore: bump version to X.Y.Z` commit is already on `main` (the bump often lands ahead of
> running this skill), just confirm the strings below are correct and skip to step 5. Any release
> commit you add afterwards (e.g. a release-readiness documentation fix) becomes the tag target — that is
> fine; the tag only needs to point at a tree carrying the right version.
First inventory intentional pre-release holdovers. A documentation change may deliberately pin the
last released version, preview image, or wording until the cut:
```bash
rg -n 'release-owned|until the cut|social preview|Upcoming|upcoming|即將推出|softwareVersion|dateModified|<span class="ver">' \
README.md README.zh-TW.md docs tests/contract
```
Review every match; negative assertions and historical upgrade prose can be legitimate. Update the
actual release surfaces:
- `package.json` → the top-level `"version": "X.Y.Z"` only
- `.prospec.yaml` → `version: X.Y.Z`
- `docs/index.html` → **three release-owned fields**: `"softwareVersion":"X.Y.Z"`, the nav brand
`<span class="ver">X.Y.Z</span>` (bare — no `v`), and `"dateModified":"YYYY-MM-DD"`.
- `tests/contract/skill-format.test.ts` → update release-readiness test names and assertions that
intentionally pinned the prior version "until the cut". Assert the new version positively; do
not merely delete the guard.
- `docs/og.png` plus the `og:image:alt` / `twitter:image:alt` text in `docs/index.html` → update when
they still identify the prior release or depict behavior that the new release changed. A prior
change may have explicitly deferred this work to release time. Do not relabel a stale image with
new alt text; update both, preferably in a separate atomic docs commit before the version bump.
- `README.md`, `README.zh-TW.md`, `docs/index.html`, and `docs/i18n.js` → remove any genuine
pre-release label that is no longer true while preserving historical upgrade guidance.
Do **not** globally replace the old version or require a bare search for it to return zero: a release
such as `1.3.0` is also a substring of an unrelated dependency/tool version such as `pnpm@11.3.0`,
and fixtures or historical prose may use it legitimately. Verify the new fields positively and
inspect only the semantic holdovers above.
### 3. Commit the bump
```bash
git diff --check
git diff -- package.json .prospec.yaml docs/index.html tests/contract/skill-format.test.ts
git add package.json .prospec.yaml docs/index.html tests/contract/skill-format.test.ts
git commit -m "chore: bump version to X.Y.Z"
```
Commit-message rules (project Constitution + memory): **bulleted body if any body is needed, no
prose paragraphs; never add `Co-Authored-By` / AI attribution** (P2). The bump commit is typically
body-less — the subject line suffices.
Re-run the gates from precondition 4 after the release edits. Then smoke-test the just-built bundle:
```bash
node dist/cli-bundle.js --version # must print X.Y.Z
```
### 4. Push `main`
```bash
git push origin main
```
### 5. Draft the release notes
Recompute release evidence **after every release commit**; the pre-bump shortstat from step 1 is
provisional:
```bash
git diff --shortstat "$LAST"..HEAD
git log --first-parent --merges --oneline "$LAST"..HEAD
git log --first-parent --no-merges --oneline "$LAST"..HEAD
```
Write to a scratch file (git-ignored), e.g. `.tasks/<branch>/release-notes-X.Y.Z.md`, following the
template below. **The file's entire contents ARE the release description, verbatim** — it is fed to
`--notes-file` as-is. So it must contain only the body (first line `# Prospec X.Y.Z`, then the
notes). Do **not** add worksheet scaffolding — no `# Release Notes X.Y.Z`, no `## Release Title`, no
`## Release Body`, no fenced title block; the title is a separate `--title` argument, never repeated
in the body. Show the draft to the user and get sign-off before publishing — the notes are public
and hard to un-see.
### 6. Publish (this builds & attaches the binaries)
```bash
gh release create X.Y.Z \
--title "X.Y.Z — Headline: subtitle" \
--notes-file .tasks/<branch>/release-notes-X.Y.Z.md
```
`gh release create` creates the lightweight tag at HEAD and fires the `published` event →
`release.yml` compiles `bun` binaries for linux-x64 / macos-arm64 / macos-x64 / windows-x64,
packages them (`.tar.gz` / `.zip`), and uploads them to the release.
### 7. Verify the release landed
```bash
gh run list --workflow=release.yml --limit 1 # watch it go green
gh release view X.Y.Z # 4 archive assets attached, notes render
```
Confirm the workflow succeeded and all four platform archives are attached. Report the release URL.
## Release-notes format
Mirror the last two releases exactly (`gh release view <LAST>` is the living reference). Structure:
**Title** — one line, no `v`, passed only via `--title` (never inside the body):
```
X.Y.Z — <Headline Name>: <2–4 comma/colon-joined themes>
```
**Body** (Markdown) = the literal `--notes-file` contents, sections in this order — omit a section
only when it genuinely has no content:
0. **`# Prospec X.Y.Z`** — the body's first line, an H1 (matches every prior release). Nothing
precedes it; no worksheet labels wrap the notes (see step 5).
1. **Lead paragraph** — one paragraph directly under the H1: `X.Y.Z is a <correctness / optimization
/ feature / …> release that <what it does and why it matters>.`
2. **Stat line** — one line, right after the lead:
`N files changed · +A / −B · M merged PRs ([#n](https://github.com/benwu95/prospec/pull/n), …)`
append `+ D direct maintenance commits` and/or `+ CI maintenance` when applicable. Use the
post-bump numbers from step 5, never the provisional step-1 shortstat.
3. `---`
4. `## ✨ Headline feature` (or `features`) — one `### <Feature Name> (PR [#n](…))` block per major
item; prose first, then bullets for enumerable specifics (forms, flags, sources of truth).
5. `## 🐛 Bug fixes` — bulleted; each starts with a **bold** one-line symptom, then the mechanism
and the fix. (Only if the release fixes bugs.)
6. `## 🔧 CI maintenance` — pinned-action bumps, workflow tweaks. (Only if applicable.)
7. `## 🔁 Dogfood` — how the change was driven through prospec's own SDD loop
(`story → plan → design (when UI-scoped) → tasks → implement → review → verify grade <S/A> →
knowledge-update → archive`), plus which REQs graduated into which Knowledge modules. Name any
quick/backfill exception instead of presenting the standard path as universal.
8. `## 🧪 Quality & tests` — bulleted: **N tests passing (F files)** up from the prev count and what
was added; **~XX.X% line coverage**; drift-check status (`prospec check`: pass/skip counts, note
any deliberate WARN); zero typecheck/lint warnings.
9. `## 📊 Compared to <LAST>` — a table `| Comparison | <LAST> | X.Y.Z |` with one row per changed
dimension; **bold** the new-version cell; last row is usually **Passing tests**.
10. `## ⬆️ Upgrade notes` — numbered downstream steps: re-run the installer (`install.sh` /
`install.ps1`, which pull `releases/latest`), run `prospec check`, plus any migration caveats
(state "no config change required" when true).
Keep the emoji headers consistent: `✨ 🐛 🔧 🔁 🧪 📊 ⬆️`. Every claim (counts, coverage, PR
numbers, file stats) must be real — derive them in step 1, never invent.
## Notes
- **This is maintainer tooling for the prospec repo itself**, not a prospec SDD skill shipped to
users. It has no `.hbs` template and is not produced by `prospec agent sync`.
- It lives under **both** `.claude/skills/release/` and `.agents/skills/release/`, each
version-controlled via its own explicit `!` exception in `.gitignore` (the repo otherwise tracks
only `.claude/skills/prospec-*` / `.agents/skills/prospec-*`). The two copies are hand-maintained
mirrors — no generator produces them and no drift check compares them, so they have silently
diverged before. Edit **both** in the same change, and keep the only permitted difference the
harness-specific wording (entry config `CLAUDE.md` vs `AGENTS.md`).
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!