# Session Release

> End-to-end release workflow that bumps version, packages artifacts, and verifies satellite content (docs sites, marketing sites, changelogs) is up-to-date. Combines project-specific release skills with a generic release surface scan. Triggers on "/session-release" or when user says "prepare the release", "do a release", or "release workflow".

- Skill: `matshoppenbrouwers/session-release` (Agent Skill)
- Install (CLI): `npx skillmds@latest add matshoppenbrouwers/session-release`
- Raw SKILL.md: https://api.skillmd.com/api/skills/matshoppenbrouwers/session-release/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Marketing & Growth
- Author: matshoppenbrouwers (https://skillmd.com/u/matshoppenbrouwers)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/matshoppenbrouwers/session-release

---


# Session Release

Orchestrate a full release cycle: version bump, artifact packaging, and satellite content verification.

Open with one sentence saying what you are about to do and what it will produce.

## Non-Negotiables

1. **Never auto-run builds.** Builds often require signing keys, CI pipelines, or Windows/macOS-specific environments. Print the command and wait for the user.
2. **Never modify lock files manually.** Lock files (`package-lock.json`, `Cargo.lock`, `pnpm-lock.yaml`) are regenerated by the toolchain. Hand-editing corrupts them.
3. **User approves at both gates.** Step 3 (build) and Step 6 (satellite updates) require explicit user confirmation, or a standing policy that already covers exactly that action. No proceeding on silence.
4. **Final version grep must be clean.** Before commit, grep the repo for the old version — nothing should remain except in `CHANGELOG.md`, lock files, and historical references.
5. **Never skip the satellite scan.** The whole point of this skill is to catch the docs site, marketing page, and download modal that still say the old version.
6. **Never accept a verification verdict without comparing its recorded commit range against the candidate revision.** A PASS is evidence about the revision it was recorded against. When they differ, the user decides reuse or rerun explicitly.
7. **Each release action is authorized on its own.** Bumping, packaging, and committing are this skill's work. Tagging, pushing, publishing, deploying, and announcing are separate actions with their own authority, and a release run never performs one because the previous step succeeded.

## Core Principle

A release is more than a version bump. Code ships alongside documentation, websites, changelogs, and download pages. This skill ensures nothing is forgotten by:

1. Running the project's own release skills (if they exist)
2. Scanning for satellite content that may need updating
3. Confirming with the user before proceeding at each gate

## Prerequisites

- All tests pass (run `/session-post-implementation` or the test suite first)
- Working tree is clean or changes are committed
- User knows the target version (or will provide it)
- If this release ships a feature with a design doc, a PASS verification artifact exists (run `/session-verify` first) and its recorded commit range covers the release candidate, or the user has recorded a reuse decision. Not required for bugfix/refactor releases.

## Workflow

### Step 1: Pre-flight checks

Verify readiness:

1. **Git status**: Check for uncommitted changes. Warn if dirty.
2. **Test status**: Ask the user to confirm tests pass (or offer to run them).
3. **Target version**: If not provided as argument, ask the user. Validate semver format.
4. **Verification status**: If this release ships a feature that had a design doc (check `.session-flow.json.paths.plans`, else a detected `plans/`), look for a corresponding `_verification/{date}-{label}-verification.md` artifact with `Verdict: PASS` (or `PASS-WITH-CAVEATS` if the user accepts the caveats). If the artifact is missing or `FAIL`, offer to run `/session-verify` first. Skip for bugfix/refactor releases with no design doc.
5. **Evidence applicability**: run the check below on the artifact found in check 4. Skip only when there is no artifact to reuse.

#### Evidence applicability check

A verdict is evidence about the revision it was recorded against, not about the release candidate.

0. Read the work item the release ships, when it has one, and re-resolve its authority before going
   further. Resolve the helper by the one rule for this host (`references/runtime-integration.md`)
   and confirm it answers with `doctor`; `$ENTRYPOINT` is the absolute path it resolves to:

   ```bash
   python3 -B "$ENTRYPOINT" --project-root "$PROJECT_ROOT" show --seq SEQ-042
   ```

   The item's `evidence` entries name the fingerprint they were gathered against. An entry whose
   fingerprint differs from the record's current `scope_fingerprint` does not apply, whatever the
   artifact says, and an item still `active` because its delivery target is unmet is not a shipped
   outcome. Report either as a gap and let the user decide, exactly as steps 1-5 do for the commit
   range. Referenced specs are identified by work-root commit; a filename alone dates nothing.

1. Read the artifact's `**Scope:**` line -- `/session-verify` writes it as `Commits {sha_first}..{sha_last} on branch {branch}`. That is the recorded commit range; take `{sha_last}` as the verified revision. If the line is absent or unparseable, or the recorded revision is not in this repository, the evidence has no applicability -- offer `/session-verify` against the candidate and do not proceed on the old verdict.
2. Resolve the candidate revision with `git rev-parse HEAD` on the branch being released.
3. Compare. The evidence covers the candidate only when the verified revision equals the candidate revision and the recorded branch is the branch being released. Otherwise report the gap using `git rev-list --count {sha_last}..HEAD` and `git diff --stat {sha_last}..HEAD`.
4. When they differ, stop and present: artifact path, verdict, verified revision, candidate revision, commit count between them, and the changed paths. Then ask for one explicit decision -- no default and no proceeding on silence:
   - **Rerun** -- invoke `/session-verify` against the candidate. Required when the diff touches source, tests, dependencies, build/packaging, or the design doc the artifact verified.
   - **Reuse** -- the user states why the diff cannot change the verified behaviour. Proportionate for documentation, comments, changelog, or satellite-content-only diffs; never inferred from a small diff or a passing test run.
5. Record the outcome. Add a `Verification evidence` block to the Step 8 commit body and repeat it in the Step 9 summary, naming the artifact path, verified revision, candidate revision, the decision (`reuse` or `rerun`), and the user's stated reason verbatim. A reuse decision that was not recorded did not happen.

### Step 2: Version bump

Look for a project-specific version bump mechanism:

**Detection order:**
1. Project skill: `/version-bump` (check `.claude/skills/version-bump/SKILL.md`)
2. Version sync script: `packaging/sync-versions.py`, `scripts/bump-version.*`
3. Standard tooling: `npm version`, `cargo set-version`, `bumpversion`, `tbump`
4. Manual: Search for version strings across config files

**If a project skill exists:** Invoke `/version-bump <version>` and follow its workflow.

**If no skill exists:** Identify all files containing the current version and update them. Common locations:
- `package.json` / `Cargo.toml` / `pyproject.toml` / `setup.cfg`
- `version.py` / `__init__.py` / `_version.py`
- `tauri.conf.json` / `Info.plist` / `build.gradle`

After bumping, verify consistency by grepping for the old version -- nothing should remain except changelogs and historical references.

### Step 3: User gate -- build

The build step often requires the user's environment (signing keys, native toolchains, CI pipelines). Present the build instructions and **wait for the user to confirm the build is complete** before proceeding.

**If a project skill exists** (`/release-package`): it will contain build instructions -- reference them.

**If no skill exists:** Check for common build commands:
- `npm run build` / `pnpm build`
- `cargo build --release`
- `python -m build` / `poetry build`
- CI/CD trigger instructions

Print the build command(s) and ask: "Run the build and let me know when it's done."

**Do NOT run builds automatically** -- they often need environment setup, signing keys, or manual oversight.

**Phase exit criterion:** user has explicitly confirmed build completion. Do not proceed to Step 4 on silence or assumed-done.

### Step 4: Package release artifacts

Look for a project-specific packaging mechanism:

**Detection order:**
1. Project skill: `/release-package` (check `.claude/skills/release-package/SKILL.md`)
2. Release scripts: `scripts/release.*`, `packaging/release.*`
3. Standard tooling: `gh release create`, `cargo publish`, `npm publish`

**If a project skill exists:** Invoke `/release-package` and follow its workflow.

**If no skill exists:** Identify artifacts and provide manual instructions.

### Step 5: Satellite content scan

This is the key differentiator. Scan the repository for content that often needs updating alongside a release but is easy to forget.

**Scan for these categories:**

#### 5a. Documentation sites

Search for documentation site directories:
```
Glob patterns: **/docusaurus.config.*, **/mkdocs.yml, **/docs/conf.py, **/.vitepress/config.*, **/astro.config.*, **/book.toml
Common dirs: docs-site/, _docs-site/, docs/, documentation/, website/docs/
```

**If found:** Check for version references, outdated screenshots, feature docs that should mention new capabilities.

#### 5b. Marketing / landing pages

Search for website directories:
```
Glob patterns: **/index.html (in website-like dirs), _website/, website/, landing/, www/
Package.json with vite/next/gatsby in non-app directories
```

**If found:** Check for version badges, download links, feature lists, changelog sections.

#### 5c. Changelogs and release notes

Search for:
```
CHANGELOG.md, CHANGES.md, HISTORY.md, RELEASES.md, NEWS.md
```

**If found:** Check if the new version has an entry. If not, draft one from recent git history.

#### 5d. README and badges

Check root `README.md` for:
- Version badges (shields.io, badgen, etc.)
- Installation instructions referencing specific versions
- Feature lists that may be outdated

#### 5e. Download / distribution files

Search for:
```
Glob patterns: **/downloads/*, **/dist/*, **/releases/*, latest.json, **/DownloadModal.*, **/download*.tsx
```

**If found:** Check if they reference the new version.

#### 5f. API documentation

Search for:
```
**/openapi.*, **/swagger.*, **/api-docs/
```

### Step 6: User gate -- satellite updates

Present findings as a checklist:

```markdown
## Release Surface Scan for v{VERSION}

### Needs attention:
- [ ] {item}: {what needs updating} ({file path})
- [ ] {item}: {what needs updating} ({file path})

### Looks current:
- [x] {item}: already up-to-date ({file path})

### Not found (skip):
- {category}: no {type} detected in this repo
```

**Ask the user:** "Which of these should we update now? (Enter numbers, 'all', or 'skip')"

Apply the updates the user approves. For each update:
- Make the minimal change needed (version string, link, date)
- Show the diff before applying if the change is non-trivial
- For changelog entries, draft from `git log` since the last tag

**Phase exit criterion:** every "Needs attention" item has either been updated (with user approval) or explicitly skipped by the user. No silent drops.

### Step 7: Final verification

Run a final check:

1. **Version grep**: Search for the OLD version across the repo. Flag any remaining references (excluding changelogs, git history, lock files).
2. **Build artifacts**: Verify expected release artifacts exist (if applicable).
3. **Satellite content**: Spot-check that updated files are consistent.

### Step 8: Release commit

If changes were made in steps 5-6, commit them:

```
release: prepare v{VERSION} for distribution
```

### Step 9: Release instructions

Print a summary of what's ready and what the user needs to do next:

```markdown
## Release v{VERSION} Ready

### Completed:
- Version bumped across {N} files
- {Artifacts packaged / listed}
- {Satellite content updated}

### Verification evidence:
- Artifact: {path} ({verdict})
- Verified revision: {sha_last} -- candidate revision: {candidate}
- Decision: {reuse | rerun} -- {user's stated reason}

### Next steps -- each its own authorized action:
1. {Push / tag / create GitHub release / publish -- project-specific}
2. {Deploy docs site -- if applicable}
3. {Deploy website -- if applicable}
4. {Announce -- if applicable}
```

These are printed, not performed. Publishing, tagging, deploying, and announcing carry their own
authority and their own rollback story; a completed release commit authorizes none of them.

## Execution Notes

- Steps 3 and 6 are **user gates** -- wait for confirmation, or for the standing policy below, before proceeding
- The reuse-or-rerun decision in Step 1 is a third user gate -- it is the user's call, recorded, not the agent's judgement
- A standing policy already covering this release -- the target version, the satellite targets, the build command -- satisfies the gate it covers: name the policy, say what it authorizes, and go on. Silence never satisfies a gate, and a policy covering the build does not cover the satellite updates
- Escalate the decisions that are actually unknown -- an action outside what the policy covers, a satellite surface nobody decided about, a verdict that no longer applies -- and bring the evidence with the question. Re-asking something already decided is not a safeguard
- Re-resolve the item's authority before each consequential effect, and stop at the boundary of what it covers: a revoked authority blocks the next action, while effects already completed stay recorded and rolling one back needs its own authority
- The satellite scan (Step 5) is intentionally broad -- it's better to flag something unnecessary than to miss something important
- Lock files (`package-lock.json`, `Cargo.lock`, `pnpm-lock.yaml`) should be regenerated by the build, not manually edited
- Exclude from old-version grep: `CHANGELOG.md`, `*.lock`, `node_modules/`, `.git/`, `target/`, `build/`, `dist/`

## Anti-Patterns

**Grepping too aggressively:**
- BAD: Flag every occurrence of "0.2.0" including in unrelated constants
- GOOD: Focus on config files, docs, and distribution -- skip test fixtures and historical references

**Treating a stored verdict as current:**
- BAD: Find `Verdict: PASS`, note the tests pass now, and release
- GOOD: Compare the artifact's recorded commit range with the candidate revision, and release on old evidence only through a recorded reuse decision

Chain context: see `references/workflow-overview.md`.

