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

無人ジョブの沈黙する失敗と効果検証の自動判定

定時ジョブが1行もログを残さずスキップされる事故の検知と、恒久対策の効果検証をジョブ自身に判定させる型。Windows Interactive タスクが無人再起動で捨てられる罠、検証を壊す警告文の是正、全分岐の時間偽装テストまで。

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

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

この巻物について

無人ジョブの沈黙する失敗と効果検証の自動判定」は、業務自動化カテゴリのAI指示書(MDファイル)です。定時ジョブが1行もログを残さずスキップされる事故の検知と、恒久対策の効果検証をジョブ自身に判定させる型。Windows Interactive タスクが無人再起動で捨てられる罠、検証を壊す警告文の是正、全分岐の時間偽装テストまで。この巻物をAIに読み込ませると、ゼロから設計・調査する場合に比べて 約3.3万トークン(API料金換算で約50円)・79%のトークンを節約できます。

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

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

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

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

中身

無人ジョブの「沈黙する失敗」と、恒久対策の効果検証を自動で判定させる型

毎朝・毎晩に無人で走るジョブ(定時配信、バッチ、同期、スクレイピング)を運用すると、 失敗が通知されず、誰も気づかないまま日数が過ぎるという事故が必ず起きる。 この指示書は、その2大原因(沈黙する失敗 / 恒久対策の効果検証が人間任せ)を潰す実装の型を示す。

前提: 言語は任意(例は Node.js)。通知先はチャット webhook を想定(Slack / Discord / Teams いずれでも同型)。


原則1: 成功判定は「ログが出ていること」ではなく「今日の成果物が存在すること」で行う

最悪の失敗は ジョブが1行もログを残さずにスキップされる ケース。 ログを読む監視は「ログが無い=チェック対象が無い=異常なし」と誤読する。

やること: ジョブ本体とは別に、成果物の存在だけを見る軽量チェックを用意する。

// check-artifact.js — ジョブ本体とは別プロセス。ジョブ実行時刻の後に走らせる
const fs = require('fs');
const path = require('path');

const ARTIFACT_DIR = process.env.ARTIFACT_DIR;      // 例: ./logs
const EXPECTED_HOUR = Number(process.env.EXPECTED_HOUR); // 例: 7 (この時刻までに成果物が出る想定)
const SUCCESS_MARKER = process.env.SUCCESS_MARKER;  // 例: '=== 完了 ==='

const today = new Date().toISOString().slice(0, 10); // 運用タイムゾーンに合わせて調整
const file = path.join(ARTIFACT_DIR, `${today}.log`);

if (!fs.existsSync(file)) {
  // ★ここが本命。「ファイルが無い」は最も見逃されやすい失敗
  notify(`🚨 本日(${today})のジョブが**一度も起動していません**(ログファイル自体が存在しない)。`
       + `スケジューラのトリガ条件・端末の稼働状況を確認してください。`);
  process.exit(1);
}
const body = fs.readFileSync(file, 'utf8');
if (!body.includes(SUCCESS_MARKER)) {
  notify(`🚨 本日(${today})のジョブは起動したが完了マーカーが出ていません(途中で異常終了)。`);
  process.exit(1);
}
console.log(`OK: ${today} 完了マーカーあり`);

設計上の要点

  • 「異常なし」を無言にしてよいが、「チェック自体が走らなかった」は無言にしてはいけない。 チェッカーもまた無人ジョブなので、同じ罠に落ちる。最低限、成功時も日次ログに1行残す。
  • 通知は「前回と違うこと」だけ送る。毎日同じ正常通知を送ると人が読まなくなり、 本当の異常が埋もれる。

原則2: Windows タスクスケジューラの Interactive タスクは無人再起動で丸ごとスキップされる

実際に起きた事故(原因特定まで数日かかった):

時刻出来事
03:59ログオフ(Winlogon イベント 7002)
04:01〜04:05OS 更新に伴う再起動が複数回
06:55定時タスクのトリガ時刻。誰もログオンしていないため起動されず、ログも残らない
08:43人がログオン(Winlogon 7001)。もう配信時刻は過ぎている

タスクのプリンシパルが LogonType=Interactive(=「ユーザーがログオンしているときのみ実行する」)だと、 未ログオン状態ではトリガが静かに捨てられるStartWhenAvailable=True でも救われないことがある。

診断コマンド(PowerShell)

$t = Get-ScheduledTask -TaskName '<タスク名>'
'LogonType={0} / UserId={1} / RunLevel={2}' -f $t.Principal.LogonType, $t.Principal.UserId, $t.Principal.RunLevel
'StartWhenAvailable={0} / WakeToRun={1}' -f $t.Settings.StartWhenAvailable, $t.Settings.WakeToRun

# 該当日のログオフ/ログオンと再起動を突き合わせる(7002=ログオフ, 7001=ログオン)
Get-WinEvent -FilterHashtable @{LogName='System'; ProviderName='Microsoft-Windows-Winlogon';
  StartTime=(Get-Date '<YYYY-MM-DD> 00:00'); EndTime=(Get-Date '<YYYY-MM-DD> 12:00')} |
  Sort-Object TimeCreated | ForEach-Object { '{0} | id={1}' -f $_.TimeCreated, $_.Id }

対処の選び方(重要な分岐)

  • GUI を必要としないジョブ(API 呼び出し、DB 同期など)→ プリンシパルを 「ユーザーがログオンしていなくても実行する」に変更する。これで根治。
  • GUI・実ブラウザ・画面共有・音声を扱うジョブ → 上の変更をしてはいけない。 非対話セッションでは実ブラウザのタブ取得や音声デバイスが機能せず、 「起動はするが無音・無画面で配信される」というより悪い失敗に化ける。 この場合は (a) OS 更新の再起動を業務時間外に固定し自動再起動を抑止する (b) 原則1のチェッカーで「未起動」を検知して人に知らせる、の2段で守る。

つまり 「起動しなかった」を根治できないケースがあると認め、 検知と通知に投資するのが正解。


原則3: 恒久対策の「効果検証」を人間のカレンダーに預けない

「設定を変えた。効いているかは N 日後にログを見れば分かる」——この N 日後は、ほぼ確実に忘れられる。 判定条件をジョブ自身に持たせ、判定日を越えたら1回だけ通知して以後黙る

例: 「セッションが既定 N 日で失効する」問題に対して無期限化の設定を入れた場合。 効いている証拠は「N 日を越えても生きていること」しか無い。

const DEFAULT_EXPIRY_DAYS = 14; // 対策前に実測した失効日数
const WARN_THRESHOLD_DAYS = 10; // 従来の事前警告の閾値

const state = loadState();           // { baselineEpochMs, verifiedForBaselineEpochMs, lastWarnedDate }
const alive = await probeLive();     // 実物を叩いて確認(推測でなく実測)
const days = Math.floor((Date.now() - state.baselineEpochMs) / 86400000);

// 判定は「いまの対象」に紐付ける。対象が更新されたら自動で判定待ちへ戻る(原則4)
const verified = state.verifiedForBaselineEpochMs === state.baselineEpochMs;

if (!alive) {
  notify(`🚨 対象が失効しています。復旧手順: ...`);   // 実害はここで即通知
} else if (!verified && days >= DEFAULT_EXPIRY_DAYS) {
  state.verifiedForBaselineEpochMs = state.baselineEpochMs;
  saveState(state);
  notify(`✅ 恒久対策が効いていることを確認しました(${days}日経過 > 既定${DEFAULT_EXPIRY_DAYS}日)。`
       + `以後この経過日数警告は停止します。最終防衛は毎回の実測チェックです。`);
} else if (verified) {
  log('確認済み → 経過日数警告はスキップ');
} else if (days >= WARN_THRESHOLD_DAYS && state.lastWarnedDate !== today) {
  // ★原則5: 検証中は文面を変える
  notify(`⚠️ ${days}日経過。**いま恒久対策の検証中です。実害が出ない限り対象を更新しないでください。**`
       + `ここで更新すると日数がリセットされ、判定(判定日 ${verdictDate})が取れなくなります。`);
  state.lastWarnedDate = today;
  saveState(state);
}

原則4: 判定フラグは「検証対象の同一性」に紐付ける

verified: true のような素のブール値で持つと、対象を作り直した後も「確認済み」のまま残り、 古い判定が新しい対象を保証してしまう。世代を表す値(epoch、世代ID、ハッシュ)を保存し、 保存値 === 現在値 で判定する。ズレたら自動的に判定待ちへ戻る。 この形にすると、対象を更新する側のコード(上の例では再ログイン処理)を一切改造せずに済む

原則5: 既存の警告文が、検証そのものを壊すことがある

上の例で最も危険なのは、従来の警告文をそのまま残すことだった。 「切れる前に更新してください」という善意の警告に人が従った瞬間、日数がリセットされ、 判定は永久に取れない。恒久対策を入れたら、既存の警告文が新しい方針と矛盾していないかを必ず見直す。

安全性とのトレードオフは次のように解く:

  • 実害が出た瞬間の通知(!alive 側)は残す・弱めない
  • 予防のための通知(日数ベース)だけ「検証中なので触らないで」に倒す

これで「本当に壊れた時は即座に人が動ける」まま、「検証は壊されない」を両立できる。


検証のやり方(この型を実装したら必ずやる)

分岐がすべて日付依存なので、時間を偽装して全分岐を実走させる。テストのために本番コードへ フラグを足すのではなく、外側から依存を差し替える。

# 依存(状態読み書き・通知)だけ stub し、実測プローブは本物のまま走らせる
node -r ./test-harness.js job.js   # harness 側で loadState/saveState/notify を差し替え
// test-harness.js(検証後は削除する)
const lib = require(require('path').join(process.cwd(), 'lib.js'));
const days = Number(process.env.TEST_DAYS);
const fake = { baselineEpochMs: Date.now() - days * 86400000 };
if (process.env.TEST_VERIFIED === '1') fake.verifiedForBaselineEpochMs = fake.baselineEpochMs;
lib.loadState = () => JSON.parse(JSON.stringify(fake));
lib.saveState = (s) => console.log('[STUB SAVE]', JSON.stringify(s));  // 本物の状態を汚さない
lib.notify = async (m) => console.log('[STUB NOTIFY]', m);             // 人に通知を飛ばさない

確認する分岐(最低4つ):

条件期待
閾値未満無言
閾値超・判定日前「検証中なので触らないで」通知
判定日到達成功通知1回+フラグ保存
判定済み・さらに経過完全にスキップ

必ず確認すること: テスト後に本物の状態ファイルが無変更であること、harness を削除したこと。 状態ファイルを実際に書き換えるテストは、翌朝の本番挙動を静かに変える。


チェックリスト

  • 成果物の存在で成功判定している(ログの有無に依存していない)
  • 「一度も起動しなかった」を検知して通知できる
  • GUI 依存ジョブに「未ログオンでも実行」を設定していない
  • 恒久対策の効果判定をジョブ自身が持ち、判定日に自動で1回通知する
  • 判定フラグが対象の世代に紐付き、対象更新で自動リセットされる
  • 検証中の通知文が「人の介入で検証が壊れる」ことを明示している
  • 実害通知(即時)は弱めていない
  • 全分岐を時間偽装で実走させ、本物の状態を汚していない

よくある質問

「無人ジョブの沈黙する失敗と効果検証の自動判定」とは何ですか?

定時ジョブが1行もログを残さずスキップされる事故の検知と、恒久対策の効果検証をジョブ自身に判定させる型。Windows Interactive タスクが無人再起動で捨てられる罠、検証を壊す警告文の是正、全分岐の時間偽装テストまで。

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

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

どうやって使いますか?

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

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

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

商用利用できますか?

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

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

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

AI代行堂を見る →

関連する巻物

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

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