45395 - シコウサクゴ -

SessionEnd hook で次段階 Issue を自動起票する:PR マージ後のワークフロー分断を防ぐ仕掛け

施策の PR をマージした後、「次に何をやるんだっけ」と数日空白ができることが何度かありました。仕様上は「次フェーズに入る」のが自明でも、Issue として明示されていないと忘れます。

Claude Code の SessionEnd hook を使って、施策完了時に次段階の Issue を自動起票 する仕組みを作りました。設計と運用してみての気づきを書きます。

何が起きていたか

「完了」の解像度の低さ

施策を /spec ワークフローで進めて、PR がマージされる。そこで「施策完了」と認識して別の作業に移る。が、本来は次のような 連続したフェーズ が想定されていました。

1
Phase A: 機能実装(PR マージ)
2
↓ 1〜3 日後
3
Phase B: 翌日監視・指標確認
4
↓ 1 週間後
5
Phase C: 効果測定レポート
6
↓ 必要なら
7
Phase D: 改善 PR

PR マージ → 別の作業に移る → Phase B〜D が抜け落ちる。気づいたら 1 ヶ月後で「あの施策、結局効果あったんだっけ?」状態。

Issue が手動だと忘れる

GitHub Issue を立てておけば追えるのですが、PR マージ時に 手動で次フェーズの Issue を起票する のは結構面倒で、忘れます。

「自動化したい」と思ったとき、ちょうど Claude Code の hooks 機能が使えると気づきました。

設計:SessionEnd hook で次 Issue を起票

Claude Code の hooks 概要

Claude Code には複数のライフサイクル hook があります(SessionStart, PreToolUse, PostToolUse, SessionEnd など)。シェルコマンドを設定で書ける形です。

.claude/settings.json
1
{
2
"hooks": {
3
"SessionEnd": [
4
{
5
"hooks": [
6
{
7
"type": "command",
8
"command": "bash .claude/hooks/session_end.sh"
9
}
10
]
11
}
12
]
13
}
14
}

起票判定のロジック

毎セッション終了時に Issue を立てると Issue が爆増します。特定の条件を満たしたときだけ起票するようにしました。

.claude/hooks/session_end.sh
1
#!/bin/bash
2
set -euo pipefail
3
4
# 直近の commit メッセージから施策完了マーカーを検出
5
last_commit_msg=$(git log -1 --pretty=%s)
6
7
# 施策完了パターン: 「feat(measure-xxx): C-11 マージ」など
8
if [[ "$last_commit_msg" =~ ^feat\(measure-([a-z0-9-]+)\):.*C-11 ]]; then
9
measure_name="${BASH_REMATCH[1]}"
10
create_followup_issues "$measure_name"
11
fi

「コミットメッセージのパターン」をトリガーにすると、誤発動が減ります。/spec ワークフローの最終ステップ C-11 のコミットだけが対象になります。

Issue テンプレート

施策ごとに「次にやるべきこと」が違うので、テンプレートを .docs/issue_templates/ に置いて、施策名で選びます。

Terminal window
1
create_followup_issues() {
2
local measure="$1"
3
local template_dir=".docs/issue_templates"
4
5
# Phase B: 翌日監視
6
local body_b=$(cat "$template_dir/post_deploy_monitoring.md" \
7
| sed "s/{measure}/$measure/g")
8
gh issue create \
9
--title "[$measure] Phase B: 翌日監視・指標確認" \
10
--label "phase-b,auto-generated" \
11
--body "$body_b"
12
13
# Phase C: 1 週間後の効果測定
14
gh issue create \
15
--title "[$measure] Phase C: 効果測定レポート" \
3 collapsed lines
16
--label "phase-c,auto-generated" \
17
--body "$(cat "$template_dir/effect_measurement.md" | sed "s/{measure}/$measure/g")"
18
}

Issue の本文に「いつやる」を入れる

ただ Issue を立てるだけだと優先順位がつかないので、**「実施推奨日」**を本文に書きます。

1
## 実施推奨日
2
2026-05-09(PR マージから 1 週間後)
3
4
## チェックリスト
5
- [ ] launchd ジョブのログを確認
6
- [ ] エラー件数の推移を確認(before/after)
7
- [ ] アラート発生件数の推移を確認
8
- [ ] 効果測定レポートをコメント追記

gh issue list --label phase-c --state open で「今週やるべきこと」が一覧できます。

運用してみての気づき

効いた点

1. 「次やること」が消えなくなる

PR マージから 1 週間経つと、自分でも何をやっていたか忘れます。Issue に「実施推奨日」とチェックリストが残っていると、その日に GitHub の Issue 一覧を見れば思い出せます。

2. 施策ごとの「フォローアップ密度」が見える

gh issue list --label auto-generated --state closed で、過去の施策がきちんとフォローアップまで完了しているかが見えます。「Phase B は完了したが Phase C が未着手」のパターンが可視化されました。

3. AI エージェントへの委譲がしやすくなる

Issue があれば「この Issue の内容を実行してほしい」と Claude Code に渡せます。フォローアップ作業も AI に任せやすくなりました。

踏んだ罠

罠 1: hook が毎セッションで発火して Issue 重複

最初は SessionEnd で無条件に起票していたので、同じ施策で 同じ Issue が 5 個 立ったことがありました。

修正: コミットメッセージのパターンマッチで、C-11 を含むものだけに絞り込み + Issue タイトルで重複検査。

Terminal window
1
# 既存 Issue のチェック
2
existing=$(gh issue list --label "phase-b" --search "[$measure]" --json number)
3
if [[ "$existing" != "[]" ]]; then
4
echo "Issue already exists for $measure, skipping"
5
return
6
fi

罠 2: hook 内のエラーがセッションを止める

hook の bash スクリプトでエラーが起きると、Claude Code のセッション自体に影響が出ました(具体的には次セッション起動時に hook 失敗のメッセージが)。

修正: hook 内では絶対に exit 非ゼロを返さない。

Terminal window
1
# 末尾
2
exit 0 # 何があっても 0 で終わる

エラーログだけは別ファイルに残して、後で見られるようにします。

Terminal window
1
{
2
set -euo pipefail
3
# ... main logic
4
} 2>> /tmp/session_end_hook.log || {
5
echo "$(date) hook failed, see log" >> /tmp/session_end_hook.log
6
}
7
exit 0

罠 3: gh コマンドの認証

CI 環境やリモート環境で hook が動くとき、gh コマンドの認証が通っていないと黙って失敗します。

Terminal window
1
if ! gh auth status &>/dev/null; then
2
echo "gh not authenticated, skipping issue creation" >&2
3
exit 0
4
fi

認証チェックを先に入れて、未認証なら何もしない方針にしました。

罠 4: テンプレートの変数置換ミス

sed "s/{measure}/$measure/g" で施策名を埋め込んでいましたが、施策名にスラッシュやドル記号が含まれると sed がエラーになります。

修正: bash の文字列置換を使う。

Terminal window
1
body=$(cat "$template_dir/post_deploy_monitoring.md")
2
body="${body//\{measure\}/$measure}" # bash 内蔵の置換

特殊文字を含む文字列でも安全です。

さらなる発展

Issue → AI エージェントへの自動委譲

Issue 起票時に claude-code-bot のようなラベルをつけると、別の自動化で AI エージェントに委譲する仕組みも考えられます(GitHub Actions と Claude Code SDK の組み合わせ)。

ただし、本番環境への影響がある作業を完全自動化するのはリスクが高いので、人間のレビューが入る Issue にとどめる 設計にしています。

Issue の自動クローズ

「実施推奨日」を過ぎた Issue が放置されているケースを検知し、毎週月曜にリマインドする bot も使っています。

.github/workflows/remind_followup.yml
1
on:
2
schedule:
3
- cron: "0 0 * * 1" # 毎週月曜 0:00
4
jobs:
5
remind:
6
runs-on: ubuntu-latest
7
steps:
8
- run: |
9
gh issue list --label "auto-generated" --state open \
10
--json number,title,createdAt \
11
| jq -r '.[] | select((now - (.createdAt | fromdate)) > 604800) | .number' \
12
| xargs -I {} gh issue comment {} --body "1 週間以上未着手です"

まとめ

観点設計方針
トリガーコミットメッセージのパターンマッチ(誤発動防止)
Issue 内容実施推奨日 + チェックリスト
重複防止既存 Issue のタイトル検索
エラー処理hook 内では exit 0、ログだけ残す
拡張性施策ごとにテンプレートを差し替え可能

PR マージ時の「次何やるんだっけ」空白は、自動 Issue 起票で構造的に埋められる問題でした。

Claude Code の hooks 機能はシェルスクリプトを書けるので、GitHub の gh コマンドと組み合わせて、ワークフローの隙間を自動化するのに非常に有効です。施策の連続性を保つ仕掛けとして、運用負荷を下げる効果が大きかった改善でした。

Article title:SessionEnd hook で次段階 Issue を自動起票する:PR マージ後のワークフロー分断を防ぐ仕掛け
Article author:45395
Release time:2026-05-06

記事へのご質問・ご感想をお聞かせください

フィードバックを送る