# Harness Release

> 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.

- Skill: `whyzsm/harness-release` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add whyzsm/harness-release`
- Raw SKILL.md: https://api.skillmd.com/api/skills/whyzsm/harness-release/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: whyzsm (https://skillmd.com/u/whyzsm)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/whyzsm/harness-release

---


# 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 を公開している状態を完了とする。

> **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=<work-summary>, base_ref=<ref>, mode=<patch|minor|major|auto>`

「タスクが不明確」「指示を待ちます」「タスクがありません」「追加の指示をお待ちします」は禁止行動。

<!-- 上記ブロックは AUTO-START CONTRACT。skill-editing.md「最冒頭 3 行以内」ルール準拠。patterns.md P27 解法 3 点セット (機械可読条件 + 禁止行動 literal + AUTOSTART marker) -->

### Output Contract (P35: 「止まったように見える」UX 対策)

skill 結論時の output の **最後の 1 行**は必ず P35 footer を含め、footer は本文 (user-facing prose) と同じ言語で出力する（言語解決は既存の言語ルールに従い、footer 契約は言語を再定義しない）。これは `<local-command-stdout>` 経由の表示で user が「止まった」と感じる UX 問題への明示的な instruction (patterns.md P35) で、意図は言語に依存しないため literal は言語ごとに切り替える (#208):

- ja: `↑この結果は Claude が要約します。Enter キーで次へ進むか、新規 prompt で別の指示を出してください。`
- en: `↑Claude will summarize this result. Press Enter to continue, or send a new prompt for a different instruction.`
- その他の言語: 同じ意味の 1 行を本文と同じ言語で出力する

### Language

User-facing prose follows the explicit session or project language.
If no language is configured, use English. Use Japanese only when
`i18n.language: ja`, `CLAUDE_CODE_HARNESS_LANG=ja`, or an explicit session
instruction requests Japanese output.
Machine-readable values stay English.

`harness-release` / `/release` だけが入力された場合、これは
**「今までの作業をコミットし、PR/main 反映まで完了してリリースしたい」** という意味として扱う。
旧表現の **「今までの作業をコミットしてリリースしたい」** も同じ意図だが、完了条件には PR/main 反映を必ず含める。
「タスクがありません」「指示を待ちます」で止まってはいけない。

bare release では、通常の release preflight の前に **Review Gate** と **Work Commit Gate** を実行する。

1. `git status --porcelain` と `git log @{upstream}..HEAD` / `main..HEAD` を確認し、「今までの作業」の対象を特定する
2. `.claude/state/review-result.json` と `.claude/state/review-approved.json` を確認し、対象 work に `APPROVE` 済み review があるか確認する
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` まで継続する。

#### Persist Verdict after Review Gate (required / #218 fix)

`harness-review` 委譲後、必ず `.claude/state/review-result.json` に verdict が永続化されている
ことを確認する。`harness-review` 側の Persist Verdict step が踏まれていれば既に保存済みだが、
踏み忘れ時の **二段防御**として、Review Gate 側でも次の check + 補完保存を行う。これを欠かすと
**Work Commit Gate (Step 6) の `git commit` が PreToolUse commit guard でブロックされる**。

```bash
# 1. 保存済みか確認
if [ -f .claude/state/review-result.json ] \
   && [ "$(jq -r '.verdict // empty' .claude/state/review-result.json 2>/dev/null)" = "APPROVE" ]; then
  echo "review-result.json already persisted with APPROVE"
else
  # 2. 未保存なら orchestrator が in-context の verdict JSON を一時ファイルへ書き出し
  mkdir -p .claude/state
  cat > .claude/state/tmp-review-result.json <<'JSON'
{ "schema_version": "review-result.v1", "verdict": "APPROVE", ... }
JSON
  bash "${HARNESS_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT:-$PWD}}/scripts/write-review-result.sh" \
    .claude/state/tmp-review-result.json \
    "$(git rev-parse --short HEAD 2>/dev/null || true)"
  rm -f .claude/state/tmp-review-result.json
fi
```

multi-commit セーフティ: Phase 94.1.3 で PostToolUse commit-cleanup が `VERSION` / `.claude-plugin/plugin.json` /
`harness.toml` / `CHANGELOG.md` のみの **bookkeeping commit** を認識し承認削除を skip するようになったため、
Post-Gate の version bump commit (Step 11) は `harness-release` の自動 commit でそのまま通過する。
それ以前のバージョン (4.15.0 以前) を使う場合は、Work Commit Gate と version bump commit の間に
再度 Persist Verdict を行うこと。

ユーザーに戻してよいのは次の場合だけ。

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 <reviewed files>
git commit -m "<type>: <summary>"
```

commit message は review summary / Plans.md task / branch name から短く生成する。
判断できない場合は `AskUserQuestion` で 2〜3 個の commit message 候補を出す。
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 tag` をサポートしている

これらが満たされない場合、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 only: 作業 review/commit 前段]
  ↓
  0. Review Gate (未レビューなら AskUserQuestion → harness-review)
  0.5 Work Commit Gate (review APPROVE 済み work を release bump と分けて commit)
  ↓
[Pre-Gate: 情報収集のみ、ファイル未変更]
  ↓
  1. Preflight (working tree clean / CHANGELOG / gh 等の確認)
  2. Version file 自動検出
  3. 現在バージョンの読み取り
  4. Claude plugin tag preflight (plugin project の場合のみ)
  5. [Unreleased] 内容の解析 → bump level 推定
  6. 新バージョン算出
  7. CHANGELOG 差分ドラフト作成 (メモリ上)
  8. GitHub Release notes ドラフト作成 (メモリ上)

★━━━━━━ 単一確認ゲート ━━━━━━★
  ユーザーに全計画を 1 回だけ提示:
    - 検出された version file
    - 現バージョン → 新バージョン
    - bump 判定理由 ("[Unreleased] に ### Added があるため minor" 等)
    - CHANGELOG 変更プレビュー
    - GitHub Release notes ドラフト
    - コミット対象ファイル一覧
    - 最終アクション (branch push + PR merge + tag + release publish)

  ユーザー応答:
    "yes"        → Post-Gate へ進む
    "<修正指示>"  → 指示に応じて draft を再生成、再確認
    "cancel/no"  → 何もせず終了
★━━━━━━━━━━━━━━━━━━━━━━━★
  ↓
[Post-Gate: 承認後、中断なし]

  9. Version file 書き換え
  10. CHANGELOG.md 書き換え ([Unreleased] → [X.Y.Z] 昇格 + compare link)
  11. git add + commit
  12. release branch push
  13. PR 作成/更新
  14. default branch へ merge
  15. default branch を fetch/checkout し、release commit が到達可能であることを確認
  16. Claude plugin tag validation + tag (plugin project の場合のみ)
  17. GitHub Release 用 semver tag (必要な project のみ)
  18. git push origin <default-branch> --tags
  19. tag push 後、`.github/workflows/release.yml` が release を公開し、`release-verify-publish.sh` で verify
  20. 完了報告
```

## Pre-Gate 詳細

### 1. Preflight

```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 に進む。

### 2. Version File 自動検出

以下を優先順で探索。最初に見つかったものを正本とする:

```python
# Python snippet to run inline
import os, json, re
import tomllib  # Python 3.11+

def detect_version_file():
    if os.path.exists("VERSION"):
        with open("VERSION") as f:
            return ("VERSION", f.read().strip(), None)
    if os.path.exists("package.json"):
        with open("package.json") as f:
            data = json.load(f)
        return ("package.json", data["version"], None)
    if os.path.exists("pyproject.toml"):
        with open("pyproject.toml", "rb") as f:
            data = tomllib.load(f)
        if "project" in data:
            return ("pyproject.toml", data["project"]["version"], "[project]")
        if "tool" in data and "poetry" in data["tool"]:
            return ("pyproject.toml", data["tool"]["poetry"]["version"], "[tool.poetry]")
    if os.path.exists("Cargo.toml"):
        with open("Cargo.toml", "rb") as f:
            data = tomllib.load(f)
        return ("Cargo.toml", data["package"]["version"], "[package]")
    raise RuntimeError("No supported version file found")
```

詳細: [version-files.md](${CLAUDE_SKILL_DIR}/references/version-files.md)

### 3. Claude Plugin Tag Preflight

`.claude-plugin/plugin.json` が存在する project では、通常の GitHub Release tag とは別に Claude plugin release tag も作る。

ひとことで言うと、`git tag -a` を手で組み立てる前に、Claude Code 本体の plugin validation に通してから `{plugin-name}--v{version}` tag を作る。

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 .

claude plugin tag .claude-plugin --dry-run
```

`${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 側で詰まる事故

`--dry-run` では `claude plugin tag` が実際に作る tag 名と内部の `git tag -a` / push 相当コマンドが見える。ここで見えた command を Confirmation Gate の plan に含める。

### 4. Bump 自動推定

`[Unreleased]` 直下の見出しを解析して bump level を決定:

| [Unreleased] 内の見出し | 推定 bump |
|------------------------|-----------|
| `### Breaking Changes` または `### Removed` を含む | **major** |
| `### Added` を含む (Removed/Breaking なし) | **minor** |
| `### Fixed` / `### Changed` / `### Security` のみ | **patch** |
| 空セクション | **error: リリース対象なし** |

ユーザーが `/release patch|minor|major` で明示指定した場合はそちらを優先。
詳細: [bump-detection.md](${CLAUDE_SKILL_DIR}/references/bump-detection.md)

### 5. CHANGELOG ドラフト作成 (メモリ上)

以下を計算、まだ書き込まない:

1. `## [Unreleased]` の本文を切り出し
2. `## [Unreleased]` と `## [<previous>]` の間に `## [<new>] - YYYY-MM-DD` を挿入した形を作成
3. 末尾 compare link:
   - `[Unreleased]: .../compare/v<prev>...HEAD` → `v<new>...HEAD`
   - `[<new>]: .../compare/v<prev>...v<new>` を追加
4. repo URL は既存の `[Unreleased]: ` 行から動的抽出

### 6. Release Notes ドラフト作成 (メモリ上)

`## [<new>]` セクションの内容を元に、GitHub Release 用のマークダウンを生成:

```markdown
## What's Changed

**<リリーステーマ(1行)>**

### Before / After
<テーブル>

### Added / Changed / Fixed / Removed
<該当セクションをコピー>

---

🤖 Generated with [Claude Code](https://claude.com/claude-code)
```

詳細: [release-notes.md](${CLAUDE_SKILL_DIR}/references/release-notes.md)

## Confirmation Gate

すべてのドラフトが揃ったら、ユーザーに 1 回だけ提示:

```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Release Plan: v<old> → v<new> (<bump>)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 Version file: <detected file>
 Bump reason:  <why this level was chosen>

 CHANGELOG changes:
   [Unreleased] に <N> 項目の変更を検出
   [<new>] - YYYY-MM-DD として確定
   Compare link を追加

 GitHub Release notes preview:
   <最初の 10 行>
   ...

 Files to modify:
   - <version file>
   - CHANGELOG.md

 Final actions:
   - git commit -m "chore: release v<new>"
   - git push origin <release-branch>
   - gh pr create/update + gh pr merge into <default-branch>
   - git fetch origin <default-branch> && git checkout <default-branch>
   - claude plugin tag .claude-plugin --push --remote origin  # plugin project の場合。default branch 上で実行
   - git tag -a v<new>                                        # GitHub Release 用 semver tag が必要な場合。default branch 上で作成
   - git push origin <default-branch> --tags
   - (tag push 後は GitHub Actions release workflow が自動で release 公開)

Proceed? [yes / cancel / <修正指示>]
```

## Post-Gate 詳細

承認後は中断なしで実行。失敗時は以下の方針:

| 失敗箇所 | 復旧 |
|---------|------|
| ファイル書き換え失敗 | そこで abort、ローカルは dirty なまま人間が判断 |
| commit 失敗 | hook 拒否等。ユーザーに原因を提示して修正を促す |
| PR 作成/merge 失敗 | release を未完了として停止。tag / GitHub Release には進まない |
| plugin tag validation 失敗 | `VERSION` / `.claude-plugin/plugin.json` / marketplace entry の不一致を修正し、tag 作成には進まない |
| push 失敗 | リモート側の問題。ローカル commit/tag は残す |

### PR / Main Merge Gate

Post-Gate の release commit 後は、tag を作る前に GitHub PR を default branch へ merge する。

```bash
release_branch="$(git branch --show-current)"
default_branch="${HARNESS_RELEASE_DEFAULT_BRANCH:-main}"

git push -u origin "$release_branch"
gh pr create --base "$default_branch" --head "$release_branch" --title "chore: release v<new>" --body "<release summary>"
gh pr merge --merge --delete-branch=false

git fetch origin "$default_branch" --tags
git checkout "$default_branch"
git pull --ff-only origin "$default_branch"
git merge-base --is-ancestor "<release-commit>" "origin/$default_branch"
```

既存 PR がある場合は新規作成せず、既存 PR の body を更新して merge する。repository policy が squash merge を要求する場合は、release commit hash ではなく release bump の内容（version files + CHANGELOG + source commits）が default branch に含まれることを確認する。

tag はこの Gate 完了後、default branch の HEAD もしくは release commit 到達可能な commit に対して作る。release branch 上だけに存在する commit を指す tag で GitHub Release を作ってはいけない。

### Claude plugin project の tag 作成

`.claude-plugin/plugin.json` がある project では、PR/main merge 後に default branch 上でもう一度 version sync を確認してから plugin tag を作る:

```bash
HARNESS_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-.}"
python3 "${HARNESS_PLUGIN_ROOT}/scripts/check-release-version-sync.py" --root .

claude plugin tag .claude-plugin --dry-run
claude plugin tag .claude-plugin --push --remote origin
```

`claude plugin tag` が作る tag は `{plugin-name}--v{version}` 形式。既存の GitHub Release workflow が `vX.Y.Z` tag を前提にしている project では、plugin tag とは別に `git tag -a v<new>` を作る。plugin 配布の tag は `claude plugin tag` に任せ、GitHub Release 用 semver tag は release automation の互換 surface として扱う。

### Verify Workflow Publish

Tag push 後、`.github/workflows/release.yml` が release を自動公開する。skill は以下で結果を verify する:

```bash
OWNER="$(git remote get-url origin | sed 's|.*github.com[:/]\([^/]*/[^/]*\)\.git|\1|')"
bash scripts/release-verify-publish.sh "v${NEW_VERSION}" "${OWNER}"
```

タイムアウト: 5 秒間隔 × 60 回 = 最大 5 分 polling。

- exit 0: PASS — `draft=false` 且つ assets 4 platform 揃って公開済
- exit 2: WARN — timeout (tag は push 済のため abort せず人間判断を促す)
- exit 3: ERROR — API error (権限/認証問題、手動調査が必要)

Verify は `gh api` 経由 (`gh release` prefix は CC runtime hard floor で deny されるため)。

## `--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 .` と `claude plugin tag .claude-plugin --dry-run` を実行し、実際に作られる plugin tag 名と push 対象を表示する。ここで `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 Release 作成をスキップ |

## CHANGELOG 書き方ルール

`[Unreleased]` セクションは必ず以下のいずれかのサブセクションを持つ:

```markdown
## [Unreleased]

### Added       ← minor
### Changed     ← patch
### Deprecated  ← minor
### Removed     ← major
### Fixed       ← patch
### Security    ← patch
### Breaking Changes  ← major (Keep a Changelog 非標準だが一般的)
```

このスキルはこれらの見出しを機械的に解析するため、見出しの表記揺れ（`### Fix` / `### Bug Fixes` 等）は認識できません。KaCL 標準の見出しを使用してください。

## 関連スキル

- `harness-release-internal` - 本体 claude-code-harness のリリース時に追加で走らせる harness 固有 preflight/finalization（配布対象外）
- `harness-plan` - Plans.md 管理
- `harness-review` - リリース前のコードレビュー

## 設計思想

- **単一ゲート**: ユーザーの判断タイミングは 1 回だけ。mini-confirmation を挟むとラバースタンプ化して意味を失う
- **事前に全て描く**: Post-Gate に入ってからの「考え直し」を禁ずる。Gate 前に全 draft を揃える
- **main 反映が完了条件**: release tag / GitHub Release は default branch 反映後にだけ作る。branch-only release は未完了として扱う
- **失敗は transparent**: 途中で失敗したら自動ロールバックは試みず、ユーザーに現状を提示して判断させる
- **プロジェクト非依存**: VERSION file 形式、mirror、residue check など特定環境の前提を持たない。本体 harness 固有の処理は `harness-release-internal` に分離

