デプロイ記録で負債の利息を測り返すときを決める
目標
デプロイ・作業記録から、DORA指標とモジュール別の利息(計画外の作業時間)を計算し、リファクタリング候補の回収期間・純節減・遅延コストで、「今返すか」を、ルールどおりに決定します。
なぜ重要なのか
技術的負債を返すか、機能を出すかは、たいてい声で決まります。利息と元本、先送りされる機能の価値を、同じ単位で並べれば、その論争が計算になります。測っていない利息は、ないもののように見えて、ある日、チーム全体の時間を食います。
用意するもの
/opt/fixtures/founder/debt/deploys.csv:deploy_id,service,committed_at,deployed_at,failed,recovered_at,unplanned(時刻はUTC、12週間)/opt/fixtures/founder/debt/worklog.csv:week,module,planned_hours,unplanned_hours(1–12週)/opt/fixtures/founder/debt/options.json:team_hours_per_week, hourly_cost_krw, horizon_weeks, refactor{모듈: {cost_hours, interest_reduction}}, feature{name, value_per_week_krw}(プレースホルダーはモジュール名です)
定義(名前はdora.devに従います)
- デプロイ頻度 = サービスのデプロイ数 ÷ 12。変更のリードタイム = deployed_at − committed_at(時間)。変更失敗率 = failed=1 ÷ 全体。失敗したデプロイの復旧時間 = failed=1のデプロイのrecovered_at − deployed_at(時間)の中央値。デプロイの手戻り率 = unplanned=1 ÷ 全体。
- 利息 = モジュールのunplanned_hours。
mean(12週間の平均)、first4(1–4週の平均)、last4(9–12週の平均)。 - 節減 = last4 × interest_reduction。回収期間 = cost_hours ÷ 節減。期間の純節減 = (節減 × horizon_weeks − cost_hours) × hourly_cost_krw。遅延コスト = cost_hours ÷ team_hours_per_week × value_per_week_krw。
- 決定: 回収期間が最も短い候補の純節減 > 遅延コストなら、そのモジュール名、そうでなければ
"feature_first"。 - 丸め: 時間・週は小数第2位、比率は第4位、ウォンは整数。
ステップ
/root/founder/debt/dora.pyに、frequency(fix, service)(週あたりのデプロイ数、実数)を作る。dora.pyに、lead_time(fix, service)→{"median_h": x, "mean_h": y}を加える。dora.pyに、change_fail_rate(fix, service)を加える。dora.pyに、recovery_median(fix, service)(時間)を加える。/root/founder/debt/dora.jsonに、サービスごとに、frequency_per_week, lead_time_median_h, lead_time_mean_h, change_fail_rate, recovery_median_h, rework_rateを書く。/root/founder/debt/interest.jsonに、モジュールごとに、mean, first4, last4, rising(last4 > first4)を書く。/root/founder/debt/plan.jsonに、リファクタリング候補ごとに、saved_per_week, payback_weeks, net_saved_krw, delay_cost_krwを書く。/root/founder/debt/decision.jsonに、decision(定義のルール)、worst_service(変更失敗率が最も高いサービス)、fastest_payback(回収期間が最も短い候補)を書く。
参考
statistics.median、statistics.mean、datetime.strptime(s, "%Y-%m-%dT%H:%M:%SZ")- よくある間違い: リードタイムを平均だけで見ること、変更失敗率の分母を障害数や日数にすること、復旧時間を平均で出すこと、増えている利息を12週間の平均で判断すること、遅延コストを抜かすことです。
デプロイ頻度
/root/founder/debt/dora.pyに、frequency(fix, service)を作る。そのサービスのデプロイ数 ÷ 12。
deploys.csvをサービスで絞った行数を、12週間で割ります。
変更のリードタイム: 中央値と平均
dora.pyに、lead_time(fix, service) → {median_h, mean_h}を加える。
各デプロイの(deployed_at − committed_at)を時間に変えてリストを作り、statisticsのmedian・meanを使います。
変更失敗率: 分母はデプロイ
dora.pyに、change_fail_rate(fix, service)を加える。
デプロイの直後に、すぐ介入が必要だったデプロイ(failed=1)の数を、そのサービスの全デプロイ数で割ります。
失敗したデプロイの復旧時間
dora.pyに、recovery_median(fix, service)を加える(失敗したデプロイだけ、時間、中央値)。
failed=1のデプロイの、(recovered_at − deployed_at)の中央値です。失敗がなければNoneです。
サービス別のDORA 1枚
/root/founder/debt/dora.jsonに、サービスごとに、frequency_per_week・lead_time_median_h・lead_time_mean_h・change_fail_rate・recovery_median_h・rework_rateを書く。
デプロイの手戻り率 = unplanned=1 ÷ 全デプロイです。時間は小数第2位、比率は第4位です。
モジュール別の利息とトレンド
/root/founder/debt/interest.jsonに、モジュールごとに、mean・first4・last4・risingを書く。
weekの順に並べ替えてから、最初の4週と最後の4週の平均を、別々に出します。
回収期間・純節減・遅延コスト
/root/founder/debt/plan.jsonに、リファクタリング候補ごとに、saved_per_week・payback_weeks・net_saved_krw・delay_cost_krwを書く。
節減は、最近の利息(last4) × interest_reductionです。遅延コストは、リファクタリングがチームの時間を使う週数 × 機能の週あたりの価値です。
ルールどおりに決定する
/root/founder/debt/decision.jsonに、decision・worst_service・fastest_paybackを書く。
回収期間が最も短い候補だけを見て、その純節減が遅延コストより大きければ、そのモジュール名、そうでなければfeature_firstです。