--- name: harness-release description: "Generic release automation for projects using Keep a Changelog + GitHub. Single confirmation gate then end-to-end automation: bump detection, CHANGELOG promotion, PR/main merge, tag, GitHub Release. Trigger: release, version bump, publish. Do NOT load for: implementation, review, planning, setup." description-en: "Generic release automation for projects using Keep a Changelog + GitHub. Single confirmation gate then end-to-end automation: bump detection, CHANGELOG promotion, PR/main merge, tag, GitHub Release. Trigger: release, version bump, publish. Do NOT load for: implementation, review, planning, setup." description-ja: "汎用リリース自動化スキル。Keep a Changelog と GitHub を使うあらゆるプロジェクトで動作。単一確認ゲートで bump 判定・CHANGELOG 昇格・PR/main 反映・タグ・GitHub Release まで全自動実行する。リリース、バージョンバンプ、タグ作成、公開で起動。実装・コードレビュー・プランニング・セットアップには使わない。" kind: workflow purpose: "Release projects through changelog, version, PR/main merge, tag, and GitHub Release gates" trigger: "release, version bump, publish" shape: workflow role: orchestrator pair: harness-review owner: harness-core since: "2026-05-05" allowed-tools: ["Read", "Write", "Edit", "Bash", "AskUserQuestion", "Skill"] argument-hint: "[patch|minor|major|--dry-run]" context: fork effort: high user-invocable: true --- # Harness Release (汎用) Keep a Changelog + GitHub を使う**あらゆるプロジェクト向け**の汎用リリース自動化スキル。 **設計原則**: 単一確認ゲート。ユーザーは 1 回だけ全体計画を見て承認する。承認後はファイル書き換え → commit → branch push → PR 作成/更新 → default branch へ merge → default branch 上で tag → GitHub Release までを中断なく実行する。 **Release complete の定義**: release は「tag と GitHub Release を作った」だけでは完了ではない。対象 work と release bump が default branch(通常 `main`)に merge 済みで、release tag が default branch 到達可能 commit を指し、GitHub Release がその tag を公開している状態を完了とする。 ## PR ready vs release ready Harness V2 では PR closeout と release closeout を混同しない。 | Gate | 意味 | 必須条件 | 停止 lane | |------|------|----------|-----------| | **PR ready** | ブランチが review 可能で merge 判断できる | `harness-review` `APPROVE`、focused tests PASS、evidence pack 完備(accepted/rejected findings、tests、release-preflight warnings 処理、residual risk) | `[lane:fast]` / `[lane:gate]` はここで停止可 | | **release ready** | 公開配布 path が preflight を通過 | PR ready 条件 + version surface sync + tag + GitHub Release + CI/public artifact 検証 | `[lane:release]` のみ | - PR ready は `harness-review` APPROVE + evidence pack で判定する。`harness-review` から push / PR / merge はしない。 - release ready は `harness-release` の Preflight / Post-Gate だけが判定する。version bump / tag / GitHub Release は release lane 専用。 - local tests passed だけでは PR ready でも release ready でもない(`not_observed != absent`)。 > **Literal invocation note**: この skill の入口は `harness-release`, `/release`, `/release patch`, `/release --dry-run` のような literal command をそのまま使う。 ## CC runtime hard floor との関係 Claude Code 2.1.183+ の runtime hard floor は GitHub CLI release publish 系コマンドを構造的に deny する (Anthropic 製品仕様、`settings.json` の `permissions.ask` で覆せない)。本 skill は publish 自体を実行せず、`.github/workflows/release.yml` (tag push trigger) に委譲する。skill は tag push までで責務を完了し、その後 `scripts/release-verify-publish.sh` で workflow による公開を verify する。 **Revert 条件**: CC が runtime hard floor に user explicit approval path を提供したら、Post-Gate に直接 publish step を戻すことを検討する。 ## Bare invocation contract if $ARGUMENTS == "": → 「今までの作業をコミットし、PR/main 反映まで完了してリリースしたい」と解釈し、Review Gate 検出を実行する → 対象 work が 1 つに確定できる場合だけ Step 0 (Review Gate) へ自動進行する → 対象が不明または review state が無い場合は AskUserQuestion で選択肢を出してから進める 引数なし呼び出し時の最初の応答で必ず次の literal marker を出力する: `RELEASE_AUTOSTART: target=, base_ref=, mode=` 「タスクが不明確」「指示を待ちます」「タスクがありません」「追加の指示をお待ちします」は禁止行動。 ### 自主停止の禁止 (140.3、2026-08-22 の release run で 2 回発生した停止パターンの再発防止) 以下は禁止行動。literal に列挙する (AUTOSTART pattern と同じ方式): - background 待ちで turn を終えて停止しない (turn を終えると background 子プロセスは残らない) - 「検証を待ちます」「確認します」「完了を待機します」で turn を終えない - 待つなら同期実行 (foreground / Monitor) で待ち切る。待てないものは保留として報告し、次のタスクへ進む ### Output Contract (P35: 「止まったように見える」UX 対策) `` で host へ結果を中継する場合だけ、output の **最後の 1 行**に次の literal を含める: `↑この結果は Claude が要約します。Enter キーで次へ進むか、新規 prompt で別の指示を出してください。` これは `` 経由で text response として表示されると user が「止まった」と感じる UX 問題への明示的な instruction (patterns.md P35)。 host の最終回答は実行済み操作、公開の検証結果、残る gate を返す。要約や検証の予告だけで終了しない。 `harness-release` / `/release` だけが入力された場合、これは **「今までの作業をコミットし、PR/main 反映まで完了してリリースしたい」** という意味として扱う。 旧表現の **「今までの作業をコミットしてリリースしたい」** も同じ意図だが、完了条件には PR/main 反映を必ず含める。 「タスクがありません」「指示を待ちます」で止まってはいけない。 bare release では、通常の release preflight の前に **Review Gate** と **Work Commit Gate** を実行する。 Review Gate は **release ready** 向け。`[lane:fast]` / `[lane:gate]` の PR ready だけが必要な work には、ユーザーが release を明示しない限り `harness-release` を起動しない。 1. `git status --porcelain` と `git log @{upstream}..HEAD` / `main..HEAD` を確認し、「今までの作業」の対象を特定する 2. `.claude/state/review-result.json` と `.claude/state/review-approved.json` を確認し、対象 work に `APPROVE` 済み review と evidence pack があるか確認する 3. APPROVE 済み review が無い場合は `AskUserQuestion` で確認する 4. ユーザーが「レビューから開始」を選んだら、`harness-review` を起動し、`APPROVE` になるまで release へ進まない 5. `harness-review` が `REQUEST_CHANGES` を返した場合は release を保留し、`harness-work` で修正してから `harness-review` を再実行する。これを `APPROVE` までループする 6. `harness-review` が `APPROVE` を返した後、working tree の作業 commit を作る 7. working tree clean になってから通常の release preflight / confirmation gate / PR merge / tag / GitHub Release へ進む ### Review Gate AskUserQuestion `harness-release` 実行時に review approval が確認できない場合は、推測で release しない。 次の Ask を出す。 ```text question: "harness-release は今までの作業をコミットしてリリースしますが、この作業の APPROVE review が見つかりません。どう進めますか?" options: - label: "レビューから開始 (Recommended)" description: "harness-review を実行し、APPROVE になった場合だけ commit/release へ進みます。" - label: "release dry-run" description: "ファイルを書き換えず、release 計画と不足 gate だけ確認します。" - label: "中止" description: "review も release も行わず止めます。" ``` ユーザーが「レビューから開始」を選んだ場合は、同じセッション内で `harness-review` から始める。 `harness-review` の対象決定は `harness-review` 側の bare review contract に従う。 review が `APPROVE` なら、そのまま `harness-release` の Work Commit Gate へ戻る。 review が `REQUEST_CHANGES` なら release は保留し、`harness-work` で修正してから `harness-review` を再実行する。 この修正後再レビュー loop は `APPROVE` まで継続する。 ユーザーに戻してよいのは次の場合だけ。 1. 修正に仕様正本 / Plans.md / API / permission / migration / billing などの意思決定が必要で、`AskUserQuestion` が必要 2. 修正方針が複数あり、どれを採るかでユーザー価値や互換性が変わる 3. ユーザーが Ask で `release dry-run` または `中止` を選んだ `REQUEST_CHANGES` 単体を最終停止理由にしてはいけない。 ### Work Commit Gate bare release で working tree に未コミット変更がある場合、release version bump commit とは別に、 review 済み work commit を先に作る。 ```bash git status --short git diff --stat git add git commit -m ": " ``` commit message は review summary / Plans.md task / branch name から短く生成する。 表現だけが未決なら既存の commit 規約に沿って生成する。review 済みの対象そのものが曖昧な場合だけ、その対象を確認する。 work commit 作成後に `.claude/state/review-result.json` の `commit_hash` を確認または更新し、 release preflight へ進む。 通常の release preflight に入った後は、これまで通り working tree dirty を fail とする。 dirty tree のまま version bump / tag / GitHub Release に進まない。 ## Quick Reference ```bash /release # 今までの作業を review gate → commit → PR/main merge → release する /release patch # bump を patch に明示指定 /release minor # bump を minor に明示指定 /release major # bump を major に明示指定 /release --dry-run # 計画の表示のみ、実行しない ``` ## 前提条件 このスキルが動くプロジェクトは以下を満たす必要があります: 1. `CHANGELOG.md` が [Keep a Changelog](https://keepachangelog.com/) 形式 2. `[Unreleased]` セクションが存在する 3. 以下のいずれかの version file を持つ: - `VERSION` (単独ファイル) - `package.json` (npm) - `pyproject.toml` (Python, `[project]` または `[tool.poetry]`) - `Cargo.toml` (Rust, `[package]`) 4. `gh` CLI がインストール済みで、認証済み 5. git リモート `origin` が GitHub を指す 6. Claude Code plugin project の場合は、`claude` CLI が `plugin validate` をサポートしている これらが満たされない場合、Preflight で detect して abort します。 `prUrlTemplate` による multi-host review URL は将来候補として認識するが、 このスキルの release automation は今も `gh` CLI と GitHub remote を primary path とする。 owner / branch / release asset / CI metadata の自動取得は host ごとの差が大きいため、Phase 56.2.3 では docs-only に留める。 ## 単一ゲートフロー Bare release(0. Review Gate → 0.5 Work Commit Gate)→ Pre-Gate(1. Preflight → 2. Version file 検出 → 3. バージョン読み取り → 4. plugin version sync preflight → 5. bump 推定 → 6. 新バージョン算出 → 7. CHANGELOG ドラフト → 8. CHANGELOG release body preview)→ **単一確認ゲート**(下記「Confirmation Gate」参照、`yes` / `<修正指示>` / `cancel` の 3 択)→ Post-Gate(9. Version file 書き換え → 10. CHANGELOG 昇格 → 11. commit → 12. branch push → 13. PR 作成/更新 → 14. default branch merge → 15. 到達可能性確認 → 16. semver tag → 17. tag push → 18. workflow publish verify → 19. 完了報告) の 3 段階で進む。各段の詳細は「Pre-Gate 詳細」「Confirmation Gate」「Post-Gate 詳細」を参照。 ## Pre-Gate 詳細 ### 1. Preflight release ready gate: PR ready 条件に加え、version / tag / GitHub Release / CI artifact path を確認する。 ```bash # 必須ツール command -v gh >/dev/null || { echo "gh CLI がありません"; exit 1; } command -v python3 >/dev/null || { echo "python3 が必要です"; exit 1; } # working tree if [ -n "$(git status --porcelain)" ]; then echo "working tree に未コミット変更があります"; exit 1; fi # CHANGELOG [ -f CHANGELOG.md ] || { echo "CHANGELOG.md がありません"; exit 1; } grep -q "^## \[Unreleased\]" CHANGELOG.md || { echo "[Unreleased] セクションがありません"; exit 1; } # plugin/mirror projects scripts/release-preflight.sh ``` この working tree clean check は通常 release preflight の gate である。 bare release で「今までの作業」を commit したい場合は、この check の前に Review Gate と Work Commit Gate を完了させる。 未レビューの dirty tree をこの check だけで abort して終わらせてはいけない。 `scripts/release-preflight.sh` は tag 作成前に `opencode/`, `skills-codex/`, `codex/.codex/skills/` の mirror drift も検出する。`node scripts/build-opencode.js` が差分を生成した場合は release を止め、その差分を commit してから tag に進む。 release preflight は host workflow smoke を `REQUIRED=1`(fail-closed)で全 dist host に対して実行する。1 host でも FAIL なら release を止める。これは multi-host bar H7(release-preflight consumes host gates fail-closed)の充足配線である。`scripts/release-preflight-host-smoke.sh` 参照。fail-closed の正本は operator マシンの preflight であり、GitHub runner(`GITHUB_ACTIONS=true`)では CLI 未 provision の host を明示 SKIP 行つきで飛ばす(tag-triggered workflow の再実行が全 release を塞がないため。v5.3.0 run 29679591686 の regression 対応)。 ### 2. Version File 自動検出 `VERSION` → `package.json` → `pyproject.toml`(`[project]` / `[tool.poetry]`)→ `Cargo.toml` の優先順で探索し、最初に見つかったものを正本とする。 検出スニペット・読み取りロジックの詳細: [version-files.md](${CLAUDE_SKILL_DIR}/references/version-files.md) ### 3. Claude Plugin Version Sync Preflight `.claude-plugin/plugin.json` が存在する project では、semver tag を切る前に plugin manifest の validation と全 version surface の同期を確認する。 > **plugin tag (`{plugin-name}--v{version}`) は 2026-08-17 に廃止**。`marketplace.json` の `source` が相対パス (`"./"`) で install は tag を参照しないため、実効性が無いまま v5.6.0 以降 3 リリース連続で欠番になっていた。GitHub Release 用 semver tag `vX.Y.Z` に一本化する (decisions.md D69)。 Pre-Gate ではファイルを書き換えず、以下を確認する。 version sync は `grep` / `sed` で拾わず、JSON は structured parser で読む: ```bash command -v claude >/dev/null || { echo "claude CLI がありません"; exit 1; } claude plugin validate .claude-plugin/plugin.json HARNESS_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-.}" python3 "${HARNESS_PLUGIN_ROOT}/scripts/check-release-version-sync.py" --root . ``` `${HARNESS_PLUGIN_ROOT}/scripts/check-release-version-sync.py` は、存在する release surface をすべて読み取り、canonical を `VERSION > package.json > .claude-plugin/plugin.json > .codex-plugin/plugin.json` の順で決める。 そのうえで、以下の不一致・欠落が 1 つでもあれば tag / release に進まない: - `VERSION` - `package.json` の `.version` - `.claude-plugin/plugin.json` の `.version` - `.codex-plugin/plugin.json` の `.version` - `.claude-plugin/marketplace.json` の `.metadata.version` - `.claude-plugin/marketplace.json` の `.plugins[].version`(配列内の各 plugin entry) 不一致時は、どの surface が canonical と違うか、またはどの field が missing / invalid かを表示する。 機械処理や CI で読む場合は `--json` を使う: ```bash python3 "${HARNESS_PLUGIN_ROOT}/scripts/check-release-version-sync.py" --root . --json ``` この check は 3 つの事故を防ぐためにある: - `VERSION` と `.claude-plugin/plugin.json` の version がずれたまま tag を切る事故 - `package.json` / marketplace entry の version が古いまま release workflow に進む事故 - plugin manifest / marketplace entry の validation を通さず、あとで plugin install / update 側で詰まる事故 この check の結果 (canonical version と各 surface の一致) を Confirmation Gate の plan に含める。 ### 4. Bump 自動推定 `[Unreleased]` 直下の見出し(`### Breaking Changes`/`### Removed` → major、`### Added` → minor、`### Fixed`/`### Changed`/`### Security` のみ → patch、空セクション → error)を解析して bump level を決定する。 ユーザーが `/release patch|minor|major` で明示指定した場合はそちらを優先。 詳細: [bump-detection.md](${CLAUDE_SKILL_DIR}/references/bump-detection.md) ### 5. CHANGELOG ドラフト作成 (メモリ上) `[Unreleased]` の内容を切り出し、`[] - YYYY-MM-DD` セクションと compare link を組み立てる(まだ書き込まない)。 詳細: [release-notes.md](${CLAUDE_SKILL_DIR}/references/release-notes.md#changelog-ドラフト作成メモリ上pre-gate-ステップ-7) ### 6. CHANGELOG release body preview (メモリ上) tag-triggered workflow が公開する本文は、昇格後の `## []` セクション本文そのもの。 別の英訳・要約・フッターを生成せず、workflow と同じ抽出境界の本文をそのまま preview する。 抽出方法・検証チェックの詳細: [release-notes.md](${CLAUDE_SKILL_DIR}/references/release-notes.md) ## Confirmation Gate すべてのドラフトが揃ったら、ユーザーに 1 回だけ提示: ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Release Plan: v → v () ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Version file: Bump reason: CHANGELOG changes: [Unreleased] に 項目の変更を検出 [] - YYYY-MM-DD として確定 Compare link を追加 CHANGELOG release body preview (workflow が公開する本文): Files to modify: - - CHANGELOG.md Final actions: - git commit -m "chore: release v" - git push origin - gh pr create/update + gh pr merge into - git fetch origin && git checkout - git tag -a v # GitHub Release 用 semver tag。default branch 上で作成 - git push origin --tags - (tag push 後は GitHub Actions release workflow が自動で release 公開) Proceed? [yes / cancel / <修正指示>] ``` ## Post-Gate 詳細 承認後は中断なしで実行。失敗時は以下の方針: | 失敗箇所 | 復旧 | |---------|------| | ファイル書き換え失敗 | そこで abort、ローカルは dirty なまま人間が判断 | | commit 失敗 | hook 拒否等。ユーザーに原因を提示して修正を促す | | PR 作成/merge 失敗 | release を未完了として停止。tag / GitHub Release には進まない | | plugin version sync 失敗 | `VERSION` / `.claude-plugin/plugin.json` / marketplace entry の不一致を修正し、tag 作成には進まない | | push 失敗 | リモート側の問題。ローカル commit/tag は残す | ### PR / Main Merge Gate、semver tag、Verify Publish Post-Gate の release commit 後、tag を作る前に GitHub PR を default branch へ merge する(`gh pr create` → `gh pr merge --merge` → default branch fetch/checkout で release commit の到達可能性を確認)。release branch 上だけに存在する commit を指す tag で GitHub Release を作ってはいけない。 `.claude-plugin/plugin.json` がある project では、merge 後に default branch 上で version sync を再確認してから semver tag `vX.Y.Z` を作る (plugin tag は 2026-08-17 廃止、D69)。 tag push 後は `bash scripts/release-verify-publish.sh` で `.github/workflows/release.yml` の公開結果を verify する(5 秒間隔 × 60 回 polling、exit 0=PASS / 2=WARN(timeout) / 3=ERROR)。 コマンド全文・失敗時の判断基準は [post-gate-detail.md](${CLAUDE_SKILL_DIR}/references/post-gate-detail.md) を参照。 ## `--dry-run` モード Pre-Gate 全てを実行し、Confirmation Gate までの内容を表示するが、**gate で止まり Post-Gate に進まない**。 Claude plugin project の場合、dry-run でも `python3 "${HARNESS_PLUGIN_ROOT}/scripts/check-release-version-sync.py" --root .` を実行し、canonical version と各 surface の一致を表示する。ここで `VERSION` / `package.json` / `.claude-plugin/plugin.json` / `.codex-plugin/plugin.json` / `.claude-plugin/marketplace.json` の version surface が不一致または欠落していれば、dry-run の時点で止める。 ## 環境変数 プロジェクトごとの調整に使用: | 変数 | 説明 | |------|------| | `HARNESS_RELEASE_PROJECT_ROOT` | リポジトリルート (デフォルト: `$(pwd)`) | | `HARNESS_RELEASE_BRANCH` | push 対象ブランチ (デフォルト: 現在のブランチ) | | `HARNESS_RELEASE_DEFAULT_BRANCH` | PR merge 先 default branch (デフォルト: `main`) | | `HARNESS_RELEASE_HEALTHCHECK_CMD` | Preflight で追加実行するコマンド | | `HARNESS_RELEASE_SKIP_GH` | `1` で GitHub publication verification をスキップ | ## CHANGELOG 書き方ルール `[Unreleased]` セクションは KaCL 標準サブセクション(`### Added`=minor / `### Changed`・`### Fixed`・`### Security`=patch / `### Deprecated`=minor / `### Removed`・`### Breaking Changes`=major)のいずれかを持つ必要がある。 このスキルはこれらの見出しを機械的に解析するため、表記揺れ(`### Fix` / `### Bug Fixes` 等)は認識できない。 CHANGELOG release body の preview 契約・CHANGELOG の書き方・merge 方式(squash 不採用)の詳細は [github-release.md](${CLAUDE_SKILL_DIR}/references/github-release.md) を参照。 SemVer 判定基準・バッチリリース方針・Release Train Proposal の詳細は [versioning.md](${CLAUDE_SKILL_DIR}/references/versioning.md) を参照。 ## 出荷前の受け入れ判断(非エンジニア向け) リリース確定の前に `harness-accept` を提案する。各合格条件が満たされたかと ship/wait/reject の 推奨を 1 枚の HTML にまとめた「受け入れ判断」画面で、発注者が専門知識なしで出荷可否を判断できる。 ## 関連スキル - `harness-release-internal` - 本体 claude-code-harness のリリース時に追加で走らせる harness 固有 preflight/finalization(配布対象外) - `harness-plan` - Plans.md 管理 - `harness-review` - リリース前のコードレビュー - `harness-accept` - 受け入れ判断 HTML(非エンジニア向け、リリース前に提案) ## 設計思想 - **PR ready / release ready 分離**: PR ready は review + evidence pack。release ready は version/tag/GitHub Release/CI まで。lane:fast / lane:gate は PR ready で止めてよい - **単一ゲート**: ユーザーの判断タイミングは 1 回だけ。mini-confirmation を挟むとラバースタンプ化して意味を失う - **事前に全て描く**: Gate 前に全 draft を揃える。Post-Gate は承認済み計画を実行し、新しい証拠で前提が崩れた場合は影響する操作を止めて報告する - **main 反映が完了条件**: release tag / GitHub Release は default branch 反映後にだけ作る。branch-only release は未完了として扱う - **失敗は transparent**: 途中で失敗したら自動ロールバックは試みず、ユーザーに現状を提示して判断させる - **プロジェクト非依存**: VERSION file 形式、mirror、residue check など特定環境の前提を持たない。本体 harness 固有の処理は `harness-release-internal` に分離