Skip to main content

Purge unused tags

houba purge is the shipped reference implementation of the reaper role introduced by delegated tag deletion (ADR 0012). It is isolated behind its own UsageOraclePort and is fully replaceable — if you already have a reaper, deletionMode: mark still works; just don't run houba purge.

(For why houba marks instead of deleting, see the deletion & retention model.)

The lifecycle of a purged tag

  1. A tag falls out of its policy selection (e.g. a version is removed from the semver range). With deletionMode: mark, houba reconcile attaches a pending-deletion OCI referrer to the tag instead of hard-deleting it. The digest is unchanged and the tag stays pullable.

  2. Run houba purge in dry-run mode (the default — no deletes happen):

    uv run houba purge
    # protect myimage:old-tag reason=prod_sighting last_seen=2026-06-12T14:05:00Z

    While the tag's digest is still seen in production (within HOUBA_PURGE_MIN_IDLE_DAYS), purge reports it as protect — nothing is removed.

  3. After HOUBA_PURGE_MIN_IDLE_DAYS pass with no production sighting, a subsequent dry run shows the tag as purge:

    uv run houba purge
    # purge myimage:old-tag idle_since=2026-06-06T14:05:00Z
  4. Apply the purge (removes the tag and clears the pending-deletion mark):

    uv run houba purge --apply
    # purge myimage:old-tag [deleted]

Fail-closed

If the usage oracle errors, times out, or returns an unparseable answer for a candidate, houba purge treats that candidate as still in use: it protects the tag (never deletes it) and continues to the next candidate. A flaky oracle can therefore only ever spare tags, never trigger a mass purge of potentially live images. (If HOUBA_USAGE_ORACLE_CMD is not configured at all, purge refuses to start — exit 3 — rather than run blind.)

The oracle is replaceable

Set HOUBA_USAGE_ORACLE_CMD to any executable that speaks the contract: reads a JSON object from stdin ({"digest","image_ref","identity","since"}) and writes {"last_seen": "<ISO timestamp or null>"} to stdout. The reference implementation for Datadog is at oracles/datadog.sh — adapt the Datadog API call to your setup (endpoint, metric/log query, environment tag).

Required config

export HOUBA_PURGE_MIN_IDLE_DAYS=7 # idle window before a tag is eligible
export HOUBA_USAGE_ORACLE_CMD=docs/examples/oracles/datadog.sh
# plus DD_API_KEY, DD_APP_KEY, DD_SITE for the Datadog oracle

Both variables are required; missing either raises a ConfigError (exit code 3) before touching the registry.