ADR-0208 (保存年限管理と期限後廃棄の運用方式 · 2026-07-04 受理) の Confirmation 6 KPI の観測結果を時系列で記録する。SQL 骨格は本ファイル各節 · SSoT は ADR-0208 §9 Confirmation。実 SQL の実行は Phase 0 dogfood 開始 (vlt/terraform/ の GCS Object Retention Lock 有効バケット + lifecycle 3 規則 + 日次巡回処理 (Cloud Scheduler → Cloud Run Job · 03:00 JST) + deletion_events 表 shipping + ${project} / ${dataset} 確定) 後に開始する。retention_sweep_runs / retention_reconcile_log / gcs_inventory_report は仮名で、PR-4 (schema.sql) + Terraform 実装時に実名へ確定する。

Week 0 (2026-07-07 · Phase 0 dogfood 前 · 準備段階)

Phase 0 dogfood 未着手のため実測データなし。6 KPI の SQL 骨格 + SLO + 実施頻度 + 撤退条件連動を先出しで整理する。dogfood 開始時点で本節を Week 1 として実測数値に置き換える。KPI 3 (保全の誤廃棄) と KPI 6 (10 年仮残留) は他 ADR の observation log と統合観測する (各節に参照先を明記)。

KPI 1: 廃棄遅延 (日次 · 目標 ≤ 24 時間)

  • SLO: 期限超過した証憑の廃棄完了までの遅延 ≤ 24 時間
  • 実施頻度: 日次 (巡回処理の完走監視 + タイムアウト中断アラート)
  • 撤退条件連動: 超過したら巡回処理を調査し手動廃棄で追いつく · 巡回 1 回の実行が 6 時間超過で ADR-0208 §8-3 (分割・並列化の実装改訂 · --task-timeout=21600 / --parallelism=4 と整合)

BigQuery SQL 骨格 (廃棄遅延の検出):

SELECT
  r.receipt_id,
  r.retention_expires_at,
  TIMESTAMP_DIFF(CURRENT_TIMESTAMP(), r.retention_expires_at, HOUR) AS overdue_hours
FROM `${project}.${dataset}.receipts` AS r
WHERE r.retention_expires_at < TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 24 HOUR)
  AND r.deleted_at IS NULL
  AND NOT EXISTS (  -- 保全中は廃棄対象外 (ADR-0218 · 正当な滞留のため除外)
    SELECT 1 FROM `${project}.${dataset}.legal_holds` AS lh
    WHERE lh.released_at IS NULL
      AND (
        lh.scope = 'ALL'
        OR (lh.scope = 'RECEIPT' AND lh.receipt_id = r.receipt_id)
        OR (lh.scope = 'PREFIX' AND STARTS_WITH(r.storage_uri, lh.scope_prefix))
      )
  );
-- 期待値: 0 行 (期限到来から 24 時間以内に廃棄が完了していること)

巡回処理の完走監視 (日次):

SELECT
  run_date,
  started_at,
  completed_at,
  TIMESTAMP_DIFF(completed_at, started_at, MINUTE) AS duration_min,
  processed_count,
  status
FROM `${project}.${dataset}.retention_sweep_runs`
WHERE run_date >= DATE_SUB(CURRENT_DATE('Asia/Tokyo'), INTERVAL 7 DAY)
ORDER BY run_date DESC;
-- 期待値: 毎日 1 行 · status = 'completed' · duration_min < 360 (6 時間 = 撤退条件 3 連動)
-- 中断時は checkpoint (最終処理済み receipt_id) から翌起動時に再開する設計 (ADR-0208 §3)

KPI 2: 記録の突合 (月次 · 目標 100%)

  • SLO: 廃棄記録表 deletion_events の全行に対応する Cloud Audit Logs 記録の存在 = 100%
  • 実施頻度: 月次の照合バッチ
  • 撤退条件連動: 欠落 1 件で 4 層記録 (deletion_events / Cloud Audit Logs / Pub/Sub 通知 / GCS usage logs) の配線を調査

BigQuery SQL 骨格 (deletion_events × Cloud Audit Logs の突合 · Cloud Logging sink 経由):

WITH primary_events AS (
  SELECT deletion_event_id, storage_uri, deleted_at
  FROM `${project}.${dataset}.deletion_events`
  WHERE deleted_at >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
),
audit_deletes AS (
  SELECT protoPayload.resourceName AS resource_name, timestamp
  FROM `${project}.audit_logs.cloudaudit_googleapis_com_data_access_*`
  WHERE _TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 31 DAY))
    AND protoPayload.methodName = 'storage.objects.delete'
    AND resource.labels.bucket_name LIKE '${bucket_prefix}%'
)
SELECT pe.deletion_event_id, pe.storage_uri, pe.deleted_at
FROM primary_events AS pe
LEFT JOIN audit_deletes AS ad
  ON ad.resource_name LIKE CONCAT('%', REGEXP_REPLACE(pe.storage_uri, r'^gs://[^/]+/', ''))
  AND ABS(TIMESTAMP_DIFF(ad.timestamp, pe.deleted_at, MINUTE)) < 60
WHERE ad.resource_name IS NULL;
-- 期待値: 0 行 (= 全行に Audit Logs 対応記録あり · 欠落 1 件で 4 層記録の配線を調査)
-- storage_uri → resourceName の対応付け (gs:// prefix 除去) は dogfood 時に実データで検証して確定

補足: Cloud Audit Logs Data Access log の有効化と BQ sink は ADR-0218 KPI 4 (網羅性監視 · docs/_internal/06_ops/adr-0218-observation-log.md) と共用する。

KPI 3: 保全の誤廃棄 (廃棄バッチごと · 目標 0 件) — ADR-0218 と統合観測

  • SLO: 保全 (legal hold) 対象の誤廃棄 = 0 件 + 保全中証憑への期限短縮試行 = 0 件
  • 実施頻度: 廃棄バッチごとに保全台帳と照合
  • 撤退条件連動: 1 件で巡回処理を即停止し復旧手順を発動 (ADR-0218 §8-1 と同一発火)

SQL は docs/_internal/06_ops/adr-0218-observation-log.md の KPI 1 (保全対象の誤廃棄件数 · 日次) + KPI 2 (保全中証憑への期限短縮試行件数 · 日次) と同一のため再掲しない。同 log の実行結果を参照する (統合観測)。

KPI 4: 段階保管の移行 (月次 · 目標 Coldline 移行完了率 ≥ 95%)

  • SLO: 365 日超の証憑の Coldline 移行完了率 ≥ 95%
  • 実施頻度: 月次
  • 撤退条件連動: 未達なら lifecycle 規則 (Coldline @365 日 · Archive @1,095 日 · 安全網 Delete @4,020 日) を調査 · GCS 保管費が月 $100 (予算 $200 の 50%) 超過で ADR-0208 §8-4 (移行日数短縮の再検討)

BigQuery SQL 骨格 (GCS inventory report の BQ export 前提):

SELECT
  COUNTIF(storage_class IN ('COLDLINE', 'ARCHIVE')) AS migrated_count,
  COUNT(*) AS eligible_count,
  SAFE_DIVIDE(COUNTIF(storage_class IN ('COLDLINE', 'ARCHIVE')), COUNT(*)) AS migration_ratio
FROM `${project}.${dataset}.gcs_inventory_report`
WHERE TIMESTAMP_DIFF(CURRENT_TIMESTAMP(), time_created, DAY) > 365;
-- 期待値: migration_ratio >= 0.95 (365 日超は Coldline · 1,095 日超は Archive へ移行済み)
-- GCS inventory report の BQ export 設定は Phase 0 dogfood の Terraform (lifecycle 3 規則と同 module) で確定

KPI 5: 期限の一致 (週次サンプリング + 廃棄時全件 · 目標 乖離 100 件未満かつ 24 時間以内解消)

  • SLO: データベースの保存期限 (receipts.retention_expires_at = 唯一の正) と GCS の削除禁止期限の乖離が 100 件未満 かつ 24 時間以内に解消
  • 実施頻度: 週次サンプリング照合 + 廃棄時の全件照合
  • 撤退条件連動: 乖離 100 件以上または 24 時間以上継続で ADR-0208 §8-6 発動 (巡回処理を止め手動再同期 + 原因調査 · ADR-0203 撤退条件 6 と連動)。単発乖離は二段階コミット (pending → confirmed) のリトライキューで解消する前提のため即時停止しない

BigQuery SQL 骨格 (二段階コミットの pending 滞留 = 乖離候補の観測):

SELECT
  COUNT(*) AS pending_count,
  COUNTIF(TIMESTAMP_DIFF(CURRENT_TIMESTAMP(), retention_sync_requested_at, HOUR) > 24) AS pending_over_24h
FROM `${project}.${dataset}.receipts`
WHERE retention_sync_status = 'pending';
-- 期待値: pending_count < 100 かつ pending_over_24h = 0 (超過で撤退条件 6)
-- 列名 (retention_sync_status / retention_sync_requested_at) は仮名 · PR-4 (schema.sql) 実装で確定

週次サンプリング照合 (DB ⟷ GCS metadata の bit 一致検証) は照合バッチの出力 log 表で観測:

SELECT checked_at, sample_size, mismatch_count
FROM `${project}.${dataset}.retention_reconcile_log`
WHERE checked_at >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
ORDER BY checked_at DESC;
-- 期待値: mismatch_count < 100 (乖離 100 件以上 or 24 時間以上継続で撤退条件 6)

KPI 6: 10 年仮設定の残留 (月次) — ADR-0217 / ADR-0215 と統合観測

  • SLO: 事業年度確定から 6 ヶ月経過しても 10 年仮設定のままの証憑数を月次観測 (6 ヶ月以内に 0 収束)
  • 実施頻度: 月次
  • 撤退条件連動: ADR 記載の対応 (「一定件数を超えたら確定申告完了イベントの連携を扱う別 ADR を優先起票する」) は ADR-0215 (確定申告完了イベント連携方式 · 2026-07-06 受理) の受理により充足済。以降の残留観測は downgrade 実行の健全性観測として継続する (>0 件で発生源 UI の運用ログ調査 + fiscal_year_close_events 表との突合 + 手動 downgrade)

SQL は docs/_internal/06_ops/adr-0217-observation-log.md の KPI 2 (= docs/_internal/06_ops/adr-0215-observation-log.md KPI 3 と同一 SQL: retention_class = '10yr' AND fiscal_year_close_confirmed_at IS NULL AND created_at < 180 日前) と同一のため再掲しない。同 log の実行結果を参照する (3 ADR 統合観測)。

KPI 総括 (ADR-0208 §9 記載)

廃棄遅延 ≤ 24 時間 / 保全対象の誤廃棄 0 件 / 期限乖離 100 件未満 / JIIMA 審査での廃棄記録提示能力 100% (KPI 2 の突合 100% が実体) / 10 年仮残留の月次観測。

Phase 0 dogfood 開始時の確定タスク

  1. table 名 / 列名の確定: deletion_events / receipts 列 (retention_sync_status 等) は PR-4 (schema.sql) で、retention_sweep_runs / retention_reconcile_log (仮名) は巡回処理 + 照合バッチの実装で確定し本 SQL 骨格へ埋め込み
  2. Cloud Audit Logs BQ sink の設定 (KPI 2 · ADR-0218 observation log KPI 4 と共用 · Data Access log 有効化は Terraform locked module 分離)
  3. GCS inventory report の BQ export 設定 (KPI 4 · lifecycle 3 規則と同 Terraform module)
  4. BQ scheduled query の登録: KPI 1 (日次) / KPI 2 (月次) / KPI 4 (月次) / KPI 5 (週次)
  5. 照合バッチの実装: KPI 2 (月次 · deletion_events × Audit Logs) + KPI 5 (週次サンプリング · DB ⟷ GCS bit 一致)
  6. 本ページ Week 1 更新: dogfood 1 週間後に本節を Week 1 として実測値へ置き換え

関連 SSoT

  • ADR-0208 (保存年限管理と期限後廃棄): docs/adr/0208-determine-record-retention-and-disposal.md (§9 Confirmation が本 SQL 骨格の SSoT)
  • ADR-0203 (receipts と audit_log の schema 基礎): 保存年限 4 列の土台 · 撤退条件 6 が KPI 5 と連動発火
  • ADR-0218 (legal_holds schema と保全解除運用): KPI 3 の統合観測先 (docs/_internal/06_ops/adr-0218-observation-log.md KPI 1/2)
  • ADR-0217 (fiscal-year-close schema amend) + ADR-0215 (確定申告完了イベント連携): KPI 6 の統合観測先 (docs/_internal/06_ops/adr-0217-observation-log.md KPI 2 = adr-0215-observation-log.md KPI 3)
  • ADR-0126 (法的保存記録の正本配置): 証憑本体 = GCS · 台帳 = Cloud SQL の前提
  • RQ-091 synthesis: docs/research/rq-091-retention-manager-synthesis.md (保存年限管理の実装戦略 · 直接素材)
  • 観測手順 pattern の先例: docs/_internal/06_ops/adr-0215-observation-log.md (Week 0 先出し pattern · vlt session 21)