Last active
April 1, 2016 04:37
-
-
Save ELLIOTTCABLE/ea78fcd84d99546c5152948bccc23ad1 to your computer and use it in GitHub Desktop.
Thoughts on `npm unpublish`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
So, this has been an excellent thread, and against all my expectations … I think @jmelfi et al. have | |
actually swung me around. It's a *really* difficult question, and both sides keep bringing up really | |
good points, but … there's something really important and subtle here: | |
Buried in all the (if I'm being honest … super-silly.) ‘legal’ and ‘licensing’ talk¹, there's a | |
pretty valid concern being raised here; and I think @isaacs brushes up against it in his recent | |
replies: I'm starting to think that it may be acting in bad faith, for npm to disallow unpublishing | |
in the main registry. | |
1. Users *expect* a particular behaviour. There's a whole UX aspect to that, sure, and that's a | |
little less … charged … but in this particular case, because each possible behaviour can | |
seriously hurt one of the involved groups of people, it also becomes an, as @isaacs put it, | |
‘ethical’ discussion. The user's expectations, in this case, are shaped by other package | |
managers: and yes, crucially, *most other package-managers I've dealt with*, allow the users to | |
*remove their code²* from the package manager. When they come to Node, and effectively thus come | |
to npm, they have that expectation: while there are exceptions (I'd posit that they are few; for | |
instance, I wouldn't count CPAN, as it intentionally *segregates* archived code, and you must go | |
through *extra work* to depend upon it / use it. I'd be fine with a solution like that.), the | |
majority of other systems seem to work that way. | |
Thus, if that is their expectations, I believe it's … well, basically, acting in bad faith, to | |
break that expectation, most especially in this particular case because this is both a. | |
emotionally-charged and b. *not reversible* (precisely the topic of hand, of course.) In other UX | |
situations, breaking with users' expectations causes them an annoying extra few taps in an | |
interface, or a Google for documentation … in *this* case, it leads to a (potentially | |
embarrassing, hurtful, … who *knows* what) mistake that will continue to affect them in | |
perpetuity. | |
2. If we can all agree that this *hurts* real people, publishing to the repository (I'm not going to | |
try and assemble a huge list of how people might be hurt by this policy, as opposed to | |
inconvenienced, I feel I can leave that up to your imagination), then, as @isaacs put it, this | |
becomes a discussion of either a. who this hurts more, or b. which wronged-party npm, Inc. has a | |
greater responsibility to protect. I want to address these separately: | |
b. This may be non-obvious, but if we're being blunt, I think npm is heavily more beholden to the | |
*content creators* than to the consumers. In an ‘if you build it, they will come’ philosophy, the | |
dependants *will come* to npm, if the content is there. (This is evidenced by all of the | |
truly-terrible-to-use³ packaging systems out there, that are still heavily used, because they | |
‘got in there early’ and gained the preponderance of content / mindshare.) | |
a. Further, I'd posit that this is in fact *not as big a deal* for the dependants, as it's been | |
cast to be over the last few days. To go straight to Everyone's Faaaaaavourite Developer | |
Argument ... I hate to say it, but the people complaining may have been *doing it wrong*. This | |
is a whole seperate discussion that I'll not even get into here, but I've recently been | |
thoroughly convinced by a friend (@alextgordon, if you're listening ...) that **end-users** | |
(applications, etc) **should be vendoring their dependencies.** The authors of Real World | |
Products depending on CoolPackage should, frankly, have their own copy of CoolPackage, that's | |
being shipped into production by their own deployment systems; they should *not* be depending | |
on npm for deployment. (That's a conversation for a different place, I suppose.) | |
Meanwhile, for library-authors, again, I'd posit that this is *their problem* to solve (as | |
aforementioned end-users, hopefully, did by vendoring their deps); not npm's. At a glance, | |
there's lots of viable options, many of which really are very accessible: implement their own | |
solution, if the dependency was small; switch to an alternative implementation or tool, if it | |
was large; even obtain the presumably-open-licensed code and publish/maintain a fork⁴ for | |
their own users! I want to emphasize, though, that in *none* of these situations, is this a | |
world-ending, or even particularly urgent, problem, for the library authors: all of these | |
dependant-authors' products are, themselves, libraries or tools: the end-users thereof, having | |
(say it with me now!) *vendored their dependencies*, are safe until such a time as the | |
dependant-library-author can preform one of these actions. (“Hey, before 3.2.0, Packifier | |
depended upon CoolPackage, which [was deprecated]; I'll be replacing it in 3.3.0. Until then, | |
if you urgently need to deploy Packifier, I've hunted down a copy of CoolPackage [here] ...”) | |
(Yes, this is a lot of mild annoyance, spread across the ecosystem, for some | |
person-you've-never-met's feelings. I think we in the JS community, out of all the programming | |
communities out there, are possibly the *only* group to whom I don't need to justify that | |
effort needing to occur nonetheless.) | |
---- | |
Because a lot of the above is pretty philosophical and detached, I want to provide a fictional | |
case-study, to bring this down to earth. (Rather obviously based on a particular individual, | |
mentioned elsewhere in this thread.) | |
Let's say Oakley, for reasons completely unnecessary to elucidate, decides that the software- | |
development scene is super-unhealthy for them. For reasons that I also believe are inherently | |
immaterial⁵, continuing to maintain any public web-presence w.r.t. their identity and past as a | |
software-developer would be as harmful to them as continuing to actively participate. (Remember the | |
[right to be forgotten][RTBF]?) | |
Oakley deletes their GitHub, officially disavows any association with their past work, perhaps | |
discarding with a pseudonym entirely in the process. In fact, let's assume for a moment that Oakley | |
is super-nice and has the spoons, and put the effort in to support some of their users through the | |
transition: they published warnings, they found new maintainers for the projects for which they were | |
able to do so, and they deprecated-in-advance the projects that they could not. | |
At some point, though, they'd done what they could (and remember: *this was not necessary*. I posit | |
that we owe them the affordance to do this, regardless of whether they have the ability / desire / | |
spoons to do the above); and now, the time has come to *depart*. They delete their GitHub (and those | |
projects that hadn't acquired new maintainers, new forks, *are gone forever*.) They [remove | |
themselves from Google][Google], they delete their Blog, their Twitter account, so on and so forth. | |
Now, they come to the npmjs.com page dedicated to their packages. They realize they must undergo an | |
onerous human-mediated decision process, to regain the *option* to have the remaining packages, | |
which haven't found a new maintainer, removed. (Remember all that effort they already put into doing | |
the kind thing? Maybe they don't have the energy *left* to deal with this rigmarole.) Then, once | |
they engage with the Nice npm Humans ... there's a difference of opinion, and those Oh-So-Nice | |
Humans decide that Oakley's reasons *aren't reason enough*. (Even if you don't think this would be | |
the case, because npm really *is* staffed by all the greatest, nicest people I've ever known: does | |
Oakley think that? This is precisely what's weighing on their mind as they try to decide whether to | |
even try.) Now, Oakley has no recourse. This is not okay. | |
---- | |
Now, finally, given everything I've said above, I want to offer some real *solutions*. I think it | |
*is* possible to offer automated, technical unpublish (or more generally, I think it's possible to | |
protect the author's wishes.) in a non-human-gatekept manner, without completely ignoring the | |
desires, needs, and hell, mental-health, of the ‘other half’ of npm's userbase: the dependant | |
library-authors, like myself. | |
Assuming `unpublish` or similar is provided, we could: | |
- Enforce a cooling-off period. (Hell, make it proportional to some heuristic of the number of | |
downloads-per-month / the number of dependant packages: something with no dependants disappears | |
instantly, as `unpublish` currently works; something with very few disappears after an hour; and | |
it tops out, for Lodash or Express, at, say, a week.) Every release of the package is immediately | |
marked as deprecated / the equivalent of the above `npm disown` or whatever happens; but after | |
the cooling-off-period, if the author doesn't cancel the operation, *the package disappears and | |
dependencies fail to resolve.* | |
- Enact *social* costs. Warn the user, if you have a bunch of dependants, that the operation will | |
*immediately* e-mail 5,000 busy humans with a notification that they need to start planning to | |
replace your package. I may be fighting for the authors' health, here, but I'm not beyond trying | |
to shame them into doing what's best for as many people as possible. `:P` (It might seem a little | |
unintuitive, but I suspect that sometimes these sorts of ‘soft’ costs can loom much larger in | |
someone's mind, than the nominally-greater ‘hard’ costs of all these packages breaking.) | |
- Compromise. Allow auto-unpublish, but place some ‘reasonable’ limitations on it. What those would | |
be will need more discussion in this thread, but at a thought, it's ‘reasonable’ to disallow a | |
user from unpublishing, say, fifty packages, without talking to a human. | |
- Allow human-appeals in the *other* direction. I recognize that the dependants are people too, and | |
are also capable of feelings beyond ‘inconvenience’ about this. Although I really have come to | |
the conclusion that the only conscionable thing here is to err on the side of the author, I *do* | |
think there's definitely situations where the opposite may be the correct response. npm Humans™ | |
may definitely be able to do some good by mediating between a truly-needful dependant and an | |
author who has unpublished; and in extreme cases, may even be in the right to resurrect an | |
unpublished package when the absentee-unpublisher is effectively unreachable. | |
- Finally, (and this is my favourite; I suspect this may be a solution that pleases all involved), | |
there's CPAN's solution: retain deprecated packages in a separate repository (obviously, one that | |
is inherently ownership-less: as mentioned above, `disown` should be an inherent prerequisite / | |
step of `unpublish`, no matter what else happens.) In fact, hell, I wouldn't even be opposed if | |
you went the extra mile: allow packages to *depend upon* disowned-and-‘archived’ packages. As | |
long as it requires *active effort* on the part of dependants, as long as it requires an active | |
admission that the dependant is going against the wishes of the author, and drawing on that FOSS- | |
licensed-right to continue to use the package ... then I think npm's due-diligence is fulfilled. | |
In fact, here, I think that bears repeating: **The point here, is that I truly believe that the | |
dependants need to each, individually, *actively*, indicate their willful acknowledgement of the | |
package-authors' wishes in unpublishing.** Whether that's by forking, vendoring, pointing your | |
dependant-library's end-users to an alternative archive of the code, or in the case of that last | |
suggestion, simply updating your dependency to `"@archive/CoolPackage": "=1.2.3"` and publishing a | |
new version of your own library ... you're acknowledging the reasons the package was unpublished, as | |
a human being, and asserting that after consideration, you still believe your needs to supersede | |
those: “The author decided the entire purpose of this package was untenable and insecure, but in our | |
specific setting, it's used in a restricted way, and the alternatives are inappropriate.” “I | |
understand that the author wishes that this work no longer exist in any form associated with them; | |
but I need to use it locally in development, until later in my project when I have the time to fork | |
their original work, anonymize it, and support it.” (Hell, even “I really, really don't care how the | |
author feels, I want to use this.” As long as *npm* has taken the route of defending the author, I | |
don't see that it's necessary to concern ourselves with how end-users might mis-use the available | |
tools: my only concern is it becoming the *default response* to disregard the author's wishes.) | |
Basically: continuing to use⁶ (and more importantly, distribute) some software that the original | |
author doesn't wish to be used anymore, should be the *exception*, not the rule. I think we should | |
collectively *very rarely* resort to continuing to use / distribute / depend-on a package that the | |
author wants to disappear, without a human actively taking upon the effort of forking, sanitizing, | |
and maintaining the parent project. It should be an *exceptional circumstance*, and npm's technical | |
decisions should reflect / encourage / even *enforce* that. | |
---- | |
If I've completely failed to convince anybody with all of the above, and it's still the consensus | |
that it's best that `unpublish` be removed entirely, here's what I think is the absolutely minimum | |
necessary concessions to the needs of authors who wish, for whatever reason, to disappear or have | |
their efforts removed: | |
- A *giant* fucking disclaimer. Put it on first `publish` of a new package, or perhaps just a | |
user's first `publish` overall; or even on their first invocation of `npm` overall (not to | |
mention documentation / website / whatever.) If users are going to be coming from the other | |
services that *do* allow them to ‘undo’ their mistakes, or to reserve a right-to-be-forgotten; | |
then they need to be informed *up front* that things work differently around here. | |
- A *strict* outline for how the human-intervention currently dictated will proceed: what are | |
acceptable reasons? More importantly, tell us, *before implementing this*, what are | |
*unacceptable* reasons? It's anxiety-inducing that, however nice they may be, this is apparently | |
left totally up to the judgement of npm Humans™. `)=` | |
- Even if the package sources are retained and may continue to be depended upon, they should be | |
sanitized and hidden: remove `author` / `description` fields and similar from the package.json in | |
an automated fashion; remove any versions not being depended upon at the time of the abandonment; | |
and remove such packages from any public npm system (search features, the web-pages, the | |
author-list, perhaps even remove them from the point of view of any API features; perhaps | |
`access-disowned` should be a special-circumstances-granted API access-right, or smth?) | |
- Finally, if possible, prevent *new* packages/versions from being published that depend upon them, | |
even if you're going to allow already-dependant packages to continue to install. | |
---- | |
#### Footnotes: | |
> 1. guys. read the TOS. *Legally*, ignoring ethics, npm has *just gained* the license to do what | |
> they're saying they're going to do. Like, that's what this entire discussion is about. All | |
> this discussion of whether FOSS licenses “allow” this or not is … completely irrelevant, | |
> because by typing `npm publish`, you're effectively *extending* your FOSS license with a | |
> clause of “oh, by the way, any npm user can download this package, in perpetuity, as long as | |
> npm, Inc. chooses to host it for them to do so.” Of course, those users can't necessarily | |
> *use*, modify, *re*distribute, etc, that software … but all of that is irrelevant to the | |
> current discussion: the point is, you don't get to say ‘my license has a clause that it | |
> expires in 2018!’, because you've basically voided that clause as it relates to npm, Inc. by | |
> `npm publish`'ing. Not-a-lawyer-not-legal-advice-etc.) | |
> 2. I want to make it clear, again, that I'm talking about that very particular, specific action: | |
> ‘unpublishing’; and I would posit that this action has nothing to do with the licensing: as | |
> with the blog-post, yes, we know that once this content is out there, we've *legally* allowed | |
> this code to float around the Internet for years. I'm not saying the publisher should be able | |
> to press a button and remove their presumably-open-licensed-code from the Entire Internet … | |
> I'm saying they should be able to press a button and remove it from *npm*. I think the | |
> distinction is important, and we should stop arguing about the former; it's a misleading | |
> straw-man. And for the latter, unlike the former, I think licensing has no relation | |
> whatsoever. | |
> 3. Note, I'm not saying we should actively make npm horrible for the dependants, or anything! I'm | |
> only saying that in *cases like this*, where the needs of the dependants, and the needs of the | |
> content-creators, are directly in opposition, npm might have an obligation to the | |
> content-creators first. | |
> 4. I want to expand on this possibility: note, again, as I've mentioned in above footnotes, that | |
> I really don't think licensing has a bearing on this issue ... but, if we'll opt to pay | |
> attention to it for a moment, all of the far-above commentary by other posters *is accurate*, | |
> here. If they published that code under a permissive license, Mx. Dependant Librarian *can* | |
> hunt down a copy of that code, and temporarily host it for *their* dependants until such a | |
> time as a better solution can be produced. (And, if it *wasn't* ... why were you using it in | |
> the first place? :) If it's irreplacable, or if it's simply just Actually Useful to Them (aand | |
> possibly other people), then, as mentioned above, they can even re-publish/claim/fork/support | |
> that dependency themselves. | |
> 5. “There are more [pains] in heaven and earth // Than are dreamt of in your philosophy.” Be | |
> wary of assuming that just because you may not be able to imagine a situation in which this is | |
> true for *you*, doesn't mean those situations won't come to pass for others. They have, | |
> repeatedly, and will continue to, in our current developer culture. /= | |
> 6. Again: regardless of the license. We have a legal system to protect us from exceptional | |
> circumstances, but we *very rarely* resort to it, if ever. | |
[RTBF]: <https://en.wikipedia.org/wiki/Right_to_be_forgotten> | |
"The European ‘Right to be Forgotten.’" | |
[Google]: <https://support.google.com/legal/contact/lr_eudpa?product=websearch> | |
"Google's RTBF forms" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment