What is the problem you're trying to solve
Customers need to combine age-based retention with minimum and maximum count limits.
For example, customers may want either of these behaviors:
- Delete tags older than 3 days or outside the 10 most recent matching tags.
- Delete tags older than 3 days only when they are outside the 10 most recent matching tags.
The existing --keep option does not express either policy consistently because it preserves items only from the set already eligible for age-based deletion. Changing its behavior would break existing purge configurations.
Describe the solution you'd like
Add explicit minimum and maximum retention options:
| Option |
Behavior |
--min-tags N |
Protect the newest N matching tags from age-based deletion |
--max-tags N |
Retain no more than N matching tags per repository |
--min-untagged-manifests N |
Protect the newest N dangling manifests from age-based deletion |
--max-untagged-manifests N |
Retain no more than N dangling manifests per repository |
Maximum retention: OR behavior
acr purge \
--registry example \
--filter "repository:.*" \
--ago 3d \
--max-tags 10
A matching tag is deleted when it is older than 3 days or outside the 10 most recent matching tags. This is a hard ceiling; fewer than 10 tags may remain after applying the age policy.
Minimum retention: AND behavior
acr purge \
--registry example \
--filter "repository:.*" \
--ago 3d \
--min-tags 10
A matching tag is deleted only when it is older than 3 days and outside the 10 most recent matching tags. The newest 10 matching tags are protected from age-based deletion.
The same behavior applies independently to dangling manifests:
acr purge \
--registry example \
--untagged-only \
--ago 3d \
--min-untagged-manifests 20 \
--max-untagged-manifests 100
Combining minimum and maximum retention
Minimum and maximum options may be combined:
acr purge \
--registry example \
--filter "repository:.*" \
--ago 3d \
--min-tags 10 \
--max-tags 50
This creates three retention zones:
- The newest 10 matching tags are protected from age pruning.
- Tags 11 through 50 are retained only while newer than 3 days.
- Tags beyond 50 are deleted regardless of age.
Equivalent selection logic:
delete :=
rank > maxTags
OR
(olderThanAgo AND rank > minTags)
Compatibility and validation
- Existing
--keep behavior remains unchanged.
--keep cannot be combined with the new count policies for the same resource.
--min-* requires --ago, because it guards age-based deletion and does not select items independently.
--max-* works with or without --ago.
- When both are supplied, the minimum must not exceed the maximum.
- Limits apply per repository and effective filter.
- Tag and dangling-manifest limits are independent.
- Items are ranked by
LastUpdateTime, newest first, with deterministic tie-breaking.
- When using
--untagged, manifest retention is evaluated after tag deletion.
- Locked items that prevent satisfying a maximum are reported clearly.
- Dry-run output identifies whether deletion is caused by age, maximum count, or both.
Repository-level conditions that determine whether purge runs at all, such as --purge-if-tags-exceed, are a separate feature and are not part of this retention proposal.
Acceptance criteria
- Age-only, minimum, maximum, and combined policies work for tags and dangling manifests.
- Minimum options provide AND behavior and maximum options provide OR behavior.
- Ranking works across paginated results.
- Existing filters and
--keep behavior remain compatible.
- Invalid flag combinations produce clear errors.
- Tests cover pagination, filters, locked items, equal timestamps, and manifests made dangling during the purge.
What is the problem you're trying to solve
Customers need to combine age-based retention with minimum and maximum count limits.
For example, customers may want either of these behaviors:
The existing
--keepoption does not express either policy consistently because it preserves items only from the set already eligible for age-based deletion. Changing its behavior would break existing purge configurations.Describe the solution you'd like
Add explicit minimum and maximum retention options:
--min-tags N--max-tags N--min-untagged-manifests N--max-untagged-manifests NMaximum retention: OR behavior
acr purge \ --registry example \ --filter "repository:.*" \ --ago 3d \ --max-tags 10A matching tag is deleted when it is older than 3 days or outside the 10 most recent matching tags. This is a hard ceiling; fewer than 10 tags may remain after applying the age policy.
Minimum retention: AND behavior
acr purge \ --registry example \ --filter "repository:.*" \ --ago 3d \ --min-tags 10A matching tag is deleted only when it is older than 3 days and outside the 10 most recent matching tags. The newest 10 matching tags are protected from age-based deletion.
The same behavior applies independently to dangling manifests:
acr purge \ --registry example \ --untagged-only \ --ago 3d \ --min-untagged-manifests 20 \ --max-untagged-manifests 100Combining minimum and maximum retention
Minimum and maximum options may be combined:
acr purge \ --registry example \ --filter "repository:.*" \ --ago 3d \ --min-tags 10 \ --max-tags 50This creates three retention zones:
Equivalent selection logic:
Compatibility and validation
--keepbehavior remains unchanged.--keepcannot be combined with the new count policies for the same resource.--min-*requires--ago, because it guards age-based deletion and does not select items independently.--max-*works with or without--ago.LastUpdateTime, newest first, with deterministic tie-breaking.--untagged, manifest retention is evaluated after tag deletion.Repository-level conditions that determine whether purge runs at all, such as
--purge-if-tags-exceed, are a separate feature and are not part of this retention proposal.Acceptance criteria
--keepbehavior remain compatible.