通知設定機能を作った一日、Claude Codeセッションの乗り継ぎ方

「あのセッション、どれだっけ」。ピッカーを開いて、似たようなタイトルの行が並ぶ画面を睨んだ経験がある人は少なくないと思う。私も先日、通知設定機能を1日かけて実装した日に、まさにこれをやらかした。/new/rename/resumeはそれぞれの使い方を知っていても、1日の中で実際にどう乗り継ぐかは、コマンド単体の説明を読んだだけでは掴みにくい。今回はその1日をほぼそのまま再現しながら、判断に迷った場面や実際に手間取った場面も含めて書いていきたい。

9:00 — 仕様を固めて区切り、それから名付ける

その日のタスクは、ユーザーごとにメール・プッシュ・Slack通知のオンオフを切り替えられる、通知設定画面の追加だった。複数日にまたがるのが分かっていたので、後から迷わず戻れるようにはしたい。ただこの時点ではまだ仕様を詰める段階で、この後/clearで区切ることも決まっている。名前を付けるのはそこから先で十分だと考え、ひとまず素のclaudeでセッションを始めた。

いきなり実装には入らず、「Interview me」と伝えてClaudeに逆質問させながらSPEC.mdを作る進め方を取った。ここで想定外の引っかかりが出た。Claudeが「この機能は、既存のnotification_level(none/important/all の3段階)とどう共存させますか」と聞いてきたのだ。今回作りたいのはチャネルごとの細かいオンオフだが、既存のユーザー設定テーブルにはすでに別の粒度の概念がある。整理を先送りすると後で作り直す羽目になる話だったので、その場でSlackの同僚に確認を取り、既存のenumは残しつつ新しくnotification_channel_settingsという別テーブルを切る方針に決め、SPEC.mdへ書き足した。

SPEC.mdが固まったのは9時40分ごろ。ここで同じセッションのまま実装に進まず、/clear/newでも同じ)で一度区切った。理由は「作法だから」ではない。ここまでの会話には、enumを使い回す案を検討して却下した経緯が50往復近く積まれている。このまま実装に入ると、却下したはずの案をClaudeが途中で持ち出してくる懸念があった。判断の経緯はSPEC.mdに残してあるので、実装セッションは判断をやり直す必要がない。だからこそ意図的に区切った。

区切った直後、いつもの癖で最初から-n notif-settingsのように名付けておけばよかったかと一瞬考えたが、これは以前別の作業で一度やらかしている。先に名付けてから/clearすると、区切った直後は名前が一瞬消えたように見えることがあるものの、実際には新しいセッション側にもその名前がそのまま引き継がれる。結果、区切る前のセッションと区切った後のセッションが同じ名前で2つ並ぶことになり、後で/resumeのピッカーを開いたとき、同名の行がそのまま並んでいてどちらが作業中の方なのか一瞬で判別できなくなった。GitHub Issue #61172でも、/clearが名前をリセットせず前のセッション名を引き継いでしまい、/resumeに同名セッションが重複して並ぶという同じ症状の報告がある。だから今回は、/clearで区切った直後のこの実装セッションに対して初めて/rename notif-settingsと打ち、名付けは区切った後に一度だけ行うことにした。これなら同じ名前が2つできる余地がない。/newが実は/clearの別名に過ぎない話や/renameの細かい操作は、以前書いた『Claude Codeのセッションを区切る・名付ける・再開する技術』という記事に譲る。

11:00 — 認証バグの割り込みに、branchでなくworktreeを選んだわけ

実装が半分ほど進んだ11時、Slackに「2段階認証(2FA)を有効にしているはずのユーザーが、2FAの入力なしでログインできてしまう」という報告が飛んできた。急ぎ対応が必要だが、今動いているnotif-settingsのセッションは潰したくない。

最初に頭をよぎったのは/branchだった。ただ/branchは同じプロセス内で分岐先に切り替える仕組みで、今のプロセスはバグ調査に専念することになる。実装セッションは見た目上残っていても実質的に手が止まる。さらに、通知設定の実装で触っていたuser_settings.rbが、認証まわりの2FA検証ロジックからも参照される共通ファイルだったことが気になった。同じ作業ディレクトリで両方のセッションが同時にファイルを触ると、編集がぶつかる懸念がある。そこで別ターミナルを開き、--worktreeで物理的に別ディレクトリを切ったセッションを新規に立ち上げた。ファイルを隔離しておけば、実装セッションを止めずにバグ調査を並走させられる。

急いでいたせいで、このセッションには名前を付けなかった。「どうせ5分で終わるだろう」と思ったからだ。この判断が、夕方に効いてくる。

原因の見立てを外し、Claudeへの訂正を3回ほど繰り返して迷走しかけたので、途中で/clearしてプロンプトを書き直した。訂正を重ねるより仕切り直した方が早いという話は前述の記事で扱った通りで、ここでは深掘りしない。

余談だが、worktree越しに作ったセッションが必ず/resumeで戻れるとは限らないらしい。GitHubのIssueでは、EnterWorktreeツールなどが自動生成するworktreeセッションは一時的な扱いになり--resumeで呼び出せないという報告があった(このIssue自体は重複扱いで既にクローズ済みだが、報告内容そのものは具体的だった)。一方で公式ドキュメントは、--worktreeフラグで起動したセッションは「resumeすればそのworktreeに戻る」と明記している。突き合わせる限り、フラグ経由かツール任せかで扱いが違いそうだ、という程度の理解でその場は進めた。今回は自分でターミナルから--worktreeを打って起動しているので、困らないはずだと判断した。

13:00〜16:00 — resumeで戻り、forkでレビューを裏で走らせる

13時、バグの原因を特定し、修正パッチを書き終えた。/resume notif-settingsで通知設定の実装セッションに戻った。戻った直後、設定ファイルを編集するたびに確認を求められることに気づいた。「さっきまで許可されていたのに」と一瞬戸惑ったが、権限モードが/resumeでは引き継がれない仕様のせいだった。この点の詳細は先述の記事で扱っている。

実装が形になったのが16時。次はレビューだ。ここでは/branchではなく/forkを選んだ。実装セッションをまだ生きたまま手元に残しておきたかったからだ。レビュー中に軽微な修正が必要になったとき、すぐ実装セッションに戻って直せる。/forkならコピーがバックグラウンドで新規作成され、元のセッションはフォアグラウンドのまま残る。

ところが、このレビューに思ったより時間がかかった。/forkは会話のコピーを引き継ぐが、9時40分に/clearで区切った後の会話しか持っていない。朝のインタビューで「なぜenumを使い回さず別テーブルにしたか」を検討した経緯は、レビューセッションの文脈にはない。実際、レビュー担当のセッションは「既存のnotification_levelで足りないのか」と、朝すでに決着した論点を蒸し返してきた。SPEC.mdの決定の経緯を読ませて説明し直す一手間が発生し、想定より15分ほど余計にかかった。区切ったこと自体は間違っていなかった。ただ、区切った先に置いた判断根拠まで後から参照するセッションに毎回渡し直す必要があるとは、正直このときまで想定していなかった。

17:00 — 名付け忘れたセッションが行方不明になる

気づけば17時を回っていた。レビューの指摘を反映し終え、朝の認証バグセッションに戻ろうと--resumeでピッカーを開いた。そこで固まった。

画面に並んでいたのは、名前ではなく会話内容から自動生成されたタイトルの行だった。「Investigate 2FA bypass issue」「Check auth token validation」「Debug MFA verification skip」。似た文言が3、4行続けて並び、どれが今日の続きなのか経過時間とタイトルの文字面だけでは判断がつかない。バグ調査の途中で無関係な調査のため一瞬別セッションを開いたことも重なり、候補がさらに増えていた。仕方なく1行ずつプレビューを開いて中身を覗き、ようやく目的のセッションを見つけた。

数分とはいえ、実装や調査そのものより「どのセッションだったか探す」ことに時間を使ったのは、正直かなり情けなかった。11時の時点で名付けていれば、少なくとも自動生成タイトルの海に埋もれることはなかったはずだ。ただし、それで完全に一瞬で終わったとまでは言い切れない。迷走の途中で/clearした瞬間、9時40分のときと同じ理屈で、名前は消えずに新しいセッション側へそのまま引き継がれる。つまり11時に名付けていたとしても、/clearのたびに/renameし直さない限り、結局は同じ名前が2つ並ぶ状態を自分で作っていたことになる。11時にセッションを分けた判断そのものは正しかった。ただ名付けを怠ったばかりに、その効果が丸ごと吹き飛びかけた。見つけたセッションで朝の議論の続きから修正を仕上げ、その日の作業は終わった。

名付け忘れを防ぐには——そして、次に活きること

この日の一番の反省は「区切る」だけでは不十分で、「名付ける」を組み合わせて初めて意味を持つ、ということだった。急ぎの作業ほど名付けを後回しにしがちで、しかも急ぎの作業ほど後で戻ってくる可能性が高い。矛盾した習性だと思う。

対策として、コミュニティで見かけた運用を1つ試すことにした。CLAUDE.mdに命名規則を書いておき、会話が2〜3往復進んだ時点でClaudeが自動的に/renameするよう仕込む、という非公式のプラクティスだ。名前は「動詞+対象」の形式(fix mfa bypassのように)で50文字以内、複数の話題にまたがるセッションでは支配的なテーマを1つ選ぶ、というルールになっている。あくまで個人のリポジトリで紹介されている一例で、Anthropicの公式推奨ではない。念のため触れておくと、/clearは名前を引き継ぐ挙動なので、この自動命名も直後の数往復は古い名前のまま始まる。9時40分のように区切った瞬間から次のテーマが決まっている場面では、待たずにその場で手動/renameする方が早い。それでも、急いでいるときほど自分の判断を信用できないという実感があったので、仕組みで補う方に一票入れたい。

/resumeのピッカー操作やセッションの保存場所については『Claude Code の /resume を使い倒す — -c だけじゃないセッション管理の全貌』という記事に詳しく書いてある。今回書きたかったのは、その1つ1つの操作が、1日の実際の作業の中でどんな順番と理由で繋がっていくかという部分だ。

今日、何か新しいセッションを開くときに、名前を付けるかどうか一瞬だけ立ち止まってみてほしい。「5分で終わるはず」と思った作業ほど、後から探す羽目になる。

参考リンク

コメント

タイトルとURLをコピーしました