マキモノ
業務自動化無料✅ 公式検証済みv1.0.0 / 更新

定期タスクが開発ツリーを直接叩いて古いコードで動き続けるのを検出して直す

毎晩動いているはずのバッチが数十コミット前のコードで走り、結果は毎回exit 0。専用クローン+同期ラッパへ張り替え、失敗注入と時間帯ゲートの罠まで含めて検証する手順。

出品者: kim@orgiast.jp📖 読込 約3,699トークン (約6円)💰 コスパ 10
トークン節約メーター86%節約
ゼロからAIに作らせた場合4.2万トークン
このMDを読ませた場合6,000トークン

3.6万トークンの節約 (API料金換算で約54円分)。 要件定義・技術調査・試行錯誤ぶんのトークンがまるごと不要になります。※ 出品者申告とレビューに基づく推定値。モデル・タスク内容により変動します。

この巻物について

定期タスクが開発ツリーを直接叩いて古いコードで動き続けるのを検出して直す」は、業務自動化カテゴリのAI指示書(MDファイル)です。毎晩動いているはずのバッチが数十コミット前のコードで走り、結果は毎回exit 0。専用クローン+同期ラッパへ張り替え、失敗注入と時間帯ゲートの罠まで含めて検証する手順。この巻物をAIに読み込ませると、ゼロから設計・調査する場合に比べて 約3.6万トークン(API料金換算で約54円)・86%のトークンを節約できます。

カテゴリ
業務自動化
対応AI
claude-code、cursor、codex-cli
ライセンス
商用利用可 (再販不可)
価格
無料
ゼロから開発時
約4.2万トークン
この巻物使用時
約6,000トークン
節約量
約3.6万トークン (約54円)
更新日
2026-08-31

使い方 (AIに渡す3つの方法)

いちばん簡単なのはワンライナー。Claude Code のターミナルに貼るだけです。

⬇ .md をダウンロード
claude "https://makimono-md.vercel.app/api/v1/files/md-b4c9bc71/raw を読み込んで、この指示書どおりに実装して"
claude-codecursorcodex-cliライセンス: 商用利用可 (再販不可)

中身

定期タスクが「開発ツリー」を直接叩いていて、何ヶ月も古いコードで動いているのを見つけて直す

毎晩動いているはずのバッチが、実は数十コミット前のコードで走り続けている——しかも タスクスケジューラの結果は毎回「0(正常)」。この記事は、その状態を検出して恒久的に潰す手順です。

対象: Windows タスクスケジューラ / cron から自動スクリプトを回している環境。 AI エージェント(Claude Code 等)にそのまま読ませて実行させられる粒度で書いています。


1. 何が起きているのか

多くのプロジェクトで、定期タスクはこう登録されています。

powershell.exe -File "<開発ツリー>\tools\nightly-batch.ps1"

<開発ツリー>人間や AI が日常的に作業しているクローンです。ここが罠になります。

  • 誰かが検証ブランチを checkout したまま放置すると、その日以降ずっとそのブランチのコードが夜間に走る
  • git pull --ff-only を回す同期処理を入れていても、そのブランチの上流に対して成功するので 「更新しました」と報告しながら main の修正は一生届かない。
  • 追加した新しいステップは、そのツリーに存在しないので実行されない。 それでもスクリプトは最後まで走り、exit 0 を返す。

実例: あるマシンで夜間バッチが feat/...(既にクローズされた PR のブランチ)に停まっており、 origin/main から 91 コミット遅れ。数週間前に追加したステップは一度も実行されていなかった。 LastTaskResult はずっと 0 だった。


2. 検出する(3コマンド)

2-1. どの定期タスクが開発ツリーを指しているか

Get-ScheduledTask | Where-Object {
  $_.Actions.Arguments -match '<開発ツリーのパスの一部>' -or
  $_.Actions.Execute   -match '<開発ツリーのパスの一部>'
} | ForEach-Object {
  '{0,-32} {1}' -f $_.TaskName, (($_.Actions | ForEach-Object { $_.Arguments }) -join ' ')
}

cron なら crontab -l | grep <開発ツリーのパスの一部>

2-2. そのツリーがどれだけ遅れているか

git -C <開発ツリー> rev-parse --abbrev-ref HEAD      # main 以外なら赤信号
git -C <開発ツリー> fetch origin main -q
git -C <開発ツリー> rev-list --count HEAD..origin/main   # 0 以外なら遅れている

2-3. 「新しいステップが本当に無い」ことを目で見る

遅れの数字だけでは実害が伝わりません。main にしか無いステップ名を grep して 0 件を確認します。 この 0 件が「夜間に一度も実行されていない」の決定的な証拠になり、同時に修理後の合否判定にも使えます

grep -c '<main にしか無いステップ名>' <開発ツリー>/tools/nightly-batch.ps1   # → 0
grep -c '<main にしか無いステップ名>' <専用クローン>/tools/nightly-batch.ps1 # → 1 以上

3. 直す — 「専用クローン + 同期ラッパ」に張り替える

開発ツリーを main に戻すのは解決になりません。開発が続く限り翌日にはまた遅れます。 恒久解は「定期タスク専用のクリーンなクローンを作り、毎回 origin/main へ同期してから実行する」ことです。

3-1. 同期ラッパ

nightly-bootstrap.ps1(要点のみ。実運用ではログ出力を必ず付ける):

[CmdletBinding()]
param(
  [Parameter(Mandatory=$true)][string]$Target,
  [Parameter(ValueFromRemainingArguments=$true)][object[]]$TargetArguments
)

$repo = if ($env:NIGHTLY_REPO) { $env:NIGHTLY_REPO } else { Join-Path $HOME '.cache\nightly-repo' }
$repoUrl = '<リポジトリのURL>'

try {
  if (-not (Test-Path (Join-Path $repo '.git'))) {
    git clone --branch main -- $repoUrl $repo
  } else {
    git -C $repo fetch origin main
    git -C $repo reset --hard origin/main
    git -C $repo clean -qfd
  }
  Write-Log 'リポ同期' ('ok:origin/main ' + (git -C $repo rev-parse --short HEAD))
} catch {
  # ★ 同期に失敗しても中断しない。夜間の仕事を同期の失敗で落とさない
  Write-Log 'リポ同期' ('warn:' + $_.Exception.Message + ' 既存版で続行')
}

$targetPath = if ([IO.Path]::IsPathRooted($Target)) { $Target } else { Join-Path $repo $Target }
if (-not (Test-Path -LiteralPath $targetPath -PathType Leaf)) {
  Write-Log '対象確認' ("error:対象が見つからない " + $targetPath); exit 1   # ★ 異常は exit 1
}

& powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File $targetPath @TargetArguments
$code = $LASTEXITCODE
Write-Log '対象実行' ("ok:" + [IO.Path]::GetFileName($targetPath) + " 終了コード=" + $code)
exit $code   # ★ 対象の終了コードをそのまま返す。後片付けの警告で塗り潰さない

設計上の要点は4つです。

  1. 同期失敗は警告どまりwarn:既存版で続行)。同期のためにその夜の仕事を落とさない。
  2. 対象が無い/対象が失敗したら、その終了コードで exit する。全パス exit 0 は監視を無意味にします。
  3. 相対パスで対象を受ける-Target tools\nightly-batch.ps1)。絶対パスを埋め込むと結局ツリーに固定される。
  4. ラッパ自身の自己更新を入れると、ラッパの修正も自動で行き渡ります (同期後に専用クローン側のラッパと自分のハッシュを比べ、違えば自分を上書きする)。

3-2. 呼び出し先の「リポの探し方」も直す(最大の罠)

これを忘れると、専用クローンから起動しても中で開発ツリーへ戻ります。 バッチ本体が子スクリプトを $HOME/<リポ名>/tools/xxx.mjs のように探していないか確認し、 候補の先頭に「自分自身のリポ」を差し込みます

$candidates = @(
  (Split-Path -Parent $PSScriptRoot),      # ★ 自分が置かれているリポを最優先
  (Join-Path $HOME '<リポ名>')             # 従来のフォールバックは残す
)

3-3. タスクを張り替える(バックアップ必須)

# 1) 戻せるようにする
New-Item -ItemType Directory -Path "$HOME\.task-backups" -Force | Out-Null
Export-ScheduledTask -TaskName '<タスク名>' |
  Set-Content -LiteralPath "$HOME\.task-backups\<タスク名>.xml" -Encoding UTF8

# 2) Action だけを差し替える(トリガーと実行アカウントは保持される)
$arg = '-NoProfile -NonInteractive -ExecutionPolicy Bypass ' +
       '-File "<専用クローン>\tools\nightly-bootstrap.ps1" -Target tools\nightly-batch.ps1'
Set-ScheduledTask -TaskName '<タスク名>' -Action (
  New-ScheduledTaskAction -Execute 'powershell.exe' -Argument $arg
)

# 3) 読み返して確認する(設定したつもりで終わらせない)
(Get-ScheduledTask -TaskName '<タスク名>').Actions | ForEach-Object { $_.Arguments }

戻すときは Register-ScheduledTask -Xml (Get-Content <xml> -Raw) -TaskName <タスク名> -Force


4. 検証する — ここが本題

4-1. 正常系だけを見ても、この型のバグは絶対に出ない

「手動実行したら正常終了しました」は何も確かめていません。必ず失敗を注入します。

# A: 存在しない対象 → exit 1 とログの error 行を期待
powershell -File <ラッパ> -Target 'tools\no-such-file.ps1'; $LASTEXITCODE   # → 1

# B: わざと exit 3 を返すスクリプトを対象にする → 3 が伝播することを期待
'exit 3' | Set-Content .\fail-probe.ps1
powershell -File <ラッパ> -Target (Resolve-Path .\fail-probe.ps1); $LASTEXITCODE   # → 3

B が 0 になるなら、ラッパが後片付けや Write-Warning で終了コードを塗り潰しています。 その状態では本番の失敗が永久に「正常」として記録されます

4-2. 「時間帯ゲート」に騙されない

夜間バッチは「深夜料金の時間帯だけ動く」ような時間帯ガードを持っていることがよくあります。

if (-not $offPeak) { Write-Log '時間帯判定' 'skip:帯域外'; exit 0 }

この場合、日中に手動実行すると数秒で exit 0 して本体を一切実行しません。 これを「正常に動いた」と読むのも「壊れている」と読むのも誤りです。実際にやってしまいがちな誤読です。

  • 手動実行が想定より桁違いに速く終わったら、まずゲートを疑うgrep -nE 'off-peak|時間帯|Hour -' <script>)。
  • 日中に確かめられるのはラッパ層まで(同期・対象解決・終了コード伝播)。そこは 4-1 の方法で確実に確かめる。
  • 本体まで含めた確認は、帯の中の実走を待つ。待つと決めたら 「どのログのどの行が出れば合格か」を1行だけ書き残す(例: <main にしか無いステップ名> / ok)。

4-3. 合否は「新しいステップのログ行」で判定する

翌朝、次の2つを見ます。

grep 'リポ同期'                       <ログ>/nightly-bootstrap-<日付>.log   # ok:origin/main <sha>
grep '<main にしか無いステップ名>'    <ログ>/nightly-batch-<日付>.log       # ok

2行目は旧ツリーの版には存在しないステップなので、出た時点で配線が効いた決定的な証拠になります。 「遅れが 0 になった」ではなく「新しい仕事が実際に走った」で判定するのがポイントです。


5. 同じ壊れ方を二度と作らないために

  • インストーラ/セットアップスクリプトを直す。タスクを登録している箇所が -File "<リポ>\tools\nightly-batch.ps1" のままだと、新しいマシンすべてに同じ地雷が配られます。 登録は必ずラッパ経由(-File "<専用クローン>\tools\nightly-bootstrap.ps1" -Target tools\<対象>)にする。
  • 棚卸しを定期化する。2-1 のコマンドを月次で回し、開発ツリーを指すタスクが 0 件であることを確認する。
  • スキップと成功を区別してログに書くskip:ok:error: を別語にしておくと、 後から grep で「本当に動いた夜」だけを数えられます。
  • 1台直しても終わりではない。同じ環境に同型のタスクが複数あるのが普通です(実例では 7 本中 1 本を直した時点で まだ 6 本残っていた)。2-1 の棚卸しコマンドを流して残数を必ず数えてから完了と報告する。

6. AI エージェントに丸ごと投げるときの指示文

このマシンの定期タスクのうち、開発用クローンを直接実行しているものを洗い出して、
専用クローン + 同期ラッパ経由へ張り替えてください。手順:
1) タスク棚卸し(開発ツリーのパスを含む Action を列挙)
2) そのツリーのブランチと origin/main からの遅れコミット数を出す
3) main にしか無いステップ名を grep して 0 件であることを示す(=実害の証拠)
4) Export-ScheduledTask で XML バックアップを取ってから Action を張り替え、読み返して確認
5) 失敗を注入して検証(存在しない対象→exit 1 / exit 3 を返す対象→exit 3 が伝播)
6) 本体に時間帯ゲートがあるか確認し、あれば日中実行で何がスキップされたかまで報告する
7) 残っている同型タスクの本数を数えて報告する
完了報告には「手動実行して正常終了」とだけ書かないこと。

よくある質問

「定期タスクが開発ツリーを直接叩いて古いコードで動き続けるのを検出して直す」とは何ですか?

毎晩動いているはずのバッチが数十コミット前のコードで走り、結果は毎回exit 0。専用クローン+同期ラッパへ張り替え、失敗注入と時間帯ゲートの罠まで含めて検証する手順。

どれくらいトークン(費用)を節約できますか?

ゼロから開発すると約4.2万トークンかかりますが、この巻物を使えば約6,000トークンで済みます。差し引き約3.6万トークン(API料金換算で約54円)・86%の節約です。

どうやって使いますか?

無料です。MDファイルを Claude Code などのAIに読み込ませるだけ。ワンライナーをターミナルに貼れば実装が始まります。要件定義や技術調査を省いて実装だけにトークンを使えます。

どのAIツールに対応していますか?

claude-code、cursor、codex-cli に対応しています。

商用利用できますか?

ライセンスは「商用利用可 (再販不可)」です。

🤝 自分でAIを動かすのは、まだ不安…という方へ

この巻物の内容を、AIを使うプロに丸ごと任せることもできます。姉妹サービスAI代行堂なら「LINEで頼むだけで、仕事が完成」。

AI代行堂を見る →

関連する巻物

この巻物、誰かのトークンも救えます

𝕏 で節約レシートをシェア