Yank a Version
Yanking marks one tag row in a package's tags map as no longer recommended for new resolution — "exists, but do not resolve by default" — without deleting anything. It is a per-tag fact, not a package-level status, and it is always a human-reviewed change.
What Yanking Does and Does Not Do
- Does: adds a
yanked: {reason, at}object to exactly one row intags, perroot.schema.json. - Does not: delete the tag row, delete or mutate the OCI image index it points at, or affect any other tag — including tags that happen to share the same
contentdigest (emergent aliases).
Image indices are immutable CAS content. A yanked tag's content digest stays exactly as fetchable as before — a consumer that already pinned that exact digest (a lockfile, a reproducible build) is unaffected. What changes is forward-looking: new resolutions SHOULD treat a yanked tag as excluded from default selection. Render-time reachability pruning (garbage collection of the deployment artifact) only drops an image index once no tag row anywhere references its digest — yanking one alias of a shared digest never orphans the object while another non-yanked tag still points at it.
Procedure
Open a PR editing
p/<namespace>/<package>.json.Add
yankedto the specific row undertagsyou want to yank:json"tags": { "3.28.0": { "content": "sha256:aaaa...", "observed": "2026-07-10T00:00:00Z", "yanked": { "reason": "build regression on arm64", "at": "2026-07-17T00:00:00Z" } } }Leave every other field untouched — do not hand-edit
contentorobserved; those stay bot-regenerated.
This PR always carries a human-review-required classification (see Governance Contracts G-05) — it never auto-merges, even though it looks like a small, otherwise-refresh-shaped change.
Un-Yanking
Remove the yanked object from the row in the same way — also a human-reviewed PR, same gate.
See Also
- Entry Schema — the
TagEntry/Yankedobject shapes - Wire Format — yank semantics in the wire contract