「直したのに効いていない」を潰す — hook と夜間ジョブが読むチェックアウトを検査する
AIエージェントに組ませた hook や夜間バッチは、main を直しても古い実体が動き続ける。設定が実際に指すファイルと origin/main の内容を比較して毎朝1通だけ通知する検査の作り方と、誤検知を殺す設計(ゼロ件カウンタ・散文ログ・VCS出力・ベースライン抑制)。
約3.7万トークンの節約 (API料金換算で約55円分)。 要件定義・技術調査・試行錯誤ぶんのトークンがまるごと不要になります。※ 出品者申告とレビューに基づく推定値。モデル・タスク内容により変動します。
この巻物について
「「直したのに効いていない」を潰す — hook と夜間ジョブが読むチェックアウトを検査する」は、業務自動化カテゴリのAI指示書(MDファイル)です。AIエージェントに組ませた hook や夜間バッチは、main を直しても古い実体が動き続ける。設定が実際に指すファイルと origin/main の内容を比較して毎朝1通だけ通知する検査の作り方と、誤検知を殺す設計(ゼロ件カウンタ・散文ログ・VCS出力・ベースライン抑制)。この巻物をAIに読み込ませると、ゼロから設計・調査する場合に比べて 約3.7万トークン(API料金換算で約55円)・88%のトークンを節約できます。
- カテゴリ
- 業務自動化
- 対応AI
- claude-code、cursor、codex-cli
- ライセンス
- 商用利用可 (再販不可)
- 価格
- 無料
- ゼロから開発時
- 約4.2万トークン
- この巻物使用時
- 約5,200トークン
- 節約量
- 約3.7万トークン (約55円)
- 更新日
- 2026-09-06
使い方 (AIに渡す3つの方法)
いちばん簡単なのはワンライナー。Claude Code のターミナルに貼るだけです。
claude "https://makimono-md.vercel.app/api/v1/files/hook/raw を読み込んで、この指示書どおりに実装して"
中身
「直したのに効いていない」を潰す — hook と夜間ジョブが読むチェックアウトを検査する
AI コーディングエージェント(Claude Code / Codex CLI 等)に hook や夜間バッチを組ませると、 main を直したのに実際に動いているのは古いコードという状態が静かに発生する。 エラーは出ない。テストも緑。だから何ヶ月でも気付けない。
この指示書は、その構造を検査して毎朝1通だけ通知する仕組みの作り方をまとめる。
なぜ起きるか — 「直した場所」と「動く場所」が違う
典型的な構成では、同じリポジトリが複数の実体として存在する。
| 実体 | 誰が読むか | 更新のされ方 |
|---|---|---|
| 作業チェックアウト | 人間とエージェントが編集する | 手動。ブランチが固着しがち |
| hook 実行パス | 設定ファイルが絶対パスで指す | 作業チェックアウトと同じとは限らない |
| ジョブ用チェックアウト | 夜間バッチのブートストラップ | 毎回 git reset --hard origin/main |
ここから2つの逆向きの事故が出る。
事故A: 直したのに反映されない
夜間バッチが reset --hard origin/main する専用チェックアウトから動く場合、
作業ツリーをいくら直してもpush するまで夜間には効かない。
実例: あるバッチのステップを「設定が悪い」と判断して直したが、
真因はそのステップ自体が未コミットで、本番では一度も実行されていなかった。
その夜のログにステップ名が出ていないことで初めて分かった。
事故B: 直したのに古い版が動き続ける hook は設定ファイルに書かれた絶対パスの実体を実行する。 そのチェックアウトが古いブランチに固着していると、main を直してもhook は古い版を実行し続ける。 実例: hook 実行パスのチェックアウトが 68 コミット遅れており、 hook が呼ぶ 36 ツールのうち 12 ツールが main と不一致だった。 毎回発火するガードが古い版で動いていたのに、誰も気付いていなかった。
検査の設計
原則1: 判定は「遅れコミット数」ではなく「実行されるファイルの内容一致」
コミット数で判定してはいけない。
- 遅れていても中身が同じなら実害はない(触っていないファイルばかりなら問題ない)
- 遅れ0でもローカル改変が乗っていれば実害がある
だから比較するのは「設定ファイルが実際に指しているファイル」の内容と、
git show origin/main:<相対パス> の内容。この2つが違うときだけ報告する。
原則2: 修正コマンドを出さない
「git reset --hard してください」と書きたくなるが、書いてはいけない。
作業ツリーには他の作業者・他セッションの未コミット変更が乗っていることがある
(実例では 66〜162 ファイル)。機械的な reset を促すと、それを丸ごと消す事故になる。
検査は「食い違っている」という事実の提示に留め、どう直すかは人間に委ねる。
原則3: 「まだ main に無いファイル」は食い違いに数えない
新規に追加したツールは main に存在しない。これを毎日「不一致」と報告すると、
正常な開発中の状態が永久に警告され、通知が読まれなくなる。
git show origin/main:<path> が失敗したファイルは対象外にする。
原則4: 取得できなかったら「異常なし」ではなく「スキップ」
オフラインや、そもそも git リポジトリでないディレクトリを設定が指していることがある。
git fetch が失敗したチェックアウトは判定をスキップし、理由を1行残す。
黙って「異常なし」にすると、検査が死んでいることに気付けない。
実装
手順1: 設定ファイルから「実際に実行されるファイル」を抜き出す
設定の全イベントを再帰的に走査し、コマンド文字列から実行対象のパスを取る。
node "<path>" と -File "<path>" の両方の形に対応する。引用符の有無も。
export function extractHookToolPaths(settings) {
const found = new Set();
const visit = (value) => {
if (Array.isArray(value)) return value.forEach(visit);
if (!value || typeof value !== 'object') return;
if (typeof value.command === 'string') {
const regex = /(?:^|\s)(?:node\s+|-File\s+)(?:"([^"]+\.(?:mjs|ps1))"|'([^']+\.(?:mjs|ps1))'|([^\s"']+\.(?:mjs|ps1)))(?=\s|$)/gi;
for (const m of value.command.matchAll(regex)) found.add(m[1] || m[2] || m[3]);
}
Object.values(value).forEach(visit);
};
visit(settings?.hooks);
return [...found];
}
設定の構造を決め打ちしないこと。イベント名が増えても壊れないよう、再帰で全部拾う。
手順2: チェックアウトのルートごとにまとめる
各パスから上へ .git を探してルートを決める。
複数のチェックアウトが混在しうるので、ルートごとにグループ化する。
同じリポを2箇所に置いていると、ディレクトリ名(basename)だけでは区別できない。
親ディレクトリ名を添える(workspace/myrepo と Downloads/myrepo のように)。
どちらを直せばいいか分からない通知は、無いのとほぼ同じ。
手順3: 内容を比較する
const relative = path.relative(root, filePath).replaceAll('\\', '/');
const mainFile = await git(['show', `origin/main:${relative}`], { cwd: root });
if (mainFile.status !== 0) continue; // main に無い新規ツール → 対象外
const local = fs.readFileSync(filePath, 'utf8');
if (local !== mainFile.stdout) mismatched.push(path.basename(filePath));
git fetch origin main はタイムアウト付き(20秒程度)で実行する。
夜間ジョブが1本のネットワーク待ちで永久に眠らないように。
手順4: 通知は「異常がある時だけ」
平穏な日に通知が来ると、人は通知を読まなくなる。次を守る。
- 異常0件なら何も送らない
- 補足情報(未登録の項目、既知の問題の抑制件数)はそれ単独では通知を発火させない。 異常があるときに末尾へ添えるだけ
- 同じ内容は24時間再送しない。ただし24時間経ったら同じ内容でも再送する (直っていない問題を忘れないため)
併せて必要になる「誤検知を殺す」設計
この種の検査は、ログ本文をキーワードで走査する処理と組み合わせることが多い。 実データで動かすと誤検知の洪水になるので、最初から次を入れておく。
ゼロ件カウンタを失敗と読まない
成功行が失敗判定に引っかかる。実測で拾ってしまった例:
[probe] https: ok=true status=200 ms=60 error=-
✅ 完走(成功38 / timeout0 / 失敗0)
health: alive=4 dead=0 error=0
キーワードの直後が「区切り+0 または -」なら失敗と見なさない、という除外を入れる。
散文が流れ込むログをキーワード走査しない
AI が書いた要約文・レポート本文がそのままログに入る種類のログがある。 そこには「失敗」「error」という語が正常な文章として含まれる。 永久に誤検知するので、ログごとに走査モード(キーワード走査 / 存在チェックのみ)を 設定で明示し、既定は走査しない方に倒す。
バージョン管理ツールの出力を除外する
HEAD is now at <sha> <コミット件名> のような行がログに混ざる。
コミット件名には任意の語が入る。実例では「失敗検知を追加」という件名が
失敗として報告された。HEAD is now at / From https:// などで始まる行は判定から外す。
既知の問題はベースラインで抑制する
作業ツリーが常に完全に綺麗とは限らない。既知の未解決項目を毎日通知すると 通知が読まれなくなる。ベースラインファイルに既知分を記録し、 ベースラインに無い新規分だけを通知する。ただし:
- ベースラインの更新は手動コマンドでのみ。自動更新にすると 新しい問題が勝手に「既知」になって検知が死ぬ
- 抑制した件数は必ず1行表示する。黙って消さない
導入時の一手間: 初回だけ「基準を記録して通知しない」モードを用意する
差分方式の検査を入れた初日は、過去に溜まった(多くは解決済みの)事象を全部拾ってしまう。 最初の通知が古い話で埋まると、その通知は信用されなくなる。
--prime のようなオプションを用意し、基準だけ記録して通知しない実行を1回できるようにする。
2回目以降は「前回以降に増えた分」だけが対象になる。
検証の作法 — テストが緑でも完了ではない
この種のツールは、テストが通っても現実では動かないことが極めて多い。 実際に踏んだ例を挙げる。
- テスト実行を子プロセスで起動する処理で、シェル経由にしたためパスが空白で分断され
(
C:\Program Files\...がC:\Programになる)、テストが一度も実行されていなかった。 それでも「失敗0件」を返すので緑に見えた - テスト結果の件数抽出が、実行系の既定の出力書式と違う前置き文字を見ていて常に0件を返していた
- LLM 応答の検証が厳しすぎて例外を投げ、
catch {}が握り潰して毎回フォールバックしていた。 痕跡が何も残らないので「動いている」と誤認していた - パス変換のコードが特定の実行環境を前提にしており、別環境では必ず失敗していた
だから委譲の完了条件は必ずこう書く。
テストが緑であることに加えて、実データで実行し、その出力を貼ること。 次の誤検知が0件であること: (具体的に列挙)。 次の値が期待どおりであること: (具体的に列挙)。
抽象的な指摘は同じ穴を再生産する。実測値を添えて差し戻す。 「25件中これとこれが誤検知」「この行が拾われている」と現物を渡す。
この仕組みが返してくれるもの
- 「直したのに効いていない」状態が翌朝には分かる
- 平穏な日は通知が来ないので、通知が来たら本物だと信じられる
- 誰も見ていなかった劣化(古いガード、止まったジョブ、増え続ける放置分)が 人間の記憶に依存せず表に出る
逆に、この仕組みを入れずに hook や夜間ジョブを増やすと、 動いているつもりの自動化だけが積み上がる。それは自動化が無い状態より危険で、 「ガードがあるから大丈夫」と誤認したまま検査を通り抜けてしまう。
よくある質問
+「「直したのに効いていない」を潰す — hook と夜間ジョブが読むチェックアウトを検査する」とは何ですか?
AIエージェントに組ませた hook や夜間バッチは、main を直しても古い実体が動き続ける。設定が実際に指すファイルと origin/main の内容を比較して毎朝1通だけ通知する検査の作り方と、誤検知を殺す設計(ゼロ件カウンタ・散文ログ・VCS出力・ベースライン抑制)。
+どれくらいトークン(費用)を節約できますか?
ゼロから開発すると約4.2万トークンかかりますが、この巻物を使えば約5,200トークンで済みます。差し引き約3.7万トークン(API料金換算で約55円)・88%の節約です。
+どうやって使いますか?
無料です。MDファイルを Claude Code などのAIに読み込ませるだけ。ワンライナーをターミナルに貼れば実装が始まります。要件定義や技術調査を省いて実装だけにトークンを使えます。
+どのAIツールに対応していますか?
claude-code、cursor、codex-cli に対応しています。
+商用利用できますか?
ライセンスは「商用利用可 (再販不可)」です。
🤝 自分でAIを動かすのは、まだ不安…という方へ
この巻物の内容を、AIを使うプロに丸ごと任せることもできます。姉妹サービスAI代行堂なら「LINEで頼むだけで、仕事が完成」。
関連する巻物
Google Meet 自動参加&動画配信Bot 開発指示書
指定した時刻に Google Meet へ自動参加し、動画を再生しながら画面共有する Bot を、Claude Code に一発で作らせる開発指示 MD。朝会の定例動画配信・ウェビナーの自動放送に。
受信メール添付を案件フォルダへ自動取込するパイプライン
メールを読むアプリとドライブに書くアプリが別、という現実的な構成で顧客メールの添付を案件フォルダへ無人保存する設計。権限追加を避ける理由、実行時間制限下の予算3本立て、二重の重複防止、base64url/行数上限/変換判定などの実装罠、案件と顧客のマッチング、名寄せは候補提示+人の承認にする型まで。
Gmail 自動仕分け&返信ドラフト生成MD
受信メールを AI が分類 (要返信/情報/営業/スパム) してラベル付けし、要返信メールには返信ドラフトまで自動生成する仕組みを作らせる指示書。DWD (ドメイン全体委任) 設定手順込み。
この巻物、誰かのトークンも救えます
𝕏 で節約レシートをシェア