一覧に戻る

ブログ

通知はアプリを開くだけでなく、正しい Session に戻すべきだ

push 通知は届いただけでは不十分です。複数 session の AI コーディングでは、正しい server、session、現在状態と一緒に届く必要があります。1.6.6 が直したのはその文脈復帰の経路です。

公開日 タグ: product / workflow / notifications / engineering
ブログ

このカテゴリのプロダクト/開発アップデートを確認できます。

カテゴリを見る

私たちは通知を「届いたかどうか」の問題として語りがちです。どれだけ速いか、ロック画面に出るか。それでも、リモート AI コーディングではその捉え方では足りません。

通知ができることが「アプリを開く」だけなら、フィードバックループは閉じていません。どのマシンか、どの session か、Claude が承認を求めているのか完了を知らせているのか、それが今見ているタスクなのか、少し前にバックグラウンドへ置いた別 session なのかを、結局自分で復元しなければならないからです。

これは文言の問題でも、アニメーションの問題でもありません。完全な状態同期の問題です。

なぜ AI コーディングではこの問題がより深刻なのか

普通のアプリでは、通知はたいてい 1 つの対象にきれいに対応します。メール 1 通、メッセージ 1 件、予定 1 件。タップした先の対象も自然に決まります。

リモート AI コーディングはそうではありません。

同時に 3 つの session が走っているかもしれません。

  • 1 つはモジュールをリファクタ中
  • 1 つはテスト結果待ち
  • もう 1 つは承認待ちで停止中

この状況で「Claude があなたを必要としている」だけでは意味がありません。本当に必要なのは次の情報です。

  • どの server から通知が出たのか
  • どの session が通知を発火したのか
  • その session が今どんな状態なのか
  • ユーザーがすでにその session を見ているのか

どれか 1 つでも欠けると、通知は曖昧な割り込みに退化します。集中を切ることはできても、次に何をすべきかは教えてくれません。

通知は「届かない」だけで壊れるわけではない

多くのシステムは通知の信頼性を「落とさないこと」だと捉えます。でも複数 session のワークフローでは、もう 1 つ同じくらい悪い失敗があります。通知は届いたのに、間違った文脈へ戻してしまうことです。

この失敗は完全に失われるより気づきにくく、しかも危険です。

ユーザーは正しい場所へ戻ったと思い込み、そのまま間違った session で操作を続けます。リモート AI コーディングではそれが次のような誤操作につながります。

  • 間違った repository で Claude に返信する
  • 間違った task を承認する
  • ある session の状態を別 session の状態だと誤認する

見た目には単なる遷移バグです。でもプロダクトとしては、リモートワークフロー全体への信頼を壊します。

通知を有用にするには、文脈が経路全体を生き残る必要がある

有用な通知は APNs payload だけでは成立しません。文脈は次の経路全体を通って失われずに残る必要があります。

  1. server hook event が作られた時点で、どの tmux_session が起点か分かっていること
  2. server が通知を broadcast する時に session を含めること
  3. push relay が dedupe する時に project だけでまとめず、session も区別すること
  4. app が cold start する時に、push の server identity をローカル保存済みの server に再対応付けできること
  5. 最終的な navigation で、正しい server に戻ったあと正しい session を選び、デフォルト画面に落ちないこと

どこか 1 箇所でも「とりあえず推測」で埋めると、最終的な挙動は不安定になります。

だからこそ 1.6.6 の通知関連の修正は iOS、Mac、server、push relay に分散して見えます。それでも本質的には同じ問題を直しています。通知を単なるリマインダーではなく、実行可能な文脈入口にすることです。

旧モデルはどう壊れていたのか

問題を抽象化すると、旧モデルには 4 つの典型的な失敗パターンがありました。

1. source event には session があるのに、通知には session がない

server 上の hook event は特定の tmux_session 由来だと分かっているのに、通知 broadcast は「通知があった」としか伝えない。その瞬間、client は「今アクティブな session に戻る」くらいのことしかできなくなります。

これが危険なのは、通知をタップすると一応どこかへ遷移するので、機能が存在しているように見えることです。実際には destination が間違っているのに、です。

2. foreground で動くことと cold start で動くことは別問題

アプリが生きている状態で通知遷移がうまく見えるのは珍しくありません。本当に難しいのは cold start です。なぜなら app はまだ完全に状態復元していないからです。

その時点では server list がロード中かもしれないし、navigation state もまだないかもしれません。ローカル ID と push payload の識別子も一致していない可能性があります。早すぎる navigation は、たいてい次のどちらかになります。

  • 何も開かない
  • 開いたが、間違った server か session に落ちる

3. dedupe が 2 つの session を 1 つの event とみなしてしまう

もし push relay の dedupe key が server + project + event だけで、session を含まないなら、同じ project の 2 つの session が近い時間に発火したとき、後の通知が前の通知に吸収されることがあります。

これは crash には見えません。最も調べにくいユーザー報告になります。「task は終わったのに、なぜ通知が来なかったのか。」

4. client が「見えている session」と「通知の source session」を混同する

これは複数 session プロダクトでよくある modeling error です。今 UI が focus している session と、通知を出した session は同じ概念ではありません。state model がそれを分けていなければ、誤遷移は避けられません。

1.6.6 が直したのはボタンではなく経路だった

この release の重要点は「通知タップで遷移できます」という文ではありません。いくつかの切れた制約がやっと接続されたことです。

1. 通知が session identity を持つようになった

以前は session B の event なのに、client には「何か通知があった」としか見えず、session A に戻ってしまうことがありました。1.6.6 では session identity が notification broadcast と push payload を通過します。通知は単に「Claude が何かを求めている」ではなく、「repo-x / session-y が何かを求めている」を意味するようになります。

難しかったのは UI 遷移そのものではありません。identity mapping です。push が持つのは server 側 identity、app が持つのはローカル object ID。cold start routing は、この 2 つの identity system を和解させて初めて本物になります。

つまり問題は「どう page を切り替えるか」ではなく、「これは同じ server だと system がどう証明するか」でした。

3. push delivery が session を optional metadata 扱いしなくなった

dedupe key に session がないと、同じ project の別 session が互いを消してしまいます。ここから分かるのは、AI workflow において session は付随情報ではなく、通知の意味そのものの一部だということです。

4. local notification、remote push、navigation がやっと同じ意味を共有し始めた

通知パイプラインで最悪なのは層ごとの意味のずれです。

  • server は「これは hook event だ」と言う

  • push service は「これは project-level alert だ」と言う

  • client は「では current page に戻っておこう」と言う

    1.6.6 の本当の価値は、これらの層が 1 つの目標に揃い始めたことです。イベントを出した server と session にユーザーを戻すことです。

これは engineering 問題である前に product 問題でもある

ここまで ID、payload、deep link の話ばかりに見えたかもしれません。でも、その下にはもっと大きな product の判断があります。

通知は、ユーザーを「意思決定が必要な正しい場所」へ戻す mechanism であるべきか。

答えが yes なら、delivery rate だけでは不十分です。通知は同時に 3 つの条件を満たす必要があります。

  • 届くこと
  • 正しい場所に落ちること
  • 落ちた瞬間に行動できること

この基準で見ると、多くのプロダクトの通知は 1 つ目しか満たしていません。

ユーザーが実際に感じる変化は何か

実装を無視して日常利用だけを見るなら、1.6.6 は少なくとも 4 つの結果を改善します。

  1. 通知タップが間違った session に落ちにくくなる
  2. lock screen や terminated state から app を起こしても文脈を失いにくくなる
  3. 一時的な network failure で通知が丸ごと失われにくくなる
  4. Live Activity の異常系 state が以前より信頼できるものになる。force-quit edge case は残るとしても

どれも単体では派手ではありません。でも合わせると、もっと重要な問いに答えます。複数の AI session を本当に background で走らせるだけの信頼を置けるかという問いです。

reliability とは、境界を正直に書くことでもある

1.6.6 では Live Activity cleanup path も見直しました。relaunch 時に stale activity を整理し、orphan reference を消し、短い切断のあとに誤って "Finished" と出る可能性を下げています。

ただし、release note で解決済みのように装わなかった edge case が 1 つあります。ユーザーが iOS app を force-quit すると、Live Activity は次回 launch か system timeout まで残ることがあるという点です。

ここを「完全修正」と書けば短期的には見栄えが良くなります。でも長期的にはプロダクトの信頼を下げます。developer tool では特にそうです。売っているのは雰囲気ではなく、予測可能性だからです。

本当の目標は通知を増やすことではない

優れた remote AI product は、通知を受け取るたびにユーザーへ「今何が起きたか」を再構築させるべきではありません。

通知が本来やるべきことは、その文脈回復を先回りして済ませておくことです。

remote AI coding では、delivery は入場券にすぎません。文脈がくっついたまま届くかどうかで、それが有用な入力になるのか、ただの割り込みになるのかが決まります。

1.6.6 は通知も複数 session も発明していません。もっと基本的で、もっと価値のあることをしました。この 2 つを、やっと正しく協調させたのです。

Tactic Remote を試す

スマートフォンからコーディングエージェントを操作

Mac、Windows、Linux 上の Claude Code や Codex などに接続。iPhone や iPad で進捗を確認し、次の指示を送れます。