active: true
derived: false
groups:
- LIFE
header: |
  LifecyclePolicy 実装
level: 2.16
links:
- SPEC016: pYeLx2dK7QDT3MJlNEPOt2oJ-OaOO1TiNw_YrV9_-Fg=
normative: true
ref: ''
references:
- path: src/beautyspot/lifecycle.py
  type: file
reviewed: AuzpsCTjPI2crw-p_NHaQ_VoXk9UCDReL_qVV6UlEVw=
text: |
  ## 実装概要

  `LifecyclePolicy` クラスは `Rule` オブジェクトのリストを保持し、
  関数名に基づいてキャッシュの保持期間を決定する。
  `resolve()` メソッドが `fnmatch.fnmatch()` を使って関数名をパターンと照合し、
  最初にマッチしたルールの保持期間を返す。

  ## 設計判断

  ### First-Match セマンティクス

  ルールのリストは順序が意味を持ち、最初にマッチしたものが採用される。
  これにより、特定プレフィックスの関数には短い保持期間を設定し、
  最後に `*`（ワイルドカード）でデフォルトポリシーを設定するような
  フォールバック構造が簡単に記述できる。

  ### resolve_with_fallback の導入

  後方互換性と柔軟性のため、まず `func_identifier` (モジュール名付きの完全修飾名) で
  マッチングを試み、マッチしなかった場合は `func_name` (短い関数名) で再度マッチングを
  試みる `resolve_with_fallback()` を提供している。

  ### default_retention の導入

  `LifecyclePolicy` コンストラクタに `default_retention` パラメータを追加。
  どのルールにもマッチしない場合に返す保持期間を指定できる。
  `LifecyclePolicy.default()` は `default_retention="30d"` で生成し、
  デフォルトで30日の保持期間を設定する。

  ## 実装メモ

  - `LifecyclePolicy.default()` は空のルールリスト + `default_retention="30d"` を持つ
  - `default_retention=None` を指定すれば従来通り無期限保持となる
