Skip to content

Report cached versions pending cooldown eligibility #338

Open

Description

@andrew

With a cooldown policy enabled, the proxy can contain cached artifacts for versions that are still inside the effective cooldown window. This can happen when a policy is enabled or increased after an artifact was cached. There is currently no way to list those versions or see when they become eligible.

Add a proxy cooldown pending report for distinct version PURLs with at least one cached artifact. A version is pending when its publication time is known and the current global, ecosystem, or package policy does not allow it yet.

Useful output would include:

  • version PURL
  • publication time
  • effective cooldown
  • eligibility time and remaining duration
  • cached artifact count and total size
  • whether direct artifact requests are currently blocked

Support JSON output so the report can feed monitoring and automation. Versions without a publication time should be reported separately as unknown and retain the cooldown library's permissive behavior.

The report depends on resolving several current gaps. Publication-time coverage and cross-registry enforcement can be separate linked issues:

  • Base the report on cached artifacts. A version counts as stored only when an artifact has both storage_path and fetched_at; one version can have several artifacts, while a version row alone does not show that its bytes are stored.
  • Persist publication times consistently. The normal artifact cache write creates or updates the version row without published_at. npm download checks and enrichment can fill it, but many cached versions have no timestamp. Registry metadata processing should save publication times where available, with a lookup or backfill path considered for existing rows.
  • Return the full cooldown evaluation result. Current handlers call IsAllowed, which discards the effective duration and eligibility time needed by the report. Done in Add cooldown package pattern overrides #407: cooldownpolicy.Policy.Evaluate now returns a cooldown.Decision with the effective duration and eligibility time.
  • Apply cooldown checks consistently to cached downloads (Cooldown is not applied to artifact downloads for Cargo, RubyGems, Hex, Conda, Pub and cached Helm charts #521). npm and PyPI (Cooldown hides the version from metadata but still serves the tarball #239), NuGet, and Composer (Withhold Composer archives still in cooldown #469) check at download time. Helm filters charts in cooldown when resolving the download URL; whether a cached chart is checked needs verifying. Cargo, Conda, RubyGems, Hex and Pub only filter metadata, so their cached artifacts can be downloaded directly. Tests should enter through each public artifact endpoint with an artifact cached before the policy changes.

This is the proxy counterpart to git-pkgs/git-pkgs#353, which reports pending registry releases for dependencies in a repository. The proxy report covers artifacts already held by the proxy.

The current behavior was checked against proxy main at 8d3dacf. To reproduce the reporting gap:

  1. Cache an artifact through the proxy.
  2. Configure a cooldown that places its version inside the waiting period.
  3. Run proxy stats or inspect the API and version page.
  4. The cached version is visible, but its pending state and eligibility time are absent.

Activity

  1. pinguinfuss commented on Oct 18, 2026

    @pinguinfuss
    Contributor

    Status

    • Full evaluation result: done (Add cooldown package pattern overrides #407).
    • Publication times: only npm stores them; the cache write and enrichment do not.
    • Download checks: missing for Cargo, RubyGems, Hex, Conda, Pub, and cached Helm charts (helm.go:101).
    • Report: not started.

    Cross-cutting

    • One policy key per ecosystem. Conda and Helm artifacts are stored under different PURLs than the cooldown checks use.
    • Routed npm/Composer packages store no time (no upstream in the PURL); report them as unknown.
    • Store published_at in UTC.

    PR 1 – download checks

    • Shared helper like npm's: DB time, else metadata lookup, then persist.
    • Check before the cache hit for the ecosystems above.
    • Test: cache artifact, raise policy, download → withheld.

    PR 2 – persist publication times

    • Cheap for Cargo, Pub, Helm (times already parsed).
    • Costs extra upstream requests elsewhere when cooldown is off.
    • Write only versions with an artifact and no time yet.

    PR 3 – proxy cooldown pending

    • Cached artifacts only (storage_path, fetched_at, not local), grouped by version.
    • Policy from config (shared loader, stats has none).
    • Fields: PURL, published, cooldown, eligible at, remaining, count, size, blocked.
    • Unknown times listed separately; table and --json.

    Overlapping PRs

    Open questions

    1. Should we fix the download bypass first and track it in its own issue, like Cooldown hides the version from metadata but still serves the tarball #239?
    2. Should publication times be stored while cooldown is off only where they are already parsed (Cargo, Pub, Helm), or everywhere, at the cost of extra upstream requests?
    3. Is it enough to list old versions without a publication time as unknown, or should the command look them up with a --resolve option?
    4. Should routed npm and Composer packages always be reported as unknown, or should we store their times per route?
    5. Should the Conda policy key include the channel (conda-forge/numpy), or stay name-only as today?
  2. andrew commented on Oct 18, 2026

    @andrew
    ContributorAuthor

    Thanks @pinguinfuss, the plan looks right. On the questions:

    1. Yes, the download bypass is now its own issue: Cooldown is not applied to artifact downloads for Cargo, RubyGems, Hex, Conda, Pub and cached Helm charts #521. It's the same class of bug as Cooldown hides the version from metadata but still serves the tarball #239 and matters more than the report, so it should go first.
    2. Store publication times only where they're already parsed (Cargo, Pub, Helm). Extra upstream requests when cooldown is off would cost everyone for a feature they haven't enabled.
    3. Listing them as unknown is enough for now. --resolve can come later if someone asks for it.
    4. Report routed npm and Composer packages as unknown.
    5. Keep the Conda key name-only, to match today's policy keys. Adding the channel would change how existing configs match.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions