あなたが Claude Code に任せたコミットは、もしかすると公開リポジトリに「あなたのプライベートなセッションの URL」を書き込んでいるかもしれません。
GitHub の issue #69669 で、ある利用者がこう報告しています。Claude Code(Opus 4.8)が、6 つのコミットすべてのメッセージの末尾に
Claude-Session: https://claude.ai/code/session_<id>
という行を付け、その private なセッションの識別子を公開の GitHub リポジトリに公開してしまった、というものです。報告者によれば、これはリポジトリ側の設定(CLAUDE.md・git hook・commit.template)にも、利用者やグローバルの設定にも書かれておらず、ハーネスの側の指示だけが出どころだといいます。本人が頼んだ覚えはない、と。
これは伝聞なので、私自身の環境でこの行が必ず出ると断定はしません。実際、私の手元の Claude Code は Co-Authored-By: の行は付けますが、Claude-Session: の URL は今のところ見ていません。出るかどうかは版や設定に依存するようです。ただ、出る環境では、認証が要るとはいえ、本来コミットの履歴に要らない private な識別子が公開の成果物に残り続ける——これはデータの最小化の観点で気持ちのいいものではありません。報告者の懸念はもっともだと思います。
この記事では、(1) 自分のリポジトリが漏らしていないかの確認、(2) これから漏らさないための検知と停止、(3) もう漏れてしまっていた場合の対処、の 3 つを順に書きます。
1. まず自分の履歴を確認する
公開しているリポジトリで、次の 1 行を走らせてみてください。
git log --all --grep='claude.ai/code/session' --grep='Claude-Session' -i --oneline
何も出なければ、そのリポジトリは(少なくとも -m で書かれたコミットの範囲では)漏らしていません。出てきたら、そのコミットのメッセージに private なセッションの URL が入っています。
ついでに、同意なく付いている Co-Authored-By: の行も見ておくとよいです。
git log --all --grep='Co-Authored-By: Claude' -i --oneline | wc -l
2. これから漏らさない——コミットの前で止める
一番確実なのは、コミットが走る前に検知して止めることです。Claude Code の PreToolUse の hook は、ツールの呼び出しの前に発火します。git commit -m "..." の形ならメッセージがコマンドの文字列に乗るので、そこにセッションの URL があれば、その時点で弾けます。
ここで一つ、正直な但し書きがあります。PreToolUse の hook はコマンドを「止める」ことはできますが、「書き換える」ことはできません。 だから、trailer をこっそり取り除くのではなく、コミットを差し戻して、モデルにその行を消させてから commit させ直す、という動きになります。
#!/bin/bash
# git commit のメッセージに private なセッションの URL が含まれていたら止める。
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
[ -z "$COMMAND" ] && exit 0
# 先頭でも 「cd repo && git commit」 の形でも捕まえる
echo "$COMMAND" | grep -qE '(^|[;&|[:space:]])git[[:space:]]+commit' || exit 0
if echo "$COMMAND" | grep -qiE 'claude\.ai/code/session|Claude-Session:'; then
echo "✖ コミットのメッセージに private なセッションの URL が含まれています。" >&2
echo " 'Claude-Session: https://claude.ai/code/session_...' の行を消してからやり直してください。" >&2
exit 2
fi
exit 0
これを settings.json の PreToolUse に、Bash を対象に、"if": "Bash(git commit *)" で配線します。
{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [
{ "type": "command", "if": "Bash(git commit *)", "command": "~/.claude/hooks/no-session-trailer.sh" }
] } ] } }
念のための確認の手順も書いておきます。お使いの版で hook が実際に発火するか、payload のどの欄にコマンドが入るかは、まず 1 行のログの hook を仕込んで、本物のコミットを 1 回観測してから本番の hook を信じるのが安全です。
# 観測用: 何が来ているかを記録するだけ
jq -c '{tool_name, command: .tool_input.command}' >> /tmp/pretooluse.log; exit 0
なお、この検知が効くのは git commit -m "<メッセージ>" の形だけです。エディタを開く形や -F <ファイル> の形では、メッセージがコマンドの文字列に乗らないので、hook からは見えません。だからこれは「最後の砦」ではなく「層の一つ」として入れてください。本筋は、そもそも既定の指示がこの URL を付けないことです。
3. もう漏れていた場合
すでに公開のリポジトリに push 済みなら、履歴の書き換えが要ります。
# 例: メッセージから該当の行を除く(履歴を書き換える)
git filter-repo --message-callback '
return re.sub(rb"^.*Claude-Session:.*$\n?", b"", message, flags=re.M)
'
そのあと force-push になります。ただし、履歴の書き換えは、共同で作業している相手の clone を壊したり、PR の参照を狂わせたりします。 影響の範囲を見てから判断してください。個人の小さなリポジトリなら気軽にやれますが、人が増えるほど慎重に。
まとめ
- Claude Code が、版や設定によっては、コミットのメッセージに
Claude-Session:の private な URL を付けて公開のリポジトリに残すことがある(#69669 の報告)。 - まず
git log --grepで自分の履歴を確認する。 - これからは
PreToolUseの hook で、そういうコミットを止める(ただし-mの形のみ・書き換えはできず差し戻す)。 - もう漏れていたら
git filter-repoで除いて force-push(共同作業では慎重に)。
この記事の hook は、私が無料で公開している cc-safe-setup(MIT)の strip-coauthored-by.sh に入れてあります。もともとこの hook には、Co-Authored-By の検知の正規表現が壊れていて何も検知できていなかったというバグがあり(grep -E で \| が「文字のパイプ」として扱われ、本来の「または」にならない)、今回そこも直してあります。コミットの trailer まわりで似た hook を使っている方は、自分のものが本当に検知できているか、一度 1 件の本物のコミットで試してみることをおすすめします。
私自身が 800 時間ほど Claude Code を「ほぼ無人」で動かして踏んだ事故と、設定で先回りして防ぐ手順は、事故防止の本(¥800・第 3 章まで無料)にまとめています。データやコードの消失、トークン費用の暴走、無断の課金といった、止められたはずの事故が中心です。