# Cargo: Allow publishing the reason for yanking?

**URL:** <https://internals.rust-lang.org/t/cargo-allow-publishing-the-reason-for-yanking/16896>\
**Category:** tools and infrastructure\
**Created:** [June 26, 2022, 10:06am UTC](https://internals.rust-lang.org/t/cargo-allow-publishing-the-reason-for-yanking/16896 "2022-06-26T10:06:12Z")\
**Posts on this page:** 9\
**Page:** 2

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [July 1, 2022, 2:41pm UTC](https://internals.rust-lang.org/t/cargo-allow-publishing-the-reason-for-yanking/16896/22 "2022-07-01T14:41:21Z")

</div>

The argument you're providing is a strong argument for `--allow-yanked` as a version resolution mode. It is also a strong argument against the current recommendation to not commit `Cargo.lock` for libraries; a `Cargo.lock` serves as a receipt that the library built and was tested against that resolution of the dependency forest.

It is not, however, an argument supporting the inability to ~~yank~~ mark any crate version as unfit for use.

An example fresh on my mind: tracing-subscriber recently published 0.3.12 and 0.3.13 with a new feature I wrote. Unfortunately, these releases had a critical bug that in certain cases would prevent the recording of any events. This makes these versions _completely unfit for use_, though, even though the fix is just replacing a single `false` with `true` in a trait implementation.

So what I would take away as the desired changes:

- Libraries should strongly consider keeping `Cargo.lock` in version control. This increases the reliability of testing historical versions, such as for bisection.
- If a dependency tree fails to resolve, and a yanked version would have been selected if it weren't yanked, cargo should _tell the user_ that yanked crate versions were excluded from consideration rather than the generic resolution failure message.
- Allow tagging yanked versions with the high-level reason for the version being excluded from default version resolution. The OP list is imho reasonable here, but the important distinction is **unfit** versus **broken**. An **unfit** version has some critical implementation issue. A **broken** version has some critical API issue, such as failing to build or a semver-wrong change.
  - (If I understand your position correctly, you argue against ever yanking a version for being **unfit**.)

- Provide a version resolution option that allows the use of yanked versions, optionally specifying specific allowed yank reasons (e.g. including **unfit** but excluding **broken** ).
- And one feature from npm that I think is very specifically useful to your use case: provide a version resolution mode that does resolution on the index **as it existed on a given date**.
  - The index (hopefully?) includes change dates on its append-only structure. This mode merely ignores any updates (new versions, yank requests) made after the specified datetime.
  - Bisection can ask to resolve commits' dependencies as they were available when the commit was made.

---

<div class="post-metadata">

**Author:** ![Nemo157](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nemo157/32/11585_2.png) [@Nemo157](https://internals.rust-lang.org/u/Nemo157)\
**Post date:** [July 1, 2022, 3:37pm UTC](https://internals.rust-lang.org/t/cargo-allow-publishing-the-reason-for-yanking/16896/23 "2022-07-01T15:37:50Z")

</div>

> [@CAD97](#):
>
> a version resolution mode that does resolution on the index **as it existed on a given date**.

This is possible on the git index by choosing to look at it via a commit from that date (though having those dates correct is not required by the registry spec, and for the [crates.io](http://crates.io) index will require pulling the old archived branches too for older dates). It's not possible via the new sparse-registry format as there are no explicitly recorded change dates anywhere.

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [July 1, 2022, 4:49pm UTC](https://internals.rust-lang.org/t/cargo-allow-publishing-the-reason-for-yanking/16896/24 "2022-07-01T16:49:13Z")

</div>

> [@Nemo157](#):
>
> It's not possible via the new sparse-registry format as there are no explicitly recorded change dates anywhere.

It's probably not possible to make this data available in the registry for existing metadata, but providing it for new changes seems like it would be useful.

---

<div class="post-metadata">

**Author:** ![afetisov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/afetisov/32/8508_2.png) [@afetisov](https://internals.rust-lang.org/u/afetisov)\
**Post date:** [July 1, 2022, 6:25pm UTC](https://internals.rust-lang.org/t/cargo-allow-publishing-the-reason-for-yanking/16896/25 "2022-07-01T18:25:30Z")

</div>

tracing-subscriber wouldn't be subject to the policy I'm proposing. Obviously there should be _some_ period when a release can be yanked, but I find it unreasonable that any version can be yanked at any time. This is just inviting the left-pad disaster into the ecosystem. It must be possible to build on a solid foundation which won't be yanked from under your feet.

The [unpublish policy](https://docs.npmjs.com/policies/unpublish) of npm looks like a generally reasonable approach. Quoting:

> For newly created packages, as long as no other packages in the npm Public Registry depend on your package, you can unpublish anytime within the first 72 hours after publishing. Regardless of how long ago a package was published, you can unpublish a package that:
> 
> - no other packages in the npm Public Registry depend on
> - had less than 300 downloads over the last week
> - has a single owner/maintainer

The exact numbers could be tweaked (e.g. I think a grace period of 1-2 weeks may be better than 3 days), but the general approach is what I would want to see in Rust: if you have published a widely used package, you cannot remove it or break people's builds in any way.

> [@CAD97](#):
>
> provide a version resolution mode that does resolution on the index **as it existed on a given date**.

That would be very useful for e.g. bisections, but I don't know how easy it would be to implement. This also wouldn't help with something like testing minimal dependencies.

---

<div class="post-metadata">

**Author:** ![bascule](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bascule/32/3057_2.png) [@bascule](https://internals.rust-lang.org/u/bascule)\
**Post date:** [July 1, 2022, 6:54pm UTC](https://internals.rust-lang.org/t/cargo-allow-publishing-the-reason-for-yanking/16896/26 "2022-07-01T18:54:00Z")

</div>

> [@afetisov](#):
>
> This is just inviting the left-pad disaster into the ecosystem

Yanking and what happened with `left-pad` aren't quite the same thing.

With npm, the `left-pad` package was effectively deleted. Even if you already had it in your `package-lock.json`, it still broke your project.

Not so with Cargo yanking, where things continue to work so long as a package is already in your Cargo.lock. This makes yanking much less disruptive than a `left-pad`-style event.

---

<div class="post-metadata">

**Author:** ![afetisov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/afetisov/32/8508_2.png) [@afetisov](https://internals.rust-lang.org/u/afetisov)\
**Post date:** [July 1, 2022, 7:00pm UTC](https://internals.rust-lang.org/t/cargo-allow-publishing-the-reason-for-yanking/16896/27 "2022-07-01T19:00:16Z")

</div>

I'd say being unable to create new projects, update dependencies or make a patch to a library counts as very disruptive in my book.

---

<div class="post-metadata">

**Author:** ![mathstuf](https://avatars.discourse-cdn.com/v4/letter/m/958977/32.png) [@mathstuf](https://internals.rust-lang.org/u/mathstuf)\
**Post date:** [July 1, 2022, 7:58pm UTC](https://internals.rust-lang.org/t/cargo-allow-publishing-the-reason-for-yanking/16896/28 "2022-07-01T19:58:21Z")

</div>

> [@afetisov](#):
>
> When I'm bisecting a bug, do I care about CVEs? No, absolutely not, I have a specific bug that I need to track down, and everything else is just a frustrating obstacle.

What you actually need is a snapshot of the index of a similar vintage to your commit (yank status and all). Otherwise you're bisecting your code against modern dependencies (e.g., a patch version of a dep may have fixed your problem and `cargo update`, with or without yanking, will hide it from you). Reading further comments, it seems that you and others agree with such a feature existing.

Alternatively:

> [@CAD97](#):
>
> It is also a strong argument against the current recommendation to not commit `Cargo.lock` for libraries

> [@afetisov](#):
>
> Rust, with its powerful type system, is much better in that regard than many other languages, but it is nothing but hubris to assume that untested dependencies don't cause issues. You can _usually_ rely on the explicit guarantees of the ecosystem (i.e. that semver keeps the API compatible, _most of the time_), but anything beyond that is a free for all.

Agreed, but I don't think removing the ability to yank will resolve the problem you're looking to tackle.

---

<div class="post-metadata">

**Author:** ![afetisov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/afetisov/32/8508_2.png) [@afetisov](https://internals.rust-lang.org/u/afetisov)\
**Post date:** [July 4, 2022, 10:16am UTC](https://internals.rust-lang.org/t/cargo-allow-publishing-the-reason-for-yanking/16896/30 "2022-07-04T10:16:58Z")

</div>

I find your tone rude. It is also quite easy to split a branch into a separate topic, if you believe that the discussion has derailed.

I don't consider my comments to be off-topic. My position is that there should be no other possible reason for yanking than "we have botched our latest release". A crate version which was released 2-3 days ago doesn't need any better reason than "we messed up", a crate which was released a long time ago shouldn't be yanked ever.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [October 2, 2022, 10:17am UTC](https://internals.rust-lang.org/t/cargo-allow-publishing-the-reason-for-yanking/16896/31 "2022-10-02T10:17:09Z")

</div>

Closed on October 2, 2022, 10:17am UTC

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.

[Previous page](https://internals.rust-lang.org/t/cargo-allow-publishing-the-reason-for-yanking/16896.md?page=1)
