1. Executive Summary

  • 文脈: 帳票 SaaS の Retention Manager (= vlt の保存期限が経過した受領書を廃棄するモジュール · ADR-0223) は receipt 論理削除と GCS オブジェクト削除を単一トランザクション内で並置し、複数のモジュールを統合したパイプラインでアトミシティを維持している。
  • 課題: GCS deleteObject は Postgres COMMIT に参加しない外部 I/O のため GCS 削除成功 → Postgres COMMIT 失敗時に「GCS オブジェクト消失 · receipt 行残存」の逆向き孤立が発生しうる (ADR-0225 の潜在リスク信頼性で指摘された課題を、エンドツーエンド検出で一時的に担保し、恒久解決は本 ADR で扱う)。
  • 対策: Phase 1 event-emitter 有効化 (ADR-0222 §3.3 仕様 + ADR-0223 §3.3 仕様 連動) と同時に GCS delete を Postgres COMMIT 後の at-least-once 補償ワーカーへ移送し、Postgres tx の atomicity を完全に切り離す。
  • 効果: 「GCS 削除成功 → Postgres COMMIT 失敗」経路の逆向き孤立 (現状 e2e 検出のみ · 手動介入 runbook 対応) を根本解消し、tx 境界を Postgres 内に閉じて sweep atomicity の設計負荷 (5 module 統合 pipeline の 4 case + 手動 runbook) を軽減する。
  • 代償: 補償ワーカー (= 新規モジュール) の新設に 5 人日 (ADR-0225 §5.4 記載) + at-least-once セマンティクス (= 少なくとも 1 回実行) 受容 (GCS delete 重複実行の冪等性を GCS 側で担保) + Phase 1 移送タイミングの 1 PR 追加。

2. 何を解決するか

2.1 直面していること

適合性:

  • ADR-0225 §2.3 潜在リスク信頼性で「GCS 削除成功 → Postgres COMMIT 失敗」経路の逆向き孤立が発生しうる旨を明記済み · §Confirmation KPI 3 で e2e 検出 case を新規追加した (発生確率不明 · 実害未発生)。
  • ADR-0175 (3 号真実性ルート 4 要素) §Confirmation では audit_log 完全性 100% を要求するが、逆向き孤立発生時は receipt 行残存 + GCS 消失で削除経路の audit 記録と物理状態が乖離するリスクが残る。

信頼性:

  • ADR-0225 §11 実装配線で GCS 削除失敗方向の手動介入 runbook を明記予定 · Phase 0 期間中は手動対応で足りるが Phase 1 商用化後は運用工数のスケーラビリティが問題となる。

2.2 放置すると起こること

適合性:

  • Phase 1 商用化 (= 2027 一般提供目標 · ADR-0206 (JIIMA の 2 つのスキームに並行して申請する)) 後にテナント数増加で GCS 削除 tx の実行回数が線形増加し、逆向き孤立の発生件数を実測した値が観測可能な水準 (月 1 件以上) に到達すると JIIMA 認証審査 (ADR-0206) の「削除経路の完全性」設問で説明不能となる。
  • 逆向き孤立の手動介入 runbook が Phase 1 で必要頻度が上昇し (Phase 0 = ゼロ想定 · Phase 1 = 月 1-3 件想定 · 実測値は本 ADR §Confirmation で追跡)、代表取締役 1 人法人体制での対応工数を圧迫する。

信頼性:

  • Phase 1 event-emitter 有効化 (VLT_AUDIT_LOG_ENABLED=true) 後に sweep atomicity 設計を継続すると、audit_log INSERT 経路が sweep 内から event-emitter 外部に移送されたにもかかわらず GCS delete のみ sweep 内に残存し、tx 境界の一貫性 (audit と GCS が同 tx 内) が崩れる。

2.3 潜在リスク (実害未発生 · 発生確率不明)

信頼性:

  • 補償ワーカー (= 新規モジュール) が Postgres COMMIT 後に GCS delete を実行するため、補償ワーカーが GCS delete 前に crash した場合、Cloud Scheduler retry で再開されるまでの遅延 (= 最大 15 分 · Cloud Scheduler default 間隔) の間 GCS オブジェクト残存となる · at-least-once セマンティクス下で GCS delete 実行数 > receipt 論理削除数 の乖離が短期発生する可能性。
  • Phase 1 移送タイミング (VLT_AUDIT_LOG_ENABLED=true 切替) と本 ADR 実装 PR の順序が逆転すると、event-emitter 有効化と GCS delete 移送が別 PR に分離される期間 (デプロイ間 buffer) に tx 境界の一貫性が崩れる · 順序制約は本 ADR §11 実装配線で明記する必要がある。
  • sweep tx が INSERT 後・COMMIT 前にプロセス crash / タイムアウトで ROLLBACK した場合、vlt_pending_gcs_delete 表への INSERT も同時に ROLLBACK され pending 行が残らず GCS delete が永遠に実行されない (=「静かな失敗」経路 · GCS オブジェクト残存 · receipt 行残存) · pending 行が存在しないため §9 KPI 1 の SELECT では検知不能 · §9 KPI 5 (孤立 receipt_id 監視) で別経路検知する。
  • GCS Object Retention Lock (= 削除保護) と receipts.retention_expires_at の時刻比較で許容誤差・タイムゾーン誤りが発生した場合、Retention Lock 有効期間中の削除リクエストが 403 で返り補償ワーカーが retry 対象外行を蓄積し続ける · 手動介入 SLA が未定義だと dead letter 化が常態化する。
  • vlt_pending_gcs_delete 表への INSERT を sweep tx 内に追加したため、テナント数増加で並列 sweep 実行時に同一テーブル集中 INSERT による HOT 更新阻害 · page bloat · 行ロック競合が発生し、sweep 全体の tx commit latency が上昇して receipt 論理削除そのものがタイムアウトする経路が生じうる。
  • GCS 側の恒常的障害 (IAM ポリシーの変更、バケットの削除、課金停止といった障害) で全件 retry 失敗が継続した場合、retry_count 上限到達行の dead letter 隔離フローがないと vlt_pending_gcs_delete 表が無制限膨張し Postgres ストレージ · sequential scan コストを圧迫する。

3. 採用したい方針

3.1 対策方針

Phase 1 event-emitter 有効化 (ADR-0222 · ADR-0223 §3.3 仕様 連動) と同時に、GCS deleteObject を Postgres COMMIT 後の at-least-once 補償ワーカー vlt/src/retention-manager/gcs-delete-compensation.ts (= 新規モジュール · Postgres COMMIT 後の非同期 GCS delete 実行本体) へ移送する。sweep atomicity は Postgres tx 内 (receipt の論理削除、監査ログの挿入経路、イベントエミッター) に閉じ、GCS delete は独立 Cloud Run Job で Cloud Scheduler 起動 (毎 15 分) する事後補償経路とする。GCS delete 重複実行の冪等性は GCS 側 (削除済みオブジェクトへの DELETE = 404 no-op 扱い) で担保する。

  • 適合性: ADR-0175 4 要素 #3 append-only の完全性は event-emitter 経路 (audit_log INSERT) で担保 · GCS delete 失敗時も receipt 行の論理削除フラグと audit_log INSERT は既に確定済みで、削除経路の audit 記録は物理状態に先行して確定する。
  • 信頼性: Postgres tx atomicity は Postgres 内に閉じ、GCS delete は補償ワーカーの at-least-once retry で eventual に一致する · 補償ワーカーが失敗を継続 (24 時間) すると Cloud Monitoring alert で代表取締役に通知。
  • 効率性: sweep atomicity 5 module 統合 pipeline の 4 case 中 2 case (GCS 削除の失敗、GCS 削除の成功後の Postgres コミット失敗) が sweep 側検証範囲から除外され、補償ワーカー側 unit test に移送されるため統合 pipeline test の複雑性が軽減される。

3.2 守るべき設計制約

  • 適合性: 本 ADR 実装 PR は VLT_AUDIT_LOG_ENABLED=true 切替 (ADR-0223 §3.3 · event-emitter 有効化) と同一 PR で必ず同梱する (別 PR 分離時は audit_log 経路と GCS delete 経路の tx 境界が不整合になる期間が生じるため · ADR-0225 §8 撤退条件 (1) 準拠)。
  • 信頼性: 補償ワーカーの retry 上限 (= 試行 96 回 = 24 時間) と Cloud Monitoring のアラートが発火する閾値を Terraform で管理し、手動介入不要の完全自動化を維持する。
  • 信頼性: GCS delete の冪等性は GCS 側の 404 no-op 挙動に依存 · Object Retention Lock (= 削除保護) 有効期間中の削除リクエストは補償ワーカー側で retention_expires_at 未到達エラーとして分離し、retry 対象外 (= 手動介入対象) とする · 手動介入 SLA は §3.3 仕様と ops runbook (docs/_internal/06_ops/gcs-delete-compensation-runbook.md 新設予定) で明記する。
  • 信頼性: 補償ワーカーのランタイムは Cloud Run Job のみとし、GAS (= Google Apps Script · 最大実行 6 分 · 同時 30 · Properties Store 500KB 制限) 実行環境との混在を禁止する · ADR-0221 outbox-relay の Cloud Run Job 稼働実績 (vlt/terraform/modules/vlt-cloud-run-job state) を PR link で明示引用し、補償ワーカーが同 pattern を再利用することを実装 PR で証跡化する。
  • 効率性: 補償ワーカーは既存 outbox-relay (ADR-0221 · Cloud Run Job + Cloud Scheduler pattern) と同じインフラ pattern を再利用し、Terraform module を共通化する · インフラ設計工数を抑制する。

3.3 仕様

  • 信頼性: vlt/src/retention-manager/gcs-delete-compensation.ts (= 新規モジュール) を実装 · retention_manager から発行されたイベント (vlt_pending_gcs_delete 表 · 新規テーブル · 3 列 = receipt_id · gcs_object_path · created_at) を polling し GCS deleteObject を実行する · Postgres COMMIT 後の同 tx で vlt_pending_gcs_delete 表への INSERT が完了しているため、event-emitter 経路と同じ tx 内に GCS delete pending 状態が確定する。
  • 信頼性: vlt_pending_gcs_delete 表は追記専用ではなく DELETE 可能 (= 補償ワーカーが GCS delete 成功後に該当行を DELETE) · UPDATE は禁止 (retry 回数のみ別列で追記) · この表は audit_log ではなく作業キューであり、ADR-0175 4 要素 #3 append-only 要件の対象外。
  • 信頼性: retry_count が上限 96 に到達した行は自動的に vlt_pending_gcs_delete_dead_letter 表 (= 新規テーブル · 隔離キュー) へ移送し、vlt_pending_gcs_delete の膨張を防ぐ · dead_letter 行数が閾値 (= 累積 100 件 or 24 時間で新規 10 件) を超えた時点で Cloud Monitoring alert を発火し、ops runbook (docs/_internal/06_ops/gcs-delete-compensation-runbook.md) に対応 SLA (= 発火から 2 営業日以内) · 担当者 (= 代表取締役) · エスカレーション先 (= GCS API サポート) を明記する。
  • 信頼性: Object Retention Lock と retention_expires_at の時刻比較は UTC 統一 · 許容誤差は Retention Lock 解除後 60 秒以上経過してから補償ワーカーが削除リクエストを発行する · タイムゾーン誤り検知のため実装 PR に UTC 明示 assertion を追加する。
  • 効率性: Cloud Run Job は既存 outbox-relay と同じ Terraform module (terraform/modules/vlt-cloud-run-job) を再利用 · Cloud Scheduler の起動間隔は 15 分 (= outbox-relay と同 default) で開始し、Phase 1 中に実測 latency を観測して調整する。
  • 柔軟性: Phase 2 (= 商用化後 6 ヶ月) で外部 message broker (Pub/Sub · Cloud Tasks) への移送を再評価する余地を残す · 移送時は vlt_pending_gcs_delete 表 polling を廃止し subscriber へ書き換える · 移行期間中は dual-write (= 表 INSERT + broker publish 併存) 方式で互換性を維持し、subscriber 稼働確認後に表 INSERT を段階廃止する。

4. 判断基準

4.1 評価軸 (4 個選定)

#軸 (Q42)日本語軸名重要度 (係数)案件特有の解釈
1#reliable信頼性Must (×2.0)Postgres tx atomicity 内に閉じ · 逆向き孤立を根本解消 · at-least-once セマンティクスで eventual consistency 担保 · K.O.: 補償ワーカー retry で eventual に一致できない案は不採用
2#suitable適合性Must (×2.0)ADR-0175 4 要素 #3 append-only 完全性 (= audit_log 経路) を維持しつつ GCS 側の物理状態と分離 · K.O.: audit 経路と GCS 経路の tx 境界不整合を生む案は不採用
3#efficient効率性High (×1.0)補償ワーカー新設 5 人日 vs sweep atomicity 5 module pipeline の複雑性軽減効果 · Cloud Run Job インフラ再利用 · sweep test case 削減
4#flexible柔軟性Medium (×0.5)Phase 2 (= 商用化後 6 ヶ月) で外部 message broker への移送余地 · Cloud Scheduler polling は initial 実装

K.O. criterion: Must 軸 score < 3 は不採用。

4.2 評価軸 × 案スコア表

係数案 1: 補償ワーカー移送案 2: sweep tx 内継続案 3: 分散 tx (2PC)
信頼性×2.0534
適合性×2.0534
効率性×1.0432
柔軟性×0.5432
加重和 (正規化)0.9090.5910.591
K.O. 通過 (Must ≥3)

5. 検討した代替案

5.1 案 1 (採用): 補償ワーカー移送 (at-least-once)

採用案。詳細は §3.1 対策方針 参照。

  • 信頼性: Postgres COMMIT 後の補償ワーカー retry で GCS delete を eventual に一致 (score 5)。
  • 適合性: audit_log 完全性 (event-emitter 経路) を維持しつつ GCS 物理状態と分離 (score 5)。
  • 効率性: sweep test case 削減 + Cloud Run Job インフラ再利用 · 補償ワーカー新設 5 人日で恒久解決 (score 4)。
  • 柔軟性: Phase 2 で外部 message broker 移送の余地 (score 4)。

5.2 案 2 (不採用): sweep tx 内継続 (現状継承)

  • 信頼性: GCS 削除成功 → Postgres COMMIT 失敗の逆向き孤立が発生確率不明のまま Phase 1 商用化後に線形増加する · 手動介入 runbook 対応で運用工数を圧迫 (score 3)。
  • 適合性: audit_log 完全性は event-emitter 経路で担保できるが GCS 側の物理状態と audit の一貫性が保てない (score 3)。
  • 効率性: sweep 5 module 統合 pipeline の 4 case を継続維持 · 補償ワーカー新設工数 0 (score 3)。
  • 柔軟性: Phase 2 の外部 broker 移送を再評価する際に sweep tx 内 GCS delete を先に外す作業が必要 · 移送コスト増 (score 3)。

5.3 案 3 (不採用): 分散トランザクション (2PC) 導入

  • 信頼性: XA プロトコル or Saga pattern で GCS delete と Postgres COMMIT を 2 phase commit する · GCS API が XA 未対応のため Saga pattern (= 補償トランザクション) 経由となり案 1 と同等の compensation 経路が必要 (score 4)。
  • 適合性: 2PC coordinator が failure すると partial commit 状態から手動復旧が必要 · audit 経路と GCS 経路の tx 境界不整合を完全解消できない (score 4)。
  • 効率性: Saga pattern の compensation ロジック実装工数 (= 推定 8 人日) が案 1 (5 人日) より大きい · インフラ再利用不可 (score 2)。
  • 柔軟性: Saga pattern を捨てる場合は case-by-case の compensation を書き直す必要 · 移送コスト増 (score 2)。

6. 影響

6.1 正の影響

  • 信頼性: 「GCS 削除成功 → Postgres COMMIT 失敗」経路の逆向き孤立発生を Phase 1 商用化後に月 0 件 (= 補償ワーカー retry で eventual に一致) を目標値とする · ADR-0225 §Confirmation KPI 3 の e2e 検出 case は継続維持しつつ、手動介入 runbook 発火頻度を月 0 件へ削減。
  • 適合性: audit_log 完全性 (= event-emitter 経路の 100% INSERT 成功) は Phase 0 期間中の実測値を継承 · GCS 側の物理状態と audit_log の一貫性が eventual consistency 内で担保される。
  • 効率性: sweep のアトミシティを保証する 5 つのモジュールを統合したパイプラインのテストの 4 case 中 2 case (GCS 削除失敗 · GCS 削除成功 → Postgres COMMIT 失敗) を補償ワーカー側 unit test へ移送 · 統合 pipeline 複雑性 50% 軽減目標。

6.2 負の影響 / リスク

  • 信頼性: GCS オブジェクト残存期間 (= receipt 論理削除完了時から補償ワーカー retry まで) が最大 15 分間存在 · 電帳法上「削除実行」は Postgres 論理削除 (= receipts.deleted_at 設定) で成立するため法的リスクはない前提だが、JIIMA 認証審査 (ADR-0206) の運用指針 (2024 年改訂版) では審査員解釈にばらつきがあるため、論理削除時点を削除実行とみなす解釈の文書確認を JIIMA 事務局から取得し §10.3 に添付する。
  • 信頼性: sweep tx 内に vlt_pending_gcs_delete INSERT を追加したため、並列 sweep 実行時の行ロック競合 · HOT 更新阻害 · page bloat による commit latency 上昇リスクが残る · 実装 PR 前にテナント 100 件規模の同時 sweep 負荷試験を実施し INSERT latency P99 を計測する (§9 KPI 6)。
  • 効率性: 補償ワーカー Cloud Run Job の毎 15 分起動でランタイム月 ~[MASKED:AMOUNT] (= Cloud Run Job Free tier 超過分推定) が発生 · outbox-relay と同 pattern のため既存予算枠内で吸収可能。

7. コスト試算

7.1 前提条件

項目根拠
補償ワーカー実装工数5 人日ADR-0225 §5.4 記載値を継承 (module 新設 + Terraform + 3 test suite)
Cloud Run Job ランタイム月 ~[MASKED:AMOUNT]outbox-relay 実績 (毎 15 分起動 · 60 秒/回) と同 pattern
GCS deleteObject 冪等性404 no-opGCS API 仕様 (削除済みオブジェクトへの DELETE は 404 · not error)
補償ワーカー retry 上限96 回 = 24 時間15 分間隔 × 96 = 24 時間 (= 手動介入判断猶予)

7.2 月コスト試算

  • 実装工数 (一括): 5 人日 (= [MASKED:AMOUNT] 相当 · 1 人日 [MASKED:AMOUNT] 換算)。
  • 月ランタイム: ~[MASKED:AMOUNT] (= Cloud Run Job 起動 + GCS API call 課金) · Phase 1 商用化後のテナント数増加に応じて線形増加想定 (= 1 テナント +[MASKED:AMOUNT] / 月)。
  • 年次サブスクリプション: なし (= 既存インフラ再利用)。
  • 代替案 2 (sweep tx 内継続) 比較: 実装工数 0 だが手動介入 runbook 対応が月 1-3 件想定で年 ~[MASKED:AMOUNT] (= 1 件 [MASKED:AMOUNT] × 3 件 × 12 ヶ月) の運用工数コスト · 本案 1 の実装工数 (= [MASKED:AMOUNT]) は 1.4 年で回収。

8. 撤退条件

  1. 補償ワーカー retry 失敗率 > 5% (= 1 週間平均) 継続 4 週間: at-least-once セマンティクス破綻の兆候 · 案 2 (sweep tx 内継続) への切戻しを再評価する · Terraform で vars.enable_gcs_delete_compensation = false flag で切戻し可能状態を維持 · 切戻し時は VLT_AUDIT_LOG_ENABLED=true を維持したまま sweep tx 内 GCS delete へ戻すことは §3.2 tx 境界一貫性制約に反するため、event-emitter を同時に false へ戻す (= ADR-0225 §8 撤退条件 (1) と連動整合) · この順序制約を切戻し runbook で明記する。
  2. GCS オブジェクト残存期間 > 24 時間 の事案が月 3 件超え: 補償ワーカーの retry 上限を延長 or Cloud Scheduler 起動間隔を短縮 (= 15 分 → 5 分) する判断 · 追加 ADR で条件明記。
  3. 月コスト超過 [MASKED:AMOUNT]/月: テナント数増加に対する Cloud Run Job ランタイム線形増加が予算枠を超過 · 外部 message broker (Cloud Tasks) への移送を Phase 2 で前倒し評価する。
  4. 法令改定で GCS 物理削除の即時性要求が発生: 電帳法・個人情報保護法の改定で「論理削除と物理削除の間隔 ≤ N 分」要件が新設された場合、補償ワーカー retry 間隔を要件に合わせて短縮 · 補償ワーカー廃止を含む再設計判断。
  5. GCS オブジェクト残存期間 P99 > 60 分 (遅延 SLA · 月次観測): Cloud Scheduler 15 分 polling では追随できないテナント負荷に到達したと判断し、Phase 2 前倒しで Pub/Sub 移送を評価する · dual-write 移行期間を含む再設計。

9. Confirmation

  1. 補償ワーカー成功率 KPI: SELECT COUNT(*) FROM vlt_pending_gcs_delete WHERE created_at < NOW() - INTERVAL '1 hour' AND retry_count < 96 = 月次で 5% 未満 · 週次で BigQuery observation dashboard に集計 · 違反時は補償ワーカー log を drill-down し原因分析 (= GCS API 429 rate limit · IAM policy 変更 · GCS bucket 権限変更 の 3 分類)。
  2. GCS オブジェクト残存期間 KPI: SELECT PERCENTILE_CONT(NOW() - created_at, 0.99) FROM vlt_pending_gcs_delete_history = P99 で 24 時間未満 · 月次観測 · 違反時は §8 撤退条件 (2) 発火 · P99 60 分超過で §8 撤退条件 (5) 発火。
  3. audit_log 完全性 (event-emitter 経路 100%): ADR-0223 §Confirmation KPI 継承 · 本 ADR で追加検証 case なし · 但し補償ワーカー実装 PR 後の初回 Phase 1 dogfood で audit_log INSERT 数 = receipts.deleted_at 設定数 の一致確認を e2e test で追加。
  4. 月コスト観測: Cloud Run Job ランタイム + GCS API call 課金の月次実測値 · [MASKED:AMOUNT]/月 超過を §8 撤退条件 (3) 発火閾値とする · 実測観測は billing export table から抽出。
  5. 孤立 receipt_id 監視 (静かな失敗検知): SELECT receipt_id FROM receipts WHERE deleted_at IS NOT NULL AND NOT EXISTS (SELECT 1 FROM vlt_pending_gcs_delete WHERE receipt_id = receipts.id) AND NOT EXISTS (SELECT 1 FROM vlt_pending_gcs_delete_history WHERE receipt_id = receipts.id) = 日次で 0 件 · 1 件でも検出したら sweep tx ROLLBACK 経路の「静かな失敗」の兆候として調査 · Cloud Monitoring alert 即時発火。
  6. sweep tx commit latency KPI (負荷試験): 実装 PR 前にテナント 100 件規模の同時 sweep 負荷試験を実施し、vlt_pending_gcs_delete INSERT 追加後の sweep tx commit latency P99 を計測する · P99 < 3 秒 (= sweep tx タイムアウト閾値の 30%) を通過条件とし、超過時は FILLFACTOR 調整 · autovacuum 設定変更 · 表分割を検討する。
  7. dead_letter 隔離キュー観測: SELECT COUNT(*) FROM vlt_pending_gcs_delete_dead_letter = 累積 100 件 or 24 時間で新規 10 件を Cloud Monitoring alert 発火閾値とする · ops runbook (docs/_internal/06_ops/gcs-delete-compensation-runbook.md) 記載の対応 SLA 2 営業日以内で 100% 対応。

10. 参照

10.1 関連 ADR

  • Refines: ADR-0225 (sweep boundary に audit_log を同梱 · Standard) — 本 ADR は §5.4 案 4 (不採用) の恒久解決を扱う · §2.3 潜在リスク信頼性の GCS 削除失敗方向の逆向き孤立を根本解消。
  • ADR-0175 (真実性確保ルート確定 · Critical) — 4 要素 #3 append-only 完全性を event-emitter 経路で担保する前提の継承 · 併立。
  • ADR-0221 (outbox-relay 実装 · Standard) — Cloud Run Job + Cloud Scheduler pattern を本 ADR 補償ワーカーが再利用 · インフラ pattern 継承。
  • ADR-0222 (append-only 監査ログ物理担保 module 単位確定 · Standard) — event-emitter 有効化 (= VLT_AUDIT_LOG_ENABLED=true) の実装 SSoT · 本 ADR は同 flag 切替と同一 PR 同梱制約を継承。
  • ADR-0223 (Retention Manager 運用実装 · Standard) — sweep atomicity 5 module pipeline の実装 SSoT · 本 ADR で 2 case を補償ワーカー側 unit test へ移送。
  • ADR-0203 (schema 基礎 · retention 4 列 pattern) — vlt_pending_gcs_delete 表の 3 列設計 pattern を継承 · KPI-4 (Phase 0 中 schema 変更 ≤ 1 回) は Phase 1 移送タイミングのため対象外。
  • ADR-0206 (JIIMA 2 スキーム並行申請 · Critical) — 削除経路完全性設問の解釈確認先 · §6.2 で JIIMA 事務局からの文書確認取得を §10.3 に添付する制約。

10.2 関連 PR/Issue

  • PR #5475 (ADR-0225 受理 PR · shipping 段階) — 本 ADR §11 起案フロー配線で明示計上済。
  • PR #5480 (ADR-0226 outbox_dead_letter 表 · MERGED) — 同 Cloud Run Job pattern の直近実例 · インフラ再利用の参考。

10.3 外部資料

11. 実装配線

  • lint 配線: scripts/vlt-schema-lint.mjs に新規 rule 追加 (vlt_pending_gcs_delete 表の 3 列存在検証 + retry_count 列 UPDATE 権限 REVOKE 検証 + vlt_pending_gcs_delete_dead_letter 表存在検証 + audit_log 経路の event-emitter 側 INSERT 数 = receipts.deleted_at 設定数 の e2e assertion + Object Retention Lock 有効期間中の 403 を retry 対象外として正しく分離する assertion + 補償ワーカー test suite が outbox-relay test suite からのコピー流用でないこと (= GCS 固有 case 5 種の独立記述) を検証する rule) · .github/workflows/vlt-schema-lint.yml で run · PR 実装時に adr-lint doc consistency check で本 ADR の implementation_status flip を検証。
  • 起案フロー配線: 本 ADR 受理 PR merge 後、下記を同一 PR で同梱 — vlt/src/db/schema.sqlvlt_pending_gcs_delete 表 + vlt_pending_gcs_delete_history 表 (= 補償ワーカー成功後の archive · KPI 2 観測用) + vlt_pending_gcs_delete_dead_letter 表 (= retry 上限到達行の隔離キュー) 追加 · vlt/src/retention-manager/gcs-delete-compensation.ts (= 補償ワーカー本体 module) 新設 · vlt/src/retention-manager/lock-transaction-boundary.ts から GCS deleteObject 呼び出しを削除し vlt_pending_gcs_delete 表への INSERT に置換 · vlt/terraform/modules/vlt-cloud-run-job を再利用して補償ワーカー Cloud Run Job + Cloud Scheduler 定義追加 (Terraform state で outbox-relay の Cloud Run Job 稼働実績を PR link で明示引用) · vlt/tests/e2e/gcs-delete-compensation.test.ts 新設 (5 case = 補償ワーカー成功 / retry 上限到達 → dead_letter 移送 / 429 rate limit / IAM policy 変更 / bucket 権限変更 · 加えて Object Retention Lock 有効期間中の 403 分離 assertion) · ADR-0223 §11 実装配線から sweep-audit-atomicity.test.ts の 2 case を補償ワーカー側 unit test へ移送 · 実装 PR 前にテナント 100 件規模同時 sweep 負荷試験を実施し §9 KPI 6 の P99 計測結果を PR description に添付。
  • docs SSoT 同期: docs/architecture/arch_jtbd012_voucher_saas_draft.md の Retention Manager 節に補償ワーカー経路追記 · docs/_internal/06_ops/adr-0225-observation-log.md (= 別途新設予定) に KPI 1-7 月次観測ログを追加 · docs/_internal/06_ops/gcs-delete-compensation-runbook.md (= 新設) に dead_letter 対応 SLA 2 営業日 · 担当者 · エスカレーション先 (GCS API サポート) を明記 · .claude/rules/vlt.md (= vlt clone のドメイン規約 · 該当あればの前提) に補償ワーカー Terraform module 再利用 pattern + GAS 実行環境混在禁止を追記 · ADR-0225 §5.4 の refined_by list に本 ADR を追記 · ADR-0206 JIIMA 事務局への削除実行解釈文書確認依頼を issue tracker に起票し取得後 §10.3 に添付。