{
  "$comment": [
    "全領域の自動化カバレッジ台帳 — 開発以外もすべて同じ物差しで測る。",
    "",
    "【なぜ作るか】2026-08-22時点で、この運用の自動化率について言えたのは",
    "**開発領域だけ**だった（AI完走率76.9% / 変更行のAI比率94.2%）。",
    "マーケティングも経営も『部分実装』としか言えず、どのくらい部分なのかを",
    "数で示せなかった。この台帳はそこを埋める。",
    "",
    "【executor の定義】タスクを**誰が実行しているか**で6分類する。",
    "  ai_autonomous     … AIが起動から完了まで単独。人の承認もゲートも待たない",
    "  ai_executes_gated … AIが実行するが、ゲート（CI・上限・品質基準）を通ったときだけ通る。",
    "                      人の個別承認は不要。**この運用の主力はここ**",
    "  ai_proposes       … AIは提案・下書き・検知まで。適用/実行は人間",
    "  human_only        … 人間が実行。AIは関与しない（または意図的に関与させない）",
    "  nobody            … 誰もやっていない（未実装）",
    "  intentional_no    … 意図的にやらない。分母から外す",
    "",
    "【4つの率を必ず並べて出す】分母を1つに決めると必ず都合のよい数字になる。",
    "  総合自動化率 = (autonomous + gated) / 定義タスク      … nobody を分母に含む。最も厳しい",
    "  AI実行率     = (autonomous + gated) / 実施中タスク    … nobody を除いた分母",
    "  AI関与率     = (上記 + proposes)    / 実施中タスク",
    "  カバー率     = 実施中タスク         / 定義タスク      … そもそも誰かがやっている割合",
    "**総合自動化率とカバー率を隠して AI関与率だけ出すのが、この台帳で一番やってはいけないこと。**",
    "",
    "【この測り方の限界（先に書く）】",
    "  1. **タスク数の重み付けが粗い。**「記事の実装」と「SBOM生成」が同じ1として数えられる。",
    "     開発領域には変更行という別の物差しがある（AI 94.2%）が、他領域には無い。",
    "     したがって領域間の比較は**傾向**であって、精度のある比較ではない。",
    "  2. **タスクの粒度が領域で揃っていない。** 法人経営は外部レビューの列挙をそのまま",
    "     採ったため粒度が粗く、マーケは実装単位まで細かい。前者が低く出るのは事実だが、",
    "     粒度の差も混ざっている。",
    "  3. **evidence が無い分類は主張として弱い。** ai_autonomous / ai_executes_gated は",
    "     証跡ファイルを持つことを CI が強制する（scripts/automation-rate.mjs --check）。",
    "",
    "【出典】タスクの列挙は docs/autopilot-maturity-backlog.md（外部レビュー由来）と、",
    "本セッションで実測した内容。分類は3リポジトリの実装を1件ずつ当てて決めた。",
    "",
    "【blocker / unblocked_by / unlock（2026-08-26追加）】",
    "AI が実行していないタスクには **なぜ実行していないか** を必ず持たせる。",
    "無いと総合自動化率は『残りぶん実装すれば埋まる』と読まれるが、実際には",
    "**大半が実装量ではなく外部データ・鍵・権限境界・検出力で止まっている。**",
    "分類は scripts/autonomy-gap.mjs の BLOCKERS が正で、CI がそれ以外の値を落とす。",
    "policy_boundary と physical_human は **オーナーが境界を動かさない限り到達しない**。",
    "この2つを到達可能側に数えるのが、この台帳で二番目にやってはいけないこと。",
    "",
    "unlock は解除条件のまとまり。**1タスク＝1作業ではない** —— ASCのレポートが降りれば",
    "複数件が同時に動く。個別に積むと順番を間違えるので、解除する行為のほうを単位にする。"
  ],
  "measured_at": "2026-08-26",
  "known_limits": [
    "タスク数の重み付けが粗い（全タスクが等価に数えられる）",
    "タスク粒度が領域間で揃っていない（法人経営は粗く、マーケは細かい）",
    "開発領域の変更行比率94.2%に相当する客観指標が他領域には無い"
  ],
  "tasks": [
    {
      "area": "① 次期機能開発",
      "task": "ビジョン文書の維持（機能追加の必読ゲート）",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/scripts/qa/check_vision.py",
        "../simplememo-ios/docs/VISION.md",
        "../simplememo-ios/.github/workflows/qa-static.yml",
        "CLAUDE.md",
        "../simplememo-api/CLAUDE.md",
        "../simplememo-ios/CLAUDE.md"
      ],
      "note": "2026-08-22実装。**参照と鮮度を機械が守る。**3リポジトリの CLAUDE.md が「設計に入る前に読め」と指す唯一の文書なのに、**参照が壊れても誰も落ちなかった** — 壊れたことは「読んだ人が違う節を読んで帰る」という形でしか現れず、しかもその人は自分が違う節を読んだことに気づかない。初回の実行で1件出た: 冒頭が「最後の『12. 機能追加時のチェック』が実際のゲート」と書いていたが §12 は「現在地」で、チェックは §13。**読者を1つ手前の節へ送っていた**（3リポジトリのCLAUDE.mdはどれも §13 と正しく書いており、間違っていたのはこの文書の自分自身への参照だけだった）。節番号の解決・必須節の存在・**現在地が90日を超えたら落とす**・未決定が空でないこと、の4つ。4通りとも壊した状態を作って落ちることを確認した。残る弱さ: **中身が正しいかは見ていない**（ビジョンの正しさは機械には決められない）。定期改訂そのものは人が書く — 機械がやるのは古くなったことを言うところまで",
      "since": "2026-08"
    },
    {
      "area": "① 次期機能開発",
      "task": "AIが変更してはいけない安全原則の固定",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/docs/VISION.md",
        ".github/workflows/seo-check.yml"
      ],
      "note": "VISION §9「作らないもの」＋§13の6問。claude.ymlのactions:write非付与"
    },
    {
      "area": "① 次期機能開発",
      "task": "要望・レビュー・問い合わせ・競合情報の重複排除",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/signal-ledger.json",
        "scripts/check-signals.mjs"
      ],
      "note": "2026-08-22実装。要望・レビュー・問い合わせ・競合・利用実態を1台帳に統合し、dedupe_key で同じ話を1行にする。**声の大きさを「何回転記されたか」で測らないため。**実際「送信の確実性」は問い合わせ・レビュー実測・アンケートの3経路から来ており、台帳を作るまで別々の紙に載っていた。declined は理由が無いとCIが落ちる",
      "since": "2026-08"
    },
    {
      "area": "① 次期機能開発",
      "task": "期待効果・確信度・工数・リスクによる自動優先順位付け",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/feature-backlog.json",
        "scripts/feature-score.mjs",
        ".github/workflows/seo-check.yml"
      ],
      "note": "2026-08-22実装。**確信度は evidence_strength から機械的に決まり、手で置けない**（主観にすると順位はいくらでも動く）。リスクは点数を下げるのではなく承認を要求する — 掛け算にすると期待効果が大きければ危険な案が1位になる。根拠が弱い候補は「やらない」ではなく「まず測る」に落ちる"
    },
    {
      "area": "① 次期機能開発",
      "task": "ユーザー要望の受領と未処理の検知",
      "executor": "ai_autonomous",
      "evidence": [
        "../simplememo-ios/scripts/asc_metrics.rb",
        "../simplememo-ios/.github/workflows/asc-metrics.yml",
        "scripts/review-intake.mjs",
        "data/review-intake.json"
      ],
      "note": "2026-08-22実装。App Store レビューを日次で取り込み、**未処理が14日を超えたらCIが落ちる**。受け取っただけで放置される状態を検知する。台帳は取り込みと同日に作ったので空から始まる — **空であること自体は異常ではなく、取り込みが動いたあとも空のままなのが異常**。日次実行そのものは run 32599889435（2026-08-22 21:32 UTC・event=schedule）で発火を確認済み"
    },
    {
      "area": "① 次期機能開発",
      "task": "受領した要望の設計への落とし込み",
      "executor": "ai_proposes",
      "evidence": [
        "../simplememo-ios/docs/reports/feature_requests_2026-07-31_obsidian_user.md"
      ],
      "note": "AIが設計文書まで。採否はオーナー判断。**受領（機械）と分けたのは、片方だけ自動化されている状態を1行に潰さないため。**混ぜると『要望を受け取れているか』と『設計まで自動か』が同じ1行になる\n\n**[2026-08-28] 到達可能側から外した（分類の訂正）。**設計文書までは機械が出しており、残っているのは**採否の判断**。そこは実装量では動かない。\n**害は件数ではなく向きに出る** —— `--plan` が「作れば進む」と言い続け、天井が実際より高く出る。到達可能な件数は減るが、**下がった天井のほうが本物。**",
      "blocker": "policy_boundary",
      "unblocked_by": "採否はオーナー判断。設計文書までは機械が出している",
      "$authority_absent": "権限表が扱うのは**実行の権限**で、機能の採否はそこに無い。採否の根拠は VISION（作らないものの定義）と data/feature-backlog.json 側にある"
    },
    {
      "area": "① 次期機能開発",
      "task": "継続率データによる優先度判断",
      "executor": "ai_proposes",
      "evidence": [
        "../simplememo-api/docs/reports/RETENTION_MONETIZATION_COHORT_2026-07-29.md"
      ],
      "note": "D7継続2.5〜3.7倍を根拠に優先度決定。決定は人",
      "blocker": "external_data",
      "unblocked_by": "**[2026-09-02 実測] 「BigQuery の28日蓄積待ち」は、この行に対しては成立しない。**\n\nBigQuery を直接叩いて中身を数えた（project `yurika-simplememo`）:\n\n    データセット   `searchconsole` **1つだけ**\n    テーブル       ExportLog / searchdata_site_impression / searchdata_url_impression\n    列             data_date / site_url / query / country / search_type / device /\n                   impressions / clicks / sum_top_position\n\n**継続率も install も user も無い。**Search Console は検索の露出とクリックであって、**アプリの継続率は原理的に出てこない。**28日たまっても、たまるのは検索データ。\n\nASC 側も見た —— Analytics Reports **156本に cohort / retention のレポートは無い**（retention を名前に含むのは `Retention Messaging` の1本だけで、これはメッセージング機能の指標）。**検索語のときと同じ形** —— カタログに無いものを『降りてくる待ち』に置いていた。\n\n**したがって 2026-09-06 が来ても、この行は動かない。**待ち先を書き直すまで、`--plan` はこの2件を『待つだけ +2』の先頭に置き続ける。\n\n**どこから取るかは未決。**候補は Firebase（③のデータ連携が `external_credential` で止まっている）と ASC の Web UI（Analytics の画面には継続率がある。ただし API 面には無い）。**決まっていないので「Firebase 待ち」とも書かない** —— 同じ誤りを別の相手で繰り返さない。",
      "unlock": "bq_28d",
      "blocked_on": [
        {
          "file": "data/autopilot-status.json",
          "path": "data_freshness.bq_export_days_accumulated",
          "atLeast": 28
        }
      ]
    },
    {
      "area": "① 次期機能開発",
      "task": "PRD・受入条件・UX・多言語の作成",
      "executor": "ai_executes_gated",
      "evidence": [
        "docs/prd/TEMPLATE.md",
        "docs/prd/undo-last-capture.md",
        "scripts/check-prd.mjs"
      ],
      "note": "[2026-08-26] docs/prd/TEMPLATE.md に定型を置き、scripts/check-prd.mjs が守る。VISION §13 の6問は**見出しがあるだけでは通らない**（各問に本文が要る）。受入条件はチェックボックス、多言語は JA/EN 両方、§1 の主張には出典。\n\n**いちばん効くのは §6「決めていないこと」。**PRD は提案であって決定ではないので、ここが空だと PRD が黙ってオーナー判断を代行できる。本当に何も無いなら「無い」と書く —— **書かないことと、無いことを分ける。**\n\n**ゲート付き実行**なのは、PRD の中身の是非は人がPRで見るから。機械が守るのは「定型を満たしていること」まで。1本目は docs/prd/undo-last-capture.md（★5レビュー 2026-07-07 が根拠、オーナー判断4件を §6 に残してある）"
    },
    {
      "area": "① 次期機能開発",
      "task": "Issue→ブランチ→PR→テスト→配信を結ぶ共通実行ID",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/autopilot-runs.json",
        "scripts/autopilot-runs.mjs"
      ],
      "note": "2026-08-22実装"
    },
    {
      "area": "① 次期機能開発",
      "task": "遠隔操作できるFeature Flag",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/SimpleMemo/FeatureFlagRollout.swift",
        "../simplememo-ios/SimpleMemo/FeatureFlags.swift",
        "../simplememo-api/src/config.ts"
      ],
      "note": "[2026-08-22訂正] 「アプリ本体に無い」は誤りだった。v4.7から WPFlag 15個が /v1/config 経由で遠隔操作できていた。同日、段階公開・キャッシュ期限・取得経路のテストを追加。**④の同名タスクだけ訂正して、この①側を直し漏らしていた**"
    },
    {
      "area": "① 次期機能開発",
      "task": "対照群・最低サンプル数・停止条件を持つ実験基盤",
      "executor": "ai_executes_gated",
      "evidence": [
        "growth/experiments/experiments.json",
        "growth/lib/ledger.mjs",
        "growth/scripts/check-experiments.mjs"
      ],
      "note": "2026-08-22実装。open な実験は control.kind（holdout/pre_post/none）・min_sample・stop_conditions が無いとCIが落ちる。**対照群が無いこと自体は禁じていない** — 無いのに書かないことを禁じている。pre_post には confounders を必須にした（書かないと因果を主張しているのと同じ）",
      "since": "2026-08"
    },
    {
      "area": "① 次期機能開発",
      "task": "D7/D28・課金・解約まで含む評価",
      "executor": "ai_proposes",
      "evidence": [
        "../simplememo-api/docs/reports/FUNNEL_EVALUATION_2026-08-20.md"
      ],
      "note": "D28はBQ蓄積28日到達待ち（9/6前後）",
      "blocker": "external_data",
      "unblocked_by": "**[2026-09-02 実測] 「BigQuery の28日蓄積待ち」は、この行に対しては成立しない。**\n\nBigQuery を直接叩いて中身を数えた（project `yurika-simplememo`）:\n\n    データセット   `searchconsole` **1つだけ**\n    テーブル       ExportLog / searchdata_site_impression / searchdata_url_impression\n    列             data_date / site_url / query / country / search_type / device /\n                   impressions / clicks / sum_top_position\n\n**継続率も install も user も無い。**Search Console は検索の露出とクリックであって、**アプリの継続率は原理的に出てこない。**28日たまっても、たまるのは検索データ。\n\nASC 側も見た —— Analytics Reports **156本に cohort / retention のレポートは無い**（retention を名前に含むのは `Retention Messaging` の1本だけで、これはメッセージング機能の指標）。**検索語のときと同じ形** —— カタログに無いものを『降りてくる待ち』に置いていた。\n\n**したがって 2026-09-06 が来ても、この行は動かない。**待ち先を書き直すまで、`--plan` はこの2件を『待つだけ +2』の先頭に置き続ける。\n\n**どこから取るかは未決。**候補は Firebase（③のデータ連携が `external_credential` で止まっている）と ASC の Web UI（Analytics の画面には継続率がある。ただし API 面には無い）。**決まっていないので「Firebase 待ち」とも書かない** —— 同じ誤りを別の相手で繰り返さない。",
      "unlock": "bq_28d",
      "blocked_on": [
        {
          "file": "data/autopilot-status.json",
          "path": "data_freshness.bq_export_days_accumulated",
          "atLeast": 28
        }
      ]
    },
    {
      "area": "① 次期機能開発",
      "task": "失敗機能の自動停止とバックログ差し戻し",
      "executor": "ai_autonomous",
      "evidence": [
        "../simplememo-api/src/rollout-guard.ts",
        "../simplememo-api/test/rollout-guard.test.ts",
        "docs/canary-testflight.md"
      ],
      "note": "ガードレール指標が有意かつ実害を伴って悪化したら kill を自律実行する（承認を挟まない＝可逆で安全な方向のため）。2026-08-22実装。**同日、kill が実機まで届いて機能が消えることを TestFlight で実証した**（docs/canary-testflight.md の実測）。ただし**押したのは人であってガードではない**。ガードの自動判定は本番でまだ1回も発火していない — TestFlight の人数では min_installs_per_cohort:30 に届かない。**止められることと、判断できることは別**。バックログ差し戻しは未実装"
    },
    {
      "area": "① 次期機能開発",
      "task": "判断理由と結果のDecision Ledger",
      "executor": "ai_autonomous",
      "evidence": [
        "docs/obsidian/AUTOPILOT_LOG.md",
        "growth/experiments/experiments.json",
        "data/autopilot-runs.json",
        "../simplememo-api/src/rollout-guard.ts",
        "../simplememo-api/test/rollout-guard.test.ts"
      ],
      "note": "機能開発の判断も入るようになった（カナリアガードが判定・根拠・実行有無を毎回KVへ記録する）。**2026-08-22実装。本番でまだ1回も発火していない**（段階公開中のフラグがゼロのため）。実装した≠動いた"
    },
    {
      "area": "① 次期機能開発",
      "task": "本番改善サイクルの完走（機能側）",
      "executor": "nobody",
      "evidence": [],
      "note": "コンテンツ側は完走。**機能側0件。** [2026-08-25] 完走させるための台帳と検査は実装した（data/feature-outcomes.json / scripts/check-feature-outcomes.mjs）が、**executor は nobody のまま。**この行が数えているのは『完走したか』であって『完走できる仕組みがあるか』ではない。**出す前に測り方を決めた機能が、まだ1件も無い** —— v5.8.0 も v5.8.1 も出荷済みだが、どちらも指標を先に宣言していない。**さかのぼって埋めない**（全件 measurement_failed になるうえ、後から指標を選んだものになる）。次に出す機能から1行足す\n\n**[2026-08-28] この行は自分の中で食い違っている。分類は動かさない。**unblocked_by は「カナリアガードを本番のフラグ1つで1周させる」と書き、note は「**出す前に測り方を決めた機能が、まだ1件も無い**」と書いている。**前者はカナリアの1周（2026-08-29 以降に判定が出る）で満たされるが、後者は満たされない** ——次に出す機能で `feature-outcomes.json` に1行先に置いたときに初めて動く。**どちらが要件かを決めるまで、この行を「カナリアが回れば動く」と数えない。**",
      "blocker": "not_started",
      "unblocked_by": "カナリアガードを本番のフラグ1つで1周させる。実装済み（rollout-guard.ts）で、要るのは実行",
      "unlock": "impl_product"
    },
    {
      "area": "① 次期機能開発",
      "task": "North Star Metric（Zero-decision Capture Rate）の実測",
      "executor": "nobody",
      "evidence": [],
      "note": "**定義はあるが実測が無い。**`../simplememo-ios/docs/VISION.md` が究極KPIとして定義し、CLAUDE.md も「Zero-decision の数値はまだ実測が無い。実測が出るまでサイトに数値を書かない」と明記している。**つまり最上位のKPIだけが、他の全指標に課している基準を満たしていない。**優先順位付けは代理指標（継続率・課金率）で回っており、NSMは判断に効いていない",
      "blocker": "not_started",
      "unblocked_by": "Capture後にユーザーが直したかをアプリ側で計装する。定義はVISIONにあり、無いのは観測",
      "unlock": "impl_measurement"
    },
    {
      "area": "① 次期機能開発",
      "task": "機能の削除・単純化・高速化の候補化",
      "executor": "nobody",
      "evidence": [],
      "note": "バックログ（data/feature-backlog.json）は**追加の候補しか持たない。**ビジョンは「作らない」を繰り返し定めている（Todo管理画面・Calendar UI・Knowledge Base を作らない）のに、**既にあるものを減らす提案が構造的に出てこない。**足すほうだけを採点する仕組みは、時間とともに必ず膨らむ方向に倒れる\n\n[2026-08-26] blocker を not_started → external_data へ。**「着手していないだけ」ではない。**器（採点の仕組み）は足せるが、減らす候補を出す根拠が無い。実測して確かめたうえで、数字のために推測で候補を作ることはしない。",
      "blocker": "external_data",
      "unblocked_by": "**採点の器ではなく、減らす根拠のほうが無い。**2026-08-26 に測った: 利用状況データ（D7/D28）は BigQuery 28日蓄積待ち（9/6前後）で、data/benchmark.json は起動0.4秒で競合の最速（Drafts 0.9秒）より速く、「速くする候補」が実測から出てこない。**根拠の無い削除提案は推測**なので、BigQuery が28日たまってから",
      "unlock": "impl_backlog",
      "blocked_on": [
        {
          "file": "data/autopilot-status.json",
          "path": "data_freshness.bq_export_days_accumulated",
          "atLeast": 28
        }
      ]
    },
    {
      "area": "① 次期機能開発",
      "task": "週次・月次・四半期ロードマップの自己生成",
      "executor": "ai_autonomous",
      "evidence": [
        "scripts/roadmap.mjs"
      ],
      "note": "[2026-08-26] scripts/roadmap.mjs が13週の窓を台帳から組み立てる。**日付を発明しない** —— 台帳に評価日があるものだけを暦に置き、順番しか決まらないもの（解除条件の梯子・機能バックログ）は順番だけ出す。オーナーの手数が要るものを機械の側と混ぜない（混ぜると「機械だけで届く」の主張が壊れる）。\n\n**週次の粒度は出していない。**台帳が週単位の日付を持たないため、週の欄を作ると構造のほうを発明することになる。この行の note が名指ししていた欠落は「次の四半期を機械が組み立てる経路が無い」で、そこは埋めた。週次が要るとわかったら別の行として足すこと。"
    },
    {
      "area": "① 次期機能開発",
      "task": "過去の失敗を参照して同じ提案を繰り返さない",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/operating-memory.json",
        "scripts/check-operating-memory.mjs",
        ".github/workflows/seo-check.yml"
      ],
      "note": "2026-08-25実装。learning に lesson_key を持たせ、**同じ key が2回出たらCIが落ちる。**2回目が出た＝1回目の学習が成果物に効かなかった、ということなのでそこで気づける。**実際にこの仕組みが無かった間に、同じ失敗が7回並んだ**（growth の基準値未記録7件）。**seed 6件はすべて後追い記録**なので、発生時記録が溜まるまで「再発を防いだ実績」は主張できない"
    },
    {
      "area": "② バグ修正",
      "task": "監視カバレッジの棚卸し",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/monitoring-coverage.json",
        "scripts/check-monitoring.mjs"
      ],
      "note": "2026-08-22実装。13系統を棚卸しし、**検知器が実在するか**と**実際に起きた障害種別に検知経路があるか**をCIが確かめる。『全部見ています』ではなく『何が空いているか』を言うための台帳"
    },
    {
      "area": "② バグ修正",
      "task": "統合監視（Crash/API/Watch/課金/問い合わせ）",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/monitoring-coverage.json",
        "scripts/check-monitoring.mjs",
        "../simplememo-api/src/inquiry.ts",
        "../simplememo-api/src/watch-health.ts",
        "../simplememo-api/src/analytics.ts",
        "../simplememo-api/src/autopilot-report.ts",
        "../simplememo-api/test/ops-alerts.test.ts",
        ".github/workflows/autopilot-health.yml",
        ".github/workflows/cron-health.yml",
        "../simplememo-ios/scripts/qa/check_analytics_crossrepo.py",
        "../simplememo-ios/data/analytics-server-allowlist.json"
      ],
      "note": "2026-08-22。棚卸しで名指しした穴3系統を、**2つの流れが別々に塞いだ。**main側で**課金とWatch同期**（データは既に取れていて閾値と通知だけが無かった）、こちら側で**問い合わせとWatch同期**（受け口はあったが来たことに気づく経路が無かったので、未応答の滞留を日報に載せた）。合流時点で**3系統とも埋まっている。**\n\nWatchは検知器が2つになった。**毎時は install 単位**（件数で見ると3秒間隔でリトライする1台が群全体を動かす — 実測で7 installが712件）、**日報は24h窓の件数と手動修復**（分母20件未満では判定しない。毎日「異常」が出る検知器は読まれなくなる）。\n\n**どちらの検知器も「読めなかった」を 0件 と書かない** — 混ぜると穴が「異常なし」に見える。\n\n[2026-08-22追記] **計測の事故が起きる境目**（iOS↔relay のイベント名）に検査を足した。従来の検査は「サーバに登録したのに iOS 側のセットに入れ忘れる」だけを見ており、**逆向き（iOSが送るのにサーバの allowlist に無い）は素通り**していた。その場合サーバは受け取って黙って捨て、端末には200が返るので送信側にも症状が出ない。サーバ allowlist の写しを iOS 側に置いたので**隣のリポジトリが無いCIでも動く** — 隣を見に行く形にすると検査が常にスキップされ、事故は起きたまま緑になる",
      "since": "2026-08"
    },
    {
      "area": "② バグ修正",
      "task": "問い合わせから再現テストを自動生成",
      "executor": "ai_proposes",
      "evidence": [
        "../simplememo-ios/docs/qa/REGRESSION_TEST_TEMPLATE.md"
      ],
      "note": "手動運用。ただしWatch同期は実績あり",
      "blocker": "external_data",
      "unblocked_by": "本文は依然 D1 にあり読めない。**2026-08-26 に端末/OS/版/分類だけを本文抜きで数える経路を作った**（simplememo-api: summarizeReproFacts / migrations/0027）。残るのは (a) 移行0027の適用、(b) その集計が日報の文面ではなく**リポジトリ側から読める形**で出ること、(c) 母数 — inquiries は現在0件",
      "unlock": "inquiry_facts"
    },
    {
      "area": "② バグ修正",
      "task": "Unit / UI / 契約テストの実行",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/.github/workflows/qa-ios.yml"
      ],
      "note": "XCTest/XCUITest＋Watchブリッジ契約テスト2コピー＋parity CI"
    },
    {
      "area": "② バグ修正",
      "task": "Visual Regression Test",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/scripts/qa/check_screenshot_baseline.py",
        "../simplememo-ios/scripts/qa/verify-screenshots.py",
        "../simplememo-ios/data/screenshot-baseline.json",
        "../simplememo-ios/.github/workflows/qa-static.yml"
      ],
      "note": "2026-08-25実装。**撮影と内在的な検査は前からあったが、前回と比べる経路が無かった** —— artifacts/ は .gitignore で追跡0件なので基準が1回も残らず、ボタンが動いても文字が切れても「PNGとして妥当で寸法が揃っている」限り通っていた。画像ではなく**指紋（12x24の平均輝度・288整数）**を置く（重さと差分の読めなさを避ける）。sha256 は1画素で別物になるので使えない。**Pillow も足していない**（同じファイルの純Python PNGデコーダに載せた）。しきい値6.0は self-test で実測 —— 1画素 0.00 で鳴らず、ボタン大の矩形 8.96 で鳴る。**撮影は macOS が要るので ubuntu の CI からは見えない。**見えないときは形だけ検査し、**『差が無い』とは書かない**（review-intake の judged と同じ）。**基準はまだ空** —— 次に Mac か Xcode Cloud で撮って --update を1度回すと入る。変化＝失敗ではなく、落ちるのは『動いたのに基準を更新していない』場合だけ"
    },
    {
      "area": "② バグ修正",
      "task": "オフライン・タイムアウト・500・429の決定論再現",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/docs/qa/AUTOMATED_QA_ARCHITECTURE.md",
        "../simplememo-ios/SimpleMemo/QA/QAStubURLProtocol.swift"
      ],
      "note": "QAStubURLProtocol。低速回線とバックグラウンド復帰は無い"
    },
    {
      "area": "② バグ修正",
      "task": "実機/シミュレータでの操作・撮影・計測",
      "executor": "human_only",
      "evidence": [
        "docs/obsidian/AUTOPILOT_RUNBOOK.md"
      ],
      "note": "macOS必須。Runbook §7「できないこと」の筆頭\n\n**[2026-08-28] 前提が広すぎた。ただし覆ってはいない。**「macOSが要る＝人間だけ」と書いてあるが、**macOSの経路は2つある** —— GitHub Actions の macOSランナー（予算保護でAIは起動しない）と、**Xcode Cloud（Apple側の課金で、GitHubの予算とは別勘定）**。後者は自動で走っている: simplememo-ios#239（2026-08-27）に `SimpleMemo | PR Check | Build - iOS` が success で出ており、**人は何も触っていない。**起動と診断のAPI経路も在る（scripts/xcode_cloud_start_build.rb / xcode_cloud_diagnose.rb）。\n\n**それでも覆せない。**同じPRに出たのは Build だけで、**UIテスト（SimpleMemoQA / SimpleMemo-iOS-PR）は出ていない。**docs/qa/XCODE_CLOUD_ONE_TIME_SETUP.md はそれを『PR Check の合格に必要』と書いているので、**書いてあることと実際が食い違っている**（変更ファイルで起動条件が絞られているのか、アクションが外れているのかは、ASCの鍵が無いのでここでは確かめられない）。撮影のほうは docs/qa/ARTICLE_SCREENSHOTS.md が『ローカルMac』での通し実行しか記録していない。\n\n**したがって分類は動かさない。**言えるのは「人間だけ」の理由が予算保護だけではないことと、**この食い違い自体が確かめるべき対象**だということ",
      "blocker": "physical_human",
      "unblocked_by": "macOSランナーが要り、予算保護で人間の名指し起動のみ。**[2026-08-28] Xcode Cloud（Apple課金）は自動で走っており、そちらには予算保護が効かない。**覆すのに要るのは (1) UIテストのアクションが実際にPRで起動しているかの確認（ASCの鍵が要る。設定書は『合格に必要』と書いているが simplememo-ios#239 では Build しか出ていない）と (2) 撮影を Xcode Cloud 側で完結させ、成果物を取り出す経路"
    },
    {
      "area": "② バグ修正",
      "task": "アクセシビリティ・文字切れ・多言語の自動検査",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/scripts/qa/check_localization.py",
        "../simplememo-ios/data/localization-baseline.json",
        "../simplememo-ios/.github/workflows/qa-static.yml",
        "scripts/seo-check.js"
      ],
      "note": "2026-08-22。**多言語だけアプリ側にも入った。**初回の実行で3件出た（どれも目視では見つからない）: NSLocalizedString の直接呼び出し2箇所（キーが無い言語では`onboarding.page2.apple_signin.error_generic` という文字列がそのままエラーとして表示されていた）/ premium.* 5キーが全10言語で二重定義（50行、後の行が静かに勝つので先の行を直しても画面は変わらない）/ premium.unlimited がどの言語にも無い。全部直した。**未翻訳では落とさない**（8言語が46.3%なのは既知）が、基準線から下がると落ちる。残る弱さ: **文字切れとアクセシビリティはアプリ側で未検査。**文字切れは実機のフォントとレイアウトが要り、文字数比での近似は誤検出だらけになるので採らなかった（ドイツ語が日本語の3倍は正常）",
      "since": "2026-08"
    },
    {
      "area": "② バグ修正",
      "task": "性能・起動時間の計測",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-api/src/launch-health-monitor.ts",
        "../simplememo-api/src/autopilot-report.ts",
        "../simplememo-api/test/launch-health-monitor.test.ts",
        "../simplememo-api/docs/launch_health.md",
        "data/monitoring-coverage.json"
      ],
      "note": "2026-08-22。**本番の常時監視になった。**それまでは段階公開中だけガードが見ており、平常時に起動が壊れても気づく経路が無かった。指標も読み方の文書も既にあり、**無かったのは毎日それを見る仕組み**だけだった（POSTを叩いた日にしか読まれていなかった）。判定は文書の読み方をそのまま機械にした: **比率をそのまま閾値にしない** — iOSは毎フォアグラウンド復帰で breadcrumb を上書きするので、正常利用後のkillでもlaunch_incomplete が出る（scene_did_become_active は恒常的に最多で実害の証拠にならない）。**前段ステージが1件でも出たら分母を問わず劣化**、比率は前週比の跳ねだけに使う。残る弱さ: **起動「時間」は測っていない。**0.4秒は今も定点実測で、本番の起動所要時間を集める経路はiOS側に無い。ここが監視しているのは完走したかどうかだけ",
      "since": "2026-08"
    },
    {
      "area": "② バグ修正",
      "task": "依存脆弱性・秘密情報・SBOM・署名検査",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-api/scripts/check-supply-chain.mjs",
        "../simplememo-api/data/sbom.json"
      ],
      "note": "2026-08-22実装（simplememo-api）。SBOM 259件（**実行時はわずか1件**、残り258は開発時）・integrity欠落0件・秘密情報スキャン。**値は出力しない**（出力に秘密を写したら意味が無い）。**既知脆弱性の照合（npm audit）は意図的に含めない** — 外部DB依存でCIの合否が日替わりになり、やがて無視されるため",
      "since": "2026-08"
    },
    {
      "area": "② バグ修正",
      "task": "Fuzz / Property-based / Mutation Test",
      "executor": "ai_executes_gated",
      "evidence": [
        "scripts/property-tests.mjs",
        "scripts/autopilot-gate.mjs",
        "scripts/autopilot-budget.mjs"
      ],
      "note": "2026-08-22実装。実行判定と予算集計の**不変条件12件**を、種を固定した乱択400ケース／件で検査する。ドリル（26の具体例）が守れない**書かなかった組み合わせ**を踏むのが目的。変異テストで検出力を確認（forceが予算を飛び越える／認証切れが予算の陰に隠れる、をどちらも検出）。**アプリ側のfuzzは未実装**",
      "since": "2026-08"
    },
    {
      "area": "② バグ修正",
      "task": "失敗の分類（独立2モデル監査）",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/scripts/qa/ai_triage.sh"
      ],
      "note": "2026-08-22実装。割れたら人間に上げる"
    },
    {
      "area": "② バグ修正",
      "task": "回帰の合否判定（決定論的）",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/docs/qa/AUTOMATED_QA_ARCHITECTURE.md",
        "../simplememo-ios/SimpleMemoTests/QATestCase.swift",
        "../simplememo-ios/SimpleMemoTests/RelayClientContractTests.swift"
      ],
      "note": "AIには判定させない設計"
    },
    {
      "area": "② バグ修正",
      "task": "セキュリティ監査と修正",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/docs/reports/SECURITY_HARDENING_2026-07.md",
        "../simplememo-ios/SimpleMemo/AnalyticsClient.swift",
        "../simplememo-ios/SimpleMemo/DraftManager.swift",
        "../simplememo-ios/SimpleMemo/ObsidianManager.swift"
      ],
      "note": "AIが発見しAIが修正。High 1件含む4件 **[2026-08-27] 証跡を報告書から修正した実物へ移した。**報告書は「見つけた」の記録であって「直した」の記録ではない。3ファイルは報告書 §が名指ししている修正先"
    },
    {
      "area": "② バグ修正",
      "task": "カナリア公開と自動ロールバック",
      "executor": "ai_autonomous",
      "evidence": [
        "../simplememo-api/src/rollout-guard.ts",
        "../simplememo-api/test/rollout-guard.test.ts",
        "docs/canary-testflight.md"
      ],
      "note": "露出群/対照群を bucketOf で復元して比較し、悪化なら自動で撤回する。2026-08-22実装。**同日、kill が実機まで届いて機能が消えることを TestFlight で実証した**（docs/canary-testflight.md の実測）。ただし**押したのは人であってガードではない**。ガードの自動判定は本番でまだ1回も発火していない — TestFlight の人数では min_installs_per_cohort:30 に届かない。**止められることと、判断できることは別**"
    },
    {
      "area": "② バグ修正",
      "task": "誤修正率・再発率・MTTRの計測",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/autopilot-runs.json",
        "scripts/autopilot-runs.mjs"
      ],
      "note": "2026-08-22に検知時刻を投入。検知まで中央値2.1h/最大50.7h、修理まで中央値0.9h。誤修正率・再発率はまだ"
    },
    {
      "area": "② バグ修正",
      "task": "基盤故障の検知と自己修復",
      "executor": "ai_executes_gated",
      "evidence": [
        "scripts/autopilot-selfheal.mjs"
      ],
      "note": "2026-08-22実装。レーンF"
    },
    {
      "area": "② バグ修正",
      "task": "不要になったテストの整理",
      "executor": "nobody",
      "evidence": [],
      "note": "テストを**足す**経路はある（回帰テスト化の実績あり）が、**減らす／直す経路が無い。**flaky を検出する仕組みも、使われなくなったテストを見つける仕組みも3リポジトリに無い。放置すると『赤いのが普通』になり、②の検査群全体の信頼が落ちる\n\n[2026-08-26] blocker を not_started → statistical_power へ。未使用テスト検出は**対象が0件**（.test.mjs 2本は両方CI配線済み）で、作っても一度も発火しない検査になる。flaky 検出は反復実行の履歴が要る。**母数が無いものを「検出できる」と数えない。**\n\n[2026-08-27] **この項目を割った。**元は「flakyテスト・不要になったテストの整理」で1件だったが、上の 08-26 の測定自身が2つを別々に論じている（未使用テスト検出＝対象0件 / flaky検出＝履歴が要る）。**片方だけ実測で動いたので、動いた分をここから出した**（② テストの順序依存の検出）。こちら（不要になったテスト）は**対象0件という測定を否定していない**ので据え置き。",
      "blocker": "not_started",
      "unblocked_by": "**器ではなく母数が無い。**2026-08-26 に測った: 未使用テスト検出は**対象が0件**（`.test.mjs` は2本で両方CI配線済み。実体の試験面は62本の `--selftest` で、そちらは check-selftests がラチェットで守っている）。flaky 検出は**同一コミットの反復実行の履歴**が要り、いまその履歴を持っていない",
      "unlock": "impl_qa"
    },
    {
      "area": "② バグ修正",
      "task": "テストの順序依存の検出",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-api/scripts/check-test-isolation.mjs",
        "../simplememo-api/test/test-isolation.test.ts",
        "../simplememo-api/.github/workflows/ci.yml",
        "../simplememo-api/test/verify-start-cooldown.test.ts"
      ],
      "note": "2026-08-27実装。**台帳のここには「flaky 検出は同一コミットの反復実行の履歴が要り、いまその履歴を持っていない」と書いてあった。順序依存については、それは誤りだった。**履歴は要らない —— `--sequence.shuffle` を種を固定して当てれば、確定的に出る。\n\n実際、履歴ゼロで本物を1件出した。`npm test` が **1770件すべて緑**の状態で、シャッフルすると3種すべてで1件落ちた: `verify-start-cooldown` の「cooldown 中は送らない」—— 7/7インシデント(R2)の番人。\n\n**落ち方が肝。**`expect(status).toBe(429)` は通っており、落ちたのは`expect(fetchSpy).not.toHaveBeenCalled()` だけだった。テスト側の `ctx.waitUntil` がPromise を捨てる空実装で、本番の Cloudflare はこれを待つので**モックがランタイムより緩かった。**捨てられた送信が宙に浮き、**次のテストの fetch スパイに着弾していた** —— 「送らないこと」の検証が、順序次第で他人の送信を数えていた。\n\n**この穴は機械が1件も出していなかった**（手で shuffle を当てて見つけた）ので、ci.yml の `npm test` 直後に配線した。種は固定（既定 1,2,3）——毎回ランダムに振ると CI が設計上ときどき落ちるものになり、直そうとしている病気そのもの。\n\n**限界を数えている。**見つかった1件は5種中2種でしか露出せず、3種なら見逃す確率は約22%。出力に「緑は『順序依存が無い』ではない」と明記した。打ち切りも「異常なし」にしない（上限5分・実測15秒の20倍。上限2秒にして発火を確認済み）。\n\n**この項目が見ているのは順序依存だけ。**実行ごとに結果が変わる真のランダム flaky は別で、そちらは依然として反復実行の履歴が要る。\n\n**since を明示している。**証跡に `ci.yml` と `verify-start-cooldown.test.ts`（どちらも以前から在るファイル）が含まれるので、`min(証跡の初出月)` だと **2026-07 に自律していたことになる。**実際に動き出したのは 2026-08-27。**遡って自律度を盛らない。**",
      "since": "2026-08"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "検索データの取り込み（GSC / BigQuery）",
      "executor": "ai_executes_gated",
      "evidence": [
        "growth/scripts/ingest-bigquery.mjs",
        ".github/workflows/seo-daily.yml"
      ],
      "note": "日次自動"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "データ鮮度の監視",
      "executor": "ai_executes_gated",
      "evidence": [
        "growth/scripts/bq-preflight.mjs"
      ],
      "note": "鮮度落ちで失敗する"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "API障害・停止・欠測からの自動復旧",
      "executor": "ai_executes_gated",
      "evidence": [
        "scripts/recover-ingest.mjs",
        "data/ingest-recovery.json",
        ".github/workflows/seo-daily.yml"
      ],
      "note": "2026-08-26実装。**分類はもう出来ていた**（bq-preflight.mjs が6通りに分ける）のに、その分類ごとに手を打つ側が無く、落ちた回は要約を人が読むまで何も起きなかった。機械が取るのは4つ: 再試行（指数バックオフ）／退避（直近のgoodスナップショット）／劣化継続（退避先が7日より古ければ新規記事を止めて保守回へ）／欠測の記録。**preflight の落ちる・落ちないは変えていない** — 変えたのは落ちた後。翌朝のレーンFが未修理の故障としてこれを拾う。**まだ本番で発火していない**（data/ingest-recovery.json は空）。確かめてあるのは判断の論理だけで、`--selftest` が9通りの分類と「退避先が無いのに退避したことにしない」「鮮度が足りていれば止めない」を実際に落として確認する",
      "since": "2026-08"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "資格情報失効からの復旧（再同意・鍵の再発行）",
      "executor": "human_only",
      "evidence": [
        "scripts/recover-ingest.mjs",
        "data/credential-expiry.json"
      ],
      "note": "**1行に潰さないために分けた。**旧行は「OAuth切れ・API障害時の自動復旧」で、機械が最後まで出来る側（API障害）と、人にしか出来ない側（再同意）が同じ1行に入っていた。混ぜると、どちらかが出来た時点で行が動いてしまう。機械が取るのは退避と自動起票まで。**ブラウザ同意と鍵の再発行は人の操作**で、そこを「自動復旧しました」と書くと嘘になる。recover-ingest.mjs の check() は `human_action_required` の回が `recovered` になっていたら落とす",
      "blocker": "human_consent",
      "unblocked_by": "**解けない。**ブラウザ同意と鍵の再発行に人の操作が要る。機械側は退避と起票まで",
      "since": "2026-08"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "施策の選定（レーンA〜E）",
      "executor": "ai_autonomous",
      "evidence": [
        "docs/obsidian/AUTOPILOT_RUNBOOK.md",
        "scripts/autopilot-gate.mjs",
        "growth/scripts/build-queues.mjs"
      ],
      "note": "ノイズフロア・品質ゲートに基づきAIが単独で選ぶ **[2026-08-27] 証跡を手順書から選定を実際に行うスクリプトへ移した。**RUNBOOK は「こう選ぶ」であって「選んだ」ではない"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "記事の実装と内部リンク配線",
      "executor": "ai_executes_gated",
      "evidence": [
        "docs/obsidian/AUTOPILOT_LOG.md"
      ],
      "note": "出荷10件すべてAIが執筆。人は中身に触っていない"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "OG画像の生成",
      "executor": "ai_executes_gated",
      "evidence": [
        "scripts/generate-og-batch.js"
      ],
      "note": "Playwright。毎回自動"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "デスクトップQRの生成と検証",
      "executor": "ai_executes_gated",
      "evidence": [
        "scripts/generate-qr-codes.mjs"
      ],
      "note": "35件を独立デコード検証"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "品質ゲート（ノイズフロア・品質80点・検証規約）",
      "executor": "ai_executes_gated",
      "evidence": [
        "docs/obsidian/AUTOPILOT_RUNBOOK.md",
        "growth/scripts/build-queues.mjs"
      ],
      "note": "「毎日出すために基準を下げる」を失敗と定義 **[2026-08-27] ノイズフロアを実際に計算しているのは build-queues.mjs。**RUNBOOK は基準の記述"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "本番デプロイ（検証済みSHAのみマージ）",
      "executor": "ai_executes_gated",
      "evidence": [
        ".github/workflows/auto-merge.yml"
      ],
      "note": "SEO Validation合格時のみ"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "停止の検知（緑のまま何もしていない）",
      "executor": "ai_executes_gated",
      "evidence": [
        ".github/workflows/autopilot-health.yml",
        ".github/workflows/cron-health.yml"
      ],
      "note": "12:00と07:00の二重"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "ahrefs / AppsFlyer / Firebase のデータ連携",
      "executor": "nobody",
      "evidence": [],
      "note": "自動連携なし。手動エクスポート",
      "blocker": "external_credential",
      "unblocked_by": "3社ぶんのAPI鍵と契約",
      "unlock": "analytics_vendors"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "App Store Connect のデータ連携",
      "executor": "ai_autonomous",
      "evidence": [
        "../simplememo-ios/scripts/asc_metrics.rb",
        "../simplememo-ios/.github/workflows/asc-metrics.yml",
        "../simplememo-ios/data/appstore/asc-metrics.json",
        "../simplememo-ios/scripts/asc_analytics.rb",
        "../simplememo-ios/.github/workflows/asc-analytics.yml",
        "growth/scripts/ingest-asc.mjs",
        "growth/data/appstore/README.md"
      ],
      "note": "2026-08-22実装。日次で取り込む（GETのみ）。**受け皿だけだったのは「ASCにエクスポートAPIが無い」という誤った前提が README に書かれていたため。**実測: レビュー8件・平均4.63を取得。ASO漏斗と購入は Analytics のレポート15種を要求済み。**[2026-08-25] instance は 10/15 まで出ている**（08-23・08-24 の2日ぶん。asc_metrics.rb の reports_with_data）。**ただし取得側は1件も落とせていなかった** —— asc_analytics.rb の欠陥2件（schedule 実行で ASC_REPORTS が空文字になり取得対象が空／既定の語 \"Sales\" が156件のカタログに0件一致）で、**毎日0件を緑で出荷していた**（run 32844534637 の実ログ「取得対象 0 件（部分一致: ）」）。2026-08-25 に修正済みだが、**次回の定時実行までは依然として0件のまま。**この経路を ai_autonomous と数えているのは『日次で自動的に走ること』についてであって、『データが降りていること』についてではない（data/operating-memory.json om-2026-08-25-asc-zero）。入金額（proceeds）だけは /v1/salesReports が必要で vendor number 未登録のため取れない。**「日次」は 2026-08-22 21:32 UTC に初めて実際に発火して裏が取れた**（run 32599889435 / event=schedule → コミット 35b8df4）。それまでは手動1回しか実績が無く、この欄の『日次』は書いただけの状態だった。この回で Analytics 要求は作り直されず既存を再利用している（created_now: false・要求IDは同一）ので、**毎日新しい ONGOING 要求が積み上がる形にはなっていない**。\n\n経路は2本ある。**metrics（asc_metrics.rb）が上記の実測を出している側**で、**Analytics Reports（asc_analytics.rb → growth/scripts/ingest-asc.mjs）は読む側の配線**。後者は **Sales and Trends ではなく Analytics Reports を使う** — 前者は vendorNumber が要り管理画面にしか無いが、後者はアプリIDだけで足りるのでオーナー作業ゼロで始められる。取り込みは**行そのものを置かず、列名・行数・日付範囲・数値列の合計・名指しした分類列ごとの内訳だけ**（個人が特定できる列が将来増えたときに気づかず貯め始めるのを防ぐ）。**[2026-08-26] 内訳を足した** —— それまで保存していたのは数値列の合計だけで、`Cancellation Reason` のような文字列の列は**列名だけが残って中身は毎回捨てられていた**（om-2026-08-26-discarded-not-missing）\n\n**[2026-08-26] 読む側が付いた。**それまでこの行が指していたのは取得だけで、落ちてきた列のうち実際に読んでいたのは数値列の合計だけだった。`Event` / `Source Type` / `Page Type` / `Download Type` / `Territory` は**届いたまま毎日捨てていた**（⑨解約理由と同じ欠陥。名指しした分類列に③の分を入れ忘れていた）。取得側の内訳に③⑥の列を足し、読む側を ../simplememo-ios/scripts/asc_funnel.rb として日次に配線した（別行「ストア内漏斗の観測」）",
      "since": "2026-08"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "AIプローブ（生成AI検索での露出確認）",
      "executor": "human_only",
      "evidence": [
        "growth/input/AI_PROBE_PROTOCOL.md"
      ],
      "note": "月1・オーナーが手動",
      "blocker": "external_credential",
      "unblocked_by": "生成AI検索を叩く経路が無い",
      "unlock": "analytics_vendors"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "言及・競合ウォッチ",
      "executor": "ai_executes_gated",
      "evidence": [
        "growth/scripts/check-mentions.mjs",
        "growth/data/mentions/",
        "growth/data/mentions/README.md",
        "docs/obsidian/AUTOPILOT_RUNBOOK.md",
        ".github/workflows/seo-check.yml"
      ],
      "note": "2026-08-22。スナップショットが1件だけだった状態から、**2件目を実際に取り、やらなかった週に落ちる検査を入れた。**手順書は「週1回・前回が7日以上前なら実行」と書いていたが、**その条件を誰も検査しておらず、実際に10日空いていた**（3日の遅れは誰にも見えていなかった）。検査は (1) 最新の古さ (2) **過去の間隔**（最新だけ見ると途中の空白が隠れる）(3) READMEの固定クエリが欠けていないか — 一部だけ検索して「やった」ことにすると**系列は連続しているのに中身が変わり**、あとから「あの週から言及が減った」に見える (4) 前回との差分が書かれているか、を見る。5通りとも壊して落ちることを確認した。**検索そのものはセッションのWebSearchで行う**（CIからは実行しない）ので、実行はAI・遅れの検知はCI、という分担。残る弱さ: **本文はフェッチしていない**（この環境のegress制限）。mentions_us は検索結果の要約だけを根拠にしており、中身の妥当性は機械には判定できない",
      "since": "2026-08"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "トレンドレーダー（Googleトレンド/はてブ/ランキング）",
      "executor": "ai_proposes",
      "evidence": [
        "docs/trend-radar-prompt.md",
        "docs/obsidian/AUTOPILOT_RUNBOOK.md"
      ],
      "note": "2026-08-22にRunbook §6の保守メニューへ組み込み。PR起案の判断は人",
      "blocker": "external_data",
      "unblocked_by": "外部の順位・トレンドを取る経路が無い",
      "unlock": "trend_source"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "PR企画の採点とゲート判定",
      "executor": "ai_executes_gated",
      "evidence": [
        "growth/scripts/d-score.mjs"
      ],
      "note": "算数とゲートの矛盾をCIが落とす。採点は人が置く"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "PR原稿の執筆",
      "executor": "ai_autonomous",
      "evidence": [
        "docs/pr-autopilot-2026-09.md",
        "scripts/check-pr-facts.mjs",
        "data/code-authorship.json"
      ],
      "note": "本原稿がその実例 **[2026-08-27] 執行面の証跡は「生成器」ではない。**原稿を書くのはセッションであってスクリプトではないので、機械側に残るのは (a) 原稿を落とす事実検査と (b) 著者がAIであることの台帳の2つ。**生成器が無いことをここに書いておく**"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "PR原稿の事実・数値・引用元の検査",
      "executor": "ai_executes_gated",
      "evidence": [
        "scripts/check-pr-facts.mjs",
        "data/site-constants.json",
        "data/benchmark.json"
      ],
      "note": "2026-08-22実装。site-constants.json と benchmark.json を正として、旧アプリ名・古い起動時間・廃止済みトライアル・誇大表現・価格ドリフトをCIが落とす。**引用元の確認（出典が実在するか）はまだ人**"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "ヒーロー画像の生成",
      "executor": "ai_executes_gated",
      "evidence": [
        "scripts/generate-pr-hero.mjs",
        "data/pr-claims.json"
      ],
      "note": "2026-08-22実装。1200x630（G1ゲート）をPlaywrightで生成し、**出力の実寸を検証する**（生成できたかではなく出た画像で判定）。文言は data/pr-claims.json から読むので、**主張検査を通っていない見出しの画像は原理的に作れない**。裏の取れていない主張があるときは既定で生成を拒否し、--allow-unsupported を付けた場合だけ DRAFT リボン付きで出る"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "PR TIMES への配信操作",
      "executor": "human_only",
      "evidence": [
        "data/authority-matrix.json"
      ],
      "note": "管理画面から手動。APIが無い **[2026-08-27 オーナー判断]「お金周りを除いて渡す」の対象。**境界は外れたので、残るのは**権限ではなく実装**。ただし宣言では終わらない —— 権限表は不可逆な領域の承認を外すのに machine_gate（実在する checker／export された関数／kill switch／正の日次上限／材料が無いときは止まる）を要求するので、**ゲートができるまで権限表の該当行は承認制のまま**。\n\n**[2026-08-28] 到達可能側から外した（分類の訂正）。**権限表「プレスリリースの配信」は `requires_approval: true`、human_only に「PR TIMES管理画面からの配信操作」「配信可否の判断」の2つを置いている。機械ゲートは無い（＝承認を外す例外に入っていない）。\n**害は件数ではなく向きに出る** —— `--plan` が「作れば進む」と言い続け、天井が実際より高く出る。到達可能な件数は減るが、**下がった天井のほうが本物。**",
      "blocker": "policy_boundary",
      "unblocked_by": "配信は不可逆。管理画面からの操作を人に残す",
      "authority": {
        "domain": "プレスリリースの配信",
        "human_only": "PR TIMES管理画面からの配信操作"
      }
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "キャンペーンパラメータの付与",
      "executor": "ai_executes_gated",
      "evidence": [
        "scripts/tag-cta-placements.js",
        "data/cpp-map.json"
      ],
      "note": "CIが強制。49件がpage-level ct=保持"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "App Store CPP（訴求別ページ）の実験",
      "executor": "nobody",
      "evidence": [
        "data/cpp-map.json"
      ],
      "note": "34本作成済みだが実験として回っていない",
      "blocker": "not_started",
      "unblocked_by": "**列は降りている。**2026-08-25 の10レポートに Page Type / Source Type / Territory があり、内訳も取得側が持つようになった（2026-08-26）。ただし**値はこの公開リポジトリに運ばない決定**なので、評価は ../simplememo-ios 側に置く。[2026-08-26] それまで「露出データがASCから降りない」と書いたままだった —— 降りていないのではなく、運んでいない",
      "unlock": "asc_dimension_read"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "SNS投稿（X日本語）",
      "executor": "ai_proposes",
      "evidence": [
        "admin/brand/docs/cowork-x-engagement-brief.md"
      ],
      "note": "Cowork定期タスクでバッチ運用\n\n**[2026-08-28] 到達可能側から外した（分類の訂正）。**権限表「SNS投稿（X・TikTok）」は `status: suspended`、ai_may は空、human_only が「再開の判断」。**止まっているのは経路ではなく再開の判断。**\n**害は件数ではなく向きに出る** —— `--plan` が「作れば進む」と言い続け、天井が実際より高く出る。到達可能な件数は減るが、**下がった天井のほうが本物。**",
      "blocker": "policy_boundary",
      "unblocked_by": "権限表で suspended。再開の判断が人",
      "authority": {
        "domain": "SNS投稿（X・TikTok）",
        "human_only": "再開の判断"
      }
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "SNS投稿（X英語・TikTok）",
      "executor": "intentional_no",
      "evidence": [
        "README.md"
      ],
      "note": "アカウントBAN／品質未達で運用停止中"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "リスティング広告の運用",
      "executor": "nobody",
      "evidence": [
        "../simplememo-ios/docs/reports/APPLE_ADS_AUTOMATION_2026-08-17.md"
      ],
      "note": "調査レポートのみ。資格情報も無い",
      "blocker": "policy_boundary",
      "unblocked_by": "自社分析が『この予算規模では日次自動入札がノイズ最適化になる』と結論済み。着手しないと決めた側",
      "authority": {
        "domain": "広告出稿・広告予算の変更",
        "human_only": "すべて"
      }
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "広告パフォーマンスの監視と自動調整",
      "executor": "intentional_no",
      "evidence": [
        "../simplememo-ios/docs/reports/APPLE_ADS_AUTOMATION_2026-08-17.md"
      ],
      "note": "自社分析が『この予算規模ではやるべきでない』と結論"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "対照群による増分効果測定",
      "executor": "nobody",
      "evidence": [],
      "note": "未実施",
      "blocker": "statistical_power",
      "unblocked_by": "App Storeのクリックが2.1件/日。分割すると両群とも検出力が出ない"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "紹介・レビュー促進・休眠復帰",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-api/src/lifecycle.ts",
        "../simplememo-api/src/nudge.ts"
      ],
      "note": "cronで自動送信"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "コンテンツDecayの検出とRefresh Queue",
      "executor": "ai_executes_gated",
      "evidence": [
        "growth/scripts/analyze.mjs",
        "growth/scripts/build-queues.mjs",
        "growth/content/refresh-queue.json",
        ".github/workflows/seo-check.yml"
      ],
      "note": "**2026-08-25、検出と待ち行列がつながった。**検出は前からあった（analyze.mjs --only decay / unanswered。ノイズフロアつき、窓が93%重なるときは比較を差し控える）が、**出力を待ち行列へ落とす経路が無く**、refresh-queue.json は 2026-08-09 に手で作られたまま更新されていなかった。build-queues.mjs が再生成する。**核心は落とした判断を復活させないこと** —— dropped/done は key で引き継いで戻さず、観測から消えた行も削除せず stale にする（直ったのか窓から外れたのか区別できないため）。**さらに experiments.json で abandoned と判定されたページへは積み直さない** —— 初回試走で実際に踏んだ（未回答クエリの第1位が、到達不能と判定済みのページへ着地していた）。self-test 17件"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "検索意図（Search Intent）の変化検出",
      "executor": "ai_autonomous",
      "evidence": [
        "growth/scripts/search-intent.mjs"
      ],
      "note": "[2026-08-26] growth/scripts/search-intent.mjs が窓をまたいで比べる。**いちばん強い信号は「当たるページが入れ替わったこと」** —— 同じクエリに Google が別のページを当てるようになったなら、検索側の解釈が動いている。実測（08-11 → 08-24）で9件。google keep 系4件が /blog/line-keep-alternatives → /blog/google-keep-shutdown で、順位 13.4 → 5.3。\n\n**出現・消滅は使っていない。**スナップショットは行数上限（1000/900）で切れており、**最小表示回数は両窓とも1**。「消えた533件」は意図の変化ではなく上限で落ちただけ。実測してからこの信号を捨てた。\n\n**窓の長さが違うので表示回数は比べない**（28日 → 13日）。比べるのは順位・CTR・当たるページという長さに依存しない量だけ。"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "施策の停止条件（Marketing stop-loss）",
      "executor": "ai_executes_gated",
      "evidence": [
        "growth/lib/stoploss.mjs",
        "growth/scripts/check-stoploss.mjs",
        "growth/lib/ledger.mjs",
        ".github/workflows/seo-check.yml"
      ],
      "note": "2026-08-25実装。進行中の実験を評価日前に見て、**戻す判断だけ**を出す（expand は返さない —— rollout-guard.ts の kill/promote と同じ非対称）。判定は Wilson 95%区間が重ならないこと＋相対20%以上の低下＋表示200以上。**母数不足・基準値なし・スナップショット欠落は hold** で、CIは落とさない（判定できないことは異常ではない）。初回実行で**偽陽性を1件出した** —— 別の指標（brand_search_impressions）を測っている実験を CTR として判定していた。対象抽出を growth/lib/ledger.mjs の measuresPageCtr に集約し、self-test 16件で固定した。**現状の対象は進行中21件のうち7件**（残りは GA4起点・複数ページ集合・別指標）。つまりこの歯止めは**マーケ施策の3分の1にしか掛かっていない** —— GA4起点の施策に同じ歯止めは無い"
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "SEOとASO間のカニバリゼーション判定",
      "executor": "nobody",
      "evidence": [],
      "note": "**サイト内のカニバリゼーション（1クエリ×複数URL）は実装済み**（growth/scripts/analyze.mjs --only cannibalisation。表示数のフロアつき）。**この行が指しているのは自社サイトとApp Storeページの間**で、そちらは未実装。同じクエリに両方が露出したときにどちらが食っているかを見ていない。**サイト内の分と混同しない**ため、行の題を SEOとASO間と明示してある。 [2026-08-26] それまで「別のレポートが要る」と書いて待ちに分類していたが、**そのレポートはカタログに存在しなかった。**待機ではなく探索。",
      "blocker": "external_data",
      "unblocked_by": "**Analytics Reports のカタログ156本に検索語のレポートは無い**（2026-08-26 に ../simplememo-ios/data/asc/status.json の available_reports を全件確認。search / term / query を名前に含むのは Spotlight Query Performance と Visual Intelligence Image Search Usage の2本だけで、どちらもストア検索語ではない）。**待っても降りてこないので「外部データ待ち」ではない。**残る面（Sales and Trends / Apple Search Ads / ASCのWeb UI）を叩いて確かめる",
      "unlock": "asc_search_terms",
      "blocked_on": [
        {
          "dir": "growth/data/appstore",
          "contains": "Search Term"
        }
      ]
    },
    {
      "area": "③ 自律型マーケティング",
      "task": "ストア内漏斗の観測（表示→ダウンロード→利用）",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/scripts/asc_funnel.rb",
        "../simplememo-ios/scripts/lib/asc_reading.rb",
        "../simplememo-ios/scripts/lib/asc_columns.rb",
        "../simplememo-ios/.github/workflows/asc-analytics.yml"
      ],
      "note": "2026-08-26実装。日次で自動的に走り、人の承認を挟まない。ゲートは**どれも「言い過ぎ」を止める向き**。(1) **Apple の Event 名を先に決めない** —— 表示に当たる名前を当てられなければ率を出さず、観測した名前をそのまま出す（次に当てられるように）。このリポジトリは「上流の仕様を叩く前に書く」を3回繰り返しているので、同じことを別の領域でやり直さない (2) **窓が違うものを割らない** —— 分子（ダウンロード）と分母（ストア表示）は別のレポートから来る。date_range が一致しなければ率を出さない。1日ぶんを28日ぶんで割ると桁が変わる (3) 分母が 20 に届かなければ率を出さない（⑨と同じ下限）。self-test 23件\n\n**2026-08-26 時点で読めているのは利用だけ** —— Sessions 573 / Unique Devices 168 / Total Session Duration 47,223（これは数値列なので以前から合計に入っていた。**入っていたのに誰も読んでいなかった**）。表示・入口・地域は手元の取得結果が内訳を持つ前の版なので no_breakdown。**次の定時取得（毎日20:30 JST）で決まる。**利用の窓は不明（この取り込みは date_range を持たない）ので、**1セッションあたりの秒数を出していない**"
    },
    {
      "area": "④ 自動本番デプロイ",
      "task": "サイトの本番デプロイ",
      "executor": "ai_executes_gated",
      "evidence": [
        ".github/workflows/auto-merge.yml"
      ],
      "note": "mainマージ＝Cloudflare Pagesが自動デプロイ"
    },
    {
      "area": "④ 自動本番デプロイ",
      "task": "バージョン・価格・名称の単一情報源化",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/site-constants.json",
        "scripts/sync_constants.js"
      ],
      "note": "CIがドリフトを落とす。App Store側とは繋がっていない"
    },
    {
      "area": "④ 自動本番デプロイ",
      "task": "ビルドとTestFlight内部配信",
      "executor": "ai_proposes",
      "evidence": [
        "../simplememo-ios/docs/release-automation.md"
      ],
      "note": "タグ作成は人。以降はXcode Cloud＋自動アタッチ **[2026-08-25] ここを gated へ上げようとして、上げてはいけないと分かった。**権限表が『タグ v* の作成』を human_only と定めており、上げるにはそれを渡すしかない —— numbers.md が『人間専任19件のうち11件をAIに渡すと境界が消える』と警告しているのと同じ行為。**代わりに、境界を動かさずに塞げる穴（出荷前のCI緑判定）を実装した。** **[2026-08-27] その境界がオーナー判断で外れた。**\n\n**[2026-08-28] 到達可能側から外した（分類の訂正）。**権限表「アプリのビルド・TestFlight内部配信」は human_only に「タグ v* の作成」を置き、ai_may は空。**タグ push を拒む設計（claude.yml に actions: write を与えない）は2026-08-27 のオーナー判断でも外れていない。**\n**害は件数ではなく向きに出る** —— `--plan` が「作れば進む」と言い続け、天井が実際より高く出る。到達可能な件数は減るが、**下がった天井のほうが本物。**",
      "blocker": "policy_boundary",
      "unblocked_by": "タグpushを意図的に拒否している（claude.yml に actions: write を与えない設計の一部）",
      "authority": {
        "domain": "アプリのビルド・TestFlight内部配信",
        "human_only": "タグ v* の作成"
      }
    },
    {
      "area": "④ 自動本番デプロイ",
      "task": "申請項目・リリースノート・サブタイトルの投入",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/scripts/prepare_app_store_version.rb"
      ],
      "note": "Apple商標スキャン込み。5.2.5リジェクトの恒久対策"
    },
    {
      "area": "④ 自動本番デプロイ",
      "task": "App Review への提出",
      "executor": "human_only",
      "evidence": [
        "../simplememo-ios/.github/workflows/submit-review.yml"
      ],
      "note": "submit-v* タグ作成は人。Hard Ruleで実機確認が先\n\n**[2026-08-28] 2つの台帳が食い違っていたので更新した（訂正ではない）。**この行の unblocked_by は境界がまだ在る前提で書かれていたが、**同じ日にオーナーが名指しで渡し、権限表は既に `requires_approval: false` ＋ machine_gate。**門は #708 で実装済み（`scripts/check-release-gate.mjs`）。\n\n**executor は動かさない。**`policy.enabled` は false で、**実行側（ASCへの提出・公開の呼び出し）がまだ無い。**「門を作った」を「動いた」と数えないための据え置きで、レビュー返信の行が実際に投稿するまで動かなかったのと同じ基準。",
      "blocker": "not_started",
      "unlock": "ship_execute",
      "unblocked_by": "**実機確認は外していない**（機械には代われないので、門が `device_verified_sha` の一致を要求する形にした）。残るのは実行側の実装と、`policy.enabled` を立てる操作（権限表で human_only）",
      "authority": {
        "domain": "App Review への提出",
        "ai_may": "**ゲートを通った提出の実行**（CI緑・実機確認の記録あり・TestFlightで24時間以上・1日1回）"
      }
    },
    {
      "area": "④ 自動本番デプロイ",
      "task": "実機での事前確認",
      "executor": "human_only",
      "evidence": [
        "../simplememo-ios/docs/release-automation.md"
      ],
      "note": "Hard Rule。技術的強制ではなく人間のルール",
      "blocker": "physical_human",
      "unblocked_by": "実機の操作"
    },
    {
      "area": "④ 自動本番デプロイ",
      "task": "App Store への公開（審査通過後）",
      "executor": "human_only",
      "evidence": [
        "../simplememo-ios/fastlane/Fastfile"
      ],
      "note": "automatic_release がハードコードで false。**[2026-08-27] 「恒久的に手動」はオーナー判断で撤回された。**ハードコードを外すには machine_gate が要る\n\n**[2026-08-28] 2つの台帳が食い違っていたので更新した（訂正ではない）。**この行の unblocked_by は境界がまだ在る前提で書かれていたが、**同じ日にオーナーが名指しで渡し、権限表は既に `requires_approval: false` ＋ machine_gate。**門は #708 で実装済み（`scripts/check-release-gate.mjs`）。\n\n**executor は動かさない。**`policy.enabled` は false で、**実行側（ASCへの提出・公開の呼び出し）がまだ無い。**「門を作った」を「動いた」と数えないための据え置きで、レビュー返信の行が実際に投稿するまで動かなかったのと同じ基準。",
      "blocker": "not_started",
      "unlock": "ship_execute",
      "unblocked_by": "**「恒久的に手動」は 2026-08-27 に撤回された。**ハードコードの automatic_release=false を外すのに要る machine_gate は #708 で入った。残るのは実行側の実装と、`policy.enabled` を立てる操作（権限表で human_only）",
      "authority": {
        "domain": "App Store への公開（審査通過後）",
        "ai_may": "**ゲートを通った公開の実行**（段階リリース限定・1日1回・クラッシュ率とkillの確認つき）"
      }
    },
    {
      "area": "④ 自動本番デプロイ",
      "task": "証明書・APIキー・Provisioning Profile の期限監視",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/credential-expiry.json",
        "scripts/check-expiry.mjs",
        ".github/workflows/seo-check.yml"
      ],
      "note": "2026-08-22実装。CIが毎PRで検査し30日前に警告・7日前で落とす。TLSは実測するが、発行元が信用集合に無ければ**期限を報告しない**（中間者復号の環境でプロキシの証明書を本番の期限として書かないため）。**critical 3件（証明書・Profile・ドメイン）の期限日はまだ未把握** — 人が調べて埋めるまで、その3件は監視できていない"
    },
    {
      "area": "④ 自動本番デプロイ",
      "task": "段階公開への自動昇格",
      "executor": "ai_proposes",
      "evidence": [
        "../simplememo-api/src/rollout-guard.ts",
        "../simplememo-api/test/rollout-guard.test.ts",
        "scripts/check-rollout-promotion.mjs",
        "data/rollout-promotion.json",
        "data/authority-matrix.json"
      ],
      "note": "**意図的に提案止まり。**露出を広げる方向は不可逆（広げてから戻しても見た人が見なかったことにはならない）なので人が承認する。/admin/rollout-guard に積まれる。v5.8.1（2026-08-22）でクライアント側が本番に載り、**昇格の判断が実際に発生しうる状態になった**（それまでは判断の対象が無かった）\n\n**[2026-08-26] 判断は実際に発生している。**`tf04_progress` が 5% で稼働中で、ガードは毎時判定を出している（decisions 30件）。ただし現在の判定は hold で、理由はサンプル不足（露出 5〜12 / 判定に要る 30 に未達）。**昇格の提案はまだ1件も積まれていない**（awaiting_approval 0）\n\n**[2026-08-27] 機械ゲートを作った。executor は動かさない。**オーナー判断で境界が外れたが、権限表は不可逆な領域の承認を外すのに machine_gate を要求するので、宣言ではなく実装で外した（`scripts/check-rollout-promotion.mjs` の `evaluatePromotion` / `data/rollout-promotion.json`）。落とすもの: ガードの判定が promote でない／判定が120分より古い／3指標のどれかが各群30の母数に届かない／梯子を飛ばす／50% を超える（**100% への最終段は人**）／48時間寝ていない／直近7日に kill／日次上限1／`drill_`／killed。**材料が欠けたら必ず hold**（13欄を1つずつ落として確かめた）。\n\n**この門は今日のボタンを押せない。設計どおり。**ガードは rollout 5% では判定に届かず、自分で『露出30には rollout 19% 以上』と計算している（run 33076125334）。**判定に届かない露出から踏み出す最初の一歩は証拠で正当化できない**ので、そこは人が押す。門が効くのは25%以降。\n\n**executor は `ai_proposes` のまま動かさない。**残っているのは (1) 実行側（simplememo-api が `--plan` を読んでフラグを設定する経路）と (2) オーナーが `auto_promote.enabled` を立てること。**「門ができた」を「昇格した」と数えない** —— レビュー返信の行が実際に投稿するまで動かなかったのと同じ基準\n\n**[2026-08-28] 入口を `impl_machine_gate`（実装）から `rollout_first_pass`（待ち）へ移した。作るものもオーナー操作も残っていない。**門は 2026-08-27 に入り（`evaluatePromotion`）、カナリアは 2026-08-27 に 25% へ上がり、`auto_promote.enabled` は 2026-08-28 にオーナーが立てた。**残っているのは 48時間の寝かせ（2026-08-29 まで必ず hold）と、3指標が各群30以上で判定できること**で、どちらも実装では早められない。`refund_observe` を implement から wait へ移したのと同じ形の訂正。",
      "blocker": "verification_pending",
      "unlock": "rollout_first_pass",
      "unblocked_by": "**[2026-08-28] ここに残件として書いてあった2つは、どちらも済んだ。**(1) 実行側の経路 … simplememo-api#190「段階公開の昇格を実行する側」。(2) `auto_promote.enabled` … `data/authority-matrix.json` に 2026-08-28 の記録があり、オーナーが名指しで委譲したのでAIが立てた。読み取り専用の実機確認（simplememo-api run 33132559234・`apply: false`）で門は `hold / 自動昇格が有効になっていない` を返しており、**止めていたのはこのフラグだけだった。**\n\n**したがって `not_started` は事実として誤り。**残っているのは実装でもオーナー操作でもなく、**門が実際に1件通ること**。hold の理由は実検査側（48時間の寝かせ・各群30の母数・梯子・上限50%・日次1段）へ移っている。ガードは rollout 5% では判定に届かず（露出30には rollout 19% 以上が要る）、**判定に届かない露出から踏み出す最初の一歩は人が押す**ので、そこは human_only のまま",
      "authority": {
        "domain": "段階公開の拡大（rollout の引き上げ）",
        "ai_may": "**ゲートを通った昇格の実行**（ガードが判定を出せた段のみ・上限 50% まで・1日1段）"
      }
    },
    {
      "area": "④ 自動本番デプロイ",
      "task": "Crash-free率・送信成功率による自動停止",
      "executor": "ai_autonomous",
      "evidence": [
        "../simplememo-api/src/rollout-guard.ts",
        "../simplememo-api/test/rollout-guard.test.ts",
        "data/stop-drills.json"
      ],
      "note": "起動完走率（launch_incomplete の裏返し＝クラッシュ代理指標）・送信成功率・エディタ→送信到達率の3本で判定。1指標でも割れたら止める。**2026-08-22実装。本番でまだ1回も発火していない**（段階公開中のフラグがゼロのため）。実装した≠動いた。同日 v5.8.1 でクライアント側の段階公開が本番に載ったので、**フラグを一つ段階公開に載せた時点で初めて発火しうる状態になる**。それまではガードが見る対象そのものが存在しない\n\n**[2026-08-26 訂正] 「段階公開中のフラグがゼロ」は事実と違っていた。**`tf04_progress` が本番で稼働している —— 08-22 に 0% で定義、08-23 に 1%、08-25 に **5%**（引き上げの description に「1% では露出3で判定に届かなかったため」と書いてある）。ガードも走っている: last_run_at 2026-08-26T04:00:01Z / decisions 30件 / promotion_frozen false。**発火しない本当の理由はサンプル不足** —— 3指標とも judged: false で、「サンプル不足（露出 12 / 対照 236 < 30）。**判定していない（異常なしではない）**」を返している。**待てば解けるものではない**（露出を上げるのは authority-matrix domain 16 で承認要）。この欄が 08-22 の記述のまま4日間止まっていたのは、**実物を叩かずに台帳の散文を引き継いだから**（data/operating-memory.json om-2026-08-26-ledger-outran-reality）\n\n**[2026-08-26] 群の作り方に fail-open の欠陥。**splitByBucket がinstall_id のハッシュだけで割っていて、版を見ていなかった。5.8.1 未満の install は機能を受け取っていないのに、bucket 次第で露出群に入る —— **差が消える＝止めない方向にだけ歪む。**版で絞る修正を実装済み（未マージ・本番未反映）。**この行を ai_autonomous と数えているのは『指標が割れたら止めること』についてであって、『正しい群で測れていること』についてではない**"
    },
    {
      "area": "④ 自動本番デプロイ",
      "task": "Remote Feature Flag と緊急Kill Switch",
      "executor": "human_only",
      "evidence": [
        "../simplememo-api/src/flags.ts",
        "../simplememo-api/src/config.ts",
        "../simplememo-ios/SimpleMemo/FeatureFlagRollout.swift",
        "../simplememo-ios/SimpleMemoTests/FeatureFlagRolloutTests.swift",
        "../simplememo-ios/docs/feature-flag-client-spec.md",
        "../simplememo-ios/release_notes/ja-JP/5.8.1.txt",
        "../simplememo-api/data/rollout-bucket-vectors.json",
        "../simplememo-api/test/rollout-vectors.test.ts",
        "../simplememo-ios/scripts/qa/check_rollout_vectors.py",
        "data/stop-drills.json"
      ],
      "note": "[2026-08-22訂正] 前回の「iOS側が入るまで実際には止められない」は誤り — v4.7から /v1/config + REMOTE_FLAGS_JSON で全体キルができていた。同日、不足分（段階公開・キャッシュ期限・取得経路のテスト）を実装し、**2026-08-22 に v5.8.1 として本番リリースした**（リリースノートも「問題があれば即座に取り下げられる仕組み」と書いている）。これで台帳上の『両側が揃った』が、実際に利用者の端末に載った状態になった。**human_only なのは kill を叩くのが人間だから** — AIが自動で kill する経路は無い。さらに**本番で kill を1回も通していない**（止まることを確かめていない停止機構は無いのと同じ）。v5.8.1 で経路が本番に載ったので、**次に確かめるべきはこれ**。**バケット割りは iOS ↔ relay の契約として固定した**（同日） — 期待値15本は元々サーバ実装を一度回して Swift にコピーしたもので、**凍っているのは Swift の期待値のほう**（サーバが変わっても Swift のテストは通り続ける）。本番に載った以降ここがずれると『サーバでは配布対象だがアプリでは対象外』になり、**出荷済みのバイナリは直せない**。両側が同じ1ファイルを読む形にした\n\n**[2026-08-26 訂正] 「本番で kill を1回も通していない」は事実と違っていた。**/admin/flags の history に残っている: 2026-08-22 14:44:53Z に `tf04_progress` を rollout 100 で作成（description「TestFlight で kill の実証を行うための一時配布」）→ 14:57:38Z に **killed: true**（actor: human）→ 15:00:12Z に解除 → 15:01:10Z に rollout 0 へ戻し description を「**kill の実証完了（2026-08-22）**」へ。**この欄を書いた日と同じ日に、実証は済んでいた。**ただし残っているのはサーバ側の状態遷移だけで、**端末で実際にオフになったことの記録は無い**（data/stop-drills.json の flag-kill）\n\n**[2026-08-28] 到達可能側から外した（分類の訂正）。**権限表「段階公開の撤回（カナリアガード）」が human_only に「ガードの判定によらない kill の実行」を置いている。**緊急停止はその定義そのもの**（ガードの判定によらない）なので、人の側に残る。\n**害は件数ではなく向きに出る** —— `--plan` が「作れば進む」と言い続け、天井が実際より高く出る。到達可能な件数は減るが、**下がった天井のほうが本物。**",
      "blocker": "policy_boundary",
      "unblocked_by": "緊急停止は人が握る",
      "authority": {
        "domain": "段階公開の撤回（カナリアガード）",
        "human_only": "ガードの判定によらない kill の実行（手動・訓練を含む）"
      }
    },
    {
      "area": "④ 自動本番デプロイ",
      "task": "審査項目・商標・プライバシー表示の整合確認",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/scripts/lib/app_metadata.rb",
        "../simplememo-ios/.github/workflows/qa-static.yml"
      ],
      "note": "2026-08-22に検査を拡張。名前・サブタイトル（5.2.5・商標）に加え、キーワード欄とリリースノート（長さ上限・3.1.2の語）も毎PRで見る。自己テスト20件追加。**キーワードの実値はまだASC内にあり移していない**ので、その分は NOTE として毎回出る"
    },
    {
      "area": "④ 自動本番デプロイ",
      "task": "AI・外部サービス停止時の独立した緊急停止経路",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/emergency-stop.json",
        "scripts/check-emergency-stop.mjs",
        "scripts/autopilot-gate.mjs",
        ".github/workflows/obsidian-autopilot.yml"
      ],
      "note": "2026-08-22実装。**主系と副系を同時に、意図が残る形で止める唯一のスイッチ。**予算ゲートは主系しか止めず、秘密鍵の削除は「静かに寝る」ので止めたのか壊れたのか区別がつかなかった。他のどの判定よりも先に効き、force でも飛び越えられない。**AIは止められるが解除できない**（非対称）。CIは台帳ではなく**配線**を見る（判定・ワークフロー・Runbookの3経路）",
      "since": "2026-08"
    },
    {
      "area": "④ 自動本番デプロイ",
      "task": "ChatOps によるリリース起動",
      "executor": "ai_proposes",
      "evidence": [
        "../simplememo-ios/.github/workflows/release-command.yml"
      ],
      "note": "issue コメントで起動。コメントするのはオーナー\n\n**[2026-08-28] 到達可能側から外した（分類の訂正）。**起動コメントを打つのがオーナー、という設計そのものが人間ゲート。**打つ主体を機械にすると、ゲートが消えて何も残らない。**\n**害は件数ではなく向きに出る** —— `--plan` が「作れば進む」と言い続け、天井が実際より高く出る。到達可能な件数は減るが、**下がった天井のほうが本物。**",
      "blocker": "policy_boundary",
      "unblocked_by": "起動コメントを打つのがオーナー。ここが人間ゲート",
      "$authority_absent": "表に領域が無い。**起動コメントを打つ主体が人**という設計そのものが人間ゲートで、打つ側を機械にすると門が消えて何も残らない"
    },
    {
      "area": "⑤ AI予算・トークン管理",
      "task": "実費の記録（月次台帳）",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/autopilot-cost.json",
        "scripts/autopilot-budget.mjs"
      ],
      "note": "2026-08-22実装"
    },
    {
      "area": "⑤ AI予算・トークン管理",
      "task": "実費の抽出（実行ログから）",
      "executor": "ai_executes_gated",
      "evidence": [
        ".github/workflows/obsidian-autopilot.yml"
      ],
      "note": "total_cost_usd を抽出しサマリと通知へ"
    },
    {
      "area": "⑤ AI予算・トークン管理",
      "task": "上限超過での自己停止",
      "executor": "ai_executes_gated",
      "evidence": [
        ".github/workflows/obsidian-autopilot.yml",
        "scripts/autopilot-budget.mjs",
        "scripts/autopilot-gate.mjs"
      ],
      "note": "予算ゲートが主系runを止める。副系は止められない。**【2026-08-25】上限は2種類あり、長く効いていたのは月次だけだった。**model-routing.json の `max_usd_per_run`（1回あたり）は宣言だけで実行時に見る経路が無く、08-23の1回は article の上限 $2.00 に対し $7.2967（3.6倍）を使い切って正常終了している。`--check-run-cap` を route ステップに配線して塞いだ。費用はrunが終わるまで確定しないので**止められるのは次の1回**。種別ごとに見るので記事の超過が修理を止めることはなく、止まるのは主系だけなのでレビュー待ちの間も副系が出荷を続ける。解除は人間のみ（`--ack-overrun`）。**本番でまだ一度も発火していない。**"
    },
    {
      "area": "⑤ AI予算・トークン管理",
      "task": "月次上限の決定",
      "executor": "human_only",
      "evidence": [
        "data/authority-matrix.json"
      ],
      "note": "現在 placeholder $40。実測由来ではない",
      "blocker": "policy_boundary",
      "unblocked_by": "支出上限の決定",
      "authority": {
        "domain": "AI実費（開発・運用のトークン費）",
        "human_only": "monthly_usd_cap の決定"
      }
    },
    {
      "area": "⑤ AI予算・トークン管理",
      "task": "1記事あたり単価の算出",
      "executor": "ai_executes_gated",
      "evidence": [
        "scripts/autopilot-budget.mjs"
      ],
      "note": "usd_per_shipped。課金者あたりは無い"
    },
    {
      "area": "⑤ AI予算・トークン管理",
      "task": "タスク単位の予算",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/autopilot-cost.json",
        "scripts/autopilot-budget.mjs",
        ".github/workflows/obsidian-autopilot.yml"
      ],
      "note": "2026-08-22実装。article/repair/analysis/pr/qa_triage の5種別に月次枠。**合計が月次上限を超えるとCIが落ちる**（超えたら枠は装飾）。種別の枠切れでは主系全体を止めない — 記事の枠切れが修理まで巻き込むため。**枠も暫定**（月次上限が placeholder なので、そこから割った枠も placeholder）",
      "since": "2026-08"
    },
    {
      "area": "⑤ AI予算・トークン管理",
      "task": "モデル別・再試行別の内訳",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/autopilot-cost.json",
        "scripts/autopilot-budget.mjs"
      ],
      "note": "2026-08-22実装。実行ログの modelUsage から記録。**費用の按分はログに無いので回数しか言えない**"
    },
    {
      "area": "⑤ AI予算・トークン管理",
      "task": "品質・速度・価格に応じたモデルルーター",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/model-routing.json",
        "scripts/check-model-routing.mjs",
        ".github/workflows/obsidian-autopilot.yml"
      ],
      "note": "2026-08-22実装。種別→モデルを台帳化し、ワークフローが --resolve で引く。**引かれない表は装飾**なので、ワークフローが実際に呼んでいることをCIが見る。**不可逆なタスク（対外配信）を最安ティアに落とすことを禁止**（節約額より失う額が大きい）",
      "since": "2026-08"
    },
    {
      "area": "⑤ AI予算・トークン管理",
      "task": "小型→大型→人間への段階的移管",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/model-routing.json",
        "scripts/check-model-routing.mjs",
        ".github/workflows/obsidian-autopilot.yml",
        "../simplememo-ios/scripts/qa/ai_triage.sh"
      ],
      "note": "2026-08-22実装。種別ごとに小型→大型→人間のはしごを台帳で持ち、`--escalate <種別> --attempt N` が次の段を返す（人間に達すると exit 3）。**すべてのはしごが human で終わること**と、1段目が rules[種別].model と一致することを検査する（不一致を実際に1件検出して直した）。主系ワークフローは --resolve の結果でモデルを選ぶので、台帳が実行に効いている。残る弱さ: attempt を数えて自動で上げる呼び出し元がまだセッション側にしかない",
      "since": "2026-08"
    },
    {
      "area": "⑤ AI予算・トークン管理",
      "task": "Prompt Cache・結果キャッシュ",
      "executor": "intentional_no",
      "evidence": [],
      "note": "**やらないと決めた。**Prompt Cache は毎朝のプロンプトが静的でAPI側のキャッシュが効く範囲にあり、こちらで持つと二重管理になる。結果キャッシュで重いのは内部リンクの200検証（13,273件）だが、これはCIの話でセッションのトークンではない — **節約したい対象が違う**"
    },
    {
      "area": "⑤ AI予算・トークン管理",
      "task": "コンテキスト圧縮（毎朝の1枚）",
      "executor": "ai_executes_gated",
      "since": "2026-08",
      "evidence": [
        "scripts/daily-brief.mjs",
        "data/emergency-stop.json",
        "data/autopilot-runs.json"
      ],
      "note": "2026-08-22実装。毎朝のセッションは着手前に Runbook・status・運転台帳・実費台帳・自己修復の判定・緊急停止・移管規則を**それぞれ読んでいた。**同じことを毎日6ファイル分のトークンで再構成していたので、1枚にまとめた。**新しい情報を作らない** — 既存の集計関数を呼ぶだけで、数字は台帳が正。未修理の故障も自己修復の判定をそのまま使う（数え直すとレーンFと表示がずれる）"
    },
    {
      "area": "⑤ AI予算・トークン管理",
      "task": "無限ループ・重複実行の防止",
      "executor": "ai_executes_gated",
      "evidence": [
        "docs/obsidian/AUTOPILOT_RUNBOOK.md",
        "scripts/autopilot-gate.mjs"
      ],
      "note": "--max-turns 250・当日ブランチ占有・冪等性チェック"
    },
    {
      "area": "⑤ AI予算・トークン管理",
      "task": "異常消費の検知",
      "executor": "ai_executes_gated",
      "evidence": [
        "scripts/autopilot-budget.mjs",
        "data/autopilot-cost.json"
      ],
      "note": "2026-08-22実装。絶対額ではなく直近中央値との比。実績5件未満では『判定していない』と言う"
    },
    {
      "area": "⑤ AI予算・トークン管理",
      "task": "モデル障害・レート制限時のフォールバック",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/model-routing.json",
        "scripts/check-model-routing.mjs",
        "scripts/autopilot-gate.mjs",
        "data/escalation-rules.json",
        "../simplememo-ios/scripts/qa/ai_triage.sh"
      ],
      "note": "2026-08-22実装。縮退先を台帳に持ち、実行判定が DEGRADE_MODEL / FAIL_NO_MODEL を返す（使えるモデルが尽きたら走らない — 静かに寝ない）。両コードに移管規則がある。**不可逆な種別に最安のモデルを割り当てると落ちる。**残る弱さ: 使えないモデルを検知して渡す経路が無いので、縮退の起点は今も人かセッションの観測",
      "since": "2026-08"
    },
    {
      "area": "⑤ AI予算・トークン管理",
      "task": "新モデル導入前の固定評価セット",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/model-eval-set.json",
        "scripts/check-model-eval.mjs",
        "data/model-routing.json"
      ],
      "note": "2026-08-22実装。失敗分類の6ケースを固定し、合格ライン83%＋**「分からない」と答えられること2件を必須通過**にした。合格条件は決定論（ラベルの照合のみ）— AIにAIを採点させると採点側を替えた時点で履歴が無効になるため。**評価はまだ一度も走らせていない**ので policy.enforce は false（true にすると現行3モデルが未評価で落ちる）",
      "since": "2026-08"
    },
    {
      "area": "⑤ AI予算・トークン管理",
      "task": "副系CCRの実費観測",
      "executor": "nobody",
      "evidence": [
        "data/autopilot-cost.json"
      ],
      "note": "スケジュール起動セッションのログが外部から読めない。構造的に不可",
      "blocker": "structural",
      "unblocked_by": "スケジュール起動セッションのログが外部から読めない。セッション自身も自分のトークン費を知らない"
    },
    {
      "area": "⑤ AI予算・トークン管理",
      "task": "採用された改善1件あたりのAI原価",
      "executor": "ai_executes_gated",
      "evidence": [
        "scripts/ai-unit-cost.mjs",
        "data/autopilot-cost.json",
        ".github/workflows/seo-check.yml"
      ],
      "note": "**[2026-08-26] 実装した。**以前ここに書いていた「分母が無い」は半分が古かった —— run には既に `outcome`（shipped / no_artifact / failed）があり、却下と計測失敗は分母から外せていた。**残っていたのは revert だけ**で、出荷したあとで戻した変更が採用として数えられていた。`outcome: reverted`（`reverted_why` 必須）を足し、分母から外すようにした。\n\n**分子には失敗した run の費用も残す。**採用1件の原価は、うまくいかなかった試行を含めた額であって、成功分だけを割った額ではない。\n\n**値はまだ名乗れない。**採用2件 < MIN_ADOPTED 10 なので `measured: false` を返す（費用の分散が大きく 0〜11.93 USD、数件の平均は方向すら示さない）。参考値 $10.02 は出力に出るが「未測定」と明示している —— **「まだ測れていない」であって「原価が低い」ではない。**",
      "since": "2026-08"
    },
    {
      "area": "⑤ AI予算・トークン管理",
      "task": "AI費用に対する粗利（AI原価の回収）",
      "executor": "nobody",
      "evidence": [],
      "note": "⑥の売上接続が前提。**ASC の課金レポートが降りていなかったので、そもそも分子が無かった**（2026-08-25 に取得側の欠陥2件を修正、data/operating-memory.json の om-2026-08-25-asc-zero）。降りたあとで初めて立てられる。[2026-08-26] **分子が無かったのではなく、積む場所が動いていなかった。**取得側で積み始めたので、ここからは実際に日数が増える",
      "blocker": "external_data",
      "unblocked_by": "**「28日たまる待ち」は成立していなかった。**積む側（growth/scripts/revenue-series.mjs）が読むのは ingest-asc.mjs の出力で、その ingest は `../simplememo-ios/data/asc/` を読む —— **このリポジトリの CI に隣は無い**（ingest-asc.mjs の冒頭が自分でそう書いている）。実測 2026-08-26: growth/data/appstore/ は1件、data/revenue-series.json は covered_days 0。08-25 に人が1回走らせたきりだった。**2026-08-26 に積む処理を取得側（../simplememo-ios/scripts/asc_revenue.rb・asc-analytics.yml が毎日実行）へ移し、ここは金額を運ばない写しにした。**待ちが本物になったのはこの日からで、28日ぶんが揃うのは 2026-09-19 前後",
      "unlock": "revenue_28d",
      "blocked_on": [
        {
          "file": "data/revenue-series.json",
          "path": "covered_days",
          "atLeast": 28
        }
      ]
    },
    {
      "area": "⑥ アプリ運営意思決定",
      "task": "ファネル分析（インストール→初回メモ→継続→課金）",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-api/src/analytics.ts",
        "../simplememo-api/docs/reports/FUNNEL_EVALUATION_2026-08-20.md"
      ],
      "note": "4回連続の定点評価\n\n**[2026-08-26] ストア側の手前が繋がった。**この行が見ているのはアプリ内（インストール以降）で、その手前の「ストアで見られた → ダウンロードされた」はどこも見ていなかった。asc_funnel.rb がそこを読む（③の別行）。**まだ繋いでいない** —— 2つは別の窓・別の分母で、**繋ぐには同じ窓に揃える必要がある**（asc_funnel.rb は窓が違えば率を出さない）"
    },
    {
      "area": "⑥ アプリ運営意思決定",
      "task": "コホート分析（継続率・課金率）",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-api/src/cohort-report.ts",
        "../simplememo-api/src/analytics.ts",
        "../simplememo-api/src/index.ts",
        "../simplememo-api/test/cohort-report.test.ts",
        "../simplememo-api/docs/reports/RETENTION_MONETIZATION_COHORT_2026-07-29.md"
      ],
      "note": "2026-08-22。**都度レポートから週次の自動実行へ。**計算も、週次サマリの中でそれを呼ぶ経路も既にあり、**無かったのは定期的に回して読む仕組み**だった（人が叩いた日にしか読まれていない）。運用報告なので ENABLED フラグでは止めず、宛先の有無だけで自己ゲートする（autopilot_report / analytics_daily_report と同じ流儀）。この領域は母数が小さいので、**成熟30件未満では変化を解釈しない**し、差が**1人ぶんの幅**に収まるなら「区別できない」と書く（前週の母数が小さければそちらの分解能を使う）。**言うことが無い週は送らない** — 読めるようになった週・言える差が出た週・集計できなかった週の3つだけ。毎週同じ行を送ると読まれなくなる。残る弱さ: **D28 は BQ の28日蓄積待ち**（9/6前後）。実際に「読める」判定が出るのは母数が30件に届いてからで、いまの規模ではしばらく『母数不足』が続く",
      "since": "2026-08"
    },
    {
      "area": "⑥ アプリ運営意思決定",
      "task": "KPI定義と集計SQLのバージョン管理",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/kpi-definitions.json",
        "scripts/check-definitions.mjs",
        ".github/workflows/seo-check.yml",
        "growth/lib/",
        "../simplememo-api/docs/analytics-golden.md",
        "scripts/code-authorship.mjs",
        "data/code-authorship.json"
      ],
      "note": "2026-08-22実装。KPI6件の定義と、**算出元ファイルの sha256** を台帳に持つ。計算コードが変われば version を上げるまでCIが落ちる（`--bump <id> --why` で履歴が残る）。狙いは数字ではなく**定義の凍結** — 「自動化率が上がった」の半分が計算を変えたからだった、を起こさないため。導入直後にRunbookの編集で実際に発火し、履歴に「定義は変えていない」と残した。残る弱さ: 集計SQLはまだ台帳に無い（BigQuery側は analytics-golden.md 止まり） [2026-08-22追記] **原稿の「変更行の98.8%」が再現できなかった**ので、数え方そのものを script にして凍結した（KPI定義7件目）。台帳の算数と、**headline が実測とずれていないこと**をCIが見る — 「数字だけ良くする」経路をつぶすため。窓の切り方1つで 94.2% ↔ 96.6% と 2.4pt 動くので、**計測日を窓に入れない**ことを定義に含めた",
      "since": "2026-08"
    },
    {
      "area": "⑥ アプリ運営意思決定",
      "task": "データ不足時に「何もしない」と判断",
      "executor": "ai_executes_gated",
      "evidence": [
        "docs/obsidian/AUTOPILOT_RUNBOOK.md",
        "scripts/autopilot-gate.mjs",
        "growth/scripts/build-queues.mjs"
      ],
      "note": "ノイズフロア＝期待クリック3未満／28日窓未満でスナップショットを作らない"
    },
    {
      "area": "⑥ アプリ運営意思決定",
      "task": "売上・課金・返金・広告の照合",
      "executor": "ai_autonomous",
      "evidence": [
        "../simplememo-ios/scripts/asc_revenue.rb",
        "../simplememo-ios/data/revenue/series.json",
        "growth/scripts/revenue-series.mjs",
        "data/revenue-series.json",
        "data/financial-policy.json"
      ],
      "note": "2026-08-26 に照合を実装（../simplememo-ios/scripts/asc_revenue.rb、asc-analytics.yml で毎日実行）。**4つの現況を実データで確かめた:** **売上・課金** … App Store Purchases Standard の Purchases / Proceeds / Sales を重ならないスパンで積む（ONGOING レポートは過去日を含めて再送されるので、重なりを足すと二重計上）。**手数料** … 実データ $3.05 / $2.59 から帯 [0.1473, 0.1544] を出し Small Business 15% と同定。セント丸めがあるので1点では比べない。30% へ移ったら（＝制度から外れたら）検知する。**返金** … Apple は負の Purchases / Sales で返す。1件も観測していないが、**範囲合計では課金と相殺されるので「返金が無かった」とは言えない**（言えるのは「返金が課金を上回る範囲は無かった」まで）。**広告** … 0 は実測（未出稿）。Campaign 列は取得側が既に読んでいるので出稿した日に現れる。CAC は広告費ゼロである以上**定義上存在しない** —— 0除算を「CAC 0円」と書かない。**まだできないこと:** レポート間の件数突き合わせ（Purchases 1件 vs Subscription Event 4件）は**窓が違う**（08-23 のみ / 08-22..08-23）うえ、保存している内訳が範囲の合計で日別ではないため構造的に不可能。日別の内訳を取得側に足すのが前提",
      "blocker": null,
      "unblocked_by": null,
      "unlock": null,
      "$prev_note_2026_08_26": "**この行は自分自身と矛盾していた。**note が「4つのうち材料が揃ったのは1つだけ」と書く一方で unblocked_by は「材料は降りた。残るのは実装」と書いていた。2026-08-26 に一次資料（data/asc/2026-08-26 の10レポート）を読んで解消した。**同じ形の食い違いはこの行で2度目**（1度目は「レポートが0件」と「降りた」の同居）"
    },
    {
      "area": "⑥ アプリ運営意思決定",
      "task": "欠損・遅延・重複データの検査",
      "executor": "ai_executes_gated",
      "evidence": [
        "growth/scripts/check-data-quality.mjs",
        "growth/scripts/ingest-gsc.mjs"
      ],
      "note": "2026-08-22実装。**作った直後の初回実行で実データの欠陥を検出した** — 2026-08-09スナップショットの /vs/ticktick/ が2行あり、クリックが二重に乗りうる状態だった（URL正規化で衝突した行を畳んでいなかった）。取り込み側に mergeByKey を入れて恒久対策。重複と内部不整合は落とし、日付の欠けと鮮度は報告のみ",
      "since": "2026-08"
    },
    {
      "area": "⑥ アプリ運営意思決定",
      "task": "CAC・LTV・回収期間・粗利の統合",
      "executor": "ai_proposes",
      "evidence": [
        "growth/scripts/ingest-asc.mjs",
        "data/financial-policy.json"
      ],
      "note": "2026-08-22にASC取得の配線が入った（③参照）。**CACは依然として存在しない**（広告費ゼロ）。**2026-08-25 に売上が降りた**ので LTV・回収期間・粗利の材料は入り始めたが、**1日ぶんでは出せない。**LTV は継続期間が要り、Subscription State Report の Counts は State Metric を跨いだ合計なので契約者数として使えない（取り込みが行を持たず数値列の合計だけを保存する設計のため）。[2026-08-26] 収入の積み上げが動き出した（上の⑤と同じ配線）。LTV に要る継続期間は Subscription State を跨いだ合計では出せないという制約は変わらない",
      "blocker": "external_data",
      "unblocked_by": "同上。**CACは広告費ゼロのため定義上存在しない**ので、出すのは LTV と回収期間と粗利",
      "unlock": "revenue_28d",
      "blocked_on": [
        {
          "file": "data/revenue-series.json",
          "path": "covered_days",
          "atLeast": 28
        }
      ]
    },
    {
      "area": "⑥ アプリ運営意思決定",
      "task": "季節性・外部要因の分離",
      "executor": "ai_executes_gated",
      "evidence": [
        "growth/scripts/decompose-series.mjs",
        "growth/data/annotations.json",
        ".github/workflows/seo-check.yml"
      ],
      "note": "2026-08-22実装。曜日係数を実測から出し（日1.17 月1.12 火0.97 水0.93 木1.05 金0.83 土0.81）、外れ値を注釈台帳と突き合わせて説明のつかないものを名指しする。**28日未満では判定を拒否する** — 足りない標本で「効いた/効かなかった」を言わせないため。金土は平日比0.8倍まで落ちるので、金曜に出した施策は何もしなくても効かなく見える。残る弱さ: 分離できるのは曜日だけで、季節・外部イベントは注釈頼み",
      "since": "2026-08"
    },
    {
      "area": "⑥ アプリ運営意思決定",
      "task": "対照群に対する増分効果の評価",
      "executor": "nobody",
      "evidence": [],
      "note": "母数が小さく（App Storeクリック2.1件/日）、対照群を割ると両群とも検出力不足",
      "blocker": "statistical_power",
      "unblocked_by": "同上"
    },
    {
      "area": "⑥ アプリ運営意思決定",
      "task": "予算変更幅・損失上限・撤回条件",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/financial-policy.json",
        "scripts/check-financial-policy.mjs",
        "data/authority-matrix.json"
      ],
      "note": "2026-08-22実装。**動かす予算が小さいうちに書いた** — 大きくなってから書くと、そのときの都合に合わせた基準になる。AI実費は稼働中（変更幅25%・間隔14日・損失上限$60・撤回条件3件）、広告は未着手、価格はAI対象外。**損失上限が現在の上限以下だとCIが落ちる**（初日から発火する上限は上限ではない）",
      "since": "2026-08"
    },
    {
      "area": "⑥ アプリ運営意思決定",
      "task": "可逆／不可逆の承認レベル分け",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/authority-matrix.json",
        "scripts/check-authority.mjs"
      ],
      "note": "2026-08-22実装。13領域中9が承認制"
    },
    {
      "area": "⑥ アプリ運営意思決定",
      "task": "月次予算の決定",
      "executor": "human_only",
      "evidence": [],
      "blocker": "policy_boundary",
      "unblocked_by": "同上",
      "authority": {
        "domain": "AI実費（開発・運用のトークン費）",
        "human_only": "monthly_usd_cap の決定"
      }
    },
    {
      "area": "⑥ アプリ運営意思決定",
      "task": "資金繰りシナリオ（悲観・標準・楽観）",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/financial-policy.json",
        "scripts/check-financial-policy.mjs",
        "data/vendor-register.json"
      ],
      "note": "2026-08-22実装。**出ていく側だけ**（悲観$150／標準$40／楽観$25）。収入はASC未接続で機械が読めないため、**ランウェイ（月数）は出さない** — 手元資金も収入も入っていないので月数を書くと嘘になる。CIが「収入未接続なのに runway_months を書いていないか」を見る",
      "since": "2026-08"
    },
    {
      "area": "⑥ アプリ運営意思決定",
      "task": "結果の5分類（成功／失敗／無変化／判断不能／計測失敗）",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/operating-memory.json",
        "scripts/check-operating-memory.mjs",
        "growth/lib/ledger.mjs",
        "growth/experiments/experiments.json"
      ],
      "note": "2026-08-25実装。**「判断不能」と「計測失敗」を分けるのが要点。**前者は待てば解け、後者は待っても解けない。分ける前は experiments.json の `inconclusive` 7件が**全件が実は計測失敗**（変更前の値を未記録）で、待てば解けるものとして扱われていた。CIは (a) 基準値が無いのに inconclusive と書く (b) 基準値を持たないまま実験を走らせる の両方を落とす"
    },
    {
      "area": "⑦ 法人経営",
      "task": "銀行・カード残高の読み取り（日次）",
      "executor": "ai_autonomous",
      "evidence": [
        "../simplememo-api/src/freee.ts",
        "../simplememo-api/test/freee.test.ts",
        "../simplememo-api/docs/freee-setup.md"
      ],
      "note": "**2026-08-27 10:00 JST、cron `freee_balance` が本番で初めて走った**（`0 1 * * *`・eligible=3 sent=2 errors=0・reason `days_left=90 complete=true counted=2 unreadable=0`）。同日、freee の画面と突き合わせて **cash_jpy 638,593 / card_jpy -1,600,509 が完全一致**することを人が確認した。カードは負債なので手元資金に足さず別枠にしてある。**書き込み経路は無い**（テストがモジュールに書き込み系の関数名が無いことを固定している）。**2026-08-27、鮮度も機械が言えるようになった。**一覧APIに `with_last_synced_at` / `with_sync_status` を渡すと `last_synced_at` / `sync_status` が返る（freee が2024-11-05に追加）。渡していなかったので7フィールドしか返っていなかった、というのが真相。本番の実測値は口座ごとに3種類に割れた —— GMOあおぞら（API連携）は `success` で `2026-08-26T23:54:28+0900`、楽天カード（CSV手入力）は `disabled`、現金は `unsupported`。**この区別が要点で**、楽天カードに同期時刻が無いのは「古い」からではなく「同期していない」から。区別せずに「時刻が無い＝古い」とすると、同期していない口座を古いと呼ぶ誤判定になる。API は真偽値1つではなく内訳（`synced` / `stale` / `not_syncing` / `no_sync` / `unknown`）を返す —— 潰すと「銀行は今朝同期済み・カードは3週間前の手入力」がどちらに倒しても嘘になる。しきい値（7日）は**分布から出した値ではない**（観測1点）。日次cronが `oldest_sync_age` を残すので、貯まってから狭める。**読み方を4回間違えた記録**は ../simplememo-api/docs/freee-setup.md にある（`up_to_date` は存在しないフィールド／`update_date` は口座レコードの更新日／`wallet_txns.date` は取引日／詳細の404を「エンドポイントが無い」と読んだが実際はパス違い）。"
    },
    {
      "area": "⑦ 法人経営",
      "task": "仕訳・請求・領収書・月次締めの統合",
      "executor": "nobody",
      "evidence": [],
      "note": "**残高の読み取りだけが別タスクとして実装済み**（同領域の「銀行・カード残高の読み取り（日次）」）。こちらは手つかず。**分けたのは、片方が動いたことで全体が動いたように数えないため。** 仕訳の作成・支払の実行は不可逆で、`data/authority-matrix.json` の「契約・支払い・送金」が `human_only: [\"すべて\"]` / `status: \"not_implemented\"`。しかも `threshold.note` が**二者承認は未設計**と書いている。着手するなら、実装より先にその承認機構から。",
      "blocker": "external_credential",
      "unblocked_by": "残高は読めるようになった。明細（wallet_txns）と仕訳側は未着手",
      "unlock": "bank_feed"
    },
    {
      "area": "⑦ 法人経営",
      "task": "税務・給与・社会保険・法定期限の管理",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/corporate-obligations.json",
        "scripts/check-corporate.mjs",
        "scripts/check-domain-expiry.mjs",
        ".github/workflows/seo-daily.yml",
        ".github/workflows/seo-check.yml"
      ],
      "note": "2026-08-22に台帳と検査を実装。**2026-08-25 に会社の事実が入り、6件中2件が実際に動く期限になった** —— 決算期2月末から法人税・地方税と消費税の申告期限を機械が導く（2027-04-30）。インボイス登録ありが確定したので、資本金や基準期間によらず課税事業者。**日付は台帳に直書きせず決算月から毎回計算する**ので、年をまたいでも古い日付が残らない。残る4件の未把握: Apple Developer の加入日・ドメイン更新日・社会保険の具体的な届出期限・法定調書の要否。**役員報酬ありも確定した**ので社会保険が該当することは決まった（従業員の有無ではなく役員報酬で決まる）。[2026-08-26] **この note と unblocked_by は、材料が届いた翌日から古いままだった。**「消費税は資本金と設立日が無いので未把握」と書いていたが、指している検査は既に期限を出していた。blocked_on を置いて、届いたことを機械が見るようにした\n\n**[2026-09-02] 6件すべてが機械の監視下に入った。executor を `ai_proposes` → `ai_executes_gated` へ。**\n\n最後まで残っていたドメインの更新日が、**週次の実行で RDAP から入った**（2027-01-30）。手で入れたのではなく `scripts/check-domain-expiry.mjs --write` が取得した値で、**外部の3経路（画面・外部調査のRDAP・オーナーのWHOIS）と一致した** —— 台帳が仕込んでいた答え合わせが、食い違いを出さずに閉じた。\n\nいま機械が持っているもの:\n\n    法人税・消費税      決算期（2月末）から毎回導出。**日付を直書きしない**\n    社会保険・法定調書  月日から毎回導出（fixed_annual）\n    ドメイン            RDAP から週次で取得（source: rdap）\n    Apple Developer     オーナー確認済（自動更新なしを4通りで確認）\n\n**人の個別承認は要らない。**期限が近づけば warning、欄が欠ければ CI が落ちる。オーナーが与えるのは「その義務が当社に当たるか」という事実（決算期・役員報酬・インボイス登録）で、**機械の実行を1件ずつ承認する形ではない。**\n\n**申告そのものは人のまま。**この行が数えているのは期限の管理であって、提出ではない（提出は⑦の別の行と士業の領域）。\n\n**あわせて `check-corporate.mjs` の「把握」の定義を直した** —— `confirmed_by_owner` だけを見ていたので、**機械が入れた権威ある値が「未把握」と表示され、しかも日付の検査を1つも受けていなかった**（期限切れ警告が飛ばされる）。出典と日付があり未確認の理由が無い行は把握とみなし、オーナー確認の行と同じ検査を受けさせる。**`confirmed_by_owner` を機械が立てる形にはしていない**（フラグ名が owner なので、機械が自己認証する経路を作らない）。"
    },
    {
      "area": "⑦ 法人経営",
      "task": "定型／非定型契約の分類",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/vendor-register.json",
        "scripts/check-vendors.mjs",
        "../simplememo-api/scripts/check-contracts.mjs",
        "../simplememo-api/data/contract-register.json",
        "scripts/check-contract-kind.mjs",
        ".github/workflows/seo-check.yml",
        "data/check-selftests.json"
      ],
      "note": "ベンダー台帳で「どの事業者とどんな関係があるか」までは機械が持つようになった。\n\n**[2026-08-28 訂正] 待っていた相手を間違えていた。**この行は `contract_docs`（契約書をリポジトリに置く）を待っていたが、この台帳自身が records で「**書面の契約書は無く、規約への同意で成立している**」と記録している。**存在しない書面を待っていた。**分類の対象は規約本文で、それは特定済み・指紋監視（**週1回・月曜**）・15/40マス読解済み。待っているのは残り34マスで、それは `vendor_terms`。\n\n**[2026-08-28 決定] 原本はどのリポジトリにも置かない。**git の履歴は消せず simplememo は公開。原本は既に居場所がある（規約＝各ベンダーの管理画面 / 請求書＝freee）ので、写しを作ると正が2つになり、古いほうを機械が読む事故を足すだけになる。\n\n**[2026-08-31 実測] この欄のマス数は古い。**`data/corporate-obligations.json` の `contract_review` を数えたところ、**44マスすべてが埋まっており `unreviewed` はゼロ**（risk 35 / ok 9）、11社すべてが `reviewed_by: \"human\"`。#726 / #728 / #731 / #732 で 08-28〜29 に埋め切られている。**「34マス未読」は事実でなくなった。**守る側も #733 で入った（`check-corporate.mjs` の `clauseGuard`）。\n\n**[2026-08-31] blocker を `missing_source_document` から `not_started` へ。****待っていた書面は「無い」のではなく「存在しない」** —— 書面契約が発生しておらず、対象は規約同意で、その台帳は既に手元にある。**「対象の書類がリポジトリに無い」は、この行については誤った待ち方だった。**\n\n**executor は動かしていない。**導く経路をまだ作っていないので、分類は誰も実行していない（`nobody` ではなく `ai_proposes` なのは、ベンダー台帳までは機械が持っているため）。**作ってから動かす。「材料が揃った」を「分類できている」と数えない。**\n\n**[2026-09-01] 導く側を作った。executor を `ai_proposes` → `ai_executes_gated` へ。**`scripts/check-contract-kind.mjs` が `data/vendor-register.json` と api の `contract-register.json` から種別を**導出**し、seo-check が毎回回す。手で書いた分類欄は作っていない —— **台帳に書くのではなく、台帳から導く。**\n\n導出: `terms_accepted_by` が在り書面が無い → 定型（附合契約）／書面が在る → 非定型／どちらも無い → **undetermined。standard に丸めない**（記録が無い＝問題なし、をやらない）。\n\n**今日の出力は11社すべて定型・非定型0件。**この行が数える側へ入る根拠は、分類が機械の出力になり、CIが食い違いで落ちるようになったこと。**非定型が現れたときの承認は人のまま**（権限表「契約・支払い・送金」が human_only）で、そこは渡していない。\n\n**空回りの疑いには入口で答えた** —— 実データを3通り壊して exit 1 を観測した（terms_accepted_by を消す／書面を入れて approved_by を \"ai\" にする／台帳に無い相手の書面を入れる）。`data/check-selftests.json` に demonstrated として記録。\n\n**隣が読めない回は照合していないと明示する。**CI に ../simplememo-api は無いので、書面との突き合わせは読めた回だけ。読めなかったことを「食い違い無し」に化けさせない。"
    },
    {
      "area": "⑦ 法人経営",
      "task": "責任上限・知財・個人情報・準拠法の条項検査",
      "executor": "ai_proposes",
      "evidence": [
        "data/corporate-obligations.json",
        "scripts/check-corporate.mjs",
        "data/vendor-register.json",
        "scripts/vendor-terms.mjs",
        "scripts/vendor-clause-worksheet.mjs"
      ],
      "note": "2026-08-22に台帳と検査を実装。10社×4観点。**書面の契約書は無く、各社の規約への同意で成立している**ので、検査対象は規約本文であり確認は人が読むことでしか進まない。**現状40マスすべて unreviewed。**機械が守るのはベンダー台帳との照合（片方だけ増えると素通りする）と、riskと書いたら理由を要求すること [2026-08-26] **改定の検知だけを機械に移した**（scripts/vendor-terms.mjs・seo-daily）。**[2026-08-28 訂正] ここは「毎日取得」と書いていたが誤り。**週1回（月曜）。**scripts/vendor-terms.mjs は seo-daily.yml の中にあるが、**月曜ゲート（steps.when.outputs.snapshot）の内側**にある。したがって改定検知は毎日ではなく週1回で、**火曜に改定されたら、翌月曜まで reviewed は緑のまま残る（最大6日）。**配線が入ったのが 2026-08-26（水）なので、**指紋は全社まだ空で、初着弾は 2026-08-31。**一度 ok と書いた判定は、改定後も ok のまま残る —— **unreviewed（見ていない）より悪い。見たという記録が嘘を守る。**本文の指紋が変われば reviewed を unreviewed へ戻し、読み直しを起こす。**executor は動かない。**本文を読んで ok / risk を決めるのは法的判断で、そこは人のまま。機械が持つのは「いつの本文を見たか」だけ\n\n**[2026-08-31 実測] この欄のマス数は古い。**`data/corporate-obligations.json` の `contract_review` を数えたところ、**44マスすべてが埋まっており `unreviewed` はゼロ**（risk 35 / ok 9）、11社すべてが `reviewed_by: \"human\"`。#726 / #728 / #731 / #732 で 08-28〜29 に埋め切られている。**「34マス未読」は事実でなくなった。**守る側も #733 で入った（`check-corporate.mjs` の `clauseGuard`）。",
      "blocker": "missing_source_document",
      "unblocked_by": "**44マスは埋まった**（2026-08-29・全社 reviewed_by: human）。本文そのものは公開リポジトリに運ばないので `missing_source_document` は残るが、**待っているのは「人が読むこと」ではなく「改定で戻されたマスを読み直すこと」**に変わった。検知は週1回（月曜・seo-daily の内側）、守る側は `clauseGuard`",
      "unlock": "vendor_terms"
    },
    {
      "area": "⑦ 法人経営",
      "task": "取引先・送金先・利用サービスの許可リスト",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/vendor-register.json",
        "scripts/check-vendors.mjs"
      ],
      "note": "2026-08-22実装。10社すべてに money_flow / payment_method / approved_by / spend_cap_ref を持たせ、金銭が動く相手は human 承認と上限の参照先が無いとCIが落ちる。**ここに無い相手への支払いは許可されていない**という形。上限が設定されているのは AI実費と広報配信の2つだけで、残り8社は \"unset\"（理由つき）",
      "since": "2026-08"
    },
    {
      "area": "⑦ 法人経営",
      "task": "支出上限と重要支出の二者承認",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/spend-approvals.json",
        "scripts/check-financial-policy.mjs",
        "data/autopilot-cost.json"
      ],
      "note": "2026-08-22実装。**実際に効いている** — autopilot-cost.json の monthly_usd_cap は承認台帳の最新値と一致していないとCIが落ちる。つまり**承認記録を書かずに上限を動かせない。**変更幅が25%を超えるときは承認者2人。**AIは承認者になれない**（止めることは許しているが、金額を上げることは許さない）。3つの分岐を差し替えで検出確認。ただし**効いている対象はAI実費1件だけ**で、広告・契約は動く金額そのものがまだ無い",
      "since": "2026-08"
    },
    {
      "area": "⑦ 法人経営",
      "task": "契約・請求・納品・支払いの照合",
      "executor": "nobody",
      "evidence": [],
      "note": "3リポジトリに証跡ゼロ。\n\n**[2026-08-28] ここだけは本当に材料が無い。**上の2行と違い、照合には請求・入金の実データが要る。ただし**要るのは書類ではなくデータ。****[2026-08-28 決定] 原本はどのリポジトリにも置かない。**git の履歴は消せず simplememo は公開。原本は既に居場所がある（規約＝各ベンダーの管理画面 / 請求書＝freee）ので、写しを作ると正が2つになり、古いほうを機械が読む事故を足すだけになる。\n\n**したがって道は「PDFを置く」ではなく「freee から金額・日付・相手・入金状態を取り出す」。**取り出し口の有無は未確認で、**あると仮定して計画に載せない。**",
      "blocker": "not_started",
      "unblocked_by": "**[2026-09-01 訂正] この行は「freee に取り出し口があるか未確認」と書いていた。誤り。**\n\n**freee の Public API は 2026-08-27 から本番で動いている。**同じ領域（⑦法人経営）の「銀行・カード残高の読み取り（日次）」が `ai_autonomous` で在り、cron `freee_balance` が毎日 `/api/1/walletables` を叩いて 200 を受け取っている。**ひとり法人プランで使えるかという問いは、5日前に本番で答えが出ていた。**\n\n**しかも `/api/1/wallet_txns`（銀行明細）も既に叩いている。**照合に足りないのは請求書側（`GET /invoices`）だけ。\n\n**残っているのは実装だけなので `blocker` を `not_started` へ、`unlock` を外した。**鍵は既に本番にある（`FREEE_CLIENT_ID` / `FREEE_CLIENT_SECRET`、refresh token は KV の `freee:refresh_token`）。**新しい鍵は要らない。**\n\n**executor は `nobody` のまま。**照合は誰もやっていない。残高が読めていることを照合ができていることに数えない（隣の「仕訳・請求・領収書・月次締めの統合」が「**分けたのは、片方が動いたことで全体が動いたように数えないため**」と同じ規律を既に書いている）。",
      "$research_2026_09_01": "**この調査は外部ディープリサーチ経由で、原文を読んだ人間は鎖の中に居ない。**vendor-register が 2026-08-29 に同じ弱さを記録しているのと同じ種類。このセッションの WebFetch は freee ドメインも含めて塞がれている。\n\n**一番効く主張だけ裏を取ろうとして、取れなかった。**\n報告は「freee会計・freee請求書ともに Public API は**全プラン**」（support.freee.co.jp の記事 115000143186・更新 2026-03-18）と書いている。これが正しければ**ひとり法人プランのまま使える**ので、計画全体がここに乗る。\nWebSearch で同じ記事を引いたが、索引が返したのは**「対象プロダクトとご契約のプランによって異なります」という前置きの文**までで、**プラン別の表そのものは取れなかった。**否定もされていないが、確認もできていない。\n\n**確認と第一歩が同じ操作である**ことが、ここでは効く —— オーナーが freee の開発者ページでプライベートアプリを作れば、**作れた時点でプランの疑問は消える。**別途の検証ラウンドを挟む必要は無い。\n\n**報告が「見つからなかった」と書いた項目（推測で埋めない）:**\n    invoice → wallet_txn の直接的な外部キー … 銀行明細1行との1対1接続\n    Public API の追加料金に関する明文        … 無料と書いてある頁も無い\n    レート制限の具体的な数値                  … 存在することは書かれている\n    `read-only` という名称の OAuth scope      … GET だけに権限を絞るのは可能\n    CSV の定期自動エクスポート                … 手動エクスポートは可能\n\n**6項目を空欄で返してきたことが、この報告を信じてよい根拠のひとつ。**埋めろと言われた欄を埋めずに返すのは、推測で埋める報告より扱いやすい。\n\n**期日つきの注意: 2026-09-21 に `GET /invoices` の破壊的変更**（`limit + offset` が 10,000 以上のリクエストが制限対象）。当社の請求書件数では当面効かないが、**実装するなら日付範囲で取る形にしておく。**いま何も作っていないので期限台帳には入れない —— **壊れるものがまだ無い。**",
      "$my_error_2026_09_01": "**隣のリポジトリを見に行かなかった。**\n\nこの行の `evidence` は空で、隣の「銀行・カード残高の読み取り（日次）」は`../simplememo-api/src/freee.ts` / `test/freee.test.ts` / `docs/freee-setup.md` を**証跡として持っていた。**同じ領域の2行しか離れていない。\n\n**害は3つ出た:**\n  1. オーナーに「freee にAPIがあるか調べて」と外部リサーチを依頼させた\n  2. その報告の「全プランで使える」を裏取りできないと書いた —— **本番で5日間200が返り続けているのが裏そのものだった**\n  3. **～オーナーに2つ目のアプリを作らせた～** ← **これは起きていなかった（下で訂正）**\n\n**「確認と第一歩が同じ操作」も再発見だった** —— `docs/freee-setup.md` が 2026-08-25 の時点で「**§1 をやってみれば30秒で分かる**」と既に書いている。\n\n**なぜ起きたか。**外部の答え（GPTの報告）が来たので、それを台帳に流し込む作業になり、**手元にある事実と突き合わせる段を飛ばした。**このリポジトリが繰り返し警告しているのは「読めなかったものを異常なしと読む」誤りだが、**これは「読めるものを読まずに、外へ聞いた」誤り**で、向きが違う。**外から答えが来たときこそ、先に手元を見る。**\n\n**[2026-09-01 訂正] 3つ目の害は起きていなかった。**\n\nオーナーが freee の画面を見せたとき、「あなたのアプリ専用の Client ID、Client Secret が発行されました」というオンボーディング枠を、**その日に新規作成されたもの**と読んだ。**枠は常に出ている案内で、作成の記録ではない。**\n\n**アプリは最初から1つで、それが本番の連携そのものだった。**オーナーの「今日は作っていません」で止まった。\n\n**害はここでも1つ出た** —— 存在しない「アプリ2つ問題」を立て、削除の危険性・10秒でできる確認手順まで詳しく説明した。**問題そのものが無かったので、その説明は全部むだだった。**\n\n**同じ日に2回、同じ形で間違えている:**\n  1回目 … 隣のリポジトリを見ずに「APIがあるか未確認」と書いた\n  2回目 … 画面の枠を読んで「今日作られた」と書いた\n**どちらも、手元／目の前にあるものを確かめる前に、話を先へ進めた。**\n\n**残った害は2つで、こちらは実際に起きた:**\n  1. オーナーに不要な外部リサーチを依頼させた\n  2. 「全プランで使える」を裏取りできないと書いた（本番で5日間200が返り続けているのが裏だった）\n\n**副産物として1つ良いことがあった** —— この取り違えのおかげで、`../simplememo-api/docs/freee-setup.md` に**「下書き・非公開のアプリが本番そのもの。削除するな」**という警告が入った（simplememo-api#210）。**手順書には「止めかた」はあったが、アプリ自体の削除は書かれていなかった** —— そちらは再認可では戻らない。",
      "unlock": "impl_invoice_reconcile"
    },
    {
      "area": "⑦ 法人経営",
      "task": "AI事業者のDPA・データ利用・SLA・撤退計画の審査",
      "executor": "ai_proposes",
      "evidence": [
        "data/vendor-register.json",
        "scripts/check-vendors.mjs",
        "scripts/vendor-terms.mjs",
        "scripts/vendor-clause-worksheet.mjs"
      ],
      "note": "2026-08-22にベンダー台帳を作成（10社）。何を渡していて・止まると何が起きて・代替があるかを機械検査する。**DPAの確認そのものは人の作業で、いま6社が未確認**。確認したら enforce_unreviewed を true にすると CI が守る [2026-08-26] **改定の検知だけを機械に移した**（scripts/vendor-terms.mjs・seo-daily）。**[2026-08-28 訂正] ここは「毎日取得」と書いていたが誤り。**週1回（月曜）。**scripts/vendor-terms.mjs は seo-daily.yml の中にあるが、**月曜ゲート（steps.when.outputs.snapshot）の内側**にある。したがって改定検知は毎日ではなく週1回で、**火曜に改定されたら、翌月曜まで reviewed は緑のまま残る（最大6日）。**配線が入ったのが 2026-08-26（水）なので、**指紋は全社まだ空で、初着弾は 2026-08-31。**一度 ok と書いた判定は、改定後も ok のまま残る —— **unreviewed（見ていない）より悪い。見たという記録が嘘を守る。**本文の指紋が変われば reviewed を unreviewed へ戻し、読み直しを起こす。**executor は動かない。**本文を読んで ok / risk を決めるのは法的判断で、そこは人のまま。機械が持つのは「いつの本文を見たか」だけ\n\n**[2026-08-29 訂正] `policy.enforce_unreviewed` は条項マスを守らない。**あのフラグは data/vendor-register.json にあり、守るのは **DPAレビュー**（personal_data が none でないのに dpa_reviewed が無いベンダー）で、条項の40/44マスとは別物。**実測した** —— 1マスを unreviewed に戻して check-corporate --check を走らせても exit 0。**条項マスを守る検査は存在しない。**改定で reviewed が戻されても、CIは何も言わない。\n\n**[2026-08-29 追記] 守る検査を作った。**`check-corporate.mjs` の `clauseGuard` が、**一度も見ていないマス**（`unreviewed_budget`・ラチェット。今は0）と**改定で戻されたまま放置されたマス**（`reset_grace_days`・14日）の2つで落とす。**実測: 1マスを unreviewed に戻すと exit 1。**（入れる前は exit 0 だった。）\n\n**猶予が要るのは膠着を避けるため** —— seo-daily は改定を検知して台帳をコミットするPRを出すので、即座に落とすと**そのPR自身が入らず、指紋の更新も入らず、翌週また同じ改定を検知する。**\n\n**[2026-08-31 実測] 未確認は6社ではなく9社。**`data/vendor-register.json` を数えた —— apple / resend / github / registrar が personal、cloudflare / google_cloud / search_console / firebase / appsflyer が pseudonymous で、**この9社すべてが `dpa_reviewed: null`。**確認済みは0社。**条項マスが埋まったこと（44/44）と混同しない** —— 別の欄で、別の文書を読む作業。",
      "blocker": "missing_source_document",
      "unblocked_by": "**[2026-08-31 実測] 「6社が未確認」は古い。**ベンダーが11社に増え、`personal_data` が none でない **9社すべてが `dpa_reviewed: null`**（確認済み0社）。`policy.enforce_unreviewed` も false のまま。**条項44マスとは別物**で、そちらが埋まってもこの行は動かない（2026-08-29 に実測で切り分け済み）。読む先は各社の DPA / Subprocessors / セキュリティ文書",
      "unlock": "vendor_terms"
    },
    {
      "area": "⑦ 法人経営",
      "task": "董事会・株主・規制・契約記録の保存",
      "executor": "ai_proposes",
      "evidence": [
        "data/corporate-obligations.json",
        "scripts/check-corporate.mjs",
        "../simplememo-api/data/incidents.json",
        "../simplememo-api/test/incidents.test.ts"
      ],
      "note": "2026-08-22に台帳と検査を実装。5件中2件は所在があり（規約への同意・App Reviewのやり取り）、**3件は所在が決まっていない**（議事録・株主名簿・事故記録）。事故記録は「発生していない」のか「記録する場所が無い」のかを区別できていない\n\n**[2026-08-28] 所在が決まった。3件のうち1件は機械の側に入った。**事故記録は ../simplememo-api/data/incidents.json を作成し、あちらの test/incidents.test.ts が形を守っている。**空の entries が「起きていない」を意味する** —— ファイルが無い状態は「起きていない」を何も意味しなかった。\n\n議事録・株主名簿は**法が保管場所を本店と指定している**ので、リポジトリには置かない（入れても義務は果たされず、正が2つになる）。株主名簿は氏名・住所が載るため非公開リポジトリでも置かない —— git の履歴は消せない。\n\n**したがってこの行がこれ以上機械側へ寄ることはない。**残るのは実在の確認1回で、それは `corp_records` が持っている。\n\n**[2026-09-01] 2件は「無い」と確定した。**オーナーの明言。**そして義務は履行されていない** —— 会社法318条2項（株主総会議事録・10年・本店）と125条1項（株主名簿・常時・本店）は、**株主が1名でも外れない。**取締役会は非設置なので371条（取締役会議事録）は発生しない。\n\n**「無い」と記録したことを「解決した」と読まない。**台帳が良くなったのは「無いと確かめた」が読めるようになった点だけで、**書面は依然として存在しない。**各 record の `obligation_status: \"unmet\"` がその状態を持つ。\n\n**株主総会そのものは開かれている可能性が高い** —— 決算期は2月末で、定時株主総会での計算書類の承認は法人税申告の前提になる。税理士が決算のたびに議事録を作っているケースもあるので、**「手元に無い」＝「存在しない」とは限らない。**確認事項として税理士へ回した。\n\n**[2026-09-01 訂正] 上の「2件とも無い」は誤りだった。**オーナーへ議事録と株主名簿を**2つまとめて聞き、「ない」という1つの答えを2つの行に配った。**実際に無いのは議事録だけで、**株主名簿は設立時の書類一式に含まれている**（125条1項は満たされている）。\n\n**まとめて聞いたから、まとめて答えが返った。**根拠条文も作成主体も違うものを1問にした私の誤り（318条2項＝会社が毎回作る／125条1項＝設立時に作って変動時に更新する）。**次に人へ事実を聞くときは、1行に1問。**\n\n**議事録は「作らない」とオーナーが決めた**（318条2項の備置義務は株主1名でも外れないことを伝えた上での判断）。`decision` 欄に持たせてあり、`obligation_status` は `unmet` のまま —— **決めたことで義務が消えるわけではない**ので「解決済み」にはしない。\n\n**行の分類は変わらない。**`physical_human` としたのは「書面が無いから」ではなく**「法が保管場所を本店と指定していて、機械がそこに居られないから」**。株主名簿が在ることが分かっても、機械が持てるようにはならない。**到達可能上限 82.9% も動かない。**",
      "blocker": "physical_human",
      "unblocked_by": "**[2026-09-01] 待ちは終わった。そして、この行はここで止まる。**\n\nオーナーが「ない」と回答した（議事録・株主名簿）。所在（本店＝事務所）は同日に確認済みで、**そこに置かれていない**という答え。`existence_confirmed_at` に日付が入り、`corp_records` の述語3つはすべて満たされた。\n\n**機械はここで「行を動かせ」と押してきた** —— `autonomy-gap --check` が「入口はもう開いているのに待ち扱いのまま」と出した。**押し返した。**\n\n**理由: 5件のうち2件は、機械が持てるようになる日が来ない。**\n\n    vendor-contracts          各ベンダーの管理画面       在る（外）\n    app-review-correspondence ASC ＋ docs/reports        在る（一部は機械側）\n    incident-records          api/data/incidents.json   **機械が持つ**（test付き）\n    board-minutes             本店                       **無い**・318条2項・作らない決定\n    shareholder-register      本店                       **在る**（設立時の書類一式）\n\n下2件は**法が保管場所を「本店」と指定している。**リポジトリに入れても義務は果たされず、正が2つになるだけ。株主名簿は氏名・住所を載せるので、**非公開リポジトリでも置かない**（git の履歴は消せない）。**オーナーが今から作っても、この構図は変わらない** —— 作られた書面は本店に置かれ、機械が持つのは所在の指示のままになる。\n\nしたがって `blocker` を `external_data`（到達可能）から `physical_human`（到達しない）へ移し、`unlock` を外した。**到達可能上限が1件下がる。**\n\n**これは数字を下げる向きの変更で、機械の催促と反対**である。前任が note に「**この行がこれ以上機械側へ寄ることはない**」と明記していたのを、+0.5% のために読み替えないこと。\n\n**旧 unblocked_by（保存）:** 本店に議事録・株主名簿が実在するかの確認（1回）。**所在は 2026-08-28 に決まった** —— 議事録・株主名簿は本店（会社法318条2項/125条1項）、事故記録は ../simplememo-api/data/incidents.json（作成済み・検査付き）"
    },
    {
      "area": "⑦ 法人経営",
      "task": "物理業務発注後の写真・受領・品質確認",
      "executor": "nobody",
      "evidence": [],
      "note": "3リポジトリに証跡ゼロ",
      "blocker": "physical_human",
      "unblocked_by": "現物の受領確認"
    },
    {
      "area": "⑦ 法人経営",
      "task": "倫理・評判・長期影響の独立監査",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/audit-charter.json",
        "scripts/check-audit-independence.mjs"
      ],
      "note": "2026-08-22実装。独立監査の4観点のうち ethics_reputation がこれ（5項目）。利用者に見えない不利益変更・実在しない実績の装い・人間だと誤認させる自動投稿・競合を貶める言及・**AIが書いたと分かる形になっているか**。**短期の指標では絶対に検知できない**種類の劣化なので別系統に置いた。**まだ一度も走らせていない**",
      "since": "2026-08"
    },
    {
      "area": "⑦ 法人経営",
      "task": "エージェントごとの権限・認証情報・失効手順",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/credential-expiry.json",
        "scripts/check-credentials.mjs",
        "data/emergency-stop.json",
        "data/authority-matrix.json",
        ".github/workflows/seo-check.yml"
      ],
      "note": "2026-08-22実装。鍵13件それぞれに**使う経路・失効のさせ方・失効させると何が止まるか**を持たせ、ワークフローが実際に読む secret を現物から走査して台帳との食い違いを落とす。`--stop <経路>` で「この経路を止めるにはどれを失効させるか」に答える。**この作業で穴が1つ出た** — 緊急停止の最終手段は「credential-expiry.json の鍵を無効化する」と書いてあったのに、主系を止める鍵（GH_PAT）が台帳に無く、使用中の secret 11件のうち載っていたのは3件だけだった。最後の手段が指す先が空だった。残る弱さ: **失効操作そのものは人**（各社コンソールへのログインが要る）。critical 5件のうち4件は期限が未把握のまま",
      "since": "2026-08"
    },
    {
      "area": "⑦ 法人経営",
      "task": "法務・税務・労務・事故時の専門家エスカレーション",
      "executor": "human_only",
      "evidence": [
        "data/authority-matrix.json"
      ],
      "note": "方針のみ。手順・連絡先・停止手段は未整備。 **[2026-08-25] 税理士と社会保険労務士の両方がついていることをオーナーが明言した。**「士業が居るか」は未把握でなくなり、**領域ごとの向き先も決まった**（税務→税理士 / 社会保険→社労士）。**ただし連絡先・エスカレーション手順・停止手段は依然として未整備。**居ることと、機械が繋げることは別。実際 corporate-obligations の未把握5件のうち2件は「士業に聞けば埋まる」状態で止まっている\n\n**[2026-08-28 訂正] 向き先の片方は存在しなかった。**この欄は「税務→税理士 / 社会保険→社労士」と書いていたが、**社労士は雇っていない**（社員がいないため・オーナー確認）。corporate-obligations の social-insurance も「社労士がついているので期限はそちらに確認する」と書いており、**居ない相手に確認する、と2か所に書いてあった。**確認先の実在を誰も検査していなかったのが原因。\n\n**手順・停止手段・起案は作った**（data/expert-escalation.json / scripts/check-expert-escalation.mjs）。⑧の返信ゲートと同じ形で、宛先が外部の専門家なので閾値は厳しい —— 送るのは台帳にある reviewed な文面だけ（送信時に作らない）／向き先が依頼済みであること／元の未把握がまだ未把握であること／金額・資格情報・利用者の識別子が入っていたら落とす／日次1通・同じ相手へ7日おき・返事待ち上限2。**連絡先は公開リポジトリに置かない** —— 第三者の個人情報なので Worker の secret に置き、台帳が持つのは在り処だけ（address_source に `@` が入っていたら検査が落とす）。\n\n**分類は動かさない。**残っているのは実行側（simplememo-api の送信経路）とオーナーが enabled を立てること。**「経路ができた」を「送った」と数えない** —— 段階公開やレビュー返信と同じ基準",
      "blocker": "physical_human",
      "unblocked_by": "対人・法的責任。**[2026-08-28] その理由は正しいが、範囲が広すぎた** —— 判断（税務・社会保険の解釈）は人のままでよく、機械が持てるのは「誰に・何を・いつまでに聞くか」の起案と送信。起案と門は作った（data/expert-escalation.json）。残るのは実行側（simplememo-api の送信経路と EXPERT_TAX_EMAIL の secret）と、オーナーが enabled を立てること"
    },
    {
      "area": "⑧ カスタマーサポート",
      "task": "問い合わせの自動分類",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-api/src/inquiry.ts",
        "../simplememo-api/migrations/0020_inquiries.sql",
        "../simplememo-api/test/inquiry.test.ts"
      ],
      "note": "2026-08-22実装（simplememo-api・24テスト）。**AIに判定させず規則で分ける** — 回帰の合否をAIに判定させない設計と同じ理由で、分類の誤りは見落としとして静かに積み上がる。分けられないものは**「その他」ではなく unclassified**（その他は見返されないが、未分類は見返される）。重い用件（個人情報・退会・返金）を先に当て、当たったら自動で人へ上げる。**受け口は既定オフ**（INQUIRY_ENABLED）で、公開ページを mailto から切り替えるかは製品の判断。テストが実バグを検出した — 「送信できません」が「できな」に当たらず未分類に落ちていた",
      "since": "2026-08"
    },
    {
      "area": "⑧ カスタマーサポート",
      "task": "問い合わせへの自動回答（承認済みテンプレート）",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-api/src/reply-gate.ts",
        "../simplememo-api/data/reply-policy.json",
        "../simplememo-api/src/inquiry.ts",
        "../simplememo-api/test/reply-gate.test.ts",
        "../simplememo-api/migrations/0026_inquiry_auto_replied.sql"
      ],
      "note": "2026-08-26実装（オーナー判断: 品質ゲート通過で自動送信）。**承認はテンプレート単位で先に取る** — メールは取り消せず、権限表の一番の規則が「不可逆な領域は承認制」なので生成文をそのまま送る形は取れない。data/reply-policy.json の編集（レビュー付きPR）がその承認で、個別送信の承認は要らない。ライフサイクルメールと同じ構造。\n\n**受付時に返す。あとから返さない。**inquiries は宛先を平文で持たない（email_hash のみ）ため、後追い返信にすると宛先を保存することになりプライバシー設計の後退になる。\n\n判定は全部決定論。返金・退会・個人情報はテンプレートを置いていない（分類器が先に弾くが登録簿でも二重に落ちる）。落ちた問い合わせは open のまま残る — **当たらなかったことを「返した」にしない。**\n\n**2026-08-26に受け口を開け、実送信へ昇格した。**INQUIRY_ENABLED=true / INQUIRY_AUTOREPLY_DRY_RUN=false（上限は5で開始。policy側の既定30へは実績を見てから）。本番D1に migration 0026 を適用済みで、本人確認済み274件・配信停止21件が突き合わせの対象。公開ページのフォームも設置した（mailto は残す）。\n\n**開ける前に3つ塞いだ。**/v1/inquiry は App Check の対象外＝無認証の公開POSTで、自動返信を足した時点で「任意の第三者へメールを送らせる経路」になる。(1) verified_registrations にあり配信停止されていない宛先にだけ返す (2) 受付そのものにIP上限（IPハッシュ×UTC日5件・survey と共用） (3) CORS は問い合わせ2経路・許可オリジン2つだけで Origin を反射しない。\n\n**まだ1件も送っていない**（問い合わせ0件・main へのマージで本番反映）。空の実績を「安定している」と読まないこと。",
      "since": "2026-08"
    },
    {
      "area": "⑧ カスタマーサポート",
      "task": "障害案内の一斉配信",
      "executor": "nobody",
      "evidence": [],
      "note": "**旧行から切り出した。**旧行は「回答・返金・障害案内」で、自動化できた回答と、権限表で人に残した返金（⑨に別行がある）と、未実装の障害案内が1行に入っていた。混ぜると、どれか1つができた時点で行が動く。障害案内は宛先の名簿と配信基準の設計が要る\n\n**[2026-08-28] この行の性格が変わった。プロダクトの機能ではなく、契約上の義務になった。**⑦の条項検査で Apple Developer Program License Agreement §3.3.3(C) を読んだところ、**利用者へのデータ侵害通知が契約で約束されている**（You agree to notify Your users ... in the event of a data breach）。\n\n**つまり「まだ作っていない機能」ではなく「約束したのに実行できない動作」。**優先順位の意味が変わるので、ここに書いておく。経路が2つとも閉じている事実（下記 unblocked_by）は変わらない —— 変わったのは、開けないままでよいかどうかの判断材料のほう。data/corporate-obligations.json の contract_review.apple.$personal_data に同じことが書いてある。",
      "blocker": "not_started",
      "unblocked_by": "**[2026-08-27 実測] 「決めれば作れる」ではなかった。**経路が2つしかなく、どちらも決定では開かない。**(a) メール** —— 宛先になりうる名簿は reminder_optin_invites だけで、同意文言は『メモが途切れた日に、そっと1通』『お届けは週2通まで』とリマインダーに限定してある。障害案内はその範囲外で、**送ると同意を超える。** **(b) アプリ内** —— /v1/config の RemoteFlagPayload は flags / rollouts / killed / maxStaleSeconds / refreshSeconds しか運ばず、**文言を運ぶ欄も表示するUIも無い。**足すには iOS 側の実装（payload の欄・バナー・テスト）が要る。したがって開くのは『閾値を決める』ではなく **(a) 障害案内という別の同意を取る**か **(b) iOS に通知面を作る**か",
      "unlock": "impl_product",
      "since": null
    },
    {
      "area": "⑧ カスタマーサポート",
      "task": "App Store レビュー返信",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/review-replies.json",
        "scripts/check-review-replies.mjs",
        "data/review-intake.json",
        "data/authority-matrix.json",
        "data/review-gate-pin.json",
        ".github/workflows/seo-check.yml",
        "../simplememo-ios/scripts/asc_review_reply.rb",
        "../simplememo-ios/data/review-responses.json",
        "../simplememo-ios/data/review-reply-gate.json",
        "../simplememo-ios/.github/workflows/asc-review-reply.yml"
      ],
      "note": "**2026-08-27、実際に投稿した。**run 33059048323 で3件 —— レビュー返信を機械が公開したのはこれが最初。記録は ../simplememo-ios/data/review-responses.json（response_id は Apple が返した値）。state は3件とも PENDING_PUBLISH で、**「POSTが通った」と「App Store に出た」は別。** **上書きしないことも実測した** —— 投稿直後に取り直したら ASC は 8/8 返信済みを返した。**PENDING_PUBLISH でも has_response=true になる**ので、翌日以降の実行は全件 hold する。 【境界】2026-08-27 にオーナーが「公開だけを人が承認する」から**「品質ゲートを通れば自動投稿」**へ変えた（権限表にゲート付き例外）。判断は公開側（evaluateAutoPost / planAutoPost）、実行は非公開側（ASCの鍵があちらにしかない）で、**ゲートの写しはあちらに置いていない。**指紋で留め、両側のCIで照合する。 【落とすもの】捌いていないレビュー / 期日・版の約束 / 個人情報 / 禁止表現と古い事実 / ★2以下 / 返金・法務・個人情報・保安・データ消失 / 日次上限3 / kill_switch / **すでに返信が付いているレビュー**（Apple の POST は上書きで、人が書いた公開返信を消しうる —— この防壁は初回の実データで実際に2件を止めた）。 【止まった回も残す】最初の実投稿は**ゲートの指紋がずれていて止まった**（run 33058628758）。公開側の写しだけ更新して非公開側を忘れたため。鳴子は「2か所に書け」と名指ししていたが**散文は止める力を持たなかった**ので、ios の qa-static に機械の照合（--check-gate）を足した。 self-test はゲート側57件・実行側34件"
    },
    {
      "area": "⑧ カスタマーサポート",
      "task": "FAQとリリース内容の同期",
      "executor": "ai_executes_gated",
      "evidence": [
        "scripts/check-public-facts.mjs",
        "faq.html",
        "data/site-constants.json",
        "scripts/check-store-facts.mjs",
        ".github/workflows/seo-daily.yml"
      ],
      "note": "2026-08-22実装。FAQ・トップ（日英）・llms.txt・運営者情報の**散文**を site-constants / benchmark と突き合わせ、旧アプリ名・古い起動時間・廃止済みトライアル・価格ドリフトで落とす。廃止済みトライアルは景表法・ストア審査上のリスク対応で消したもので、それまで「出現回数0」を確かめていたのは人の目視だった。**リリースノート本文との突き合わせは隣リポジトリのためCI外** [2026-08-22追記] **公開表示の鮮度**も機械が見るようにした。評価（4.4）と件数（22）は JSON-LD の aggregateRating として12ページに出ているのに、どちらも人が App Store Connect を見て手で書いた値で、台帳のメモにも「NOT machine-verified」と書いてあった — **古くなっても誰も気づかない。**CIは45日を超えた確認日で落とす（ネットには触らない — PRのたびに外部APIを叩くと向こうの不調でCIが赤くなり、やがて無視される）。実物との突き合わせは日次ワークフローの --net で行う（**GitHubのランナーは itunes.apple.com に到達できる**が、エージェントのサンドボックスはプロキシがCONNECTを拒否するので確認できない）。**件数0で平均を出していないか**も見る — 実体の無い集計評価は公開してはいけない表示",
      "since": "2026-08"
    },
    {
      "area": "⑧ カスタマーサポート",
      "task": "CSAT計測",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-api/src/inquiry.ts",
        "../simplememo-api/src/reply-gate.ts",
        "growth/scripts/ingest-asc.mjs"
      ],
      "note": "2026-08-22。**計測する接点のうち「問い合わせ」はできた**（inquiry.ts）が、返信の自動化が無いので発火しない。answered のものだけ受ける設計にしてあり、返信を人がやった件だけ測れる。**まだ1件も測っていない** **[2026-08-25] 返信の下書きまでは出るようになった**が、CSAT は answered のものだけを受ける設計なので、**投稿が人の手で行われるまで依然として発火しない。** **[2026-08-26] 問い合わせ側の発火経路が閉じた。**自動回答が status を answered にするので、そちらは人手を介さず測れるようになった（レビュー返信は投稿が人のままなので、あちらは従来どおり）。auto_replied 列で「自動で返した件」と「人が返した件」を分けて読める —— **混ぜると、自動返信を入れてよかったのかが永久に分からない。****まだ1件も測っていない**（問い合わせ0件）"
    },
    {
      "area": "⑧ カスタマーサポート",
      "task": "重大案件の有人移管",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/escalation-rules.json",
        "scripts/check-escalation.mjs",
        "data/authority-matrix.json"
      ],
      "note": "2026-08-22実装。実行判定が返す故障・縮退コード5件と、運転台帳に**実際に現れた** failure_class 4件の全部に規則が要る（規則の無い種別があると落ちる）。危機領域は stop_automation: true を強制。**owner_direct の経路は未整備**で、名前が付いただけであることも台帳に書いてある",
      "since": "2026-08"
    },
    {
      "area": "⑧ カスタマーサポート",
      "task": "問い合わせからIssueと回帰テストを作成",
      "executor": "ai_proposes",
      "evidence": [
        "../simplememo-ios/docs/reports/watch_sync_診断改修案_2026-07-26.md"
      ],
      "note": "手動では実績あり（Watch同期4往復→v4.9.30→回帰テスト化）",
      "blocker": "external_data",
      "unblocked_by": "本文は依然 D1 にあり読めない。**2026-08-26 に端末/OS/版/分類だけを本文抜きで数える経路を作った**（simplememo-api: summarizeReproFacts / migrations/0027）。残るのは (a) 移行0027の適用、(b) その集計が日報の文面ではなく**リポジトリ側から読める形**で出ること、(c) 母数 — inquiries は現在0件",
      "unlock": "inquiry_facts"
    },
    {
      "area": "⑧ カスタマーサポート",
      "task": "ライフサイクルメール（歓迎・確認・リマインド）",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-api/src/lifecycle.ts",
        "../simplememo-api/src/reminder.ts"
      ],
      "note": "cronで自動送信。DRY_RUN/KILL_SWITCH/DAILY_CAP付き"
    },
    {
      "area": "⑨ マネタイズ",
      "task": "価格・プラン・ペイウォールの実験",
      "executor": "nobody",
      "evidence": [],
      "note": "課金は不可逆で既存契約者への影響が読めない。権限表でAIは提案もしない扱い",
      "blocker": "policy_boundary",
      "unblocked_by": "権限表で AI は提案もしない（既存契約者への影響が読めない）",
      "authority": {
        "domain": "価格・プラン・無料枠の変更",
        "human_only": "すべて"
      }
    },
    {
      "area": "⑨ マネタイズ",
      "task": "オンボーディング改善（課金導線）",
      "executor": "ai_proposes",
      "evidence": [
        "../simplememo-ios/docs/reports/ONBOARDING_REDESIGN_2026-08-06.md"
      ],
      "note": "データ起点の再設計。実施は人の判断\n\n**[2026-08-28] 到達可能側から外した（分類の訂正）。**2026-08-27 のオーナー判断は「**お金周りを除いて**渡す」で、課金導線はその除外側。\n**害は件数ではなく向きに出る** —— `--plan` が「作れば進む」と言い続け、天井が実際より高く出る。到達可能な件数は減るが、**下がった天井のほうが本物。**",
      "blocker": "policy_boundary",
      "unblocked_by": "課金導線の変更判断が人",
      "$authority_absent": "表は「価格・プラン・無料枠の変更」を持つが、**課金導線そのものの領域は無い。**2026-08-27 のオーナー判断「お金周りを除いて渡す」の除外側にあたる、という読みで人へ残している"
    },
    {
      "area": "⑨ マネタイズ",
      "task": "プレミアム機能の設計判断",
      "executor": "ai_proposes",
      "evidence": [
        "../simplememo-ios/docs/obsidian-only-mode-design.md"
      ],
      "note": "Obsidianのみモードをプレミアム限定にする判断はオーナー",
      "blocker": "policy_boundary",
      "unblocked_by": "何を有料にするかはオーナー判断",
      "$authority_absent": "同じく表に領域が無い。**何を有料にするかは価格の決定と地続き**なので「価格・プラン・無料枠の変更（human_only: すべて）」の隣に置いている"
    },
    {
      "area": "⑨ マネタイズ",
      "task": "解約理由分析",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/scripts/asc_subscription.rb",
        "../simplememo-ios/scripts/asc_analytics.rb",
        "../simplememo-ios/.github/workflows/asc-analytics.yml",
        "../simplememo-api/src/autopilot-report.ts",
        "../simplememo-ios/SimpleMemo/CancelFlowManager.swift"
      ],
      "note": "**[2026-08-26] 前提が間違っていた。**この欄は長らく「Apple が解約理由をくれるか未確認」と書いていたが、`Cancellation Reason` 列は **2026-08-25 の取得で既に届いていた**（Subscription Event Report / State Report のどちらの columns にも入っている）。読めなかった理由は Apple 側ではなく**こちらの保存の形**で、asc_analytics.rb が残すのは数値列の合計だけだった。解約理由は文字列なので合計対象に入らず、**列名だけが残って中身は1件も残っていなかった。**「取れない」と「捨てている」を取り違えていた（data/operating-memory.json om-2026-08-26-breakdown）。\n\n取得側に名指しの分類列 × 名指しの測定列の内訳を足し（BREAKDOWN_DIMENSIONS）、読む側を asc_subscription.rb として asc-analytics.yml の日次に配線した。**ただし 2026-08-26 時点で読めた項目は 0/3。**手元にある取得結果は内訳を持つ前の版なので no_breakdown を返す。**次の定時実行（毎日 20:30 JST）で決まる。**\n\n**空欄しか無い可能性は残る。**Apple 側で解約理由は任意項目であり、埋まらないほうが普通。読む側は空欄を捨てず `(空欄)` として数え、all_blank を readable と区別する ——**「解約理由が読めなかった」を「解約が無かった」と読ませないため。**空欄だった場合、⑨を実物にするにはアプリ内で理由を聞く導線が要る（未実装）。実施は引き続き人の判断なので ai_proposes のまま\n\n**[2026-08-26 決着] 空欄だった。**予定の定時実行（20:30 JST）を待たずに asc-analytics.yml を手動で回して確かめた。取得は成功し、内訳つきで降りてきて、`asc_subscription.rb` は 3項目中2項目を読めた（契約の状態 155/33・契約イベント 4件）。**しかし `Cancellation Reason` は列も値も届くのに、値が全部空欄**（all_blank）。上に書いてあった「空欄しか無い可能性」がそのまま当たった。\n\n**したがってこの行はもう『データ待ち』ではない。**待っていたものは降りて、空だと分かった。実物にするには**アプリ内で理由を聞く導線**が要る（未実装）。ブロッカーを external_data から not_started へ移した —— **降りない物を待ち続ける行にしないため。**\n\n**[2026-08-26 実装] 詰まっていたのは聞く側ではなく読む側だった。**上の unblocked_by は「解約時にアプリ内で理由を聞く導線」が要ると書いていたが、**その導線は既にあった** —— CancelFlowManager が v5.7.9 からイベントを送り、v5.7.11 で `reason` も乗るようになっている（SceneDelegate から配線済み）。本当に無かったのは**集計する経路**で、`cancel_flow_*` は `src/analytics.ts` の allowlist とコメントにしか名前が出てこなかった —— 2026-08-15 から入っているのに、**11日間、誰も読んでいなかった。**\n\n`src/cancel-flow.ts` を作って日報へ配線した。本番D1を引くと11日ぶんで9行あり、**2026-08-24 に引き止めが1件成立していた**（reason=price → offer=free_plan → exit=stay）。フロー導入後の初めての成功で、誰も知らなかった。\n\n**率は出さない。**実データは表示4件 / 理由を答えた1件で、CLAUDE.md の運転規則（根拠にしてよいのは 0/非0 の事実か、分母20の累積）に従い分母が20に届くまで率を1つも出さず「分母 4 < 20」と足りないことごと書く。引き止めの成立件数だけは率ではなく事実なので n=1 でも出す。`reason:\"none\"`（未選択の番人の値）は理由の内訳に混ぜない。\n\n**分類を ai_proposes → ai_executes_gated へ。**集計は毎朝の日報として出て、人が手を動かして初めて分析が走る段は無い。「読めなかった / 出ていない / 答えが無い」を別々の文面で出し、13通りの壊し方すべてで検査が落ちることを確認した。**「何を作るか」の判断は人のまま**で、それはこの行ではなくプロダクト側の行が数えている **[2026-08-27] 証跡から2件落とした** —— `../simplememo-api/src/cancel-flow.ts` と その検査は**存在しない**（解約フローの実装は iOS 側の CancelFlowManager.swift / CancelFlowViewController.swift で、API 側に同名のものは無い）。**CIが `../` の実在を見ていなかったので、誰にも気づかれずに残っていた。**見える場所（3リポジトリが揃ったセッション）では見るようにした。"
    },
    {
      "area": "⑨ マネタイズ",
      "task": "課金失敗の回復",
      "executor": "nobody",
      "evidence": [],
      "note": "StoreKit側の失敗イベントを受ける経路が未実装。**[2026-08-26] 検知の側だけ配線が入った** ——Subscription State Report の `State Metric` に Billing Retry / Grace Period が入るので、asc_subscription.rb がそれを課金失敗として拾う（別行「課金失敗・解約の観測」）。**この行は nobody のまま。**数えているのは『回復させたか』であって『気づけるか』ではない。回復（アプリ内での告知・支払い方法の更新導線）は1つも実装していない。**気づけることを回復と数えない。**",
      "blocker": "not_started",
      "unblocked_by": "StoreKit の失敗イベントを受ける経路を作れば動く",
      "unlock": "impl_product"
    },
    {
      "area": "⑨ マネタイズ",
      "task": "返金の検出（Get Refund History）",
      "executor": "nobody",
      "evidence": [
        "../simplememo-api/src/apple-asn.ts",
        "../simplememo-api/src/apple-jws.ts",
        "../simplememo-api/src/der.ts",
        "../simplememo-api/test/fixtures/asc-test-notification.jws",
        "../simplememo-ios/data/asc-server-api.json",
        "../simplememo-ios/scripts/asc_refund_probe.rb",
        "../simplememo-ios/scripts/lib/asc_api.rb"
      ],
      "note": "**旧行から切り出した。**旧行は「返金・不正課金・チャージバック対応」で、検出・応答・意見表明が1行に入っていた。混ぜると、どれか1つができた時点で行が動く。 これは**観測だけ**で、外に何も出ない可逆な操作 —— 権限表の非対称でいえばAI側。 **[2026-08-27 実測 — この2つは「未確認」ではなくなった]** `POST /inApps/v1/notifications/test` を1回叩いた（../simplememo-ios/data/asc-server-api.json・run 33029719938）。HTTP 404 / ServerNotificationURLNotFound。読みは2つ: **(1) 鍵は通る。**いまの App Store Connect API の鍵で App Store Server API を叩ける（JWT に `bid` クレームを足すだけ。別の In-App Purchase 鍵は要らなかった）—— **「別の鍵が要る」と推測で書かなくてよかった。** **(2) 通知URLが設定されていない。**したがって CONSUMPTION_REQUEST はどこにも届いていない。 残っているのは実装だけ: `GET /inApps/v2/refund/lookup/{transactionId}` は**取引IDを要求する**ので、まず取引を1つ手に入れる経路が要る（Get Transaction History / 通知）。**そこは叩いていないので、取引IDの出どころが実在するかはまだ書かない。**\n\n**[2026-08-27 追記 — 取引IDの出どころは、探さなくてよかった]** 上で「取引IDの出どころが実在するかはまだ書かない」と保留していた点が解けた。Apple の notificationType の一覧を取って確かめたところ、返金は**通知として押されてくる**: `REFUND`（返金した）／`REFUND_DECLINED`（アプリ内の要求を却下した）／`REFUND_REVERSED`（争議で返金を取り消した）。つまり `refund/lookup` に渡す取引IDを別経路で先に手に入れる必要は無く、**通知が運んでくる。** \n\n同日、その通知を受ける側が揃った: 受け口（simplememo-api の `/webhooks/apple-asn`）、通知URLの設定（Apple の実配信が `first_attempt_result: SUCCESS`）、そして **signedPayload の検証器**（`src/apple-jws.ts`）。検証器は**Apple が実際に署名した TEST 通知**で通ることを確かめてある。信頼の起点は通知に入っていた root ではなく、Apple の公開ページからランナーが取った実物（`data/apple-root-pin.json`・583 bytes / sha256 63343abf…。両者はバイト単位で一致した）。\n\n**残っているのは、受け口が検証器を呼ぶ配線と、通知を残す部分。**後者は simplememo-api の保持台帳（`data/data-retention.json`）に何をどれだけ持つかを書いてからでないと着手しない —— 受け口はいま**意図的に env を取らない**形で、書き込む手段そのものを持っていない。",
      "blocker": "verification_pending",
      "unblocked_by": "**[2026-08-28] ここに残件として書いてあった2つは、どちらも既に済んでいた。**(1) 受け口から検証器を呼ぶ配線 … `src/apple-asn.ts` が `isRefundNotification` → `buildRefundEvent` → `recordRefundEvent` を呼ぶ（simplememo-api#193・main の 8f036b7）。(2) 保持台帳に載せてから残す部分 … `apple_refund_events` は `data-retention.json` に載り、migration 0028 ／ `refund_retention` cron ／ `REFUND_RETENTION_DAYS=180` ／ `/admin/refunds` まで入っている。通知URLも設定済み（`../simplememo-ios/data/asc-server-api.json` の `notification_url_configured: true`、Apple のテスト配信が `first_attempt_result: SUCCESS`）。\n\n**したがって `not_started`（着手していないだけ）は事実として誤りだった。**残っているのは実装ではなく、**実際の返金が1件届くこと**。届くまで executor は動かさない —— 「作った」と「動いた」を分ける。\n\n**この行が古くなった理由のほうを書いておく。**#193 は 2026-08-28 に main へ入ったが、台帳の `measured_at` は 08-26 のまま。**出荷が台帳より速い日には、台帳のほうが嘘になる。**同じ日に手で書いた3本の監査（#692 / #704 / #705）も、この行を `not_started` として数えている。",
      "unlock": "refund_observe"
    },
    {
      "area": "⑨ マネタイズ",
      "task": "返金要求への消費情報の応答（CONSUMPTION_REQUEST）",
      "executor": "intentional_no",
      "evidence": [
        "../simplememo-api/src/apple-asn.ts",
        "../simplememo-api/src/apple-jws.ts",
        "../simplememo-api/data/apple-root-pin.json",
        "../simplememo-ios/data/asc-server-api.json",
        "../simplememo-ios/scripts/asc_refund_probe.rb"
      ],
      "note": "**旧行の「上限額を決めない限り自動側へ置けない」という前提は誤りだった。**2026-08-27 に Apple のドキュメントを取って確かめた —— **返金を発行するエンドポイントが存在しない。**あるのは Get Refund History（履歴）、Refund lookup（照会）、Send Consumption Information（消費情報の送信）の3つで、**機械が返金できないので上限額は何も止めない。** 実在するのはこちら: 顧客が返金を要求すると Apple が CONSUMPTION_REQUEST を送り、開発者は `PUT /inApps/v2/transactions/consumption/{transactionId}` で応える。**期限は「受信から12時間以内」**（同エンドポイントのドキュメントに明記）。応えなければ Apple はこちらのデータ無しで判断する。**12時間は人が確実に守れる窓ではない**（個人開発・時差・睡眠）。だから自動化の利得は「速さ」ではなく**「窓を落とさないこと」**にある。 **[2026-08-27 実測 — この2つは「未確認」ではなくなった]** `POST /inApps/v1/notifications/test` を1回叩いた（../simplememo-ios/data/asc-server-api.json・run 33029719938）。HTTP 404 / ServerNotificationURLNotFound。読みは2つ: **(1) 鍵は通る。**いまの App Store Connect API の鍵で App Store Server API を叩ける（JWT に `bid` クレームを足すだけ。別の In-App Purchase 鍵は要らなかった）—— **「別の鍵が要る」と推測で書かなくてよかった。** **(2) 通知URLが設定されていない。**したがって CONSUMPTION_REQUEST はどこにも届いていない。 **通知URLを設定する経路が機械には無い。**App Store Connect API の索引（webhooks は BUILD_UPLOAD_STATE_UPDATED など**ビルド・審査の事象だけ**で、CONSUMPTION_REQUEST は入っていない）と App Store Server API の索引の**両方を数えた**が、通知URLを設定する面はどちらにも無かった。**人が App Store Connect の画面で1回設定する**しかない。設定さえ済めば、受け口も応答も機械側で完結する。 受け口自体もまだ無い（simplememo-api の /v1/* にASC通知の口は1本も無い）。 **述語について**: 待ちが解けたかどうかは、隣の実測台帳（../simplememo-ios/data/asc-server-api.json）を probe が書き直したときに分かる。**このリポジトリのCIには隣が無いので、CIからは常に「まだ待っている」と読める** —— 3リポジトリの揃ったセッションでだけ「もう届いている」と鳴る。散文で「未設定」と書いておくよりはましだが、**片側でしか鳴らない述語であることは承知の上**（隣が無ければ満たされない側に倒れるので、見落とす方向ではなく待ち続ける方向に外れる）。\n\n**[2026-08-27 追記 — 待っていた設定は済んだ。そして本当の門は別にあった]** オーナーが App Store Connect で通知URLを設定した（`https://api.simplememofast.com/webhooks/apple-asn`）。実測で裏が取れている: `POST /inApps/v1/notifications/test` が HTTP 200、`notification_url_configured: true`、そして **Apple の実配信が `first_attempt_result: SUCCESS`**（../simplememo-ios/data/asc-server-api.json・run 33067382043）。受け口も検証器も揃い、**Apple が実際に署名した通知を検証できることまで確かめた。**\n\n**それでもこの行は機械に渡せない。**Send Consumption Information のドキュメントを取って読んだ:\n\n  「If the customer provided consent, respond by calling this API … **If not, don't respond to the CONSUMPTION_REQUEST notification.**」\n  「The App Store server **rejects requests that have a customerConsented value other than `true`** by returning an HTTP 400 error with an InvalidCustomerConsentedError」\n\n**`customerConsented: false` は「正直な応答」ではなく、400 で弾かれる。**応答するには**顧客がアプリ内で明示的に opt-in している**必要があり、Apple は「いつでも撤回できること」「撤回の方法を示すこと」「privacy label に書くこと」まで要求している。SimpleMemo にはその同意フローが無い。\n\n**ここで止まるのは実装が足りないからではない。**「顧客の利用状況を Apple に渡して、その顧客の返金要求に反論してよいか」を顧客に opt-in で問う、という製品の判断が先にある。プロダクトの立て付け（何も所有しない・整理させない）と正面から擦れる話で、**しかも現時点の実績は購入1件**（../simplememo-ios/data/revenue/series.json）。得られるものが小さく、聞くこと自体に costs がある。**だから機械の側で既成事実にしない。**\n\n（前の版はここを external_credential と書いていた。設定が済んだのでその塞ぎは外れたが、外れた先に出てきたのは実装ではなく境界だった。**塞ぎが1つ外れても、その先が自動側とは限らない。**）\n\n**[2026-08-27 決定 — オーナー判断「作らない」]** 同意フローは作らない。したがってこの行は**意図的にやらない**側へ移す。\n\n**放置ではなく、仕様どおりの振る舞い。**Apple は「同意が無ければ CONSUMPTION_REQUEST に応答するな」と明示しており、同意フローを作らない以上、**応答しないことが正しい。**受け口・署名検証は動いたまま残る（通知は受け取って検証し、CONSUMPTION_REQUEST だと分かった時点で応答せずに終える）。\n\n判断の材料: (1) 返金申請が発生する頻度が極めて低い規模（取得できている売上は1日分・購入1件）。(2) **正直に説明すればほぼ誰も許可しない**トグルで、許可を得るために説明を曖昧にするのは、やってはいけないことそのもの。既定ONも不可（Apple 自身が \"only if the customer consented\" と書いている）。(3) 顧客に「返金の話」を先に持ち出すUIが増え、VISION の「何も整理させない」と逆行する。\n\n**⚠ この決定で総合自動化率は 65.3% → 65.7% へ上がる**（分母から1件外れるため）。**やめたことで数字が良くなる**という形なので、動いたことを台帳と配信稿の両方に書いてある。下がった回を書くのと同じ理由で、上がった回も書く。\n\n**取り消せる判断。**作ると決めた日に効く配線（受け口・検証・応答の組み立て・`lookupConsumptionConsent()`）は全部入っているので、残作業はアプリ側の同意UIと privacy label だけ。"
    },
    {
      "area": "⑨ マネタイズ",
      "task": "返金の可否についてAppleに意見を出す（refundPreference）",
      "executor": "nobody",
      "evidence": [],
      "note": "**ここが本当の境界。**ConsumptionRequest の必須欄は customerConsented / deliveryStatus / sampleContentProvided の3つで、**どれも事実**（同意の有無・配信できたか・購入前に無料で試せたか）。SimpleMemo は無料枠があるので sampleContentProvided は定数に近い。**事実だけで有効な応答が作れる。** 判断が入るのは `refundPreference` **1欄だけ**で、しかも**必須ではない。**値は DECLINE / GRANT_FULL / GRANT_PRORATED の3つ。Apple は「your refund preference is one of a variety of factors that the App Store uses to inform its refund decisions」と書いている。 つまり DECLINE を出すことは、**機械が「この客に返金しないでほしい」とAppleに言う**ということ。定型文でレビューに返すのとは性質が違う —— 相手は返金を求めている個人で、こちらの一言が不利に働きうる。 **設計としては、この欄を省いて応答できる。**期限内に事実を出す（＝窓を落とさない）ことと、可否に意見を言うことは分けられる。**分けられるものを一緒に自動化しない。** 自動化するなら Level を明示すること（返信のゲートと同じ）。既定は「refundPreference を送らない」",
      "blocker": "policy_boundary",
      "unblocked_by": "**機械が「返金しないでほしい」と言ってよいか。**事実だけの応答（refundPreference 無し）はこの行の外で、そちらは境界ではなく実装",
      "$authority_absent": "表に領域が無い。**機械が「返金しないでほしい」と言ってよいか**という問いで、事実だけの応答（refundPreference 無し）はこの行の外"
    },
    {
      "area": "⑨ マネタイズ",
      "task": "短期CVRよりLTVと信頼を守る制約",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/docs/VISION.md",
        "scripts/check-prd.mjs"
      ],
      "note": "VISION §0「AIを前面に出さない」・§9「所有しない」が実質この制約。§13の6問がゲート **[2026-08-27] §13の6問を実際に検査しているのは check-prd.mjs。**VISION は制約の本文で、読むだけでは1件も止まらない"
    },
    {
      "area": "⑨ マネタイズ",
      "task": "価格の変更",
      "executor": "human_only",
      "evidence": [
        "data/authority-matrix.json"
      ],
      "note": "AIは提案もしない（不可逆・既存契約者への影響が読めない）",
      "blocker": "policy_boundary",
      "unblocked_by": "不可逆・既存契約者に影響",
      "authority": {
        "domain": "価格・プラン・無料枠の変更",
        "human_only": "すべて"
      }
    },
    {
      "area": "⑨ マネタイズ",
      "task": "課金失敗・解約の観測（内訳の取得と読み）",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/scripts/asc_subscription.rb",
        "../simplememo-ios/scripts/asc_analytics.rb",
        "../simplememo-ios/.github/workflows/asc-analytics.yml"
      ],
      "note": "2026-08-26実装。取得（日次・GETのみ）から読みまで人の承認を挟まない。ゲートは3つで、**どれも「言い過ぎ」を止める向き**に置いてある。(1) 読めない理由を1語に潰さず7状態に分け、**数を出してよいのは readable のときだけ** (2) 分母が 20 に届かないうちは率を出さない（解約1件から解約率100%を作らない。simplememo-api の CLAUDE.md「単日の率では何も決めない」と同じ下限） (3) 知らない State Metric を健全側に寄せず unclassified として名前ごと残す ——**寄せると Apple が新しい失敗状態を足した日に課金失敗が消える。**内部矛盾（readable なのに値が無い／分母不足で率がある）は exit 1 で日次を赤にする。\n\n**この行が数えているのは『毎日走ること』であって『値が降りていること』ではない。**2026-08-26 時点の読みは 0/3（手元の取得結果は内訳を持つ前の版）。self-test 28件。\n\n**読みは非公開リポジトリ側に置いた。**一度サイト側（growth/scripts/）に書いたが、simplememofast/simplememo は GitHub 上で公開されており（api.github.com が private: false）、契約者が1桁のいま解約・課金失敗の件数を公開リポジトリへ日次で積むのは「広げる」方向の変更になる。加えてあちらの CI からは隣のリポジトリが見えず**日次では動かない。**動かない場所に検査を置かない"
    },
    {
      "area": "⑩ AgentOps・ガバナンス",
      "task": "実行の完全記録（主系）",
      "executor": "ai_executes_gated",
      "evidence": [
        ".github/workflows/obsidian-autopilot.yml"
      ],
      "note": "Actionsのrunログは全部読める"
    },
    {
      "area": "⑩ AgentOps・ガバナンス",
      "task": "実行の完全記録（副系）",
      "executor": "nobody",
      "evidence": [
        "docs/obsidian/AUTOPILOT_RUNBOOK.md",
        "docs/routine-snapshot-setup.md",
        "scripts/check-routine-runs.mjs",
        "data/routine-runs.json",
        ".github/workflows/seo-check.yml"
      ],
      "note": "スケジュール起動セッションのログが外部から読めない。構造的に不可\n\n**[2026-08-28] 「構造的に不可」は半分だけ正しかった。**セッションの中身（transcript）は依然として外から読めないが、**走ったかどうかは読める** —— Routines API の `last_run` が status / fired_at / finished_at / session_id を返す。**読む側を一度も試さずに不能と書いていた。**\n\n**読んだ瞬間に4件見つかった。**副系A（07:30）と副系B（08:30）が 2026-08-25 を最後に停止したまま2日以上、週次2本（SEO Weekly / マーケデータ）が 08-24 に FAILED のまま次の発火は 08-31。**どれも次の発火まで誰も気づかない形だった。**これが「完全な記録が無い」ということそのもの。\n\n**主系と副系で、記録の完結の仕方が違う。**主系（Actions）は run を全部列挙できるので記録が完結する。副系は**セッションが自分で書いたときだけ**行が残る（autopilot-runs.json の source:session）ので、**書かずに死んだ回はどこにも現れない。**自己申告だけでは完全にならない。\n\n実装は scripts/check-routine-runs.mjs（写しの鮮度・列挙の網羅・ラチェット）。list_triggers はCIから叩けないので、セッションが data/routine-runs.json へ写しを置きCIが検査する（ASCのレポートと同じ形）。**executor はまだ動かさない** —— 写しを取り直す経路がまだ人の手で、そこが自動になって初めて『記録が完結している』と言える。鮮度検査が3日で赤くなるので放置はできない\n\n**[2026-08-28 追記] 残る未検証2つのうち1つを叩いた。決まらなかった。**現に動いている副系（`trig_01ESF9AHax6buS9X1pdFv657`・Obsidian再試行 v3）の最新セッションを `get_session` で読んだ。\n\n**分かったこと** —— `session_context.sources` にリポジトリが入り、`outcomes` に `claude/obsidian-auto-20260828` が出ている（＝**この経路は sources を持ち、ブランチも作れている**）。tags は `routine:agent-minted`。\n\n**分からなかったこと** —— `get_session` の応答に `allowed_tools` が**含まれていない**ので、**このセッションが `mcp__*` を持つかは読めなかった。**\n\n**「欄が無い」を「MCPが無い」と読まない。**朝の記録が「`allowed_tools` に `mcp__*` は1つも無い」と書けたのは、`create_trigger` で自分が作った Routine の応答に**その欄が在った**から。**欄そのものが返らないケースと同じにしない。**\n\n確かめる手は残っている（この副系の prompt に `list_triggers` を1回呼ばせて結果を書かせる）が、**日次で動いている本番ジョブの prompt を書き換える操作なので、オーナーに聞いてから。**自己バインド側は未着手のまま。\n\n**[2026-08-28 夕・実測] 対照が取れた。「副系は MCP を持てない」は一般化しすぎだった。**\n\n**持たない側（実挙動で確認）** —— このCCRセッションが `create_trigger` で作った routine（`environment_id` を明示）を `fire_trigger` で1回走らせた。**17.5秒で SUCCEEDED、ブランチ0、$0.29**（`cse_01MWDUzNh1Df8EyF7oNEz2Ws`）。prompt は「`list_triggers` が呼べたら写しを取り直してPRを出す／呼べなければ報告だけして終われ」で、**Step 2 に到達していない**（`claude/routine-snapshot-20260828` は作られていない）。作成時に警告が返っており、そこに理由が書いてある —— 「Connectors on triggers created via this tool are limited to those the calling session itself holds; **this call had none to pass through**」。**このセッション自身は `mcp__*` を持っているのに、渡せる grant としては持っていない。**確認後この routine は削除した。\n\n**持つ側（実測）** —— 同じ日、`ccr-0920`（`trig_01ESF9AHax6buS9X1pdFv657`・オーナーのセッションが作った routine）のスケジュールセッションが **PR #696 を実際に作っている。**根拠はPR本文のフッタが `session_01UuFE2rHRSKuqKLeoAuGFQg` を名指ししていること（`get_session` で読んだのと同じセッション）と、本文が「§0の(a)〜(e)で確認済み」と書いていること —— (e) は prompt が**GitHub MCP の `actions_list`** と定義している手順。この環境に `gh` CLI は無く、PR作成は GitHub MCP を通る。\n\n**したがって差は「副系かどうか」ではなく「どのセッションが routine を作ったか」。**CCRセッションが作った routine には connector が渡らず、オーナーのセッションが作った routine には渡っている。\n\n**それでも ⑩ は閉じない。**分かったのは **GitHub MCP** を持つことで、要るのは `claude-code-remote` の `list_triggers`。**別のサーバなので片方から他方を推定しない**（このファイルが 08-26 と 08-27 に続けてやった「辻褄が合うことを証明に使う」がまさにこれ）。\n\n**確かめ方は仕込んだ。**本番 prompt は書き換えていない —— あの prompt 自身が「`docs/obsidian/AUTOPILOT_RUNBOOK.md`（mainの最新版）が優先します」と書いているので、**Runbook に §0-3 として一時的な確認を足した**（2026-08-29 まで・記事の作業に影響させない・失敗しても run を落とさない）。9,358字の prompt を打ち直す経路より、**PRでレビューでき git で戻せる**ほうを選んだ。\n\n次の発火は 2026-08-29T00:20Z。報告に `ROUTINE_MCP_PROBE:` の1行が出たら、この行を更新して Runbook の §0-3 を削除する。\n\n**「SUCCEEDED」がまた何も言っていない。**上の使い捨て routine は 17.5秒で成功扱いで終わり、**やるはずのことは1つも起きていない。**この台帳が `intentional_stops` に書いたのと同じ形が、同じ日にもう一度出た。\n\n**[2026-08-31] 仕込んだ確認は走っていない。理由は2つあって、1つ目はこちらの手落ち。**\n\n**(1) §0-3 が main に無い。**prompt は「`docs/obsidian/AUTOPILOT_RUNBOOK.md`（**mainの最新版**）が優先します」と書いていて、こちらはその一文を引用したうえで §0-3 を `claude/score-improvement-nug323` に置いたまま**PRを作らなかった。**日次セッションが読むのは main なので、**一度も届いていない。**「Runbook に置けば伝わる」は、mainに入って初めて成り立つ。\n\n**(2) そもそも日次が落ちている。**ccr-0920 は 2026-08-31 に FAILED（13秒）。原因は週次利用枠の枯渇で、同日 obsidian-community と SEO Weekly も同じ形で落ちている（`data/routine-runs.json` の open_findings 参照）。**仮に §0-3 が main に入っていても、この回は走らなかった。**\n\n**したがって「副系のセッションが `claude-code-remote` の MCP を持つか」は未検証のまま。**08-28 に取れた対照（CCRセッション製の routine は持たない／ccr-0920 は GitHub MCP を持つ）はそのまま有効で、**動いていないのは確認の経路のほう。**\n\n**[2026-09-01] 確認は走ったが、答えたのが違う経路だった。**§0-3 は #742 で main に入り（2026-08-31T23:50Z）、枠のリセット後の 09-01 に主系・副系とも動いた。**ところが `ROUTINE_MCP_PROBE:` を報告したのは主系（Actions）で、内容は `unavailable 主系Actions環境にCCRのMCPが無い`。**\n\n**これは正しい観測だが、この行が聞きたい問いではない。**Actions のランナーに CCR の MCP が無いのは自明で、知りたいのは**スケジュール起動された CCR セッション**が持つかどうか。**節を Runbook に置いたので両方の経路が読んだ** —— 経路を限らなかったこちらの設計ミス。同じ変更で「実行するのは CCR 経路だけ」と限定した。\n\n**副系（ccr-0920）は 09-01T00:20:49Z に SUCCEEDED で走ったが、主系が当日ロックを先に取っていたためスキップした**（70秒・$0.42・`cse_012o7p4daBaPPPRwsuRdpZtT`）。**スキップ回は LOG を書かないので、リポジトリには何も残らない。**報告自体はセッションの中にあるが、**成功したセッションの `post_turn_summary` は `get_session` から返らない**（失敗したセッションでは返る。08-31 の3本がそれ）。\n\n**したがって答えが届くのは、ccr-0920 が実際にその日の仕事をした回** ——つまり主系が当日ロックを取らなかった日。**それまでこの行は動かない。**待ち方が1つ増えたのであって、2026-08-28 に取れた対照（CCRセッション製の routine は持たない／ccr-0920 は GitHub MCP を持つ）は変わっていない。",
      "blocker": "not_started",
      "unlock": "impl_routine_snapshot",
      "unblocked_by": "**2026-08-28 に「読めない」が崩れた。**Routines API の last_run で発火・成否・時刻が外から読める。残るのは**写しを定期的に取り直す経路**（list_triggers はCIから叩けないので、セッションが取る）。取り直しが自動になれば、記録は主系と同じ意味で完結する\n\n**[2026-08-28 夕・実際に作って回して確かめた] 自動化は Routine 側の壁で止まる。**`create_trigger` で日次 Routine（`trig_01Gb9SYzhT7C7YjAvz5dNzD1`）を作り、`fire_trigger` で1回走らせた。結果:\n\n- **`environment_id` は引き継がれた。**明示すれば `env_01RmhZUdCQoTVYsGM6Ly45oP` が `job_config.ccr` に入る。**`docs/reaching-85-audit-2026-08-28.md` の「sources も MCP connector も付かず」のうち、sources 側は環境IDを渡さなかった場合の話だった。**\n- **`mcp__*` は引き継がれない。**作成時に警告が返る（「this trigger stores no MCP connectors, so the sessions it fires will run without connector tools」）。`session_context.allowed_tools` にも `mcp__*` は1つも無い。\n- 実走（`cse_015iYEg3GrcfQ2A55jv9aZD1`・3分35秒・$0.83）は `SUCCEEDED` で終わり、**ブランチもPRも作られなかった** —— 「list_triggers が呼べなければ何も書かずに報告して終われ」と指示した経路と一致する。\n\n**Routine は日次で失敗し続けて未対応枠を食うので削除した。**残る未検証の道は1つ、**claude.ai の Routines UI から作った Routine なら `mcp__*` を持てるか**（作成時の警告文が案内している経路）。これはオーナーの画面操作なので、`impl_routine_snapshot` は実装ではなく owner_input へ移した。**「不能」とは書かない** —— 叩いていない面が1つ残っている\n\n**[2026-08-28 夕・経路2も叩いた。閉じた。]**オーナーが claude.ai の Routines UI から実際に作り（`trig_01TixKQ5Sovfjfn8rRVQCrYf`）、1回走らせた。**ブランチ0・PR0**（05:42:56Z→05:46:32Z・3分36秒・$2.46）。原因は connector ではなくリポジトリのほうだった —— **編集画面にリポジトリを指定する欄が無い**（名前 / 手順 / 頻度 / 権限の4つだけ）。発火したのは Cowork のセッションで、`environment_id` は汎用値 `env_011111111111111111111117`、tags は `cowork-remote / cowork-scheduled`、`folders_state: FOLDERS_STATE_NONE`、sources 無し。**`simplememo` に辿り着けない。**Routine は削除せず、名前に理由を書いて停止した（`data/routine-runs.json` が求めている形に合わせた）。\n\n**それでも `structural` へは落とさない。叩いていない面が2つある。**(1) **既存の副系Routineのセッションが `mcp__*` を持つか** —— `Obsidianオートパイロット再試行 v3` などは `job_config.ccr.environment_id` に副系の env を持ち、現にリポジトリへ到達してPRを作っている。UIで作ったものとは作られ方が違う。ただし確かめるには本番の記事パイプラインを1回走らせることになる（前回25分）ので、ついでに確かめられる機会を待つほうが安い。(2) **自己バインドの Routine**（`bound_session: true`・`カナリア48時間後` がこの形）—— 既存セッションへ配信されるので、そのセッションが持つMCPがそのまま使える。\n\n**2回とも `last_run: SUCCEEDED` で終わっている。**できないセッションは「できないので何も書かずに終わる」で成功になる。**判定はブランチ・PR・observed_at の3つで行うこと。** ／ **[2026-09-01] 『Routineはリポジトリを持てない』が崩れた。**13本の `session_context.sources` を実測したら4本が repo を持っている（副系A・副系B・ccr-0920・SEO Weekly）。止まっていた routine は `sources: null` で作られていただけ。**経路は作れる。**残る未確認はスケジュール起動セッションが `claude-code-remote` MCP を持つかの1点（Runbook の ROUTINE_MCP_PROBE）"
    },
    {
      "area": "⑩ AgentOps・ガバナンス",
      "task": "誰が何を変更したかの監査ログ",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/autopilot-runs.json"
      ],
      "note": "経路・結果・介入は機械可読。判断の根拠はまだ散文"
    },
    {
      "area": "⑩ AgentOps・ガバナンス",
      "task": "最小権限（AIに与えない権限の明文化）",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/.github/workflows/claude.yml",
        "scripts/check-authority.mjs"
      ],
      "note": "actions:write 非付与。CIが実際に検出する"
    },
    {
      "area": "⑩ AgentOps・ガバナンス",
      "task": "Prompt Injection・Tool Poisoning対策",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/injection-surface.json",
        "scripts/check-injection-surface.mjs",
        ".github/workflows/seo-check.yml",
        "../simplememo-ios/.github/workflows/release-command.yml"
      ],
      "note": "2026-08-22実装。外部文字列が入る口6件を台帳にし、口ごとに緩和策と**残存リスク**を必須にした（残存リスクが空＝考えていない、として落とす）。ワークフローの run: に ${{ github.event.* }} が直接埋まっていないかを走査する（env: 経由は安全なので除外）。自己検証で、脆弱なワークフローを差し込むと検出し、env: 経由では誤検出しないことを確認した。残る弱さ: **検査できるのは口の棚卸しとシェル注入だけ**で、モデルが読んだ本文に従ってしまう経路そのものは検査していない",
      "since": "2026-08"
    },
    {
      "area": "⑩ AgentOps・ガバナンス",
      "task": "AIへの送信内容のredact",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/scripts/qa/build-ai-triage-bundle.sh"
      ],
      "note": "PII無し・サイズ上限つき要約のみ"
    },
    {
      "area": "⑩ AgentOps・ガバナンス",
      "task": "エージェント別 Kill Switch",
      "executor": "ai_executes_gated",
      "evidence": [
        ".github/workflows/obsidian-autopilot.yml",
        "data/emergency-stop.json",
        "scripts/check-emergency-stop.mjs",
        "scripts/autopilot-gate.mjs",
        "scripts/autopilot-selfheal.mjs",
        "scripts/autopilot-drill.mjs"
      ],
      "note": "2026-08-22実装。経路6件（主系・副系2・代走・監査・ASC）を個別に止められる。実行判定が AGENT_STOPPED を返し、**全体停止は常にこれより強い**（両方立っているとき経路側が先に出たら落ちる）。主系ワークフローも全体と agents.actions の両方を見る。止めるのはAIができる（`--contain` / `--trip`、理由は escalation-rules の trigger に限定）が、**解除の関数はスクリプトに存在せず、追加すると検査が落ちる。**修理上限に達した経路は着手前に落ちる（--contain --dry-run）。残る弱さ: **本番で1回も止めていない**（止まることを確かめていない停止機構は、無いのと同じに近い）",
      "since": "2026-08"
    },
    {
      "area": "⑩ AgentOps・ガバナンス",
      "task": "失敗理由とバックアップ切替の観測",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/autopilot-runs.json",
        "scripts/autopilot-runs.mjs"
      ],
      "note": "by_route・primary_ever_shipped・failure_class"
    },
    {
      "area": "⑩ AgentOps・ガバナンス",
      "task": "基盤故障の自己修復と、その歯止め",
      "executor": "ai_executes_gated",
      "evidence": [
        "scripts/autopilot-selfheal.mjs",
        "scripts/check-authority.mjs"
      ],
      "note": "検証の弱体化・権限の拡大をCIが実検出"
    },
    {
      "area": "⑩ AgentOps・ガバナンス",
      "task": "バックアップ切替の演習",
      "executor": "ai_executes_gated",
      "evidence": [
        "scripts/autopilot-drill.mjs"
      ],
      "note": "2026-08-22実装。判定の論理を15シナリオで検証。**実際のネットワーク・認証の挙動は証明しない**"
    },
    {
      "area": "⑩ AgentOps・ガバナンス",
      "task": "自律システムとは別系統の監査AI",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/audit-charter.json",
        "data/audit-findings.json",
        "scripts/check-audit-independence.mjs",
        "data/model-routing.json"
      ],
      "note": "2026-08-22実装。**監査の中身ではなく独立を機械が守る**：①憲章と所見を自己修復レーンが書き換えられない ②監査は repair と別モデル ③所見は追記のみ（連番が飛ぶと落ちる）。監査AIは何も直さない（直す権限を持たせると「直したことにして所見を閉じる」が最短経路になる）。**まだ一度も走らせていない。**残る弱点（監査が article と同じモデル）も憲章に明記",
      "since": "2026-08"
    },
    {
      "area": "⑩ AgentOps・ガバナンス",
      "task": "認証切れ・モデル障害・API障害の演習",
      "executor": "ai_executes_gated",
      "evidence": [
        "scripts/autopilot-gate.mjs",
        "scripts/autopilot-drill.mjs"
      ],
      "note": "2026-08-22実装。判定に4つの故障軸（資格情報の拒否・モデル全滅/縮退・GitHub API到達不能・egress遮断）を足し、26シナリオで固定。**「秘密鍵が無い」と「拒否された」を別コードにした** — 混ぜると期限切れが毎日「設計どおりのスキップ」として黙殺される。**本番を落とす本物の演習ではない**（判定の論理だけ）",
      "since": "2026-08"
    },
    {
      "area": "⑩ AgentOps・ガバナンス",
      "task": "判断→実行→結果→次の判断を結ぶ運転記憶",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/operating-memory.json",
        "scripts/check-operating-memory.mjs",
        ".github/workflows/seo-check.yml"
      ],
      "note": "2026-08-25実装。signal / hypothesis / decision / execution / verification / outcome / verdict / learning を1レコードで持ち、**learning.changed が実在の成果物を指さない行は落とす**（感想を学習と呼ばせない）。**率は出していない** —— 全判断の母数を持っていないので『判断の◯%を記録』は言えない。**seed 6件は後追いで、発生時記録はまだ0件**"
    },
    {
      "area": "⑪ データ・プライバシー",
      "task": "データ分類（送信可否の allowlist）",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/scripts/qa/check_analytics_allowlist.py"
      ],
      "note": "CIで強制"
    },
    {
      "area": "⑪ データ・プライバシー",
      "task": "収集同意",
      "executor": "ai_proposes",
      "evidence": [],
      "note": "App Analytics共有オプトイン依存\n\n**[2026-08-28] 到達可能側から外した（分類の訂正）。****これは境界ですらない。**依存しているのは App Analytics の共有オプトインで、**同意するのは利用者本人**。オーナーが権限表を書き換えても動かないので、owner_only ではなく never 側（`human_consent`）。\n**害は件数ではなく向きに出る** —— `--plan` が「作れば進む」と言い続け、天井が実際より高く出る。到達可能な件数は減るが、**下がった天井のほうが本物。**",
      "blocker": "human_consent",
      "unblocked_by": "App Analytics 共有オプトイン依存。ユーザー本人の同意"
    },
    {
      "area": "⑪ データ・プライバシー",
      "task": "保持期間の定義（棚卸しと逸脱検査）",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-api/data/data-retention.json",
        "../simplememo-api/test/data-retention.test.ts",
        "../simplememo-api/scripts/check-write-only-tables.mjs",
        "../simplememo-api/src/webhook-redact.ts",
        "../simplememo-api/scripts/check-retention-schema.mjs"
      ],
      "note": "2026-08-22実装。23ストアを棚卸しし、**ずれたらCIが落ちる**形にした（新テーブルは保持方針を書くまで通らない／保持期間を宣言したのに削除コードが無いと落ちる） [2026-08-22追記] 棚卸しの記述そのものが実態と違っていた例が1件出た — reminder_events は `holds: [email_hash, event, at]` と書いてあったが **email_hash 列は存在せず、webhook の生の本文（宛先の平文・件名）を無期限に持っていた。**許可リストで落とし、窓180日にして剪定へ入れた。**誰も読まないテーブルを検出する検査**も足した（DELETE は読者に数えない） さらに、**台帳の記述そのものをスキーマと突き合わせる検査**を足した（2方向 — 存在しない列を書いていないか／書かれていない自由文の列が無いか）。**22表中14表がずれていた。**求めるのは TEXT/BLOB と身元を示唆する名前の列だけで、全列を書かせると台帳が読まれなくなる（読まれない台帳は無いのと同じ）"
    },
    {
      "area": "⑪ データ・プライバシー",
      "task": "保持期間の自動削除",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-api/src/analytics.ts",
        "../simplememo-api/test/analytics-retention.test.ts",
        "../simplememo-api/data/data-retention.json"
      ],
      "note": "2026-08-22に app_analytics_events を90日で剪定するようにした（オーナー判断）。棚卸しで見つかった最大の穴がこれ。**23ストア中6つが自動削除つき**になった。**残る10ストアはまだ無期限**（重複送信防止の台帳が中心。email_suppression は意図的に無期限）"
    },
    {
      "area": "⑪ データ・プライバシー",
      "task": "削除要求への対応",
      "executor": "ai_proposes",
      "evidence": [
        "../simplememo-api/scripts/check-deletion-coverage.mjs",
        "../simplememo-api/data/data-retention.json",
        "../simplememo-api/src/index.ts",
        "../simplememo-api/test/deletion-coverage.test.ts",
        "../simplememo-api/.github/workflows/ci.yml",
        "data/authority-matrix.json"
      ],
      "note": "2026-08-22に網羅の検査を実装。**ただし実行者は提案のまま。**権限表はこの領域を `requires_approval: true` / `human_only: [実行の承認]` と定めており、それに反する分類はしない。\n\n実装したこと: 消す対象をハンドラの中に手で並べるのをやめ、保持台帳（data-retention.json）を正にして実装との食い違いをCIで落とす。27ストアを4分類（削除14 / 意図的に残す2 / 届かない2 / 個人に紐づかない9）。**この作業で穴が2つ出た** — 同じ日に作った inquiries（personal・本文を保持）と email_dead_letters が削除経路に入っていなかった。症状が出るのは削除要求が来た日で、差分に「消し忘れ」は現れないのでレビューでは気づけない。**「届かない」に名前を与えたのが要点**（消せないものを「消している」と書かないため）。\n\n**オーナー確認事項:** 権限表のこの領域は2つの別物を1つに束ねている。(a) アプリ内の自己削除（POST /v1/account/delete）は承認を挟まず完了する — App Store Guideline 5.1.1(v) がそれを要求している。(b) 個別の連絡による削除要求は本人確認と承認が要る。いまの権限表は (b) の記述で (a) を覆っており、**実装は権限表より広い。**分けるかどうかは権限の話なので、こちらでは変えない\n\n**[2026-08-28] 到達可能側から外した（分類の訂正）。**権限表「ユーザーデータの削除要求への対応（個別の連絡）」は `requires_approval: true`、human_only が「本人確認」「実行の承認」、ai_may は「受付の検知」だけ。**この行の unblocked_by は元からそう書いてある。**\n**害は件数ではなく向きに出る** —— `--plan` が「作れば進む」と言い続け、天井が実際より高く出る。到達可能な件数は減るが、**下がった天井のほうが本物。**",
      "since": "2026-08",
      "blocker": "policy_boundary",
      "unblocked_by": "権限表が human_only[実行の承認] と定めている",
      "authority": {
        "domain": "ユーザーデータの削除要求への対応（個別の連絡）",
        "human_only": "実行の承認"
      }
    },
    {
      "area": "⑪ データ・プライバシー",
      "task": "AIへの送信可否の制御",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/scripts/qa/build-ai-triage-bundle.sh"
      ],
      "note": "redact済み要約のみ。メモ本文fixtureは架空"
    },
    {
      "area": "⑪ データ・プライバシー",
      "task": "端末内の暗号化",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/docs/reports/SECURITY_HARDENING_2026-07.md",
        "../simplememo-ios/SimpleMemo/CryptoStorage.swift",
        "../simplememo-ios/SimpleMemoTests/CryptoStorageTests.swift"
      ],
      "note": "AES-GCM-256・Keychain・Data Protection属性"
    },
    {
      "area": "⑪ データ・プライバシー",
      "task": "アクセス履歴",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-api/src/access-log.ts",
        "../simplememo-api/migrations/0019_admin_access_log.sql",
        "../simplememo-api/src/index.ts",
        "../simplememo-api/scripts/check-write-only-tables.mjs"
      ],
      "note": "2026-08-22実装（simplememo-api）。保持の棚卸しで「どこに何があるか」は分かったが、**そこへ誰がいつ触ったかの記録が無かった。**/admin/* は本番D1を読み書きしCSVも取り込む — **一番強い権限の操作だけが記録の外にあった。****認証の失敗こそ残す**（成功だけだと総当たりが残らない）。リクエストボディは入れない（監査の記録が監査対象になってはいけない）。保持180日 [2026-08-22追記] **記録するだけで、その記録を読むコードが無かった。**書き込み専用テーブルの検査で自分の作った穴として出た。認証失敗の件数と経路を日報に出す読者を足した — 記録しただけの監査ログは監査ではない",
      "since": "2026-08"
    },
    {
      "area": "⑪ データ・プライバシー",
      "task": "第三者SDKのデータ送信監査",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/scripts/qa/check_third_party_egress.py",
        "../simplememo-ios/data/third-party-egress.json",
        "../simplememo-ios/SimpleMemo/PrivacyInfo.xcprivacy",
        "../simplememo-ios/scripts/qa/check_privacy_manifest.py",
        "../simplememo-ios/data/privacy-manifest-policy.json"
      ],
      "note": "2026-08-22実装（simplememo-ios）。送信先ホスト4件・第三者SDK5件を棚卸しし、宣言していないホスト・SDKが増えると落ちる。宣言どうしの矛盾（台帳は「トラッキングしない」/ PrivacyInfoがtrue）も見る。**作った初回実行で AppsFlyerLib の記載漏れを自分で検出した。****実際に飛んでいるパケットは見ていない**（実機のプロキシ観測が要る）ので runtime_verified は全部 false [2026-08-22追記] **申告そのものと実装の突き合わせ**も足した。PrivacyInfo.xcprivacy は手で書いた宣言なので実装が増えても追随せず、**足りない申告は書いた本人には見えない。**突き合わせたら2種別が未申告だった。**オーナー指示で申告を実装に合わせた**（同日）: Product Interaction（387種のイベント）／Device ID（anonymous_install_id は**Keychain保存なのでアプリを削除しても残る**）／Other Diagnostic Data。**Crash Data では申告していない** — クラッシュログは集めていないので、そこで申告すると過剰申告になる。すべて Linked: false（analytics は email_hash を持たない設計）。検査の enforce も true にした。**将来の分岐を検査が見張る**: relay 側には analytics → email の結合が実装済みで待っており（send_correlation × client_send_id）、iOSがそれを送り始めた日に Linked が true になる — 送り始めたのに false のままなら落ちる。残る作業: **ASCの「App のプライバシー」への回答**はリポジトリの外なので検査できない",
      "since": "2026-08"
    },
    {
      "area": "⑪ データ・プライバシー",
      "task": "推論をどこで回すかの決定",
      "executor": "human_only",
      "evidence": [
        "../simplememo-ios/docs/VISION.md"
      ],
      "note": "VISION §14 未決定論点。Capture本文は個人情報そのもの\n\n**[2026-08-28] 到達可能側から外した（分類の訂正）。**VISION §14 の未決定論点で、**決めるのがオーナー。**`relay に推論や Capture 本文の保持を足す変更は、この論点を決めてから`と../simplememo-api/CLAUDE.md が明記している。\n**害は件数ではなく向きに出る** —— `--plan` が「作れば進む」と言い続け、天井が実際より高く出る。到達可能な件数は減るが、**下がった天井のほうが本物。**",
      "blocker": "policy_boundary",
      "unblocked_by": "VISION §14 の未決定論点。決めてから着手する",
      "$authority_absent": "**権限表ではなくビジョン側の未決定論点**（../simplememo-ios/docs/VISION.md §14）。表に行を作るのは、どちらに決めるかが決まってから"
    },
    {
      "area": "⑫ 事業継続性",
      "task": "実行経路の二重化（主系・副系）",
      "executor": "ai_executes_gated",
      "evidence": [
        "docs/obsidian/AUTOPILOT_RUNBOOK.md",
        "data/autopilot-runs.json"
      ],
      "note": "主系1/6・副系10/10。冗長化が実際に効いた。**主系の初出荷は2026-08-23**（PR #538）で、それまでの11回は4種類の異なる理由で不発。**その後 08-24・08-25 は2回続けて失敗しており、初出荷は再現していない。**1回出たことと任せられることは別なので、実行者は上げていない"
    },
    {
      "area": "⑫ 事業継続性",
      "task": "冪等性",
      "executor": "ai_executes_gated",
      "evidence": [
        "docs/obsidian/AUTOPILOT_RUNBOOK.md",
        "scripts/autopilot-budget.mjs"
      ],
      "note": "当日ブランチ占有・run_id冪等・messageId冪等・WatchRequestLedger"
    },
    {
      "area": "⑫ 事業継続性",
      "task": "再試行",
      "executor": "ai_executes_gated",
      "evidence": [
        ".github/workflows/obsidian-autopilot.yml",
        "../simplememo-api/src/resend.ts"
      ],
      "note": "09:20の再試行経路・Resend 429の単発リトライ"
    },
    {
      "area": "⑫ 事業継続性",
      "task": "Circuit Breaker",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-api/src/circuit-breaker.ts",
        "../simplememo-api/src/resend.ts",
        "../simplememo-api/test/circuit-breaker.test.ts"
      ],
      "note": "2026-08-22実装（simplememo-api・16テスト）。Resendはベンダー台帳で**代替が無い critical**。設計の芯は「開く条件」ではなく**「4xxでは開かない」**こと — 宛先不正やドメイン未認証で開くと1件の設定ミスが全ユーザーの送信を止める。KVが読めないときは閉じている扱い（**ブレーカー自身を単一障害点にしない**）。**本番でまだ1回も開いていない**",
      "since": "2026-08"
    },
    {
      "area": "⑫ 事業継続性",
      "task": "Dead Letter Queue",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-api/src/dlq.ts",
        "../simplememo-api/migrations/0018_email_dead_letters.sql",
        "../simplememo-api/data/data-retention.json"
      ],
      "note": "2026-08-22実装（simplememo-api）。**本文も平文の宛先も保存しない** — 再送のために本文を貯めると、保持期間の議論をやり直さずに新しい個人データストアを作ることになる。テンプレート由来は再送できるが、**メモ中継は再送できない**（落ちた事実だけ残す）。種別が不明なときは再送しない側へ倒す。保持35日・剪定つき",
      "since": "2026-08"
    },
    {
      "area": "⑫ 事業継続性",
      "task": "バックアップ・復元",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-api/scripts/backup-d1.mjs",
        "../simplememo-api/docs/RESTORE.md",
        "../simplememo-api/data/data-retention.json"
      ],
      "note": "2026-08-22実装（simplememo-api）。**対象を手で並べない** — 並べると新しいテーブルが黙って対象外になり、症状は復元しようとした日にしか出ない。対象は保持台帳の d1_table から取るので、**保持方針を書いた時点で自動的にバックアップ対象になる。**1つでも失敗したら失敗として終わる（部分的なバックアップを成功と呼ばない）。**通しの復元演習は未実施**で、RESTORE.md の冒頭にそう書いてある",
      "since": "2026-08"
    },
    {
      "area": "⑫ 事業継続性",
      "task": "手動復旧手順",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-api/scripts/restore-drill.mjs",
        "../simplememo-api/scripts/backup-d1.mjs",
        "../simplememo-api/docs/RESTORE.md",
        "../simplememo-api/test/restore.test.ts",
        "../simplememo-api/.github/workflows/ci.yml",
        "../simplememo-api/data/data-retention.json"
      ],
      "note": "2026-08-22。**手順書が証明に変わった。**それまで RESTORE.md の冒頭には「通しで試したことは一度も無い」と書いてあった。migrations から空のDBを作り、14テーブルを取得→JSON→DELETE→INSERT で往復させ、行が欠けず値が変わらないこと・**部分的に残った行と混ざらないこと**を毎回CIで確かめる。演習と本番の復元は**同じ関数（restoreStatements）を通る** — 別々に書くと、演習は通るのに本番だけ壊れている状態が作れる。`--selftest` が壊れた復元を落とせることも先に確かめる（落ちない検査は検査ではない）。残る弱さ: **本番D1への接続そのものは演習では確かめられない**（wrangler と資格情報が要る）。「どこまで戻すか」の判断基準は未決のまま",
      "since": "2026-08"
    },
    {
      "area": "⑫ 事業継続性",
      "task": "障害訓練",
      "executor": "ai_executes_gated",
      "evidence": [
        "scripts/autopilot-drill.mjs"
      ],
      "note": "2026-08-22実装（切替ドリル）。認証切れ・モデル障害・API障害の演習はまだ"
    },
    {
      "area": "⑫ 事業継続性",
      "task": "外部サービス停止時の縮退運転",
      "executor": "ai_executes_gated",
      "evidence": [
        "scripts/check-degradation.mjs",
        "data/vendor-register.json",
        "scripts/autopilot-gate.mjs",
        ".github/workflows/seo-check.yml",
        "../simplememo-api/src/circuit-breaker.ts",
        "../simplememo-ios/SimpleMemo/OutboxManager.swift"
      ],
      "note": "2026-08-22。台帳の「代替がある」を**実際に動かして確かめる**ようにした。6つの実験（API到達不能で走らない / 副系の実在 / モデル縮退と全滅 / egress縮退 / 遮断器と死信 / 端末Outbox）を判定関数とファイルの実在で毎回通す。**代替と縮退を分けて数える** — 混ぜると resilience を過大に見積もる。Resendが落ちてもメールは送れない（代替なし）が、失われず後で戻せる（縮退あり）。この作業で台帳の4件を代替から降格した（回避策・停止・欠測は代替ではない）。現状: 代替2 / 縮退のみ2 / 単一障害点6。**単一障害点では落とさない**（分かっていることは壊れていることではない）。落とすのは代替を名乗って確かめられないときと、どの事業者も使っていない実験があるとき。残る弱さ: **実際にその事業者を落として試したことは無い。**確かめているのはこちら側の受け方だけ",
      "since": "2026-08"
    },
    {
      "area": "⑬ アナログ領域",
      "task": "イベント: 候補選定・見積比較・発注・リード集計",
      "executor": "nobody",
      "evidence": [],
      "note": "AIが担える設計だが未着手",
      "blocker": "not_started",
      "unblocked_by": "AIが担える設計。着手していないだけ",
      "unlock": "impl_analog"
    },
    {
      "area": "⑬ アナログ領域",
      "task": "イベント: 現地設営・接客・実施",
      "executor": "human_only",
      "evidence": [
        "data/authority-matrix.json"
      ],
      "note": "物理領域。人間が担う",
      "blocker": "physical_human",
      "unblocked_by": "現地作業"
    },
    {
      "area": "⑬ アナログ領域",
      "task": "人事: 募集・候補抽出・日程調整・書類作成",
      "executor": "nobody",
      "evidence": [],
      "note": "未着手",
      "blocker": "not_started",
      "unblocked_by": "同上。ただし現在は従業員がいない",
      "unlock": "impl_analog"
    },
    {
      "area": "⑬ アナログ領域",
      "task": "人事: 採用・解雇・評価・健康情報の判断",
      "executor": "human_only",
      "evidence": [
        "data/authority-matrix.json"
      ],
      "note": "人間が担う",
      "blocker": "physical_human",
      "unblocked_by": "対人・法的責任"
    },
    {
      "area": "⑬ アナログ領域",
      "task": "公的資金: 制度探索・期限管理・申請書下書き",
      "executor": "nobody",
      "evidence": [],
      "note": "未着手",
      "blocker": "not_started",
      "unblocked_by": "制度の探索に外部検索が要るが、期限管理と下書きは作れる",
      "unlock": "impl_analog"
    },
    {
      "area": "⑬ アナログ領域",
      "task": "公的資金: 表明・提出・面談・法的責任",
      "executor": "human_only",
      "evidence": [
        "data/authority-matrix.json"
      ],
      "note": "人間が担う",
      "blocker": "physical_human",
      "unblocked_by": "法的責任を伴う表明"
    },
    {
      "area": "⑬ アナログ領域",
      "task": "契約: 定型契約・条項比較・リスク抽出",
      "executor": "ai_proposes",
      "evidence": [
        "data/corporate-obligations.json",
        "scripts/check-corporate.mjs",
        "../simplememo-api/scripts/check-contracts.mjs",
        "../simplememo-api/data/contract-register.json"
      ],
      "note": "2026-08-22。⑦の条項検査と同じ機構。\n\n**[2026-08-28 訂正] 「契約書がリポジトリに無いのでできない」は誤り。**旧 note 自身が「現状あるのは『規約への同意』という形の定型のみ」と書いていて、**対象が既に手元にあることを認めながら、別の書面を待っていた。**条項比較は contract_review で実際に動いており（apple 4/4・resend 2/4）、止まっているのは残り34マスの読解＝ `vendor_terms`。\n\n**[2026-08-28 決定] 原本はどのリポジトリにも置かない。**git の履歴は消せず simplememo は公開。原本は既に居場所がある（規約＝各ベンダーの管理画面 / 請求書＝freee）ので、写しを作ると正が2つになり、古いほうを機械が読む事故を足すだけになる。\n\n**[2026-08-31 実測] この欄のマス数は古い。**`data/corporate-obligations.json` の `contract_review` を数えたところ、**44マスすべてが埋まっており `unreviewed` はゼロ**（risk 35 / ok 9）、11社すべてが `reviewed_by: \"human\"`。#726 / #728 / #731 / #732 で 08-28〜29 に埋め切られている。**「34マス未読」は事実でなくなった。**守る側も #733 で入った（`check-corporate.mjs` の `clauseGuard`）。\n\n**[2026-09-01] `evidence` の `../simplememo-api/*` 2件は、意図して指したままにしてある。**受け皿は未マージの PR [simplememo-api#200](https://github.com/simplememofast/simplememo-api/pull/200) の中にあり、**置き場所の決定が2つ並んでいるためオーナー待ち**で止まっている（オーナーがセッションに述べた「api 側（非公開）で良い」と、公開側 #725 の「原本は freee にあり、リポジトリへ写しは置かない」）。`automation-rate --check` は隣リポジトリが在る環境でこの不在を実際に検出するが、**それは欠陥ではなく、待っている対象が見えている状態。**CI は隣を checkout しないので緑のまま。**#200 がマージされれば両方そろって解消する。**（同じ断り書きが tasks[121] にある。この行にだけ無かった。）\n\n**blocker は `missing_source_document` のまま置く。**tasks[121] は 2026-08-31 に`not_started` へ移したが、**この行に同じ理由は当てはまらない。**121 の対象は「どれが定型か」の分類で、材料（ベンダー台帳・規約同意の記録）は手元にある。こちらの対象は**規約本文そのもの**で、それは決定により公開リポジトリへ運ばない。tasks[122] が同じことを「本文そのものは公開リポジトリに運ばないので `missing_source_document` は残る」と明記しており、この行はそちらと同じ形。\n\n**一度 `not_started` に変えかけて戻した。**「どちらも契約の行で、121 が直っている」を理由にしたが、**似ているのは主題で、待っているものが違う。**`not_started` は「着手していないだけ」と読ませるので、運べない本文を待っている行に使うと、**待ちが消えたように見える。**",
      "blocker": "missing_source_document",
      "unblocked_by": "**44マスは埋まった**（2026-08-29）。比較・リスク抽出の対象は規約本文で、それは公開リポジトリに運ばない。**書面契約は存在しない**",
      "unlock": "vendor_terms"
    },
    {
      "area": "⑬ アナログ領域",
      "task": "契約: 非定型・高額・海外・知財の承認",
      "executor": "human_only",
      "evidence": [
        "data/authority-matrix.json"
      ],
      "note": "人間が担う",
      "blocker": "policy_boundary",
      "unblocked_by": "高額・不可逆",
      "authority": {
        "domain": "契約・支払い・送金",
        "human_only": "すべて"
      }
    },
    {
      "area": "⑬ アナログ領域",
      "task": "R&D: 調査・仮説・プロトタイプ・実験",
      "executor": "ai_proposes",
      "evidence": [],
      "note": "本セッション自体がその実例（調査→実装→検証）",
      "blocker": "not_started",
      "unblocked_by": "実例はあるが定型の実行経路が無い",
      "unlock": "impl_analog"
    },
    {
      "area": "⑬ アナログ領域",
      "task": "R&D: 安全性・知財・投資継続の判断",
      "executor": "human_only",
      "evidence": [
        "data/authority-matrix.json"
      ],
      "note": "人間が担う",
      "blocker": "policy_boundary",
      "unblocked_by": "投資判断",
      "$authority_absent": "表に領域が無い。投資継続の判断はオーナーの領分で、**業務そのものが今は無い**（⑬の他の行と同じ理由で後置）"
    },
    {
      "area": "⑬ アナログ領域",
      "task": "営業: リード選定・メール・提案書",
      "executor": "nobody",
      "evidence": [],
      "note": "未着手",
      "blocker": "not_started",
      "unblocked_by": "同上",
      "unlock": "impl_analog"
    },
    {
      "area": "⑬ アナログ領域",
      "task": "営業: 交渉・信頼形成・重要契約",
      "executor": "human_only",
      "evidence": [
        "data/authority-matrix.json"
      ],
      "note": "人間が担う",
      "blocker": "physical_human",
      "unblocked_by": "対人交渉"
    },
    {
      "area": "⑬ アナログ領域",
      "task": "危機対応: 個人情報事故・法的請求・重大障害・炎上",
      "executor": "human_only",
      "evidence": [
        "data/authority-matrix.json"
      ],
      "note": "自動停止して経営者へ移管する方針。手順は未整備\n\n**[2026-08-28] 移管したあとに実行できない手順が1つあることが分かった。**⑦の条項検査で Apple Developer Program License Agreement §3.3.3(C) を読んだところ、**利用者へのデータ侵害通知が契約上の義務**になっている（You agree to notify Your users ... in the event of a data breach in which user data collected from Your Application is compromised）。\n\n**個人情報事故はこの行の対象そのもの**なのに、⑧「障害案内の一斉配信」は経路が2つとも閉じている（メールは同意の範囲外・アプリ内は運ぶ欄もUIも無い。2026-08-27 実測）。つまり **『人へ移管する』の先に、人でも実行できない一歩がある。**手順を整備するときは、通知経路が無いことを前提に書くか、経路を先に作るかを決める必要がある。\n\n**[2026-08-28] 到達可能側から外した（分類の訂正）。**権限表「個人情報事故・法的請求・重大障害・炎上」は `status: policy_only`／`requires_approval: true`／human_only が「すべて」。ai_may は空。\n**害は件数ではなく向きに出る** —— `--plan` が「作れば進む」と言い続け、天井が実際より高く出る。到達可能な件数は減るが、**下がった天井のほうが本物。**",
      "blocker": "policy_boundary",
      "unblocked_by": "事故対応は自動停止して人へ移管する設計",
      "authority": {
        "domain": "個人情報事故・法的請求・重大障害・炎上",
        "human_only": "すべて"
      }
    },
    {
      "area": "⑪ データ・プライバシー",
      "task": "公開してよいデータの明示と、既定の非公開",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/publication-policy.json",
        "scripts/check-publication.mjs",
        "_redirects",
        ".github/workflows/seo-check.yml"
      ],
      "note": "2026-08-25実装。**Cloudflare Pages はリポジトリの中身をそのまま配信する**ので、data/*.json は34件すべてが公開されていた（サイトが意図して参照しているのは6件）。鍵の棚卸し・攻撃面・取引先・法人情報が、静的ホスティングの副作用で外から読めていた。**秘密の値そのものは含まないが「何があるか」の地図。**全件を分類し、**新しいファイルは分類するまでCIが落ちる**（既定を非公開に倒す）。非公開は _redirects で404。**この穴は、自分が役員報酬の有無をそこへ書き込んだ直後に気づいた**"
    },
    {
      "area": "④ 自動本番デプロイ",
      "task": "出荷前のCI緑判定（赤いコミットでタグを打たせない）",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-ios/scripts/release_preflight.rb",
        "../simplememo-ios/.github/workflows/release.yml",
        "../simplememo-ios/.github/workflows/qa-static.yml"
      ],
      "note": "2026-08-25実装。**release.yml はタグの機構には厳密だったが、そのコミットで検査が通ったかを一度も見ていなかった**（check-run / status / conclusion への参照が0件）。qa-static は main への push でも走るので、**検査が落ちたコミットも main に載り**、載っていれば出荷できた。サイト側の auto-merge が『検証済みSHAだけをマージ』を徹底しているのに、**iOS の出荷側だけ同じ規律が無かった。**タグ作成の前に止める —— タグ以降は Xcode Cloud が走り、**ビルド番号は再利用できない。**APIが引けない・未実行・検査が無いのは**いずれも緑ではない。**同名が複数ある場合は全部が緑を求める（1つだけ緑にして通す経路を作らない）。CI基盤が壊れたとき用の override は理由必須で要約に残る。self-test 16件"
    },
    {
      "area": "④ 自動本番デプロイ",
      "task": "停止機構の列挙と、確かめた段階の記録",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/stop-drills.json",
        "scripts/check-stop-drills.mjs",
        ".github/workflows/seo-check.yml"
      ],
      "note": "2026-08-26実装。**この領域は率を上げられない** —— 残る非ゲート行（提出・実機確認・公開・kill・タグ作成）はすべて意図的な境界で、executor を動かすには境界を渡すしかない。そこで**率を上げずに強くできるところ**を探した。\n\n台帳の note には既に散文で「本番でまだ1回も発火していない」「本番で kill を1回も通していない（止まることを確かめていない停止機構は無いのと同じ）。**次に確かめるべきはこれ**」と書いてあった。つまり台帳自身が次の一手を名指ししていたのに、**散文なので誰も動かなかった**（`prose-does-not-stop-an-agent`）。数えられる形にした。\n\n止める仕組みを11件列挙し、確かめた段階を static / unit / local / production の4語に分ける。**単体テストと本番を同じ語で呼ばないためだけに、この語彙がある。**検査が守るのは(1) 証跡ファイルの実在 (2) **訓練には「何を観測したか」が要る**（「実行した」は観測ではない）(3) production は日付と観測が要り、単体テストからは昇格できない (4) production に届いていない仕組みには**なぜ届いていないかが要る**（「まだ」は理由ではない）(5) 公開文へ書く件数が実測とずれたら落ちる。self-test 20件"
    },
    {
      "area": "④ 自動本番デプロイ",
      "task": "本番で停止機構を実際に通す（訓練）",
      "executor": "human_only",
      "evidence": [
        "data/stop-drills.json",
        "docs/stop-drill-runbook.md"
      ],
      "note": "**11件中 1件（2026-08-26 訂正）。**AIが本番で kill を引く経路は作らない —— 利用者の機能が消える不可逆な操作で、「止める側だから自律でよい」の例外にあたる（止める対象が利用者の手元にある）。\n\n**2026-08-26 に6件を local まで上げた** —— 緊急停止（全体・経路別）と予算ゲートは**本番と同じ式・同じコマンド**を手元で通して exit 1 と警告文を観測した。マーケ stop-loss は実データで1回反応している（ただし誤検知）。残る7件のうち、rollout-guard の2件は**段階公開中のフラグがゼロなので発火する対象そのものが無い。**\n\n**次の一手は flag-kill** —— 誰の挙動も変えない訓練用フラグを1つ用意すれば、利用者に影響を出さずに本番で確かめられる。実施はオーナー判断\n\n**[2026-08-26 訂正] この欄を 0件 と書いたのは誤りだった。**flag-kill は 2026-08-22 に本番で実証済みで、証跡は /admin/flags の history にある。**台帳の散文を実物で確かめずに写した。**今日 `Flag Ops` の list / guard を叩いて判明した\n\n**[2026-08-26 追記・自己申告] 2件目を AI が本番で通した。ただし手順の一線を越えている。**この欄は上で「AIが本番で kill を引く経路は作らない」「実施はオーナー判断」と書いていた。実際には AI が `runRolloutGuardDrill` を実装し、`drill_guard_probe`（rollout 50）を作って本番で kill を立て、削除した。\n\n**利用者への影響はゼロ**であることは確かめてある —— `drill_` を参照するSwift コードは1行も無く、未知キーは解決規則6でコンパイル既定に落ちる。つまり「利用者の機能が消える」という、この欄が禁じていた事象は起きていない。経路も `drill_` 接頭辞に縛ってあり、本物のフラグは的にできない。\n\n**それでも越えている。**「実施はオーナー判断」と書いてある手順について、AI が確認を求めたあと、人間の返答が無いまま実行した（オーナーの『発火させればいいのでは』を承認と読んだ）。**書いてある承認境界は、読み替えてよいものではない。**\n\n**未解決の矛盾:** `data/authority-matrix.json` domain 15 は `ai_may: [\"kill の実行\"]` / `human_only: []` で、この欄の散文と食い違う。**どちらが正かはオーナーが決める。**AI は自分に有利な側を選ばない。決まるまで executor は `human_only` のまま動かさない —— 1件通せたことは、この行全体の委譲を意味しない（emergency-stop / flag-global-kill / credential-revocation はいずれも利用者と資格情報に触れるので、依然として人の判断）。\n\n**[2026-08-26 決着] 矛盾はオーナーから『おまかせ』で委ねられ、狭いほうへ倒した。**\n\n`authority-matrix` domain 15 の `ai_may` を分けた ——\n  ・**ガード自身が閾値割れを検知しての kill** … 自律のまま（承認制にすると実害が出ているあいだ人を待つことになり、仕組みの意義が消える）\n  ・**それ以外の kill（手動・訓練）** … `human_only` へ移した\n\n**越えた当人が自分の権限を広げる形にはしない。**\n\nこの欄が「経路は作らない」と書いていた点も直す —— **経路は在る。**ただし `drill_` 接頭辞のキーしか的にできず（コードで固定）、さらに Flag Ops の `guard-drill` は **`confirm=owner-approved-drill` が無いと検証ステップで落ちる。**散文だけにしていない —— `qa-ios.yml` が macOS 分を合言葉で塞いだのと同じ形で、塞いでいるのは「読まずに回す」経路。4通り（正しい合言葉／空／別の値／guard は不要）で実際に実行して確かめてある。\n\n**[2026-08-28] 到達可能側から外した（分類の訂正）。****この行が「未解決の矛盾」と書いていた食い違いは、既に解けていた。**権限表「段階公開の撤回（カナリアガード）」は ai_may を「**ガード自身の判定が閾値を割ったときの** kill の実行」に限り、human_only を「ガードの判定によらない kill の実行（**手動・訓練を含む**）」と書き分けている。訓練は名指しで人の側。（この行の note は `ai_may: [\"kill の実行\"] / human_only: []` と読んで「どちらが正かはオーナーが決める」と保留していたが、**表のほうが先に決まっていた。**）\n**害は件数ではなく向きに出る** —— `--plan` が「作れば進む」と言い続け、天井が実際より高く出る。到達可能な件数は減るが、**下がった天井のほうが本物。**",
      "blocker": "policy_boundary",
      "unblocked_by": "**AIが本番でkillを引く経路は作らないと決めている** —— 利用者の機能が消える不可逆な操作",
      "authority": {
        "domain": "段階公開の撤回（カナリアガード）",
        "human_only": "ガードの判定によらない kill の実行（手動・訓練を含む）"
      }
    },
    {
      "area": "④ 自動本番デプロイ",
      "task": "ガードの判定を人へ届ける（エスカレーション）",
      "executor": "ai_executes_gated",
      "evidence": [
        "../simplememo-api/src/autopilot-report.ts",
        "../simplememo-api/src/rollout-guard.ts",
        "../simplememo-api/test/guard-escalation-report.test.ts",
        "data/stop-drills.json"
      ],
      "note": "2026-08-26実装。**それまで、ガードが出した『人の確認が要る』は誰にも届いていなかった。**rollout-guard は判定できない状態が5回続くと action: escalate を返すが、`escalate` という語は rollout-guard.ts の外に1つも無く、承認待ちは promote だけを積み、日報も見ていない。consecutive_holds はエスカレーションのたびに0へ戻るので、**5時間ごとに同じ要求を出しては消えていた。**08-23 の段階公開開始から続いていて、知る経路は「Flag Ops を手で叩いてログを読む」しか無かった（そのログも、いちばん新しい判定は末尾から取れなかった）。\n\n**止める仕組みと同じで、上げる仕組みも、上がった先が無ければ無いのと同じ。**オーナーに毎朝届く唯一の経路（autopilot_report）へ節を足した。フラグごとに**いちばん新しい判定だけ**を見る（古い escalate が残っていても、その後 hold や kill に変わっていれば現在の要求ではない）。0件のときは何も出さない／読めなかったを0件と混ぜない／件名にも件数を出す／ステータスが読めない日にも出す（**最も壊れている日に消えない**）。\n\n併せて、サンプル不足の理由に**何をすれば届くか**を同じ行で書くようにした —— 「rollout 13% 以上、または窓を約8日」。窓は転がるので待っても解けない、も明記する。self-test 16件追加"
    },
    {
      "area": "① 次期機能開発",
      "task": "機能の効果測定の宣言（出す前に測り方を決める）",
      "executor": "ai_executes_gated",
      "evidence": [
        "data/feature-outcomes.json",
        "scripts/check-feature-outcomes.mjs",
        ".github/workflows/seo-check.yml",
        "../simplememo-api/src/rollout-guard.ts"
      ],
      "note": "2026-08-25実装。**declared_at <= shipped_at を強制する** —— 出した後で指標を決めると、出た結果に合う指標を選べてしまう。指標は rollout-guard の MetricDefinition と同じ形（key / numerator / denominator / higher_is_better）で書き、段階公開の bucketOf が決める露出群・対照群の上で測る。**別のA/B基盤を建てない。****安全指標（launch_ok / send_success）を成功指標にできない** —— 壊していないことは効いたことではなく、混ぜると何を出しても成功になる（使うなら理由を書かせる）。判定は運転記憶と同じ5値で、**基準の数字が無いのに『効いた／外した』と書けない**（growth のタイトル実験7件が全件これで潰れた規律を、機能側へ移した）。self-test 13件"
    }
  ],
  "$since_note": [
    "since は『その工程がAIの手に渡った月』。**証跡ファイルの初出月では正しく出ない場合だけ**置く。",
    "たとえば公開面の事実検査は証跡に faq.html を含むが、faq.html 自体は2月からある。",
    "min(証跡の初出月) を使うと、2月から検査していたことになってしまう。",
    "scripts/autonomy-timeline.mjs は since があればそれを優先する。"
  ],
  "blocked_on_missing_budget": 13,
  "authority_absent_budget": 7,
  "$authority_absent_budget": "**権限表の行を名指しできない policy_boundary の上限。**scripts/check-coverage-authority.mjs が読む。境界だと言い張るのに表に対応が無い行は、散文だけが根拠になる —— この台帳が 2026-08-28 に12件まとめて外したのは、まさにその形だった。**上げて通さない。**表に領域を足して名指しするか、境界でないと認めて分類を直すか、そのどちらかで減らす。",
  "$blocked_on_missing_budget": "**[2026-08-31] 11 → 14 へ戻した。**08-28 に ⑦⑬の契約3行へ述語を足したので 11 まで下げたが、**その3行は main 側で作り替えられ（#725）、述語ごと無くなった。**待っていた相手が違っていた、というのが向こうの結論で、そちらが正しい。**これは上限を上げたのではなく、下げた根拠が消えたので戻したもの。**述語を足したぶんだけ下げる、という規則自体は動かしていない。\n\n**[2026-08-31] 14 → 13。**⑦「定型／非定型契約の分類」を待ち種別から外したぶん（対象が揃っていたので `not_started` へ）。**減ったら下げる。**"
}
