作業リストが「未処理41件」と言い、実際は11件だった|完了リストをコードに焼くと必ず腐る

作業リストが「未処理41件」と言い、実際は11件だった|完了リストをコードに焼くと必ず腐る

🧭 この記事の前提 AIエージェント(Claude Code)に記事の執筆とPinterestの投稿計画を任せている個人サイトの話です。投稿そのものは人間かAIがブラウザでやるので、AIは「次に投稿する順番の一覧(手作業シート)」を作ります。
困ったのは、そのシートが「未投稿41枚」と出したのに、実物は11枚だったこと。しかも同じズレで、その1週間前に重複投稿を12件出していました。
持ち帰れるもの:AIやスクリプトに「やった/やっていない」の管理を任せている人向けに、台帳が腐る構造と、出どころを実測1つに固定する直し方を出します。手で一覧を管理している人には不要です。

結論:完了リストをコードに書いた時点で、その一覧は腐り始める

📌 先に結論 ① 「完了済み」の一覧をスクリプトの中に直書きすると、作業のたびに実態と離れていく ② 離れたまま動かすと、同じものを2回やる(今回は重複投稿12件) ③ 直し方は「更新を頑張る」ではなく、判定の出どころを実測1つに固定する

① シートは41枚、実物は11枚

投稿の手作業シートを開いたら、こう出ていました。

未投稿 41枚(8/31 15:00 から1日3枚で予約する)

一方で、状態を出す別のスクリプトは未処理4枚と言っていました。41と4。どちらも信用できない数字です。

前回、こういう食い違いを放置して投稿を進めたら、重複が12件出ました。だから今回は投稿する前に、Pinterestの画面を開いて実物を数えました

出どころ未投稿の数
手作業シート41枚
状態スクリプト4枚
実物(予約29枚+公開50枚を全件照合)11枚

シートが「未投稿」と出した中に、すでに予約済みのものが多数含まれていました。「AIに書かせると被リンク0の孤児が増える」「74本書いて検索に出たのは3ページ」「奥行き60cmに27インチ」——どれも予約一覧に入っていたものです。

② 原因:完了リストがコードの中に焼かれていた

シートを作るスクリプトの先頭に、こう書いてありました。

const PUBLISHED = `webcam katakori me-tsukare keyboard suwarikata ai-prompt ...`;
const SCHEDULED = `monitor-light samusa-goods tsukareru ai-douga claude-benri ...`;
const DONE = new Set((PUBLISHED + ' ' + SCHEDULED).split(/\s+/));

「もう投稿したもの」の一覧が、ソースコードの定数でした。

これは書いた時点では正しかった。ところが投稿は毎日続きます。投稿するたびにこの定数を手で足さないと、「未投稿」の判定がズレていく。そして足す作業は、投稿の手順に入っていなかった

つまり、このスクリプトは動かすほど嘘が増える構造でした。8/24に作ったとき、投稿済みは35枚。8/31には79枚。差の44枚ぶん、シートは「まだやっていない」と言い続けました。

③ 同じズレで、1週間前に重複投稿を12件出していた

このズレは今回が初めてではありません。8/24に同じ構造で重複ピンを12件投稿しています。

そのときはシートを作り直して日付フォルダを入れ替えた直後で、古いシートと新しいシートの両方から投稿が進んだことが原因でした。気づいたのは、Pinterestの一覧で同じタイトルの画像が2枚並んでいるのを見たときです。

削除は1件ずつ、日付とタイトルを照合してから押しました。9件を消して、3件は承認を取ってから対処しました。「未公開なので削除しても失うものはない」とはいえ、削除は取り消せない操作です。ここで雑にやると別の事故になります。

同じ穴を2回踏んだ。 1回目は削除で片付けて、原因を直していませんでした。

④ 直し方:出どころを「実測1つ」に固定した

「定数をこまめに更新する」は直し方ではありません。更新を忘れる構造がそのまま残るからです。

やったのは3つです。

(1) 実物から全件のタイトルを取る

Pinterestの予約一覧と公開一覧をブラウザで開き、全ピンのタイトルを取ってJSONに保存しました(予約29+公開50)。これが唯一の「完了」の出どころになります。

{
  "asOf": "2026-08-31T22:50:00+09:00",
  "source": "jp.pinterest.com 実査(予約一覧+作成コンテンツのalt)",
  "scheduled": ["尖った記事ほど「本人にしか分からない」", "..."],
  "published": ["自分の site: 検索が順位データを汚していた", "..."]
}

asOf を必ず入れています。いつ測った数字かが無い台帳は、古いのか新しいのか判別できないからです。

(2) 手元の画像と突き合わせる差分スクリプト

89枚のピン画像それぞれについて、タイトルが上のJSONに含まれていなければ未投稿、という判定だけをします。完了リストは持ちません。

const live = JSON.parse(fs.readFileSync('state/pinterest-live.json', 'utf8'));
const done = new Set([...live.scheduled, ...live.published].map(norm));

for (const f of pinFiles) {
  const title = titleOf(f);
  if (!done.has(norm(title))) unposted.push({ file: f, title });
}

(3) 表記のゆれを畳む

ここで1つ落とし穴がありました。公開側は「原因つ」、手元のキューは「原因6つ」。全角と半角です。畳まないと投稿済みのものが未投稿に見える

const norm = (s) => String(s)
  .replace(/[0-9]/g, (c) => String.fromCharCode(c.charCodeAt(0) - 0xfee0)) // 0-9 → 0-9
  .replace(/[!-~]/g, (c) => String.fromCharCode(c.charCodeAt(0) - 0xfee0)) // !-~ → !-~
  .replace(/\s+/g, '').replace(/[|| ]/g, '').toLowerCase();

これを入れる前は「未投稿26枚」、入れた後は「11枚」でした。15枚は表記ゆれだけの差です。

(4) 機械で消し込めないものに印を付ける

最後に残った11枚のうち1枚は、タイトルを言い換えて投稿済みでした。手元は「夏に冷やすのは部屋ではなく自分と機器」、予約一覧は「在宅の夏に効く道具を効果の大きい順に5つ」。同じ記事です。

これは機械では判定できません。だから差分スクリプトは、似たタイトルが既にあるものに⚠を付けて人の照合に回すようにしました。判定はしない。順番だけ出す。

📌 ここだけ持ち帰るなら 完了リストは持たない。実物から毎回取る。取った日時を残す。機械で決められないものは決めずに印を付ける。

⑤ 直した後に分かったこと

実測で数え直したら、台帳の「公開47件」も誤りで、実際は50件でした。手で書いた数字は、書いた瞬間から古くなります。

差分スクリプトが「未投稿11枚」を出した時点で、投稿は1晩で終わりました。数える手間が消えたので、投稿そのものに時間を使えた。それまでは「今どれが未投稿か」を確かめるだけで毎回30分かかっていました。

自分でやる手順

  1. 「完了」の一覧がどこにあるかを探す。 スクリプトの定数、スプレッドシートの手入力列、チャットの記憶——そこにあるなら腐る
  2. 実物から取る手段を作る。 APIでも、画面のスクレイプでも、手でコピーしても構わない。測った日時を必ず残す
  3. 判定は「実物に無いもの=未完了」の1方向だけにする。 完了リストを別に持たない
  4. 表記ゆれを畳む。 全角半角・空白・記号。畳む前と後の件数の差が、ゆれの量
  5. 機械で決められないものは決めない。 印を付けて人に回す
  6. 削除は照合結果のファイル名をそのまま使う。 手で並べ直した瞬間、照合は無効になる

やりがちな失敗

失敗何が起きるか直し方
完了リストをコードに直書きする作業のたびにズレる。ズレは増える一方実物から毎回取る
「こまめに更新する」で直そうとする更新を忘れる構造が残る更新が要らない形にする
台帳の数字を信じて作業を始める同じものを2回やる(今回は重複12件)作業の直前に数え直す
表記ゆれを畳まない投稿済みが未投稿に見える(今回15枚)全角半角・空白・記号を正規化する
機械に合否を出させる言い換えたものを見逃す順番だけ出して合否は人が決める
削除リストを手で書く照合していないものを消す照合結果をそのまま入力にする

似た構造の事故はほかにもありました。作業リストの「残り6社」のうち4社が存在しなかった話はAIのTODOは実査で棚卸しする、検査スクリプト自体が嘘をついた話はAIの成果物を計算で検証するにあります。同じ検査を2度サボって同じ穴に落ちた記録は被リンク0の孤児が量産されるに、Pinterestのピンを実際の表示幅で検品する話は原寸で検品してはいけないにまとめています。

まとめ

  1. 完了リストをコードに書いた時点で、その一覧は腐り始める。 動かすほど嘘が増える
  2. 腐った台帳で作業すると、同じものを2回やる。 今回は重複投稿12件だった
  3. 直し方は更新ではなく、出どころを実測1つに固定すること。 完了リストを持たない
  4. 測った日時を残す。表記ゆれを畳む。機械で決められないものは決めない
  5. 削除は照合結果をそのまま使う。 手で並べ直したら、照合はしていないのと同じ