merge-and-release · git:20261101.fe898b3 · 2026-11-01 · sha256 7231cd4637ffd0b5
merge-and-release git:20261101.fe898b3A
Immutable. This exact content never changes and is served at /api/v1/blob/7231cd4637ffd0b5.
--- name: merge-and-release description: "Reference document describing merge prerequisites (approval, CI checks, mergeable, conversations resolved, stale approval), release versioning (semantic semver), and changelog generation. Explains why Tier 3 confirmation is structural: merge and release cost is borne by downstream people. Reference only (`disable-model-invocation: true`); consumed by `/flow:merge` and `/flow:release`." allowed-tools: Read agent: Explore disable-model-invocation: true --- # Merge and Release Policy reference for `/flow:merge` and `/flow:release`; the runnable bash lives in `commands/merge.md` and `commands/release.md`, and the detail in `references/merge-and-release.md`. ## Contract Iron law: **merge is irreversible in practice — every prerequisite is verified with fresh evidence, never memory, and merge and release are Tier 3 (explicit human confirmation, even in autonomous mode).** Consumed by `/flow:merge` Phase 1 (five-check gate plus finding-ledger check), Phase 2 (Merge Assessment), Phase 3 (confirm and execute), Phase 4 (post-merge), and by `/flow:release` Phases 2–5 (version and version files, changelog, assessment and publish, post-release). Returns the checks, stop conditions, settings, and execution sequence those commands apply. Permitted skips: none — a failed prerequisite stops the command without asking "merge anyway?"; an override happens only by the human acting outside the command. ## Five-Check Gate (`/flow:merge` Phase 1) | # | Check | Requirement | |---|-------|-------------| | 1 | Approval | At least one approval, no outstanding requested changes | | 2 | CI checks | `statusCheckRollup` all success | | 3 | Mergeable | `mergeable == "MERGEABLE"` | | 4 | Conversations | Unresolved review threads == 0 (GraphQL `reviewThreads`; the REST field is incomplete) | | 5 | Stale approval | No commits after the last approval timestamp | Plus the `pr-lifecycle` finding-ledger check: non-empty `ESCALATED` or unmatched `FINDINGS` blocks. **Stale approval** (compared as in `references/merge-and-release.md`): commits after approval: warn "Approval may be stale", request re-review, do not merge — the approver has not seen what would be merged. ## Stop Conditions Any prerequisite fails, stale approval, unresolved conversations > 0, unfinished checks, or ledger gate fails: stop. No "override the gate" option exists in autonomous mode. Never `--auto`: it waits only for *required* checks (`commands/merge.md`). ## Merge Execution (Phases 2–4) Display the Merge Assessment table as text, confirm via `AskUserQuestion`, and merge only after the user confirms. The `tier-gate.sh` hook asks again when `gh pr merge` runs (`tiers.merge` is always `confirm`). A merge cancelled at the question or declined at the prompt stops the command. - `merge.strategy`: `squash` | `merge` | `rebase` (default `squash`) - `merge.deleteBranch`: default `true`; named in the merge question - `merge.markerTrust.allowedAssociations`: whose ledger markers are honored; read through the settings cascade, user and plugin tiers only from an install outside the repository (`references/finding-ledger-parser.md`) Post-merge: `gh pr view $PR_NUM --json state` must return `MERGED`; then suggest switching to the default branch and pulling. ## Release (`/flow:release`) **Two runs.** A release reaches the default branch only through a release pull request: the first run bumps the version files and the changelog on a release branch and opens that pull request; the second, after it is merged, tags the merge commit and publishes the GitHub release. **Version** (Phase 2): tag = `release.tagPrefix` (default `v`) + version, bumped by semver (`patch`, `minor`, `major`). In a plugin marketplace the version is the marketplace's `metadata.version`, bumped by minor for a minor or major plugin release and by patch for a patch unless a type is named. `bin/flow-release-versions.sh --plan` lists the version files to bump and the files it skips; files that disagree on the current version stop the release. No version file and no prior tag: first release is `v1.0.0`. **Changelog** (Phase 3) and **Execute** (Phase 4): show the Release Preview as text. The first run commits only the bumped files and the changelog and pushes nothing to the default branch. The second confirms via `AskUserQuestion` before it tags or publishes; the tier hook asks again when the command runs. **Post-release** (Phase 5, second run): `gh release view "$TAG"` must succeed; the summary lists every version file bumped and every file skipped.