Skip to content

Show cooldown status and withheld versions in the web UI #617

Open

Description

@simonchrz

The web UI doesn't show whether cooldown is on, or which versions it holds back. A user asked why the proxy offered phpunit 13.4.3 when Packagist had 13.4.4. The answer was cooldown: 13.4.4 was a few hours old. The only place to see that today is the cooldown: filtering composer version log line.

#338 covers cached artifacts waiting for cooldown, as a CLI command. This issue is about the UI and about versions that were never downloaded, since the filter keeps them out of the metadata.

Proposal

  1. Dashboard: a cooldown panel with the default, the ecosystem overrides, the package overrides and the patterns, or "off".
  2. Package page: the cooldown that applies to this package (Policy.For), overrides included.
  3. Package page: versions held back, with their publish time and when they become available (Policy.Evaluate, AvailableAt).

Items 1 and 2 only read the config. Item 3 needs the withheld versions, which aren't in the database: versions gets a row only when an artifact is resolved or downloaded.

Getting the withheld versions

  • a) When the metadata filter removes a version, store its publish time with SetVersionPublishedAt. The time is already parsed for the filter, so this costs no upstream request. It runs only with cooldown on, and only for versions without a stored time, so each version is written once. The UI then evaluates the policy over the stored rows.
  • b) Fetch the package's metadata when the page is viewed and run the filter on it. This needs no writes, but every page view costs a metadata request (or a cache read) and a parser per ecosystem in the UI.

I'd go with (a). It follows your answer on #338 about storing times only where they're already parsed.

Questions

  1. Is (a) acceptable? It adds rows to versions for releases nobody downloaded, so the version list on the package page would show them too, marked as held back.
  2. Should (a) go through the filter interface from Generalise cooldown into a version filter interface #127, or call SetVersionPublishedAt at each filter site as the download checks do today?
  3. Should the cooldown config also be shown on the dashboard when the UI is public, or only the effective cooldown per package?
  4. Should /api/package/{ecosystem}/{name} return the same fields (cooldown, available_at per version)?

Activity

  1. andrew commented on Oct 27, 2026

    @andrew
    Contributor

    Thanks, this is well scoped. On the questions:

    1. (a) is fine, with two changes. SetVersionPublishedAt overwrites published_at on conflict, so add a variant that only fills an empty time (DO UPDATE ... WHERE versions.published_at IS NULL) rather than reading before each write; the filter runs on every uncached metadata request, and a read per filtered version adds up on large packuments. On the package page, show a version with no cached artifact only while it's still held back. After AvailableAt it's just a release nobody fetched. That rule should cover the rows the download checks already create too, since GetVersionsByPackagePURL returns everything.

    2. Call it at each filter site through one shared helper, so the guarded write and PURL handling live in one place. Generalise cooldown into a version filter interface #127 hasn't started and shouldn't block this; it can take over the helper when it lands. Please base this on Check cooldown on artifact downloads for cargo, gem, hex, pub, conda and helm #533 once it merges, since both touch the same handlers.

    3. The UI has no auth, so the dashboard is visible to anyone who can reach it. Show the default and the ecosystem overrides there, and a count of package overrides and patterns, but not their names: they often list internal packages. Each package page can show its effective cooldown and which rule it came from.

    4. Yes. Add a package-level cooldown in the same duration syntax as the config, and available_at on held versions only, both omitempty, using the same timestamp format as published_at.

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