| name | release |
| description | Create changelogs and release notes — releasing, documenting, shipping. Use after validate. Detects version, categorizes commits, generates changelog, commits, merges or creates PR. |
/release
Detect version, categorize commits, generate changelog, commit, merge or PR, tag.
No release without passing validation.
Guiding Principles
- Bump type auto-detected, not user-prompted — commit message conventions determine major/minor/patch automatically
- Warn-and-continue for non-blocking failures — report problems, attempt fixes, only hard-stop on critical validation failures
Phase 1: Execute
1. Stage Uncommitted Changes
Stage all uncommitted changes from implement/validate phases so they're included in the squash merge.
git add -A
Report: "All changes staged. Ready for release."
2. Determine Version Bump Type
last_tag=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
git log ${last_tag}..HEAD --oneline
Detect version bump type from commit messages:
- Any
BREAKING CHANGE or !: suffix → major bump
- Any
feat: or feat( prefix → minor bump
- Otherwise → patch bump
Important: Do NOT read plugin.json for the current version — the worktree's copy is stale. The actual version bump happens post-merge on main in the checkpoint phase.
Use the auto-detected bump type without asking.
3. Categorize Commits
last_tag=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
git log ${last_tag}..HEAD --oneline
Group commits by type:
- Breaking Changes —
BREAKING CHANGE, !: suffix
- Features —
feat: or feat(
- Fixes —
fix: or fix(
- Docs —
docs: or docs(
- Chores —
chore:, refactor:, ci:, build:
4. Generate Release Notes
Save to .beastmode/artifacts/release/YYYY-MM-DD-<epic-name>.md using the Release Notes Template (see Reference section).
Omit empty sections (e.g., no Breaking Changes → skip that heading).
Use **Bump:** major|minor|patch instead of a concrete version — the actual version is computed post-merge from main's current state.
Phase 2: Validate
1. Verify Release Notes
Check that release notes file exists in .beastmode/artifacts/release/ with correct feature name and bump type.
2. Verify Commit Categorization
Check that release notes contain categorized commits (Features, Fixes, etc.) with no empty sections.
3. Validation Gate
If any check fails:
- Report specific problems
- Do NOT proceed to checkpoint
If all clean:
- Report: "Release verified. Proceeding to checkpoint."
Phase 3: Checkpoint
1. Release Retro
Run a context reconciliation pass across all phase artifacts before releasing.
-
Gather Phase Artifacts — Enumerate all artifact directories for the current feature slug:
.beastmode/artifacts/design/
.beastmode/artifacts/plan/
.beastmode/artifacts/implement/
.beastmode/artifacts/validate/ (if exists)
.beastmode/artifacts/release/
For each directory, collect all files matching the current feature slug. Build a flat list of all artifact paths.
Additionally, include any hitl-log.md files found in the phase artifact directories. These contain HITL decision logs from the pipeline run and do not follow the slug-naming convention.
If no artifacts found, print "Retro: no artifacts found. Skipping." and proceed to Step 2.
-
Spawn Context Walker — Spawn a general-purpose agent as the context walker. It receives the phase artifacts and L1 context path, analyzes for promotable learnings, and proposes hierarchy updates.
Build the session context block providing ALL phase artifacts:
## Session Context
- **Phase**: release
- **Feature**: <feature name>
- **Artifacts**: <list of ALL phase artifact paths for this feature>
- **L1 context path**: `.beastmode/context/` (all phase directories)
- **Working directory**: <current working directory>
Spawn: Agent(subagent_type="general-purpose", prompt=<agent prompt + session context>)
Wait for completion.
If context walker returned "No changes needed", print "Retro: no changes needed." and proceed to Step 2.
-
Apply Changes (Bottom-Up) — Apply all proposed changes from the context walker automatically in hierarchy order:
- L3 — Records: Create/append approved records automatically
- L2 — Context docs: Apply L2 edits/creates automatically
- L1 — Phase summaries: Recompute L1 summaries automatically
- L0 — BEASTMODE.md: Apply via sub-step 4 below
-
Apply BEASTMODE.md Updates — If no L0 changes proposed, skip this step. Apply L0 changes and log.
TRANSITION BOUNDARY — Steps below operate from main repo, NOT the feature branch working directory.
2. Commit to Feature Branch
Before merging to main, commit all release artifacts to the feature branch:
git add -A
git commit -m "release(<epic-name>): checkpoint"
3. Squash Merge to Main
feature_dir=$(pwd)
feature_branch=$(git branch --show-current)
main_repo=$(git rev-parse --show-toplevel)/..
cd "$main_repo"
git checkout main
git pull
git tag "archive/$feature_branch"
cd "$feature_dir"
git rebase main
If the rebase encounters conflicts, resolve them interactively per commit:
- Examine each conflicted file
- Resolve the conflict (edit the file to produce the correct merged content)
git add <resolved-file>
git rebase --continue
- Repeat until rebase completes
After rebase completes:
cd "$main_repo"
git merge --squash "$feature_branch"
Important: The squash merge stages changes but does NOT commit. Proceed to step 4.
If the squash merge produces conflicts after rebase, resolve as follows:
- CHANGELOG.md: resolve with
--ours (main has the complete history; new entry is added in step 5)
- Version files (plugin.json, marketplace.json): resolve with
--ours (main has the correct current version; bump happens in step 6)
- All other files: any remaining conflicts after rebase indicate genuine divergence — fail loudly and report for manual review. Do NOT auto-resolve with
--theirs.
4. Compute Version
Read the current version from main (not from the worktree):
current_version=$(grep -o '"version": "[^"]*"' plugin/plugin.json | head -1 | cut -d'"' -f4)
echo "Current version on main: $current_version"
Read the bump type from the release notes YAML frontmatter (written during execute):
---
phase: release
epic-id: <epic-id>
epic-slug: <epic-name>
bump: minor
---
Apply:
- major: increment major, reset minor and patch to 0
- minor: increment minor, reset patch to 0
- patch: increment patch
5. Update CHANGELOG.md
Prepend the new release section to CHANGELOG.md on main using the computed version. Use the categorized changes from the release notes generated in execute step 4.
6. Bump Version Files
Update version in all files on main:
plugin/plugin.json → "version": "X.Y.Z"
.claude-plugin/marketplace.json → version in plugins array
7. Update Release Artifacts
Update the release notes on main to include the actual computed version:
.beastmode/artifacts/release/YYYY-MM-DD-<epic-name>.md → replace **Bump:** type with **Version:** vX.Y.Z
8. Commit Release
Create the single commit with GitHub release style message using the Commit Message Template (see Reference section).
Use the release notes generated in execute step 4 and categorized commits from execute step 3 as the commit body. Omit empty sections (no Fixes if none exist).
9. Git Tagging
git tag -a vX.Y.Z -m "Release X.Y.Z"
Suggest: git push origin main && git push origin vX.Y.Z
10. Plugin Marketplace Update
Suggest running:
claude plugin marketplace update
claude plugin update beastmode@beastmode-marketplace --scope user
11. Complete
"Release complete."
Constraints
- Do NOT proceed to checkpoint if validation fails
Reference
Release Notes Template
# Release: <epic-name>
**Bump:** minor
**Date:** YYYY-MM-DD
## Highlights
[1-2 sentence summary of key changes]
## Breaking Changes
- [Change description]
## Features
- [Feature description]
## Fixes
- [Fix description]
## Full Changelog
[Link to commit comparison or list all commits]
Commit Message Template
git add -A
git commit -m "Release vX.Y.Z — <Title from CHANGELOG>
## Features
- <feature 1>
- <feature 2>
## Fixes
- <fix 1>
## Artifacts
- Design: .beastmode/artifacts/design/YYYY-MM-DD-<epic-name>.md
- Plan: .beastmode/artifacts/plan/YYYY-MM-DD-<epic-name>.md
- Release: .beastmode/artifacts/release/YYYY-MM-DD-<epic-name>.md
"