• Status: Accepted (PR #652 merge = 受理の規約により 2026-05-13 受理。2026-06-11 の Status×Impl 整合調査で遡及反映・代表取締役指示)
  • Mode: Standard
  • Kruchten Type: Existence
  • Scope: product
  • Implementation Status: Done (PR #656、RUNTIME_METRICS + Utils.measureRuntime)
  • 起案者: [email protected]
  • 起案日時 (JST): 2026-05-13 01:27
  • 承認日時 (JST): 2026-05-13 01:33
  • Deciders: [email protected] (単独)

Kruchten Type は ADR-0031 (2026-05-13) で遡及追加。分類根拠は ADR-0031 §決定セクションおよび docs/adr/README.md の Kruchten 3 分類ガイドを参照。 Status / Mode / Scope は 2026-06-11 に遡及追加 (ADR-0031 corrigendum パターン)。出典: Status = 旧形式「## ステータス」節の機械転記 / Mode = 旧 README §既存 ADR 一覧の推定値 (git 履歴) / Scope = ADR-0049 4 層分類の遡及付与 (PR レビューで確定)。

コンテキスト

1.1 背景 (Background)

ADR-0021 (Walking Skeleton 段階展開) の Gate 3 で、懸念点 D3「6 分超スライスの早期検知」が積み残されていた。2026-10 入社の Jr エンジニアが UC スライスを切る際の粒度判断の客観的根拠が必要なため、入社前に対応する必要がある。

1.2 現状 (Current State / As-Is)

GAS の 1 関数 6 分 (360 秒) 実行制限は Walking Skeleton 設計の最大制約だが、現状はテスト実行後に Apps Script 実行ログを手動確認するしかなく、slice_id 別の実行時間が蓄積・可視化されていない。

1.3 課題 (Problem)

スライスの粒度判断が属人化しており、6 分制限を超過してから気付くケースが発生し得る。Jr 入社後は「このスライスは大丈夫か」を判断する客観的根拠が無いと、属人化リスクが拡大する。ADR-0021 の Gate 3 D3 として明示済の問題。

1.4 制約・要件 (Constraints & Requirements)

判断基準として以下を満たすこと:

  • 観測可能性: slice_id 別の実行時間が _RUNTIME_METRICS で可視化され、月次レビューで確認できる
  • 既存 API 非破壊: Utils.auditLog / Env._getProps 等のシグネチャを変更しない
  • GAS 制限準拠: _RUNTIME_METRICS シートへの書込が LockService でシリアライズされる
  • コスト: MailApp は Workspace 無料枠内、_RUNTIME_METRICS は既存スプレッドシート内で追加費用なし

1.5 目標 (Goals / To-Be)

GAS 6 分制限への接近を slice_id 別に事前検知できる状態を達成し、粒度判断に客観的根拠を提供する。Non-Goals: Cloud Logging への移行、prod 環境への GCP 課金プロジェクト適用、リアルタイム可視化ダッシュボード (Looker Studio 等)。

過去決定との整合性 (補足)

  • ADR-0021: 本 ADR はその実装詳細として位置づける (子 ADR)。Supersede ではない
  • ADR-0013 (Env モジュール経由の環境値取得) 準拠: ADMIN_EMAILEnv.getAdminEmail_() 経由で取得。Conflict なし
  • ADR-0011 (ヘッダー名ベース列参照) 準拠: _RUNTIME_METRICS の列参照は buildHeaderIndex_ を使用。Conflict なし
  • Supersedes: なし / Conflicts: なし / References: ADR-0021, ADR-0013, ADR-0011

決定

GAS 6 分制限の早期検知のため、(1) setupAllSchemasDDL に新規シート _RUNTIME_METRICS(列: 日時 / 関数名 / slice_id / 実行時間秒 / 環境(dev/prod) / 備考)を追加し、(2) 000_infra/004_utils.jsUtils.measureRuntime_(funcName, sliceId, fn) を新設して LockService シリアライズ書込・300 秒超 WARN ログ・360 秒超 ADMIN_EMAIL 通知を実装し、(3) 901_test_runner.js の新規テスト関数(test_{slice_id}_{condition}_())を本関数でラップする。ADMIN_EMAIL は ADR-0013 準拠で Env.getAdminEmail_() 経由とし、MailApp 失敗は try/catch でテスト継続を保証する。

検討した代替案 (Alternatives Considered)

  • 案 A: 何もしない(現状維持) — 手動で Stackdriver / Apps Script 実行ログを都度確認する。不採用理由: slice_id 別の集計ができず、6 分制限への接近を事前検知できない。Jr 入社後の属人化リスクが高い。
  • 案 B: Google Cloud Logging(Stackdriver)活用console.log() の出力を Cloud Logging に集約し、ログベースのメトリクスで可視化。不採用理由: Cloud Logging 有効化は GCP 課金 dev プロジェクト限定(prod は無課金・ADR 記録あり)。Sheets ダッシュボードと分離するため Jr が参照しにくい。セットアップコストも高い。
  • 案 C: Properties Service バッファリング方式 — 実行時間を ScriptProperties に一時保存し、日次 Trigger でまとめて _RUNTIME_METRICS に書き込む。不採用理由: リアルタイム性がなく、6 分超過を即時検知できない。Properties の 9KB/値制限に抵触するリスクがある。採用案の LockService シリアライズで競合問題は解決できる。

影響 (Consequences)

5.1 正の影響 (Good)

  • slice_id 別実行時間が _RUNTIME_METRICS に蓄積され、6 分制限への接近を事前検知可能
  • 300 秒超で 99_error_log に WARN、360 秒超で ADMIN_EMAIL 通知により即時アラート
  • Jr 入社後の粒度判断に客観的根拠を提供(属人化リスク低減)
  • ADR-0021 Gate 3 懸念点 D3 を解消

5.2 負の影響 (Bad)

  • 実装工数: DDL 定義 0.5h + Utils.measureRuntime_ 2h + ラップ適用 0.5h + テスト 1h = 合計約 4 時間
  • 新規テスト関数を追加するたびにラップを書く必要があり、規約逸脱リスクが残る
  • _RUNTIME_METRICS は 1 行/計測。1 年最大 500 行(月 40 実行 × 12)で Sheets 上限に対して無視できる程度の増加

5.3 中立・トレードオフ (Neutral / Trade-offs)

  • MailApp レート制限: Workspace アカウントで 1,500 通/日。月次テスト 20〜30 回運用では制限に抵触しない。制限到達時は sendEmail が例外をスロー → try/catch で console.error に降格し、テストは継続(追加費用なし)
  • OAuth スコープ: MailApp は 800_ops/ で利用実績あり、LockService は 400_domain/ で利用実績あり。追加スコープ・manifest 変更不要。権限確認手順: dev 環境 push 後、GAS エディタの「サービス」タブで OAuth スコープに変更がないことを目視確認してから prod push する
  • 規約逸脱の蓄積: Utils.measureRuntime_ を使わずスライスを追加するとカバレッジが低下する

撤退条件 (Rollback Plan)

完了条件(実装直後):

  • setupAllSchemas 実行後に _RUNTIME_METRICS シートが dev スプレッドシートに作成される
  • test_UC4_S01_normal_()Utils.measureRuntime_ でラップして実行し、_RUNTIME_METRICS に duration 行が記録される
  • 300 秒超のスリープを含むテスト関数を実行し、99_error_log に WARN レコードが追記される
  • 360 秒超のケースで ADMIN_EMAIL に通知メールが届く

Review After: 3 ヶ月後

  • Utils.measureRuntime_ カバレッジが新規スライスの 80% 以上 であることを確認。未達なら CLAUDE.md の「変更時テスト」表に必須ラップとして明記する

撤退・縮退条件:

  • _RUNTIME_METRICS への書込が LockService タイムアウト(10 秒)を常時超過する場合 → Properties 経由バッファリングの別 ADR を起案
  • MailApp が月次レート制限に抵触する場合 → 通知方式を GAS Apps Script API エラーログのみに縮退

Confirmation (準拠確認 / Fitness Function)

本セクションは ADR-0036 (Accepted 2026-05-14) で遡及追加された。ADR-0031 パターン (業界標準準拠メタデータ後付け = 誤字修正範疇) に準拠する遡及で本文の意思決定内容は不変。

  • 検証手段: RUNTIME_METRICS シート + Utils.measureRuntime 監視
  • 実行頻度: Nightly
  • 違反時の対応: Slack 通知

参照 (References)

  • 関連 ADR: ADR-0021(親: Walking Skeleton 段階展開 / Gate 3 D3), ADR-0013(Env モジュール経由の環境値取得), ADR-0011(ヘッダー名ベース列参照)
  • 関連 PR/Issue: -(要追記)
  • 外部資料:
    • 影響ファイル: 100_config/101_sys_config.jssetupAllSchemas への DDL 追加), 000_infra/004_utils.js(L539 付近、auditLog 近傍に Utils.measureRuntime_ 追加), 900_test/901_test_runner.js(新規テスト関数のラップ)
    • 関連: CLAUDE.md L58(LockService 書込シリアライズ規約)