Skip to content

Proposal: centralize release-age cooldown in CooldownPolicy on Settings #1178

@LalatenduMohanty

Description

@LalatenduMohanty

Summary

Proposal from @tiran to refactor release-age cooldown management around a single CooldownPolicy object owned by Settings, replacing today's split between WorkContext.cooldown, per-request resolve_package_cooldown(), and post-construction provider.cooldown mutation.

POC branch: https://github.com/tiran/fromager/tree/cooldown-policy
POC commit: tiran@aa7666d

Problem

Release-age cooldown (#877) works, but policy state and enforcement are scattered:

Layer Role today
WorkContext.cooldown Global Cooldown from --min-release-age
resolve_package_cooldown() Per-request effective cooldown (per-package override, top-level == bypass)
provider.cooldown Post-construction mutation at 3 call sites (#1081)
BaseProvider.is_blocked_by_cooldown() Per-candidate enforcement with provider-specific timestamp semantics

This makes cooldown hard to inspect, test in isolation, and easy to mis-wire (forgetting provider.cooldown = … silently disables enforcement).

Proposed architecture

Move cooldown configuration and filtering into one policy object on Settings:

CLI --min-release-age
        │
        ▼
Settings.cooldown (CooldownPolicy)
  ├── min_release_age          # global default
  ├── package_cooldowns        # pre-loaded from resolver_dist.min_release_age
  ├── cooldown_exempt_versions # from top-level == pins (see #1123)
  └── bootstrap_time           # fixed reference time for the run
        │
        ▼
filter_candidates(candidates)  # single enforcement point after find_candidates

CooldownPolicy responsibilities

  1. Configuration — hold global min_release_age, indexed per-package overrides, and version exemptions.
  2. Initializationset_package_cooldowns() pre-loads overrides from package settings once at startup (via Settings._reset()).
  3. Exemptionsadd_cooldown_exempt_versions() registers (name, version) pairs from exact == pins.
  4. Enforcementfilter_candidates() returns only candidates that satisfy the effective minimum age.

Integration points

  • --min-release-age passed to Settings.from_files() instead of constructing Cooldown on WorkContext.
  • Providers call ctx.settings.cooldown.filter_candidates() after find_candidates(), eliminating provider.cooldown mutation.
  • resolve_package_cooldown() and per-provider is_blocked_by_cooldown() logic retired once parity is verified.

Benefits

  • Single inspectable object — dump settings.cooldown to see global default, all overrides, and exemptions.
  • No post-construction mutation — addresses the fragility described in Avoid post-construction mutation of provider cooldown settings #1081 without adding provider wrapper indirection.
  • Pure filter functionfilter_candidates() is testable without network or resolvelib.
  • Co-located with resolver config — cooldown overrides already live in resolver_dist; policy belongs on Settings.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions