dev-agent-teamシリーズの15本目。 前回(いま dev-agent-team は何なのか【再掲】)で、 キットの価値は「賢さの明文化」ではなく「現場でしか得られない台帳」のほうにある、 という結論を出した。今回はその実践第1弾—— 台帳に入れる材料を、自分の失敗ログから採ってくる話。
- Claude Codeが生成した利用分析レポート(実務セッション28本 / 590メッセージ)を、自作キットの取り込みプロセスに通した
- 母数はキットを使っていない素の実務セッション。つまり「型なしで運用すると何が起きるか」の実測データとして読める
- 記録された事故の多くはキットの守備範囲だったが、守備範囲のはずなのに明文ルールが無い箇所が5つ見つかった
- 最重要はリモート状態の信頼境界——「最初のpushの承認は、その後の全pushの承認ではない」
- 取り込まなかったものが3分類ある。何を入れないかのほうが、取り込み基準の説明としては正直だ
Claude Codeが、自分の利用ログから分析レポートを出してくれる。 何にどれだけ時間を使い、どこで詰まり、どういうやり取りが繰り返されているか。 はじめて出力させたとき、いちばん目を引いたのは効率の数字ではなく、 失敗の並び方のほうだった。
そして気づいた。このレポートの母数は、 自作キットをまったく使っていない、素の実務セッションだけだ。 ということはこれは、 「型を敷かずにAIと開発を回すと何が起きるか」の実測データとして読める。
自分のキットは、まさにその「何が起きるか」を防ぐために作ったものだった。 だから、答え合わせができる。
1. 自己言及ループ
今回やったことは、図にするとこの一周だ。
AIの使い方の失敗が、AIの使い方の型に還流する。 シリーズを通してやってきたのはずっとこれだが、 今回は入力側が実測ログになった点が違う。 これまでは「事故が起きた → 悔しいのでルールを書く」という単発の反応だった。 今回は4か月分の事故を一度に並べて、共通の形を探す作業になっている。
精査の結果はこうだ。 レポートに記録された事故の多く——無断push、推論ベースの分析、スコープ超過——は、 キットが守備範囲だと主張している領域だった。 そこは良い。問題は次で、 守備範囲のはずなのに、それを禁じる明文ルールが無い箇所が5つあった。
「思想としては書いてある」と「実行ルールとして書いてある」は違う。 前者はAIが読み飛ばせる。 今回見つかった5つは全部この隙間に落ちていた。
以下、取り込んだ5点を、それぞれの由来となった実際の事故とセットで書く。 実務側の固有情報は出せないので、事故の説明は一般化した形に留める。
2. 取り込んだ5点
2-1. リモート状態の信頼境界(最重要)
承認済みのPRに、AIが追加のpushを勝手にやった。 後始末はPRの閉鎖とリモートブランチの削除になった。
なぜ止まらなかったのかを追うと、構造的な穴だった。 キットには人間ゲートの一覧表があり、そこには「マージ可否」は載っている。 だがpush そのものを人間ゲートとする明文ルールが無かった。 そしてAI側の理屈はこうだ——このブランチへのpushはさっき承認された。
最初のpushの承認は、その後の全pushの承認ではない。
この一文を核にして、境界を引き直した。
- ファイル編集
- ブランチ作成
- コミットまでは自由
- push
- PRの作成・更新
- Secretの登録
- タグの作成
ポイントは、境界を「危険な操作かどうか」ではなく「他人から見える状態が変わるかどうか」で 引いたことだ。前者は程度問題になってAIが解釈する余地が残るが、後者は二値で判定できる。 ローカルのコミットは、間違えても本人がやり直せばいい。 リモートに出た瞬間、CIが走り、レビュアーに通知が飛び、取り消しが共同作業になる。
なお、このシリーズで
レビュー前のコミットがmasterに直pushされた事故を
書いたことがある。あのときはgitの既定動作が原因だったので、
deny ルールと Ruleset で物理的に塞いだ。
今回のはAIの解釈が原因で、塞ぐべきは承認の有効範囲のほうだった。
同じ「無断push」でも、原因が違えば対策の層も違う。
2-2. 質問には、回答のみ返す
「〜すればいいだけだよね?」という確認の質問を投げたら、 AIがフルの実装をやり、さらにクラウド側にリソースまで登録していた。 結果はブランチごと廃棄。
これは意地悪な事故で、AIの側に悪意も勘違いも無い。 質問文には確かに「やるべきこと」が書いてある。親切心の暴走だ。 だからルールとしては、親切心を否定するのではなく、応答の形式を固定した。
yes/no を問う質問に対する正しい応答は「Yes/No+その根拠」であって、実装ではない。 実装が必要だと判断したなら、それは次のターンで提案するもの。
これを思想の記述ではなく実行ルールに昇格させた。 「スコープを守れ」だと守りようがないが、 「疑問符で終わる入力には散文で答える」なら判定できる。
2-3. 分析成果物の証拠規律
AIに issue の分類をやらせた。整った表が出てきた。 後で別のエージェントに独立レビューさせたら、母数ごと覆った。 47件だと思って分類していたが、実データに当たったら60件あり、 優先順位も別物になっていた。
怖いのは、最初の表が間違って見えなかったことだ。 推論だけで書かれた主張が、実測と同じ顔をして並んでいた。
検証済みの顔をした推論が、いちばん危ない。 明らかに雑な出力は捨てられる。整った推論は採用されてしまう。
対策は、判断ではなくテンプレート側に入れた。 調査レポートのテンプレに「データソースと母数」の表を新設し、 実データに当たっていない主張には「未検証」と明記させる。
ラベルを貼らせるだけ、というのがミソだと思っている。 「推測で書くな」は守れないが、「推測なら未検証と書け」は守れる。 そして未検証だらけのレポートは、書いているAI自身が違和感を持つ。
2-4. 「等価な」書き換えは、件数の一致で検証する
SQLの WHERE 句を「意味は同じなので」と単純化した。 実際には、現行の条件だけが拾っていたレガシーなステータス値の行があり、 それが静かに落ちるところだった。
これはリファクタリング全般に効く話なので、判定条件をひとつ足した。
条件式の「等価な」書き換えは、実データで件数の一致を確認するまで等価ではない。 件数が合わない単純化は、リファクタリングではなく仕様変更だ。
AIは条件式を論理式として読む。だから論理的には正しく等価にする。 だが実運用のデータには、論理式に書かれていない歴史が入っている。 廃止されたはずのステータス値が残っている、といった類のものだ。 この差は、コードを読んでいる限り絶対に出てこない。
2-5. Environment Notes——環境制約を台帳にする
最後の1つは事故というより反復パターンで、 ログを並べたから見つかったものだ。
4セッションで同じ形が繰り返されていた—— 環境の制約や権限のブロックが、 作業がほぼ完成した最終盤で発覚して停滞する。 ホスト側のランタイム制約、権限的に触れないファイル、外部連携の認証が切れている、など。
1回ずつ見ていたときは「運が悪かった」で流していた。4回並べると別の話になる。
環境制約はタスクごとに再発見するものではなく、 そのマシンの安定した事実だ。
なので Project Rules に Environment Notes という台帳を新設して、 Phase 0(着手前の状況把握)で必ず読むようにした。 一度踏んだ制約は、次から設計時点で回避される。
地味だが、これがいちばん前回記事で言った「台帳」そのものだと思う。 汎用の賢さではまったく到達できない情報で、 かつこの環境で作業した人間しか持っていない。
3. 取り込まなかったもの
レポートには他にも提案が並んでいた。3分類は見送っている。 何を入れたかより、何を入れなかったかのほうが取り込み基準の説明になるので、書いておく。
- 多層レビューの追認——すでにキットにある。追認は行数が増えるだけ
- ユーザー固有の設定提案——自分の環境の話であって、型に書くものではない
- MCPの導入提案——有用かもしれないが、人間ゲートの位置は動かない
- 人間ゲートの位置または強度が変わるもの
- 実際の事故が由来になっている
- 思想ではなく実行ルールとして書ける
3つ目のMCPの件は、便利さで言えば入れたくなる。 だが前回書いた取り込み基準は 「人間ゲートの位置または強度が変わるものだけ」だ。 便利さで例外を作ると、この基準は1回で壊れる。
逆に言えば、今回5点は全部この基準を通っている。 pushの境界(ゲートの位置)、質問への応答(ゲートの手前で止まる)、 未検証ラベル(人間が判断するための材料)、件数一致(人間が承認する前の検証)、 Environment Notes(Phase 0で人間が状況を掴む)。
4. これが「台帳路線」の実践第1弾になる
ここ3本の記事は、振り返るとひと続きになっている。
②で「汎用の賢さは本体に吸収されるが、現場の台帳は吸収されない」と書いた。 威勢のいい結論だが、言っただけでは何も蓄積されない。 台帳路線を名乗るなら、台帳を実際に太らせる作業を回さないと嘘になる。
今回それをやってみて分かったのは、 材料は自分のログの中にすでにあるということだった。 4か月分の事故は、起きた当日には全部「その日の失敗」として処理されていて、 共通の形が見えていなかった。 並べて初めて、5つが同じ隙間——「思想としては書いてあるが実行ルールが無い」——に 落ちていると分かった。
そしてこの並べ替えは、人間には面倒すぎてやらない作業だ。 28セッション590メッセージを読み直す気には、まずならない。 AIに自分の失敗ログを読ませる用途は、思っていたより真面目に価値があった。
5. まとめ
- Claude Codeの利用分析レポート(28セッション / 590メッセージ)を、自作キットの取り込みプロセスに通した
- 母数はキット未使用の素の実務セッション——「型なしで運用すると何が起きるか」の実測データ
- 事故の多くは守備範囲だったが、明文ルールが無い隙間が5つあった。全部取り込んだ
- 核心は「最初のpushの承認は、その後の全pushの承認ではない」——承認に有効範囲を書く
- 検証済みの顔をした推論が、いちばん危ない。だから「未検証」ラベルを義務にした
- 環境制約はタスクごとの発見ではなく、マシンの安定した事実。台帳に書いてPhase 0で読む
- 便利そうでも人間ゲートを動かさないものは入れない。基準は1回の例外で壊れる
自分の失敗ログを自分のツールに食わせる、という一周は思ったより素直に回った。 失敗は、単発では反省で終わるが、並べると仕様になる。
github.com/fecot/dev-agent-team ——本記事の5点は PR #32 にまとめてある(執筆時点ではレビュー中)。 対応表はPR本文に載せた。