Cut Release (Gait)
Execute this workflow for: "cut release", "ship vX.Y.Z", "push tag and monitor release."
Scope
- Repository:
/Users/tr/gait
- Tag source branch:
main only
- No pre-release branch creation
- No pre-release PR creation
- Branch/PR flow is used only for hotfixes after failed checks
- No changelog editing in this skill
Input Contract
- Mandatory input argument:
release_version
- Normalize to
vX.Y.Z
- If missing, resolve silently from first semantic version token in user request; otherwise use latest tag + patch increment.
Constants
MAX_HOTFIX_LOOPS=2
CI_TIMEOUT_MIN=25
RELEASE_TIMEOUT_MIN=40
POLL_SECONDS=10
Safety Rules
- Tag must always be created and pushed from
main
main must be fast-forward synced with origin/main before each tag push
- No force-push to tags
- No destructive git commands
- No commit amend unless explicitly requested
- No changelog modifications
- PR bodies/comments must use EOF heredoc (
--body-file - <<'EOF' ... EOF)
- Do not stop at an external async gate merely because CI, review, merge, or post-merge monitoring is still in progress
- Continue waiting, polling, merging, retagging, rerunning UAT, and re-monitoring until a success condition or an explicit hard stop condition is reached
Workflow
Phase 0: Main Sync and Pre-Tag Validation
git fetch origin main
git checkout main
git pull --ff-only origin main
- Ensure clean worktree (
git status --porcelain must be empty)
- Ensure target tag does not already exist locally/remotely
- Run local release preflight (mirror release workflow gate coverage):
make prepush-full
make test-v2-3-acceptance
make test-v2-4-acceptance
make test-packspec-tck
make test-e2e
go test ./internal/integration -count=1
make test-chaos
make test-runtime-slo
make bench-check
make test-v2-5-acceptance
make test-context-conformance
make test-context-chaos
make test-release-smoke
If any step fails, stop and report blocker.
Do not stop merely because a release run is still pending; continue polling until completion or timeout.
Phase 1: Tag and Release Monitor
- Create annotated tag on
main:
git tag -a <version> -m "<version>"
- Push tag:
git push origin <version>
- Monitor GitHub workflow
release for that tag until green (RELEASE_TIMEOUT_MIN)
- If release run fails:
- classify failure as actionable, transient/infra, or non-actionable
- transient/infra: rerun workflow once, re-monitor
- actionable: go to hotfix loop
- non-actionable: stop with blocker report
- If release is still running, keep polling until it reaches a terminal state or the timeout is hit.
Phase 2: Post-Release UAT
- Run full local UAT against released tag:
GAIT_UAT_RELEASE_VERSION=<version> bash scripts/test_uat_local.sh
- If UAT is green, release is complete.
- If UAT fails:
- classify actionable vs non-actionable
- actionable: go to hotfix loop
- non-actionable: stop with blocker report
- If UAT-related async validation is still in progress, continue waiting; async wait alone is not a blocker.
Phase 3: Hotfix Loop (Only if Needed, Max 2)
For loop r1..r2:
- Sync main:
git fetch origin main
git checkout main
git pull --ff-only origin main
- Create hotfix branch:
git checkout -b codex/release-hotfix-<base-version>-r<rN>
Implement minimal fix for the identified failure.
Validate locally:
make prepush-full
- rerun the failing lane locally (release lane or UAT subset as applicable)
- Commit and push all unstaged files:
git add -A
git commit -m "hotfix: release stabilization for <base-version> (r<rN>)"
git push -u origin <hotfix-branch>
- Open PR using EOF body:
gh pr create --title "hotfix: release stabilization <base-version> (r<rN>)" --body-file - <<'EOF'
- include: problem, root cause, fix, validation
EOF
Monitor PR CI (ci and codeql) to green (CI_TIMEOUT_MIN).
If PR CI is red and actionable, fix the full known actionable set on the same hotfix branch, rerun local validation, push again, and continue monitoring.
After PR CI is green, wait for required passive review/release gates as applicable; do not stop merely because those checks are still pending inside their timeout windows.
Merge PR after green and satisfied review gates.
Sync and monitor post-merge main CI:
git checkout main
git pull --ff-only origin main
- monitor
ci and codeql on main (CI_TIMEOUT_MIN)
- if post-merge main CI is red and actionable, continue same loop (counts against max)
- if post-merge main CI is still running, continue polling until terminal or timeout; async wait alone is not a blocker
- Bump patch version:
- Create/push new tag from
main and monitor release workflow again:
- tag from
main only
- monitor until green (
RELEASE_TIMEOUT_MIN)
- Rerun full UAT for the new tag:
GAIT_UAT_RELEASE_VERSION=<new-version> bash scripts/test_uat_local.sh
- Exit conditions:
- if release + UAT green: success
- if loop count exceeds 2: stop with blocker report
- if non-actionable failure appears: stop with blocker report
Global Wait Rule
- Pending GitHub Actions runs, pending passive review signals, pending merge propagation, and pending post-merge
main checks are not blockers by themselves.
- While within the configured timeout windows, keep polling and continue the workflow.
- Only stop for:
- explicit failure classified as non-actionable or unsafe
- timeout expiry for the current wait window
- exhausted hotfix loop budget
- unexpected repo state that cannot be reconciled safely
Command Contract (JSON Required)
Capture release diagnostics using gait commands with --json, for example:
gait doctor --json
gait pack verify gait-out/pack_<id>.zip --json
EOF Rule (Mandatory)
All PR body/comment text must be provided with heredoc EOF.
No inline multi-line --body strings.
Expected Output
- Initial requested version and final shipped version
- All tags pushed (with confirmation each was cut from
main)
- Release workflow run URL/status per tag
- UAT result per released tag
- Hotfix branch/PR URLs and commit SHAs (if any)
- Loop count used
- Final status: success or blocker with last failing gate
- If blocked, distinguish
hard blocker from async gate still in progress; never report a mere in-progress async wait as the final blocker
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: cut-release-23description: Cut a new Gait release tag directly from main, monitor release/post-release validation, and run up to 2 hotfix PR loops when failures are actionable. Use when this capability is needed.4---56# Cut Release (Gait)78Execute this workflow for: "cut release", "ship vX.Y.Z", "push tag and monitor release."910## Scope1112- Repository: `/Users/tr/gait`13- Tag source branch: `main` only14- No pre-release branch creation15- No pre-release PR creation16- Branch/PR flow is used only for hotfixes after failed checks17- No changelog editing in this skill1819## Input Contract2021- Mandatory input argument: `release_version`22- Normalize to `vX.Y.Z`23- If missing, resolve silently from first semantic version token in user request; otherwise use latest tag + patch increment.2425## Constants2627- `MAX_HOTFIX_LOOPS=2`28- `CI_TIMEOUT_MIN=25`29- `RELEASE_TIMEOUT_MIN=40`30- `POLL_SECONDS=10`3132## Safety Rules3334- Tag must always be created and pushed from `main`35- `main` must be fast-forward synced with `origin/main` before each tag push36- No force-push to tags37- No destructive git commands38- No commit amend unless explicitly requested39- No changelog modifications40- PR bodies/comments must use EOF heredoc (`--body-file - <<'EOF' ... EOF`)41- Do not stop at an external async gate merely because CI, review, merge, or post-merge monitoring is still in progress42- Continue waiting, polling, merging, retagging, rerunning UAT, and re-monitoring until a success condition or an explicit hard stop condition is reached4344## Workflow4546### Phase 0: Main Sync and Pre-Tag Validation47481. `git fetch origin main`492. `git checkout main`503. `git pull --ff-only origin main`514. Ensure clean worktree (`git status --porcelain` must be empty)525. Ensure target tag does not already exist locally/remotely536. Run local release preflight (mirror release workflow gate coverage):54- `make prepush-full`55- `make test-v2-3-acceptance`56- `make test-v2-4-acceptance`57- `make test-packspec-tck`58- `make test-e2e`59- `go test ./internal/integration -count=1`60- `make test-chaos`61- `make test-runtime-slo`62- `make bench-check`63- `make test-v2-5-acceptance`64- `make test-context-conformance`65- `make test-context-chaos`66- `make test-release-smoke`6768If any step fails, stop and report blocker.69Do not stop merely because a release run is still pending; continue polling until completion or timeout.7071### Phase 1: Tag and Release Monitor72731. Create annotated tag on `main`:74- `git tag -a <version> -m "<version>"`752. Push tag:76- `git push origin <version>`773. Monitor GitHub workflow `release` for that tag until green (`RELEASE_TIMEOUT_MIN`)784. If release run fails:79- classify failure as actionable, transient/infra, or non-actionable80- transient/infra: rerun workflow once, re-monitor81- actionable: go to hotfix loop82- non-actionable: stop with blocker report835. If release is still running, keep polling until it reaches a terminal state or the timeout is hit.8485### Phase 2: Post-Release UAT86871. Run full local UAT against released tag:88- `GAIT_UAT_RELEASE_VERSION=<version> bash scripts/test_uat_local.sh`892. If UAT is green, release is complete.903. If UAT fails:91- classify actionable vs non-actionable92- actionable: go to hotfix loop93- non-actionable: stop with blocker report944. If UAT-related async validation is still in progress, continue waiting; async wait alone is not a blocker.9596### Phase 3: Hotfix Loop (Only if Needed, Max 2)9798For loop `r1..r2`:991001. Sync main:101- `git fetch origin main`102- `git checkout main`103- `git pull --ff-only origin main`1041052. Create hotfix branch:106- `git checkout -b codex/release-hotfix-<base-version>-r<rN>`1071083. Implement minimal fix for the identified failure.1091104. Validate locally:111- `make prepush-full`112- rerun the failing lane locally (release lane or UAT subset as applicable)1131145. Commit and push all unstaged files:115- `git add -A`116- `git commit -m "hotfix: release stabilization for <base-version> (r<rN>)"`117- `git push -u origin <hotfix-branch>`1181196. Open PR using EOF body:120- `gh pr create --title "hotfix: release stabilization <base-version> (r<rN>)" --body-file - <<'EOF'`121- include: problem, root cause, fix, validation122- `EOF`1231247. Monitor PR CI (`ci` and `codeql`) to green (`CI_TIMEOUT_MIN`).1258. If PR CI is red and actionable, fix the full known actionable set on the same hotfix branch, rerun local validation, push again, and continue monitoring.1261279. After PR CI is green, wait for required passive review/release gates as applicable; do not stop merely because those checks are still pending inside their timeout windows.12812910. Merge PR after green and satisfied review gates.13013111. Sync and monitor post-merge main CI:132- `git checkout main`133- `git pull --ff-only origin main`134- monitor `ci` and `codeql` on `main` (`CI_TIMEOUT_MIN`)135- if post-merge main CI is red and actionable, continue same loop (counts against max)136- if post-merge main CI is still running, continue polling until terminal or timeout; async wait alone is not a blocker13713812. Bump patch version:139- `vX.Y.Z -> vX.Y.(Z+1)`14014113. Create/push new tag from `main` and monitor `release` workflow again:142- tag from `main` only143- monitor until green (`RELEASE_TIMEOUT_MIN`)14414514. Rerun full UAT for the new tag:146- `GAIT_UAT_RELEASE_VERSION=<new-version> bash scripts/test_uat_local.sh`14714815. Exit conditions:149- if release + UAT green: success150- if loop count exceeds 2: stop with blocker report151- if non-actionable failure appears: stop with blocker report152153### Global Wait Rule154155- Pending GitHub Actions runs, pending passive review signals, pending merge propagation, and pending post-merge `main` checks are not blockers by themselves.156- While within the configured timeout windows, keep polling and continue the workflow.157- Only stop for:158- explicit failure classified as non-actionable or unsafe159- timeout expiry for the current wait window160- exhausted hotfix loop budget161- unexpected repo state that cannot be reconciled safely162163## Command Contract (JSON Required)164165Capture release diagnostics using `gait` commands with `--json`, for example:166167- `gait doctor --json`168- `gait pack verify gait-out/pack_<id>.zip --json`169170## EOF Rule (Mandatory)171172All PR body/comment text must be provided with heredoc EOF. 173No inline multi-line `--body` strings.174175## Expected Output176177- Initial requested version and final shipped version178- All tags pushed (with confirmation each was cut from `main`)179- Release workflow run URL/status per tag180- UAT result per released tag181- Hotfix branch/PR URLs and commit SHAs (if any)182- Loop count used183- Final status: success or blocker with last failing gate184- If blocked, distinguish `hard blocker` from `async gate still in progress`; never report a mere in-progress async wait as the final blocker185186---187> Converted and distributed by [TomeVault](https://tomevault.io/claim/clyra-ai) — claim your Tome and manage your conversions.188<!-- tomevault:4.0:skill_md:2026-04-12 -->