ADR-0226 週次観測ログ
ADR-0226 (outbox_dead_letter 表の schema と permanent event 物理 move 経路を確定 · 2026-07-08 受理) の Confirmation 4 KPI の観測結果を時系列で記録する。SQL 骨格は本ファイル各節 · SSoT は ADR-0226 §9 Confirmation。実 SQL の実行は Phase B (dead-letter-alerter 実装 + integration test 5-8 case · vlt session 49 Phase A shipping 後の別 PR) 完了後に開始する。
Week 0 (2026-07-09 · Phase A shipping · dead-letter-alerter 実装前 · 準備段階)
Phase A (schema.sql 追加 + vlt-schema-lint 4 rule 追加 + docs 3 種同期) の shipping 完了時点。dead-letter-alerter.ts 実装 (Phase B 予定) 未着手のため実測データなし。4 KPI の SQL 骨格 + SLO + 実施頻度 + 撤退条件連動を先出しで整理する。Phase B (dead-letter-alerter 実装 + integration test) merge 完了時点で本節を Week 1 として実測数値に置き換える。
KPI 1: outbox_dead_letter 表への物理 move 成功率 ≥ 99% (月次)
- SLO: 成功 / (成功 + move_failed) ≥ 99%
- 実施頻度: 月次 (BQ scheduled query · Cloud SQL export 経由で BigQuery mirror へ)
- 撤退条件連動: <99% で dead-letter-alerter 実装の tx 境界 review + move_failed 経路の手動介入手順 (ADR-0221 §3.3 L101 pattern) · ADR-0226 §8 撤退条件 1 と連動
BigQuery SQL 骨格 (Cloud SQL export の日次 mirror テーブル前提):
WITH
moved AS (
SELECT COUNT(*) AS moved_count
FROM `${project}.${dataset}.outbox_dead_letter`
WHERE classified_at > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
),
failed AS (
SELECT COUNT(*) AS failed_count
FROM `${project}.${dataset}.pubsub_outbox`
WHERE STARTS_WITH(CAST(published_at AS STRING), 'error:move_failed:')
AND created_at > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
)
SELECT
moved.moved_count,
failed.failed_count,
SAFE_DIVIDE(moved.moved_count, moved.moved_count + failed.failed_count) AS move_success_rate
FROM moved, failed;
-- 期待値: move_success_rate >= 0.99
KPI 2: alert 発火から代表取締役 drill-down までの中央値 ≤ 15 分 (月次)
- SLO: 中央値 ≤ 15 分
- 実施頻度: 月次
- 撤退条件連動: >15 分で alert 内容の情報密度改善 (event 概要を alert body に埋込 · ADR-0221 §3.3 L94 payload マスキングとの両立)
BigQuery SQL 骨格 (Cloud Monitoring incident notification + docs.bizlp.dev retrieve_evidence log 突合):
WITH
alerts AS (
SELECT incident_id, alert_fire_time
FROM `${project}.${dataset}.cloud_monitoring_incidents`
WHERE policy_name = 'outbox-dead-letter-permanent-move'
AND alert_fire_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
),
drill_downs AS (
SELECT incident_id, MIN(access_time) AS first_drill_down
FROM `${project}.${dataset}.docs_retrieve_evidence_access_log`
WHERE resource_pattern LIKE 'outbox_dead_letter%'
GROUP BY incident_id
)
SELECT
APPROX_QUANTILES(
TIMESTAMP_DIFF(d.first_drill_down, a.alert_fire_time, MINUTE), 100
)[OFFSET(50)] AS median_response_minutes
FROM alerts a
LEFT JOIN drill_downs d USING (incident_id);
-- 期待値: median_response_minutes <= 15
KPI 3: 追記専用性の DB REVOKE 検査 (週次)
- SLO: 常時 0 件 (vlt_app に UPDATE / DELETE 権限が付与されていないこと)
- 実施頻度: 週次 (vlt-schema-lint の schema-side rule
missing-outbox-dead-letter-app-user-revokeが CI で発火 · runtime side は本 KPI で監視) - 撤退条件連動: >0 件で即座に REVOKE 再実行 + 追記経路の監査 (audit_log 側 SoT で GRANT 変更履歴を照合) · ADR-0226 §8 撤退条件 2 と連動 (
role_table_grants定期照合)
Cloud SQL (Postgres) 側 SQL 骨格 (Cloud SQL Studio または export 経由で BQ mirror):
SELECT COUNT(*) AS bad_grant_count
FROM information_schema.role_table_grants
WHERE table_name = 'outbox_dead_letter'
AND grantee = 'vlt_app'
AND privilege_type IN ('UPDATE', 'DELETE');
-- 期待値: 0
KPI 4: retention_expires_at 到来行の sweep 完遂率 (月次)
- SLO: 常時 0 件 (Phase 0 は 7 年 retention なので 2033 以降まで自然到来なし · sweep 経路の smoke test は synthetic data で実施)
- 実施頻度: 月次
- 撤退条件連動: >0 件で Retention Manager sweep 経路の実装再検討 (P3-2 意思決定 = ADR-0225 flag flip と連動)
Cloud SQL SQL 骨格:
SELECT COUNT(*) AS expired_unswept_count
FROM outbox_dead_letter
WHERE retention_expires_at <= NOW();
-- 期待値: 0 (すべて sweep 済で物理削除)
変更履歴
- 2026-07-09: 新設 (Phase A shipping · Week 0 preseed pattern に従い 4 KPI 骨格 + SLO + 実施頻度 + 撤退条件連動を先出し · dead-letter-alerter 実装 = Phase B PR で Week 1 実測に置換予定)