
Claude Codeのルーチンでラベル付きIssueをサンドボックスのPRにする — 追加の質問はできない
Claude Codeのクラウドルーチンを2つの使い捨てGitHub Issueで検証しました。ラベルを付けると本物のPRがサンドボックスから届きますが、ルーチンにはAskUserQuestionツールがありません。
目次
はじめに
Claude Codeが「cowork」と呼ばれるクラウド機能を提供していると聞きました。サンドボックスを起動し、GitHub Issueを渡せば、マシンを起動したままにしなくてもスマートフォンから結果を確認できるという機能です。実際に何かを任せる前に、宣伝文句だけでなく、このワークフローが日々どう動くのか知りたいと思いました。このブログにはすでにリリースパイプラインがあり、鋭い落とし穴もいくつか抱えているため、監督なしでルーチンに間違ったことを静かにやらせたくなかったからです。2つの使い捨てGitHub Issueを経て、答えは1つの欠けたツールに行き着きました。Claude CodeのルーチンはAskUserQuestionをまったく呼び出せません。これは「Issueにラベルを付ければあとは任せられる」という触れ込みが想定していないことです。この記事では、最初にぶつかったセットアップの摩擦、悪い設計のまま実行されていたら何も証明できなかったはずのテスト、その発見そのもの、ドキュメントの記述に反して届いた通知、そしてこの制約を踏まえてこのブログで実際にルーチンへ任せる価値があるものについて扱います。
表示されなかったプライベートリポジトリ
最初のつまずきは、まだルーチンとは関係ありませんでした。このブログのリポジトリはプライベートで、claude.ai/codeのリポジトリピッカーに単純に表示されなかったのです。名前を入力すると「No repos match」と返ってきました。

プライベートリポジトリ自体はサポートされていますが、このリポジトリがアクセスを許可するアプリの対象に含まれていなかっただけでした。 Claude GitHub Appはインストール時に、アカウント上のすべてのリポジトリを見せるか、選択したリポジトリだけを見せるかを尋ねてきますが、このリポジトリはその一覧に追加されていませんでした。

github.com/settings/installationsでアプリのリポジトリアクセスを再設定し、再接続することで解決しました。これはその修正とは別に、文書化された繰り返し起きる不具合でもあります。Anthropic自身のIssueトラッカーには、アプリが実際にアクセス権を持っているはずのプライベートリポジトリが表示されない、あるいは断続的に消えるという報告がいくつもあり、アカウント設定の問題というよりバックエンドのインデックス処理の問題として読めます。
ラベルを付けた使い捨てファイル
リポジトリにアクセスできるようになったところで、最初の本番テストにはルーチンを使いました。保存されたプロンプトとGitHubトリガーを1度だけclaude.ai/code/routinesで設定するものです。タスク固有のプロンプトを書く代わりに、ルーチンの指示はあえて汎用的にしました。トリガーとなったGitHub Issueを読み、書かれている通りにそれだけを行う、というものです。

エージェントは使い捨ての最初のタスクを提案しました。決まった一文だけを含む使い捨てファイル(docs/cloud-agent-shakedown.md)を1つ作り、他には一切手を触れず、リポジトリ自身のpnpm checkを実行し、マージはせずにPRを開く、というものです。これをGitHub Issueに書き、専用のcloud-agent-testラベルをそのIssueに付けることでルーチンを起動させました。
![「[test] Cloud agent shakedown」というタイトルのGitHub Issue。ラベルパネルが開いており、cloud-agent-testラベルを付けようとしている](/_astro/issue-166-apply-label.D6asaGIu_ZUV4UN.webp)
無人のまま、1回目の試行できれいに動きました。 ルーチンはリポジトリをクローンし、依頼された1つのファイルだけを作成し、検証スイートを実行し、実際のコマンド出力を本文に貼り付けたPRを開きました。
$ astro check && pnpm run check:types && pnpm run check:i18n …
05:57:16 [check] Getting diagnostics for Astro filesResult (244 files):- 0 errors- 0 warnings- 0 hints誰にも頼まれていないことまで報告していました。 リポジトリに固定されたNodeバージョンについての、無関係で以前から存在していたUnsupported engineという警告を、黙って無視するのではなくPRに書き添えていたのです。小さなことですが、これはこのブログ自身のツール運用の方針が求めている振る舞いそのものであり、ルーチンは指示されないままそれをやってのけました。
自分で質問に答えても、ルーチンの検証にはならない
次の疑問は、ルーチンがタスクの途中で本当の判断を止めて待ち、後からスマートフォンでの返信によって再開できるかどうかでした。これがこの機能の「手放しでいい」という宣伝文句の半分に当たる部分だからです。そのテストの最初の設計は間違っていて、実行される前に気づけてよかったと思っています。計画は、スマートフォンから直接セッションを開き、AskUserQuestionの呼び出しを強制するプロンプトを貼り付けて、その場で答えるというものでした。
自分で始めて自分で見ているセッションでは、無人実行のパスを検証できません。 自分が能動的に進めている会話の中で質問に答えても、証明できるのはライブの会話が機能するということだけで、それは最初から疑っていませんでした。本当に知りたかったのは性質の異なる主張です。誰も見ていない状態でトリガーによって起動された実行が、止まって待ち、後からスマートフォンの返信で再開できるかどうかでした。
再設計では、最初のテストと同じ汎用ルーチンを使い回しました。2つ目の使い捨てIssueは同じ種類の使い捨てファイルを求めるものですが、今回はルーチンが何かを作成する前にAskUserQuestionを呼び出して答えを待つ必要があり、トリガーも手で開いたセッションではなくラベルにしました。
AskUserQuestionはルーチンが呼び出せるツールではない

ラベルを付けるとルーチンが起動し、何かを作成する前にほぼ即座に止まりました。

実行そのものの言葉です。「AskUserQuestionはこのルーチン/トリガーセッションでは利用できるツールではありません。ツール一覧に存在せず、ToolSearchでも一致するものが見つかりません……答えを捏造したり選択肢AとBの間で当てずっぽうを選んだりする代わりに停止しました。ファイルは作成されず、コミットもされず、PRも開かれませんでした。」
これはAnthropic自身の公開ドキュメントよりも強く、正確な発見です。 ドキュメントには「実行中は承認プロンプトが一切ない」としか書かれておらず、これはツールの権限プロンプトについての記述のように読めて、会話的にユーザーへ尋ねる別のツールについての記述ではありません。実際の挙動はどちらにせよ決着をつけます。そのツールはそもそもルーチンの道具箱に入っていないのです。 だから何かを「断る」のではなく、そもそも呼び出す対象が存在しません。壁に突き当たったときの失敗の仕方は正しいものでした。2つの選択肢の間で当てずっぽうを選ぶこともせず、黙って既定値を選ぶこともしませんでした。停止して報告したのであり、これは本当に先へ進めないときに無人自動化がとるべき振る舞いです。
私はこのツールがここに存在してほしいと思っています。ルーチンがAskUserQuestionを呼び出し、本当の判断で止まり、既にアドホックなクラウドセッションがそうしているようにスマートフォンからの返信で再開できるようになれば、ルーチンのプロンプトを何も尋ねる余地のない完全な仕様書として書かなければならない唯一の理由がなくなります。それが実現するまでは、この制約は回避すべき好みの問題ではなく、設計上の前提そのものです。
アドホックセッションで行った3つ目のテスト
「既にアドホックなクラウドセッションがそうしているように」というこの比較は、実際に確かめたわけではなく、Anthropic自身のドキュメントを根拠に書いたものでした。ここまでの2つのテストはどちらもルーチンの経路しか試していなかったからです。3つ目のテストはそのギャップを埋めるものでした。 ラベル付きIssue経由ではなく、スマートフォンから直接セッションを開始し、同じ使い捨てタスクと同じ強制的なAskUserQuestion呼び出しを使いましたが、今回はルーチンとしての実行は一切ありませんでした。

うまくいきました。アプリは必要になった瞬間に通知を送ってきました。「Claude has a question — Shakedown line」。開いてみると、テキストによる代替手段ではなく、本物のネイティブな質問カードが表示されました。

質問は12分間、答えられないまま残りました。 スマートフォン上のタイムスタンプによれば、質問が来たのは1時26分、結果が完成したのは1時38分でした。最初のルーチンテスト設計が抱えていた「ライブ会話の欠陥」を否定するには十分な長さです。

間隔を置いてから回答すると、セッションは正しく再開しました。選ばれた選択肢でファイルを作成し、pnpm checkをクリーンな状態で実行し、依頼どおりマージせずにmainへのプルリクエストを開きました。この制約はルーチンに固有のもので、クラウドセッション全般の話ではありません。 AskUserQuestionはルーチンの無人実行の中を除けば、どこでも実際に機能し、プッシュ通知も届く本物のツールです。これは上で述べた設計上の前提が成り立つもう1つの理由でもあります。ルーチンのプロンプトは、このツールが存在しないものとして書くべきです。ルーチンにとっては、実際に存在しないのですから。
それでも通知は届いた
Anthropicのモバイル向けドキュメントは、プッシュ通知の対象を狭く限定しています。「Remote Controlが有効なとき、Claudeはスマートフォンに通知を送ることができます……典型的には長時間実行のタスクが終わったときや、ユーザーの判断が必要なときです。」 Remote Controlはルーチンとは別の機能です。 自分のマシン上でライブに動いているセッションとスマートフォンをつなぐもので、そのマシンを起動したままにする必要があり、これはクラウド上で動くルーチンがラップトップを閉じたままにできるという利点を打ち消してしまいます。
この限定にもかかわらず、行き詰まった上記のルーチンの実行は、Remote Controlのセッションがどこにも動いていない状態でも、スマートフォンに通知を届けました。ドキュメントと実際に観測された挙動はここで食い違っています。実務的に重要なのはこちらの読み方です。Remote Controlがなくても、少なくとも1種類のルーチンのイベント、つまり完全な行き詰まりは、スマートフォンまで届くということです。まだ検証できていないのは、タスクの途中で完全に諦めるのではなく、何かを待つ形で止まるルーチンが、同じように通知を送るかどうかです。その一時停止を引き起こすはずのツールが存在しないため、検証のしようがありませんでした。
このブログで実際にルーチンへ任せる価値があるもの
ターミナルから離れてClaude Codeを動かす方法は4種類あり、どれも同じ2つのことを引き換えにしています。マシンを起動したままにする必要があるかどうかと、人間が途中で操作できるかどうかです。
| 手段 | 動く場所 | マシンを起動したままにする必要 | 途中で止まって入力を待てるか |
|---|---|---|---|
| クラウドセッション(アドホック) | Anthropicのクラウド | 不要 | 可能。返信するまでアイドル状態で待ちます |
| ルーチン | Anthropicのクラウド | 不要 | 不可:そのためのツールが存在しません |
| Remote Control | 自分のマシン | 必要 | 可能。通知も送れます |
| Dispatch | 自分のマシン上のDesktopアプリ | 必要 | 可能。Desktopアプリ経由です |
ルーチンだけが、無人でありながらマシンを起動したままにする必要もない唯一の手段であり、同時に何も尋ね返せない唯一の手段でもあります。 この引き換えが発見のすべてであり、何をルーチンに任せてよく何を任せてはいけないかを決めています。
このブログ自身のリリーススキルは、タイトルの決定からラベル付け、PRのマージ、バージョンのタグ付けまで、リリース全体を一気通貫でまとめます。あえてすべての判断点で対話的な状態を保っており、2回の実地テストが示したことを踏まえれば、そのどれもルーチンには向いていません。ルーチンはどちらのプレースホルダーの一文を使うか尋ねられないのと同じように、どのタイトルを使うか尋ねることもできません。
2回のテストを乗り越えたのは、判断を一切必要としないほど手順が具体的なものでした。このブログのCHANGELOGは、依存関係更新ボットが通常のリリースフローの外でマージを行うたびにずれていきますが、その修正はすでに書かれた固定の手順です。前回のタグ以降に何が入ったかを読み、抜けているエントリを追加し、そのファイルだけに触れるPRを開く、というものです。この手順のどこにもルーチンが尋ねる必要のある分岐点はなく、これはこのセッションが2回のテストをかけて確かめた、まさに重要な性質です。
まとめ
GitHub Issueにラベルを付け、ルーチンにリポジトリのクローンから作業、PRの作成までを任せることは実際に機能し、監督なしの最初の試行でうまくいきました。より重要な制約は「ルーチンに判断を任せられない」よりも狭く機械的なもので、AskUserQuestionはルーチンセッションが呼び出せるツールでは単純にないということです。これは実行がまさにその壁にぶつかり、当てずっぽうを選ばずに停止するのを見て確認しました。その発見に至るまでには、最初のテスト設計を捨てる必要がありました。手で始めて手で答えたセッションは、どれだけ説得力があっても、無人のトリガーの代わりにはならないからです。Anthropicのドキュメントは、マシンを起動したままにする必要がある機能にプッシュ通知の対象を限定していますが、それでも行き詰まったルーチンの実行はスマートフォンまで届いており、これは書かれた挙動と観測された挙動が一致しなかったもう1つの例です。そこから導かれる実務上のルールは、ルーチンのプロンプトは不確実なケースまで解決済みの完全な仕様書として書くことです。尋ねて待つという逃げ道は存在しないからです。3つ目のテストは、残っていた1つの疑問に決着をつけました。アドホックセッションでは同じツールが正しく機能し、通知を送り、実際の遅延の後に再開できることを確認したのです。これにより、欠けているツールはルーチンに固有の性質であり、クラウドセッション全体の性質ではないことが確認されました。

