Release Skill
Handles the complete release workflow: version bump, CHANGELOG, merge, tag, and GitHub release.
Triggering
Use this skill when the request requires release-specific git/version actions.
Use this skill when prompts include:
- release, cut a release, ship, publish, or tag a version
- bump version (
major/minor/patch) and update changelog for release - merge a release PR to
main
Do not use this skill for:
- regular feature PR creation to
dev(usecommit-pr) - implementation-only or planning-only requests
- explanation-only prompts with no release action request
- explain release strategy options
Acceptance Tests
| Test ID | Type | Prompt / Condition | Expected Result |
|---|---|---|---|
| RLS-T1 | Positive trigger | "Cut a patch release and tag it" | skill triggers |
| RLS-T2 | Positive trigger | "Merge this release PR to main and publish notes" | skill triggers |
| RLS-T3 | Negative trigger | "Create a PR to dev for this feature" | skill does not trigger |
| RLS-T4 | Negative trigger | "Explain release strategy options" | skill does not trigger |
| RLS-T5 | Behavior | skill triggered for release flow | enforces release gates, worktree/branch policy, and explicit approval for non-draft publish |
| RLS-T6 | Behavior | missing autonomy.system_level in user ica.config.json |
asks user, persists autonomy.system_level, then proceeds |
| RLS-T7 | Behavior | missing autonomy.project_level in project ica.config.json |
asks user, persists autonomy.project_level, then proceeds |
| RLS-T8 | Behavior | project autonomy is follow-system |
resolves effective autonomy and applies it to release confirmation behavior |
| RLS-T9 | Behavior | release PR missing ICA-REVIEW-RECEIPT |
runs post-PR review loop, refreshes receipt for current head SHA, then re-checks gates |
| RLS-T10 | Behavior | release PR missing ICA-SECURITY-REVIEW-RECEIPT |
runs post-PR security loop, refreshes receipt for current head SHA, then re-checks gates |
| RLS-T11 | Behavior | release PR has no required checks configured | treats checks gate as pass-with-note (no required checks configured) |
| RLS-T12 | Behavior | release flow reaches merge gate | requires current review+security receipts and checks result before merge |
| RLS-T13 | Behavior | security receipt missing dedicated-subagent verification fields | fails release merge gate and requires refreshed verified security receipt |
Autonomy Level Resolution (MANDATORY)
Resolve autonomy settings from ica.config.json hierarchy (not tracking config):
- user config:
${ICA_HOME}/ica.config.json$HOME/.codex/ica.config.json$HOME/.claude/ica.config.json
- project config:
./ica.config.json
Required keys:
autonomy.system_level:L1|L2|L3(defaultL2)autonomy.project_level:follow-system|L1|L2|L3(defaultfollow-system)
Bootstrap prompts (if missing):
- If
autonomy.system_levelmissing:- ask: "No system autonomy level is configured. Set system autonomy level to
L2(recommended),L1, orL3?" - persist in user
ica.config.json
- ask: "No system autonomy level is configured. Set system autonomy level to
- If
autonomy.project_levelmissing:- ask: "No project autonomy level is configured. Set project autonomy level to
follow-system(recommended),L1,L2, orL3?" - persist in project
ica.config.json
- ask: "No project autonomy level is configured. Set project autonomy level to
Compatibility:
- If legacy
autonomy.levelexists andautonomy.system_levelis missing, treat legacy value as system level for this run and persist it asautonomy.system_level.
Effective level:
- if
project_levelisL1/L2/L3, use project level - if
project_levelisfollow-system, use system level
Effective-level behavior for release:
L1: require explicit confirmation for each release transition (version bump commit, PR merge, tag, publish)L2: standard release flow; explicit confirmation remains mandatory for larger-change release actionsL3: automate mechanical release actions when gates pass and release automation is enabled, while still requiring explicit approval for non-draft publish
Auto-Merge vs Agent Merge
This skill does NOT require GitHub "auto-merge" (gh pr merge --auto).
When automation is enabled, the agent performs the merge itself (runs gh pr merge) once the merge gates pass.
When to Use
- User asks to "release", "cut a release", "ship it"
- User asks to "bump version" (major/minor/patch)
- User asks to "merge to main" after PR approval
- User asks to "tag a version" or "create a release"
Prerequisites
Before releasing:
- All changes committed and pushed
- PR created and reviewed (ICA Stage 3 receipt is the required review gate by default)
- Security review receipt exists and is current for release PR head SHA
- Tests passing
- No blocking review findings
validatechecks pass for release scope- Backend-aware tracking verification passes
- Worktree/branch policy resolved from ICA config (
git.worktree_branch_behavior) - Effective autonomy level resolved from ICA config (
autonomy.system_level+autonomy.project_level) - Explicit user confirmation for larger changes (release is always a larger change)
Worktree + Branch Policy (ICA Config)
Read git.worktree_branch_behavior from ica.config.json hierarchy.
Allowed values:
always_newaskcurrent_branch
If missing:
- ask user which behavior to use
- persist in project/user
ica.config.json
Release enforcement:
- if
always_new, use a dedicated release worktree + branch before release actions - if
ask, ask before release actions and follow response - even with
current_branch, release remains a larger-change flow and requires explicit confirmation
Validation And Check Gates (MANDATORY)
Pre-release gate:
- release request explicitly confirmed by user
- tests + reviewer + security review + validate all pass
- backend-aware tracking verification passes
- release PR target is
main - branch/worktree policy is satisfied for release scope
- autonomy level resolved and applied for release scope
- required checks are green (or no required checks are configured)
Pre-tag gate:
- release PR merged successfully
- local
mainis up to date and clean - validate checks pass for release artifacts (version/changelog)
- autonomy level resolved and applied for release scope
Pre-publish gate:
- tag exists remotely
- release notes prepared and reviewed
- explicit user approval for non-draft publish (draft creation is safe-default)
- autonomy level resolved and applied for release scope
Fail-closed behavior:
- if any gate fails, STOP release progression and surface exact blocker.
Automation Controls (Skills-Level)
These controls are driven by workflow configuration (AgentTask workflow.* and ica.workflow.json):
workflow.auto_merge=true: standing approval to merge PRs once gates passworkflow.release_automation=true: automate the mechanical release steps (tag + GitHub release creation)
Safety defaults:
- Never auto-merge to
mainunless the user explicitly requested a release workflow. - Never publish a non-draft GitHub release without explicit user approval (draft releases are OK).
Autonomy-level enforcement:
L1: pause for explicit user confirmation at each release transition.L2: continue routine release steps after gates pass; keep explicit confirmations for larger-change actions.L3: may proceed through gated release steps automatically when workflow settings allow, but must still respect explicit-approval rules above.
Pre-Release Receipt And Checks Loop (MANDATORY)
Before merge, release flow must verify receipts/checks for the current release PR head SHA.
If any receipt/check gate fails:
- Run post-PR reviewer Stage 3 loop on the release PR branch.
- Run post-PR security review loop on the release PR branch in a dedicated security subagent context.
- Preferred:
security-best-practices - Escalation option:
security-engineerfor high-risk/complex findings
- Preferred:
- Push fixes when needed.
- Re-run receipt and checks verification.
Required receipt outcomes for current head SHA:
ICA-REVIEW-RECEIPT:Findings: 0,Result: PASSICA-SECURITY-REVIEW-RECEIPT:Findings: 0,Result: PASS, and:Security-Reviewer-Stage: post-pr (temp checkout)Security-Reviewer-Agent: ... (subagent)Security-Reviewer-Execution: dedicated-security-subagentSecurity-Reviewer-Executor: github:<login>Security-Reviewer-Run-ID: <non-empty run id>- comment author login must match
Security-Reviewer-Executor
Checks behavior:
- If required checks exist: all required checks must pass.
- If no required checks exist: record
no required checks configuredand treat checks gate as pass-with-note.
Release Workflow
Step 1: Verify Ready to Release
# Check PR status
gh pr status
# Verify PR is approved
gh pr view <PR-number> --json reviews
# Verify checks pass
CHECKS_OUTPUT=$(gh pr checks <PR-number> 2>&1 || true)
if echo "$CHECKS_OUTPUT" | rg -q "no checks reported"; then
echo "No required checks configured; checks gate = pass-with-note."
else
echo "$CHECKS_OUTPUT"
fi
# Verify this is a release PR (base should be main)
gh pr view <PR-number> --json baseRefName --jq .baseRefName
# Verify reviewer Stage 3 receipt exists (ICA-REVIEW-RECEIPT) and matches current head SHA
PR=<PR-number>
HEAD_SHA=$(gh pr view "$PR" --json headRefOid --jq .headRefOid)
RECEIPT=$(gh pr view "$PR" --json comments --jq '.comments | map(select(.body | contains("ICA-REVIEW-RECEIPT"))) | last | .body // ""')
echo "$RECEIPT" | rg -q "Reviewer-Stage: 3 \\(temp checkout\\)"
echo "$RECEIPT" | rg -q "Head-SHA: $HEAD_SHA"
echo "$RECEIPT" | rg -q "Result: PASS"
# Verify security review receipt exists (ICA-SECURITY-REVIEW-RECEIPT) and matches current head SHA
SEC_RECEIPT=$(gh pr view "$PR" --json comments --jq '.comments | map(select(.body | contains("ICA-SECURITY-REVIEW-RECEIPT"))) | last | .body // ""')
echo "$SEC_RECEIPT" | rg -q "Security-Reviewer-Stage: post-pr \\(temp checkout\\)"
echo "$SEC_RECEIPT" | rg -q "Security-Reviewer-Agent:.*\\(subagent\\)"
echo "$SEC_RECEIPT" | rg -q "Security-Reviewer-Execution: dedicated-security-subagent"
echo "$SEC_RECEIPT" | rg -q "^Security-Reviewer-Run-ID: [A-Za-z0-9._:-][A-Za-z0-9._:-]*$"
echo "$SEC_RECEIPT" | rg -q "Head-SHA: $HEAD_SHA"
echo "$SEC_RECEIPT" | rg -q "Result: PASS"
SEC_EXECUTOR=$(echo "$SEC_RECEIPT" | sed -n 's/^Security-Reviewer-Executor: github:\\(.*\\)$/\\1/p' | head -n1)
SEC_AUTHOR=$(gh pr view "$PR" --json comments --jq '.comments | map(select(.body | contains("ICA-SECURITY-REVIEW-RECEIPT"))) | last | .author.login // ""')
test -n "$SEC_EXECUTOR"
[ "$SEC_AUTHOR" = "$SEC_EXECUTOR" ]
Security Receipt Template (Copy/Paste)
PR=<PR-number>
HEAD_SHA=$(gh pr view "$PR" --json headRefOid --jq .headRefOid)
BASE_BRANCH=$(gh pr view "$PR" --json baseRefName --jq .baseRefName)
DATE_UTC=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
SEC_REVIEWER=$(gh api user --jq .login)
SEC_RUN_ID="sec-$(date -u +%Y%m%dT%H%M%SZ)-${HEAD_SHA:0:12}"
gh pr comment "$PR" --body "$(cat <<EOF
ICA-SECURITY-REVIEW
ICA-SECURITY-REVIEW-RECEIPT
Security-Reviewer-Stage: post-pr (temp checkout)
Security-Reviewer-Agent: security reviewer (subagent)
Security-Reviewer-Execution: dedicated-security-subagent
Security-Reviewer-Executor: github:$SEC_REVIEWER
Security-Reviewer-Run-ID: $SEC_RUN_ID
PR: #$PR
Base: $BASE_BRANCH
Head-SHA: $HEAD_SHA
Date-UTC: $DATE_UTC
Findings: 0
NO FINDINGS
Result: PASS
EOF
)"
Step 2: Determine Version Bump
Ask user if not specified:
| Type | When | Example |
|---|---|---|
major |
Breaking changes | 1.0.0 → 2.0.0 |
minor |
New features, backward compatible | 1.0.0 → 1.1.0 |
patch |
Bug fixes, no new features | 1.0.0 → 1.0.1 |
Step 3: Update VERSION File
# Read current version
CURRENT=$(cat src/VERSION 2>/dev/null || cat VERSION 2>/dev/null || echo "0.0.0")
# Calculate new version based on bump type
# For patch: increment last number
# For minor: increment middle, reset last to 0
# For major: increment first, reset others to 0
Step 4: Update CHANGELOG
Add new section at top of CHANGELOG.md:
## [X.Y.Z] - YYYY-MM-DD
### Added
- New features
### Changed
- Changes to existing features
### Fixed
- Bug fixes
### Removed
- Removed features
Derive changes from:
git log --oneline $(git describe --tags --abbrev=0 2>/dev/null || echo "HEAD~10")..HEAD
Step 5: Commit Version Bump
# Re-run quality/validation gate before release commit
# - tests pass
# - reviewer has no blocking findings
# - security review has no blocking findings
# - validate checks pass
# - tracking verification passes
git add VERSION src/VERSION CHANGELOG.md
git commit -m "chore: Bump version to X.Y.Z"
git push
Step 6: Merge PR
# Merge gate (required):
# - Reviewer Stage 3 receipt exists and matches head SHA (ICA-REVIEW-RECEIPT)
# - Security review receipt exists and matches head SHA (ICA-SECURITY-REVIEW-RECEIPT)
# - Security receipt includes dedicated-subagent verification fields and executor/author match
# - Required checks passing (or no required checks configured)
# - Validate checks pass
# - Backend-aware tracking verification passes
# - User explicitly approved the release/merge
#
# Only then merge the PR (squash or merge based on project preference)
gh pr merge <PR-number> --squash --delete-branch
Or if merge commit preferred:
gh pr merge <PR-number> --merge --delete-branch
Step 7: Create Git Tag
# Checkout main after merge
git checkout main
git pull origin main
# Create annotated tag
git tag -a "vX.Y.Z" -m "Release vX.Y.Z"
git push origin "vX.Y.Z"
Step 8: Create GitHub Release (if using GitHub)
# Default: create DRAFT release (safe). Publish only if user explicitly requests.
gh release create "vX.Y.Z" \
--draft \
--title "vX.Y.Z" \
--notes "$(cat <<'EOF'
## What's Changed
### Added
- Feature 1
- Feature 2
### Fixed
- Bug fix 1
**Full Changelog**: https://github.com/OWNER/REPO/compare/vPREV...vX.Y.Z
EOF
)"
Or generate notes automatically:
gh release create "vX.Y.Z" --generate-notes
Version File Locations
Check for VERSION in order:
src/VERSIONVERSIONpackage.json(for Node projects)pyproject.toml(for Python projects)
CHANGELOG Format
Follow Keep a Changelog format:
# Changelog
All notable changes to this project will be documented in this file.
## [Unreleased]
## [X.Y.Z] - YYYY-MM-DD
### Added
### Changed
### Deprecated
### Removed
### Fixed
### Security
Safety Checks
Before any release action:
- Confirm user approval for merge
- Verify on correct branch
- Check no uncommitted changes
- Verify review and security receipts are current for PR head SHA
- Verify security receipt has dedicated-subagent verification fields and executor/author match
- Verify required checks pass (or note
no required checks configured) - Run
validatechecks for current release step - Run backend-aware tracking verification
Integration
Works with:
- commit-pr skill - For version bump commit
- git-privacy skill - No AI attribution in release notes
- branch-protection skill - Respect branch rules
- reviewer skill - Verify no blocking findings
Examples
Patch Release
User: "Release a patch for the bug fixes"
→ Bump 1.2.3 → 1.2.4
→ Update CHANGELOG
→ Commit, merge, tag, release
Minor Release
User: "Cut a minor release with the new features"
→ Bump 1.2.3 → 1.3.0
→ Update CHANGELOG
→ Commit, merge, tag, release
Major Release
User: "Major release - we have breaking changes"
→ Bump 1.2.3 → 2.0.0
→ Update CHANGELOG (note breaking changes)
→ Commit, merge, tag, release
Rollback
If release needs to be reverted:
# Delete the tag locally and remotely
git tag -d vX.Y.Z
git push origin :refs/tags/vX.Y.Z
# Delete the GitHub release
gh release delete vX.Y.Z --yes
# Revert the merge commit if needed
git revert <merge-commit-sha>
Validation Checklist
- Acceptance tests cover trigger behavior and release-gate behavior (including receipts/checks cases)
- Effective autonomy level is resolved before release transitions
- Pre-release gate includes reviewer + security + validate + tracking verification
- Receipt/checks loop auto-remediates missing/stale receipts before merge attempt
- Security receipt verification requires dedicated-subagent fields + executor/author match
- Required checks gate handles both configured-checks and no-required-checks repos
- Non-draft publish still requires explicit approval
Output Contract
When this skill runs, produce:
- release scope confirmation (repo, PR, branch target, bump type)
- autonomy resolution (
system_level,project_level, effective level, and whether defaults were bootstrapped) - resolved branch/worktree policy (
git.worktree_branch_behavior) and enforcement result - gate summary (tests, reviewer receipt, security receipt, validate, tracking verification, checks status)
- pre-release loop status (auto-remediation attempts, receipt refresh result, checks-gate result)
- security executor verification result (subagent marker, run-id, executor/author match)
- version/changelog update summary
- merge/tag/release results (PR merge status, tag, release URL/draft status)
- explicit blocker details when any gate fails