{
  "$comment": [
    "オートパイロットの実費台帳。VISION/Runbookが『判断の根拠はファイルに落とす』",
    "と定めているのと同じ理由で、AIの実費も散文ではなくファイルに置く。",
    "",
    "【なぜ必要か】2026-08-22時点で、この運用のトークン実費は『1回だけ観測された",
    "0.81 USD』しか無かった。予算の話は全部その1点の周りの推測で行われており、",
    "『予算に応じて配分する』と外に言える状態ではなかった。まず測る。",
    "",
    "【誰が書くか】obsidian-autopilot.yml の post ステップが、claude-code-action の",
    "実行ログ（claude-execution-output.json）から total_cost_usd / num_turns を取って",
    "1行追記する。手で書かない。追記に失敗しても出荷は止めない（continue-on-error）",
    "— フォント導入と同じで、計測は記事より優先されてはいけない。",
    "",
    "【何を測れていないか（重要）】CCR Routine（副系07:30 / 再試行09:20）の実費は",
    "ここに入らない。スケジュール起動セッションのログは外部から読めないため",
    "（Runbook §0-2）。2026-08-22時点で実出荷はすべて副系が行っているので、",
    "この台帳がカバーしているのは『主系の消費』だけであり、運用全体の実費ではない。",
    "route フィールドでどちらか分かるようにしてあり、集計もrouteごとに出す。",
    "measured_coverage に、その月に主系が何回動いたかを併記する。",
    "",
    "【上限の使われ方】scripts/autopilot-budget.mjs --check が当月実績を集計し、",
    "monthly_usd_cap を超えていれば exit 1 を返す。obsidian-autopilot.yml の Gate が",
    "これを見て run=false にする。つまり上限は表示用ではなく、実際に自分を止める。"
  ],
  "$weekly_quota_note": "**月次上限（$280）と、週次の使用量上限は別物。**混ぜると片方が緑でもう片方で止まる。（2026-09-03）\n\n  この台帳の monthly_usd_cap … トークンのAPI換算額を月で積んだ notional な上限。\n                               autopilot-budget --check が見て、主系の Gate を止める。\n  週次の使用量上限           … Claude サブスクのレート上限（rate_limit_info の seven_day）。\n                               **アカウント全体で共有**され、同じアカウントの対話セッションも同じ枠を食う。\n\n**2026-08-30・08-31 に出荷が丸ごと消えたのは後者で、この台帳の数字がいくら小さくても起きる。**実際その2日の当月実費は上限の1割にも届いていなかった。実測（2026-09-03）でも、ある週次窓で枠を消費していたのは圧倒的に autopilot 以外で、autopilot の寄与はごく一部だった。**金額は書かない** —— この台帳は data/autopilot-status.json 経由で本番に公開されるので、オーナー個人の対話セッションの消費額を載せる場所ではない（Runbook §5-5 と同じ規律）。\n\n**したがって『AI実費 $X / 上限 $280』を週次上限の余力として読まないこと。**この2つは分母が違う。月次上限を上げても週次上限は1ミリも動かない（逆も同じ）。\n\n**副系CCRの実費は「観測手段が無い」と上に書いてあるが、正確には経路による。**オーナー起動の対話セッションは `list_sessions` / `get_session` の `external_metadata.usage.cost_usd` で読める（2026-09-03 に実測）。**スケジュール起動（Routine）の副系が同じように読めるかは未確認** —— `list_sessions` の既定はトリガー発火ぶんを返さない。**読めるようにする＝公開面に載せる**ことでもあるので、取り込むかどうかはオーナーの判断（金額の公開可否）。\n\n**対応はプラン階層（オーナー判断・2026-09-03）。**実際の消費は x20 プランに収まるという判断で、追加の課金経路（ANTHROPIC_API_KEY）は引き続き使わない（PR #808）。",
  "budget": {
    "monthly_usd_cap": 280,
    "cap_set_by": "ai",
    "cap_note": "9/1〜9/7の主系実測9回は$67.0402（記事5回$34.1601、修理3回$32.6421、分析1回$0.2380）。修理は旧月次枠$60の54.4%を既に消化し、記事は旧$180の19.0%。月次総額は$280を維持し、月初の少数標本や未観測CCRを根拠に総額を増やさない。分析・広報・QA・監査の予備枠$40を維持し、主たる2種別の$240を実消費比で配分、修理枠を$5刻みに丸めて$115、記事を残り$125にする。最適配分や月次実費の確定値ではなく、修理が枠を先に使い切る偏りへの暫定対応。1回上限・月次停止・未レビュー超過の停止・開始前想定の5倍超エスカレーションを維持する。\n決定: data/spend-approvals.json#seq=3。副系CCRは未観測、月次実測完了とは扱わない。",
    "on_exceed": "skip_run",
    "on_exceed_note": "上限超過時は当日の主系runをGateで止める。副系CCRは別経路なので止まらない（止める手段が無い — Runbook §0-2の『CCRのログは外部から読めない』と同じ制約）。ここも正直に書いておく。",
    "anomaly": {
      "$comment": [
        "異常消費の検知。**絶対額のしきい値は置かない。**",
        "実績が1点しか無い段階で『$5を超えたら異常』と決めると、それは推測であって基準ではない。",
        "代わりに**直近の中央値との比**で見る。中央値は実績が増えるほど正確になるので、",
        "基準そのものが自己較正される。",
        "",
        "median_window … 中央値を取る直近run数",
        "multiple      … 中央値の何倍を異常とみなすか",
        "min_samples   … これ未満の実績数では判定しない（**判定できないことを異常と言わない**）",
        "min_absolute  … 中央値が極小のとき比だけだと過敏になるので、この額未満は無視する"
      ],
      "median_window": 14,
      "multiple": 4,
      "min_samples": 5,
      "min_absolute_usd": 2
    },
    "task_budgets": {
      "article": {
        "monthly_usd_cap": 125,
        "note": "2026-09-07 AI月次決定。data/spend-approvals.json#seq=3の実績・理由に基づく配分。"
      },
      "repair": {
        "monthly_usd_cap": 115,
        "note": "2026-09-07 AI月次決定。data/spend-approvals.json#seq=3の実績・理由に基づく配分。"
      },
      "analysis": {
        "monthly_usd_cap": 12,
        "note": "2026-09-07 AI月次決定。data/spend-approvals.json#seq=3の実績・理由に基づく配分。"
      },
      "pr": {
        "monthly_usd_cap": 12,
        "note": "2026-09-07 AI月次決定。data/spend-approvals.json#seq=3の実績・理由に基づく配分。"
      },
      "qa_triage": {
        "monthly_usd_cap": 8,
        "note": "2026-09-07 AI月次決定。data/spend-approvals.json#seq=3の実績・理由に基づく配分。"
      },
      "audit": {
        "monthly_usd_cap": 8,
        "note": "2026-09-07 AI月次決定。data/spend-approvals.json#seq=3の実績・理由に基づく配分。"
      }
    },
    "$task_budgets_note": [
      "種別配分の合計はmonthly_usd_cap以下。monthly-budgetのAI判断は主系の部分月観測に限り、全体費用の最適配分の実証ではない。",
      "runtimeBudgetが月次残枠・種別残枠・1回上限の最小値をSDKへ渡す。ある種別の枠切れで他種別まで停止せず、月次枠は全体を止める。"
    ],
    "task_budgets_set_by": "ai_monthly_decision",
    "cap_basis": "extrapolation",
    "$cap_basis_note": "上限が何に基づくか。**'measured' になるまで「予算に応じて配分している」と対外的に言わない。**\n  placeholder    … 実測1点からの粗い外挿（〜2026-09-02）\n  extrapolation  … run 単位の実測（n=6）を日次×30日へ伸ばした外挿（2026-09-03〜）\n  measured       … 月次の実測が2週間ぶん貯まり、そこから決め直した\n**[なぜ足したか] 自制が散文だけになりかけた。**この注記を出す条件は cap_set_by === 'placeholder' で、オーナーが額を決めた瞬間に**注記ごと消える**形になっていた。だが消えてよいのは「オーナー未確認」の部分だけで、「まだ実測ではない」ほうは残る。**額を誰が決めたか（cap_set_by）と、何に基づくか（cap_basis）は別。**",
    "decision_ref": "data/spend-approvals.json#seq=3"
  },
  "runs": [
    {
      "date_jst": "2026-08-22",
      "route": "actions",
      "run_id": "32528028588",
      "job_id": "96914156036",
      "total_cost_usd": 0.8149038,
      "num_turns": 30,
      "outcome": "no_artifact",
      "note": "permission_denials_count=14 で成果物ゼロのまま success 終了。modelUsage は claude-haiku-4-5 と claude-sonnet-5 の2つ。実費は発生しているが記事は出ていない — 『成功したのに何も出ていない』回のコストがここに残る。",
      "models": [
        "claude-haiku-4-5-20251001",
        "claude-sonnet-5"
      ],
      "task_kind": "article"
    },
    {
      "date_jst": "2026-08-23",
      "route": "actions",
      "run_id": "32599191984",
      "total_cost_usd": 7.296703800000001,
      "num_turns": 150,
      "outcome": "shipped",
      "note": "日次アクチュエータが自動追記（ジョブログの result 行） ／【2026-08-25 追記】**task_kind が空だった。**アクチュエータは lane/action から種別を導けるとき『だけ』書く規則で、この行は導出が入る前に追記されている。**種別が無い run は1回あたりの上限を判定しない**（判定していない ≠ 上限内）ので、空のままだと article の上限 $2.00 に対する $7.2967（3.6倍）が素通りする。手で補った。",
      "job_id": "97094799837",
      "task_kind": "article",
      "models": [
        "claude-haiku-4-5-20251001",
        "claude-sonnet-5"
      ],
      "cap_review": {
        "at": "2026-08-25",
        "by": "owner",
        "why": "主系の初出荷回。前日の故障（ap-20260822-actions）の修理を含む150ターン・17分の実行で、内容そのものは妥当と判断した。上限$2.00は実績n=1（$0.8149）から置いた暫定値で、上限側が過小。実測5件で異常検知が自己較正されるので、そこから再導出する。オーナー承認 2026-08-25"
      }
    },
    {
      "date_jst": "2026-08-24",
      "route": "actions",
      "run_id": "32667079679",
      "total_cost_usd": 0,
      "num_turns": 1,
      "outcome": "failed",
      "note": "日次アクチュエータが自動追記（ジョブログの result 行）",
      "task_kind_unavailable": {
        "provider": "github_job",
        "reason": "predates_routing_step",
        "run_id": "32667079679",
        "job_id": "97262077233",
        "run_attempt": 1,
        "started_at": "2026-08-23T21:17:50Z",
        "completed_at": "2026-08-23T21:18:43Z",
        "routing_step_count": 0,
        "model_step_number": 6
      }
    },
    {
      "date_jst": "2026-08-25",
      "route": "actions",
      "run_id": "32779337325",
      "total_cost_usd": 0,
      "num_turns": 1,
      "outcome": "failed",
      "note": "日次アクチュエータが自動追記（ジョブログの result 行）",
      "task_kind_unavailable": {
        "provider": "github_job",
        "reason": "predates_routing_step",
        "run_id": "32779337325",
        "job_id": "97597672697",
        "run_attempt": 1,
        "started_at": "2026-08-24T21:24:43Z",
        "completed_at": "2026-08-24T21:25:27Z",
        "routing_step_count": 0,
        "model_step_number": 6
      }
    },
    {
      "date_jst": "2026-08-25",
      "route": "actions",
      "run_id": "32816234185",
      "job_id": "97704991438",
      "total_cost_usd": 11.932870250000008,
      "num_turns": 104,
      "task_kind": "repair",
      "outcome": "shipped",
      "note": "レーンF（修理）。ap-20260824-actions / ap-20260825-actions の即時失敗を修理し、両方に resolved_at が入った（data/autopilot-runs.json の ap-20260825-actions-force）。104ターン・27分。**repair の1回上限 $3.00 に対し 3.98倍。**月枠 $8.00 も、この1回だけで超えている。**この行は2026-08-25に手で入れた** — 日次アクチュエータの追記は09:00 JSTで、この run が終わったのは15:44 JST。次の追記は翌日09:00 JSTになるが、翌日の主系は06:17 JSTに走るので、**このままだとゲートが超過を知らないまま1日走る**　【2026-08-25 訂正】この note は当初「認証系即時失敗」と書いていたが、**種別は誤りだった。**実際は上流 claude-code-action の版の破損（upstream_action_regression）で、data/autopilot-runs.json の failure_class_original / reclassified_note に経緯がある。ただし同runの直前にオーナーが CLAUDE_CODE_OAUTH_TOKEN も更新しているため、**版とトークンのどちらが効いたかはこの観測からは分離できていない**（版の相関は強いが排除ではない）。",
      "cap_review": {
        "at": "2026-08-25",
        "by": "owner",
        "why": "2026-08-25のセッションでオーナーが明示的に権限を委譲して解除（「権限を与えるのでやって」）。支出そのものは妥当と判断した: 104ターン・27分で ap-20260824/25 の2件を修理して出荷しており、内容に無駄な反復は無い。**ただし本質は支出ではなく上限の較正。** 実測5件のうち task_kind が付いた3件を見ると、実際に仕事をして出荷した run は2件（article $7.2967 / repair $11.9329）で、そのどちらも1回上限を超えている。**上限を満たしたのは失敗した run（$0.8149）だけ。** 上限 $2.00/$3.00 は失敗runのn=1から外挿した placeholder で、成功runを一度も許容していない。さらに repair は monthly_usd_cap $8 に対し1回が $11.93 で、月枠が1回分に足りていない。上限の再設定は monthly_usd_cap の決定を含み権限表で human_only なので、ここでは解除だけを行い、較正は数値つきで台帳に残す（act-budget-recalibrate）"
      }
    },
    {
      "date_jst": "2026-08-26",
      "route": "actions",
      "run_id": "32900786201",
      "total_cost_usd": 7.877065000000003,
      "num_turns": 162,
      "task_kind": "article",
      "outcome": "shipped",
      "note": "日次アクチュエータが自動追記（ジョブログの result 行）"
    },
    {
      "date_jst": "2026-08-30",
      "route": "actions",
      "run_id": "33279844326",
      "total_cost_usd": 0,
      "num_turns": 1,
      "outcome": "failed",
      "note": "日次アクチュエータが自動追記（ジョブログの result 行）",
      "task_kind": "article",
      "task_kind_source": {
        "provider": "github_job_log",
        "run_id": "33279844326",
        "job_id": "99173041910",
        "run_attempt": 1,
        "step_number": 7,
        "observed_at": "2026-08-29T22:58:23.2955913Z",
        "task_kind": "article"
      }
    },
    {
      "date_jst": "2026-08-31",
      "route": "actions",
      "run_id": "33340960317",
      "total_cost_usd": 0,
      "num_turns": 1,
      "outcome": "failed",
      "note": "日次アクチュエータが自動追記（ジョブログの result 行）",
      "task_kind": "article",
      "task_kind_source": {
        "provider": "github_job_log",
        "run_id": "33340960317",
        "job_id": "99336390574",
        "run_attempt": 1,
        "step_number": 7,
        "observed_at": "2026-08-30T23:07:35.0288424Z",
        "task_kind": "article"
      }
    },
    {
      "date_jst": "2026-09-01",
      "route": "actions",
      "run_id": "33454414490",
      "total_cost_usd": 9.3726075,
      "num_turns": 99,
      "task_kind": "repair",
      "outcome": "shipped",
      "note": "本日（09-02）のセッションがジョブログの result 行から追記。09-01 の主系はレーンFで PR #749 を出しており、運転台帳には行が無い（act-ledger-sync として未処理）。"
    },
    {
      "date_jst": "2026-09-02",
      "route": "actions",
      "run_id": "33568838189",
      "total_cost_usd": 13.5739125,
      "num_turns": 139,
      "task_kind": "repair",
      "outcome": "shipped",
      "note": "日次アクチュエータが自動追記（ジョブログの result 行）"
    },
    {
      "date_jst": "2026-09-03",
      "route": "actions",
      "run_id": "33692832179",
      "total_cost_usd": 3.7802126000000005,
      "num_turns": 103,
      "task_kind": "article",
      "outcome": "shipped",
      "note": "日次アクチュエータが自動追記（ジョブログの result 行）"
    },
    {
      "date_jst": "2026-09-04",
      "route": "actions",
      "run_id": "33815445009",
      "total_cost_usd": 5.0613790000000005,
      "num_turns": 114,
      "task_kind": "article",
      "outcome": "shipped",
      "note": "日次アクチュエータが自動追記（ジョブログの result 行）"
    },
    {
      "date_jst": "2026-09-05",
      "route": "actions",
      "run_id": "33926832821",
      "total_cost_usd": 4.8768404,
      "num_turns": 94,
      "outcome": "failed",
      "note": "日次アクチュエータが自動追記（ジョブログの result 行）",
      "task_kind": "article",
      "task_kind_source": {
        "provider": "github_job_log",
        "run_id": "33926832821",
        "job_id": "101197075645",
        "run_attempt": 1,
        "step_number": 8,
        "observed_at": "2026-09-04T22:45:53.1410848Z",
        "task_kind": "article"
      }
    },
    {
      "date_jst": "2026-09-05",
      "route": "actions",
      "run_id": "33959414641",
      "total_cost_usd": 0.8407852,
      "num_turns": 20,
      "note": "日次アクチュエータが自動追記（ジョブログの result 行。結果は運転台帳で判明した場合のみ）",
      "task_kind": "article",
      "task_kind_source": {
        "provider": "github_job_log",
        "run_id": "33959414641",
        "job_id": "101288543517",
        "run_attempt": 1,
        "step_number": 8,
        "observed_at": "2026-09-05T09:59:17.1464223Z",
        "task_kind": "article"
      },
      "outcome": "no_artifact"
    },
    {
      "date_jst": "2026-09-06",
      "route": "actions",
      "run_id": "33996430959",
      "total_cost_usd": 19.600872199999998,
      "num_turns": 251,
      "outcome": "failed",
      "note": "日次アクチュエータが自動追記（ジョブログの result 行。結果は運転台帳で判明した場合のみ）",
      "task_kind": "article",
      "task_kind_source": {
        "provider": "github_job_log",
        "run_id": "33996430959",
        "job_id": "101387673341",
        "run_attempt": 1,
        "step_number": 8,
        "observed_at": "2026-09-05T22:37:27.1089806Z",
        "task_kind": "article"
      },
      "cap_review": {
        "at": "2026-09-06",
        "by": "owner",
        "why": "オーナーが2026-09-06に今回の19.6009ドル超過と主系停止の確認へ「上限あげていいです」と応答し、上限引き上げと停止解除を委譲した。実測19.6008722ドルを収める1回20ドルへ設定し、月次280ドルは維持する。failedの結果と実費は変更せず、当時の10ドル超過をレビュー済みとして保存する。"
      }
    },
    {
      "date_jst": "2026-09-06",
      "route": "actions",
      "run_id": "34016914073",
      "total_cost_usd": 0.23801699999999998,
      "task_kind": "analysis",
      "note": "AI visibility measurement; measured CLI cost. Observation status is in data/ai-visibility-probe.json; no product shipment is claimed."
    },
    {
      "date_jst": "2026-09-07",
      "route": "actions",
      "run_id": "34064655036",
      "total_cost_usd": 9.695607500000003,
      "num_turns": 95,
      "task_kind": "repair",
      "task_kind_source": {
        "provider": "github_job_log",
        "run_id": "34064655036",
        "job_id": "101571187173",
        "run_attempt": 1,
        "step_number": 8,
        "observed_at": "2026-09-06T22:39:41.4514479Z",
        "task_kind": "repair"
      },
      "note": "日次アクチュエータが自動追記（ジョブログの result 行。結果は運転台帳で判明した場合のみ）",
      "outcome": "shipped"
    },
    {
      "date_jst": "2026-09-09",
      "route": "actions",
      "run_id": "34291656440",
      "total_cost_usd": 0,
      "task_kind": "analysis",
      "note": "AI visibility measurement; measured CLI cost. Observation status is in data/ai-visibility-probe.json; no product shipment is claimed."
    },
    {
      "date_jst": "2026-09-12",
      "route": "actions",
      "run_id": "34698479441",
      "total_cost_usd": 0,
      "task_kind": "analysis",
      "note": "AI visibility measurement; measured CLI cost. Observation status is in data/ai-visibility-probe.json; no product shipment is claimed."
    },
    {
      "date_jst": "2026-09-19",
      "route": "actions",
      "run_id": "35415451723",
      "total_cost_usd": 6.044565000000002,
      "num_turns": 66,
      "task_kind": "repair",
      "task_kind_source": {
        "provider": "github_job_log",
        "run_id": "35415451723",
        "job_id": "105823105725",
        "run_attempt": 1,
        "step_number": 8,
        "observed_at": "2026-09-19T02:22:38.0265735Z",
        "task_kind": "repair"
      },
      "outcome": "shipped",
      "note": "日次アクチュエータが自動追記（ジョブログの result 行。結果は運転台帳で判明した場合のみ）"
    }
  ],
  "$backfill_note": "**2026-08-25 更新。**旧記述は『runs は 2026-08-22 の1件のみ／この台帳に欠落は無い』だったが、**それは run 1〜11 までの話で、その後の3回を数えていなかった。**run 12（08-23・$7.2967・出荷）が抜けており、当月の実費を $0.8149 と表示していた。実際は $8.1116。\n\n抜けた原因は構造にあった。ワークフローの実費ステップは**金額を出力して『翌日のセッションが台帳へ入れること』と書くだけ**で、追記する主体が翌日の実行そのもの。その翌日（08-24）の主系が即時失敗したため、追記する者がいなかった。**記録が最も要る回＝失敗した回に、記録が落ちる。**\n\n**この穴は日次アクチュエータ（scripts/autopilot-act.mjs の append-cost）で塞がれた。**ジョブログから読んで自動追記するので、翌日の実行が落ちても記録は残る。ただし**種別（task_kind）は lane/action から導けるときだけ書く**規則なので、導出できない回は空のまま残る。空の行は1回あたりの上限を判定しないため、**種別の欠落は上限の素通りに直結する。**08-23 の行はこれに当たり、手で補った。\n\n現在の内訳: run 1〜8 Gateスキップ（Claude Code未実行＝実費ゼロ）／9 apt詰まりで cancelled／10 allowed_bots で failure／11 成果物ゼロ $0.8149／**12 出荷 $7.2967**／13・14（08-24・08-25）は初回モデル呼び出しの時点で失敗し modelUsage が空・$0。",
  "$schedule_note": "**追記のタイミングと、1回上限ゲートの関係。**（2026-08-25）\n\n**定時実行に穴は無い。**主系 obsidian-autopilot は 06:00 JST 起動・timeout-minutes 90 なので、遅くとも 07:30 JST には終わる。日次アクチュエータ（autopilot-act の append-cost）は 09:00 JST なので、その日の実費を必ず同じ朝のうちに拾う。翌日 06:00 の主系は、前日分が入った台帳を読む。\n\n**穴があるのは臨時実行だけ。**`workflow_dispatch` で走らせて **09:00 JST を過ぎて終わった回**は、アクチュエータの次の追記が翌日09:00になる。翌日の主系は06:00＝それより前に走るので、**その回の超過を知らないまま1日走る。**実際に run 32816234185（15:44 JST 終了・$11.9329）で起きたので、この行は手で `--append` した。**臨時実行を撃ったら、終了時刻を見て手で入れること。**\n\n**⛔ アクチュエータを主系より前へ動かして直そうとしないこと。**05:00 JST に動かすと、前日分は前日09:00に追記済みで新しいものが無く、その日の実費は翌日05:00まで入らない。**いま動いているサイクルを1日ぶん悪化させる。**\n\n**訂正:** PR #570 の本文とコミット文に『同じ順序である限り毎回1日遅れる』と書いたが、**これは誤り。**定時実行では起きない。Actionsのログが UTC 表示であるのを JST と読み違えたことによる一般化の誤りで、run 32816234185 についての記述自体（15:44 JST 終了）は正しい。"
}
