Proposal: Add Minimum and Maximum Retention Policies to Acr Purge
- Dominant language
- Go
- Stars
- 70
- Forks
- 52
- Avg merge
- 3d 2h
- Merged PRs (30d)
- 12
Description
**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
```sh
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
```sh
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:
```sh
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:
```sh
acr purge \
--registry example \
--filter "repository:.*" \
--ago 3d \
--min-tags 10 \
--max-tags 50
```
This creates three retention zones:
1. The newest 10 matching tags are protected from age pruning.
2. Tags 11 through 50 are retained only while newer than 3 days.
3. Tags beyond 50 are deleted regardless of age.
Equivalent selection logic:
```text
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.
Contributor guide
Research direction
Start with the acr purge entry point and trace the existing --keep behavior, tag and dangling-manifest filtering, ranking, pagination, and dry-run reporting. Use the acceptance criteria as the definition of done: preserve compatibility, validate flag combinations, apply minimum/maximum policies independently, and cover pagination, filters, locked items, equal timestamps, and newly dangling manifests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- cli
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100