diff --git a/.agents/skills/deploy/SKILL.md b/.agents/skills/deploy/SKILL.md index 6ea2c90..4c47792 100644 --- a/.agents/skills/deploy/SKILL.md +++ b/.agents/skills/deploy/SKILL.md @@ -228,6 +228,14 @@ gh pr merge --merge ## Step 8 — Create GitHub Release +**Publish confirmation — required before writing the release notes or creating the Release.** The GitHub Release is a public-surface action. The single word from Step 5 authorized the promotion/merge (already done); the public publish gets its own explicit confirmation. Tell the user (substitute the actual tag, e.g. `v0.13.0`): + +> Publishing GitHub Release `` — the final public step. Confirm by pasting: `publish ` + +Wait for the user to paste `publish ` (or an explicit version-named variant such as `ship `). Any other response → stop and ask what they'd like to change. The version-named phrase is deliberate: Claude Code's auto-mode safety classifier requires authorization that names the release before `gh release create` runs, so the generic Step 5 confirmation is not relied on for the public publish. If a harness still blocks the call after this confirmation (e.g. an older client), the user can re-confirm with `publish release` to unblock. + +--- + The version tag (from Step 3) and the PR/issue list (from Step 4) are already known. Find the previous tag to build the changelog link: ```bash @@ -266,4 +274,4 @@ After the command runs, note the release URL from the output. Tell the user: > "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." - + diff --git a/.claude/commands/deploy.md b/.claude/commands/deploy.md index fa549ef..0c69306 100644 --- a/.claude/commands/deploy.md +++ b/.claude/commands/deploy.md @@ -223,6 +223,14 @@ gh pr merge --merge ## Step 8 — Create GitHub Release +**Publish confirmation — required before writing the release notes or creating the Release.** The GitHub Release is a public-surface action. The single word from Step 5 authorized the promotion/merge (already done); the public publish gets its own explicit confirmation. Tell the user (substitute the actual tag, e.g. `v0.13.0`): + +> Publishing GitHub Release `` — the final public step. Confirm by pasting: `publish ` + +Wait for the user to paste `publish ` (or an explicit version-named variant such as `ship `). Any other response → stop and ask what they'd like to change. The version-named phrase is deliberate: Claude Code's auto-mode safety classifier requires authorization that names the release before `gh release create` runs, so the generic Step 5 confirmation is not relied on for the public publish. If a harness still blocks the call after this confirmation (e.g. an older client), the user can re-confirm with `publish release` to unblock. + +--- + The version tag (from Step 3) and the PR/issue list (from Step 4) are already known. Find the previous tag to build the changelog link: ```bash @@ -261,4 +269,4 @@ After the command runs, note the release URL from the output. Tell the user: > "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." - + diff --git a/.cursor/rules/deploy.mdc b/.cursor/rules/deploy.mdc index 9e1b332..0a4b3ee 100644 --- a/.cursor/rules/deploy.mdc +++ b/.cursor/rules/deploy.mdc @@ -229,6 +229,14 @@ gh pr merge --merge ## Step 8 — Create GitHub Release +**Publish confirmation — required before writing the release notes or creating the Release.** The GitHub Release is a public-surface action. The single word from Step 5 authorized the promotion/merge (already done); the public publish gets its own explicit confirmation. Tell the user (substitute the actual tag, e.g. `v0.13.0`): + +> Publishing GitHub Release `` — the final public step. Confirm by pasting: `publish ` + +Wait for the user to paste `publish ` (or an explicit version-named variant such as `ship `). Any other response → stop and ask what they'd like to change. The version-named phrase is deliberate: Claude Code's auto-mode safety classifier requires authorization that names the release before `gh release create` runs, so the generic Step 5 confirmation is not relied on for the public publish. If a harness still blocks the call after this confirmation (e.g. an older client), the user can re-confirm with `publish release` to unblock. + +--- + The version tag (from Step 3) and the PR/issue list (from Step 4) are already known. Find the previous tag to build the changelog link: ```bash @@ -267,4 +275,4 @@ After the command runs, note the release URL from the output. Tell the user: > "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." - + diff --git a/.gemini/skills/deploy/SKILL.md b/.gemini/skills/deploy/SKILL.md index f6bcbac..08b6afe 100644 --- a/.gemini/skills/deploy/SKILL.md +++ b/.gemini/skills/deploy/SKILL.md @@ -228,6 +228,14 @@ gh pr merge --merge ## Step 8 — Create GitHub Release +**Publish confirmation — required before writing the release notes or creating the Release.** The GitHub Release is a public-surface action. The single word from Step 5 authorized the promotion/merge (already done); the public publish gets its own explicit confirmation. Tell the user (substitute the actual tag, e.g. `v0.13.0`): + +> Publishing GitHub Release `` — the final public step. Confirm by pasting: `publish ` + +Wait for the user to paste `publish ` (or an explicit version-named variant such as `ship `). Any other response → stop and ask what they'd like to change. The version-named phrase is deliberate: Claude Code's auto-mode safety classifier requires authorization that names the release before `gh release create` runs, so the generic Step 5 confirmation is not relied on for the public publish. If a harness still blocks the call after this confirmation (e.g. an older client), the user can re-confirm with `publish release` to unblock. + +--- + The version tag (from Step 3) and the PR/issue list (from Step 4) are already known. Find the previous tag to build the changelog link: ```bash @@ -266,4 +274,4 @@ After the command runs, note the release URL from the output. Tell the user: > "Released vX.Y.Z. Issues #N, #M closed automatically. GitHub Release vX.Y.Z created at ``. Run `make deploy-prod` to ship to production." - + diff --git a/docs/skills/deploy.md b/docs/skills/deploy.md index e9d5d06..90d8b99 100644 --- a/docs/skills/deploy.md +++ b/docs/skills/deploy.md @@ -44,7 +44,7 @@ No arguments. Must be run from the correct branch (determined by your branching 6. **Human gate** — shows a release summary and waits for you to type "release". -7. **Create GitHub Release** (trunk mode) or **Create promotion PR, merge, then create GitHub Release** (multi-branch modes). +7. **Create GitHub Release** (trunk mode) or **Create promotion PR, merge, then create GitHub Release** (multi-branch modes). Creating the public Release has its own confirmation: you paste `publish vX.Y.Z` (the actual version) right before it publishes. ## Why it's built this way @@ -52,6 +52,8 @@ No arguments. Must be run from the correct branch (determined by your branching **Human gate is mandatory.** The "type release to confirm" gate exists because promoting to production is irreversible in practice. The summary gives you one last chance to verify that the right changes are going out. +**The public Release has a second, version-named gate.** Single-word `release` authorizes the promotion and merge, but creating the public GitHub Release asks you to paste `publish vX.Y.Z` (with the real version). Two reasons: (1) it names the exact version you're publishing, so the authorization is unambiguous in the audit trail; and (2) Claude Code's auto-mode safety classifier treats publishing a Release as a public-surface action that needs authorization naming the release — a bare word doesn't satisfy it. Making this an expected, designed step means the publish never stops as a surprise mid-flow after the merge has already landed. If a harness still blocks after you confirm, re-paste `publish vX.Y.Z release` to unblock. + **Issues close on release, not on feature merge.** In multi-branch modes, feature PRs use `Closes #N`, but the keyword is inert until it reaches the default branch — so issues only auto-close when the promotion PR merges to `BRANCH_PROD`. This means issues stay open through the QA/staging phase, giving you visibility into what's deployed where. `/deploy` parses each constituent PR's `Closes #N` lines into a **close set** (reproduced verbatim into the promotion PR, so nothing is dropped) and keeps `Related to #N` / legacy `Issue #N` references in a separate **reference set** that the human gate lists as "referenced but not closing" — letting you catch any straggler that should have closed. **State check surfaces surprises early.** Showing open unmerged PRs at the start prevents accidental releases that miss in-flight work. diff --git a/skills/github-agile/deploy.md b/skills/github-agile/deploy.md index 4aee1d2..97b7666 100644 --- a/skills/github-agile/deploy.md +++ b/skills/github-agile/deploy.md @@ -264,6 +264,14 @@ Wait for the user to type "release" or an explicit confirmation. Any other respo {{#if !BRANCH_DEV}} ## Step 6 — Create GitHub Release +**Publish confirmation — required before writing the release notes or creating the Release.** The GitHub Release is a public-surface action. The single word from Step 5 authorizes the promotion/merge; the public publish gets its own explicit confirmation. Tell the user (substitute the actual tag, e.g. `v0.13.0`): + +> Publishing GitHub Release `` — the final public step. Confirm by pasting: `publish ` + +Wait for the user to paste `publish ` (or an explicit version-named variant such as `ship `). Any other response → stop and ask what they'd like to change. The version-named phrase is deliberate: Claude Code's auto-mode safety classifier requires authorization that names the release before `gh release create` runs, so the generic Step 5 confirmation is not relied on for the public publish. If a harness still blocks the call after this confirmation (e.g. an older client), the user can re-confirm with `publish release` to unblock. + +--- + The version tag and PR/issue list are already known. If no previous tag exists, omit the "Full changelog" line. First, create a temp directory for this invocation: @@ -362,6 +370,14 @@ gh pr merge --merge ## Step 8 — Create GitHub Release +**Publish confirmation — required before writing the release notes or creating the Release.** The GitHub Release is a public-surface action. The single word from Step 5 authorized the promotion/merge (already done); the public publish gets its own explicit confirmation. Tell the user (substitute the actual tag, e.g. `v0.13.0`): + +> Publishing GitHub Release `` — the final public step. Confirm by pasting: `publish ` + +Wait for the user to paste `publish ` (or an explicit version-named variant such as `ship `). Any other response → stop and ask what they'd like to change. The version-named phrase is deliberate: Claude Code's auto-mode safety classifier requires authorization that names the release before `gh release create` runs, so the generic Step 5 confirmation is not relied on for the public publish. If a harness still blocks the call after this confirmation (e.g. an older client), the user can re-confirm with `publish release` to unblock. + +--- + The version tag (from Step 3) and the PR/issue list (from Step 4) are already known. Find the previous tag to build the changelog link: ```bash @@ -457,6 +473,14 @@ gh pr merge --merge ## Step 8 — Create GitHub Release +**Publish confirmation — required before writing the release notes or creating the Release.** The GitHub Release is a public-surface action. The single word from Step 5 authorized the promotion/merge (already done); the public publish gets its own explicit confirmation. Tell the user (substitute the actual tag, e.g. `v0.13.0`): + +> Publishing GitHub Release `` — the final public step. Confirm by pasting: `publish ` + +Wait for the user to paste `publish ` (or an explicit version-named variant such as `ship `). Any other response → stop and ask what they'd like to change. The version-named phrase is deliberate: Claude Code's auto-mode safety classifier requires authorization that names the release before `gh release create` runs, so the generic Step 5 confirmation is not relied on for the public publish. If a harness still blocks the call after this confirmation (e.g. an older client), the user can re-confirm with `publish release` to unblock. + +--- + The version tag (from Step 3) and the PR/issue list (from Step 4) are already known. Find the previous tag to build the changelog link: ```bash