17 ms·
I really like this post. While the author clearly feels bad about the fact that they've lost his community and that GitHub didn't restore it (which is honestly
by vaishnavsm 4y ago
I really like this post.
While the author clearly feels bad about the fact that they've lost his community and that GitHub didn't restore it (which is honestly what any of us would've felt under similar circumstances), they're also focusing towards the future and using their personal experience as a parable all of us can learn from.
Lesson 1 on UI design I think is really important. I often think scary popup boxes are enough to get people to think about what they're doing, but this example clearly demonstrates that what's important is to use design not to scare (alone?), but to convey the information which makes a dangerous action dangerous as well. I also really like the fact that when the action isn't dangerous, the distractions ("Type this repo's name", etc) just go away. It's super intuitive, and (for a newbie designer like me) really helps build an intuition for various design principles put in action.
Lesson 2, which was to use soft deletes, is something I have more thoughts about. I assume that the cascading done on GitHub would be done on a FK constraint, but I'm not really sure how you'd do a "cascading soft delete" without making some kind of manual cascading logic? If anyone's aware of a standard way to accomplish this, please do let me know. Of course, the best way may just be to simplify the model so they aren't needed at all haha.
As designers and developers we've been given a chance to sharpen our toolkit. Thanks, HTTPie! You've gained a new star :)
Edit: Changed GitHub couldn't restore to GitHub didn't restore, as pointed out by @ncmncm (https://news.ycombinator.com/item?id=31033758#31034195 https://news.ycombinator.com/item?id=31033758#31034195)
- harg 4y agoRegarding cascading logic with soft deletes; I think the answer is that you don't cascade anything. You basically need to have `deleted_at IS NULL` conditions in your queries to exclude them.
- SkyBelow 4y ago>I often think scary popup boxes are enough to get people to think about what they're doing This would entirely depend upon how often it shows up. The more often it shows up when the scare isn't relevant, the less people will pay attention to it. >the distractions ("Type this repo's name", etc) just go away I think it shows that what one types needs to be relevant information. In this case, due to the similarity between when the author would've been asked if they did what they were intending to do and what they typed to do what they actually did, we can judge the prompt isn't enough. If this also asked you to type in the number of git stars you were about to lose, that would've been enough to make author recheck exactly what they were doing.
- ezfe 4y agoFactorio doesn't say "You'll lose unsaved changes" if you close the game immediately after saving, which is super nice. The number of games that DO ask this question, immediately after saving, is ridiculously high it's so frustrating.
- belter 4y agoYour comment missed the main lesson of the post. GitHub (Microsoft) had a non intuitive UI feature, they themselves were victim of. They restored for their own repo but not for the customer repo...Zero customer focus is the lesson here. "...In our case, however, they refuse to do that, citing undesirable side effects and the cost of resources. We even offered GitHub financial compensation for any resources required. But, sadly, they declined. They have other priorities than resurrecting the community of one of the oldest and most popular community projects on their platform..." "...So the answer to the question is, unfortunately, the following: GitHub will restore a repo damaged by making it private. But only if it’s one of their own projects, not a community one.."
- metaltyphoon 4y ago> I'm not really sure how you'd do a "cascading soft delete" without making some kind of manual cascading logic? Perhaps the delete action is not accomplished right away and a column is checked. Then after a X amount of months a worker process goes around actually deleting things?
- brightball 4y agoThe complicated thing is that every query has to look for the column. Ideally, moving the entire serialized record to an archive table keeps things as clean as possible.
- vaishnavsm 4y agoI meant to focus on the cascade part of the equation here. For example, lets say `stars` are foreign keyed (FKed henceforth) to repos, and (say) `X` are FKed to `stars`, and `Y` is FKed to `X`. Then if you do a "hard" delete of the repo status (or the stars), then we can set that to cascade to `X` and `Y` as well. Otoh, I don't think you can apply a cascade like that automatically when you're just changing a value (which is how a soft delete would be implemented, ig). Can you? Is there some really cool hook that allows this?
- deleted 4y ago[deleted]
- ncmncm 4y agoThere is no need to delete anything at all. Set the "private" flag when the user asks for to make it private. Unset the "private" flag when they make it public again. If it is needful to be able to delete stars, make a separate button for that. But it is hard to imagine such a need.
- mypalmike 4y agoStop. You've said the same thing a dozen times in this thread. Besides being repetitive, you're overlooking the obvious fact that having associations from non members of private repos to those repos is problematic. At the very least at the UI level, maintaining known dead internal links is bad form. So you'd be creating edge cases for the UI and probably numerous places deeper in the tech stack as well. Which is fine if you engineer solutions to all the edge cases. Perhaps after this incident they will consider doing so. But it's certainly not as trivial as you imply.
- ncmncm 4y ago> "that GitHub couldn't restore it" What an odd turn of phrase.
- vaishnavsm 4y agoNot sure what you meant? Are you pointing out couldn't vs didn't? If so, I didn't really think about it, although now that you point it out, I think didn't would've been a better fit. I'll edit it, thanks!
- ncmncm 4y agoI mean "refused to". There was absolutely no value to Microsoft in refusing to restore the deleted information, and there was no practical reason to have deleted it at all. Ultimately, it just amounts to contempt.
- lalopalota 4y ago"I screwed up. By the way, it's your fault. I hope you realize how many people think more highly of your service because my project is there. Why wont you accept some money for a service you don't provide?" What's the value in capitulating to that? Also, a user saying "delete this stuff" is a pretty practical reason to do so. Indifference != contempt.
- ncmncm 4y agoDefine the difference.
- a-dub 4y agoor maybe just incompetence? or just retro-1990s microsoft? what is this? slashdot in 1998? i mean, this is the company that perfected the "throw it all away and start over" serviceability paradigm and the "we don't know what's wrong with it just reboot it every six hours" reliability paradigm for systems. totally reliable business partner to trust for outsourcing critical business and government infrastructure for sure! those who are serious and prudent seek assurance, for the reckless and feckless, there's azurance. if the blog post doesn't work, i'd suggest renaming the project (specifically the cli) such that it makes reference to the hollowness of the new microsoft's apparent love for open source. that way when those thousands of developers (who happen the be of the exact variety that the dinosaur is trying to court) are invoking it every day, it can burn into their skulls to never ever work for, or choose technologies made by, microsoft. score 5: funny, insightful
- benjaminjackman 4y agoFor Lesson 1: I think the general pattern that ought to be followed is to "prefer undo to warnings." Undo is often harder to implement, however it's usually a superior experience.
- SnowHill9902 4y agoRollbacks even better.
- vaishnavsm 4y agoI agree that undos are pretty nice for when errors are possible, but I think there's a really good reason to put up warnings too. Let's say they accidentally made the repo private, but didn't notice it (unlike what happened here). Although you would be able to undo the change, it may have only kicked in once the news spread around (followed by reputation damage, etc). A well worded warning would prevent that. In a way, I think warnings and undo serve two different functions-warnings are meant to inform the user of their action, and undos are meant to roll back actions taken.
- lolinder 4y agoThere are definitely still cases where warnings are important, but the point of "prefer undo to warnings" is to eliminate as many warnings as possible to avoid desensitizing users. I should only see a scary pop-up if the action that I'm performing is going to be well and truly destructive. Undo-instead-of-warning is a great pattern for lower-stakes actions that are easy to undo and cause minimal damage if left done. This allows the few warnings you do show to be recognized as truly important.
- ncmncm 4y agoEven better, flipping "public/private" has absolutely no need to delete any information at all. There could be separate buttons, "Delete all my stars", "Delete all my watches".
- hk__2 4y ago
- cmeacham98 4y agoI specifically dislike the "Lessons" section, as it throws all the blame on github and doesn't mention the seemingly obvious advice: "make sure you're not on autopilot when taking potentially dangerous actions, on github or any website". Yes, GitHub probably should show the stars in the warning UI, and hopefully that will prevent some of these mistakes. But GitHub makes it pretty hard to make this mistake already - the author had to _type out_ the name of the repo they wanted deleted into the warning box. At that point, it's hard to believe the author when they claim that this one addition to the warning UI would have definitely stopped them when they weren't paying enough attention to notice they had typed the entirely wrong repo into the confirmation box.
- johnywalks 4y ago> make sure you're not on autopilot when taking potentially dangerous actions Humans will be humans, we can't help it. Structures or systems that handle large amounts of user interactions should predict such use cases and design accordingly. a.k.a make them "idiot proof".
- Abishek_Muthian 4y ago> "make sure you're not on autopilot when taking potentially dangerous actions, on github or any website". Have the advertisements/sign-up/GDPR pop-ups trained us to 'engage autopilot to dismiss the pop-up' as soon as possible irrespective of its importance?
- mherdeg 4y agoMy favorite example of this is that the cloudflare.com web UI has some extremely scary buttons, like a little "bypass CDN" button with a cloud on it that will rapidly increase traffic to your site 2-100x if you accidentally click. I mean this isn't exactly how it works. But it's a bit scary.
- wpietri 4y agoI suggest you read "The Field Guide to Understanding 'Human Error'". You'd learn a lot. https://www.amazon.com/Field-Guide-Understanding-Human-Error/dp/1472439058 https://www.amazon.com/Field-Guide-Understanding-Human-Error... My view is that expecting humans to stop making mistakes is much less effective than fixing the systems that amplify those mistakes into large, irreversible impacts.
- jdmichal 4y agoI ran into this in pgAdmin recently. When right-clicking on a server, the options to disconnect the server and remove the server are right next to each other. Clicking disconnect presents you with the following dialog box: "Are you sure you want to disconnect the server? No / Yes" Click remove presents you with the following dialog box: "Are you sure you want to remove the server? No / Yes" Good luck! I mean, it's not a super huge deal to recreate the server entry, but still annoying when you're in the middle of something and just realized what you did. Honestly, just replacing the "Yes" button with the action being taken would be enough to improve this. "No / Disconnect" and "No / Remove". But my personal opinion is that disconnecting is not a destructive action unless there's an open transaction or running query. So the dialog box should be contextual on that scenario, and otherwise it should just disconnect. "Disconnecting will cancel executing queries and rollback open transactions. Continue? No / Disconnect"
- david_allison 4y agoWould you consider submitting a patch?
- jdmichal 4y agoActually, I should. The biggest hold up will probably be translations though, unless they have that already translated.
- JJMcJ 4y ago> just replacing the "Yes" button Or the lazy web dialog popup with "Cancel" and "OK". So you click on "Cancel Glorping The Frobnitz" and up pops a dialog with "Cancel" and "OK". It always takes a moments thought does the "Cancel" on the popup mean cancel the cancel glorping or cancel the cancel. Since it takes literally seconds to change the button captions it might be nice to think of something clearer. Seconds if you're a UI expert which I'm not. Of course the webdev part of changing the captions on the page really would be seconds for me to do.
- JJMcJ 4y ago
- mherdeg 4y ago> While the author clearly feels bad about the fact that they've lost his community and that GitHub couldn't restore it (which is honestly what any of us would've felt under similar circumstances), they're also focusing towards the future and using their personal experience as a parable all of us can learn from. Also, writing a solid blog post about a customer-service corner case and getting it to the top of news.ycombinator can be a great, if somewhat last-ditch, opportunity to escalate a problem.
- bokwoon 4y ago> I assume that the cascading done on GitHub would be done on a FK constraint GitHub doesn’t use foreign keys, the cascade delete must have been manually implemented. https://news.ycombinator.com/item?id=21486494 https://news.ycombinator.com/item?id=21486494
- CodeWriter23 4y agoI’ve adopted a pattern of: <dialog-text> If they click ok: Asking again to be sure you want to destroy masses of data <dialog-text> But even that fails if there is a language barrier.
- organsnyder 4y ago> But even that fails if there is a language barrier. Surely GitHub is localized? (and if not, why the hell not?)
- sparqlittlestar 4y agoI recall that GitHub used to be localised in several languages, but no more. And I can’t seem to find any references to it anymore, either. “GitHub interface translation” gives search results about code, not about GitHub’s interface
- whack 4y ago> Lesson 2, which was to use soft deletes, is something I have more thoughts about. I assume that the cascading done on GitHub would be done on a FK constraint, but I'm not really sure how you'd do a "cascading soft delete" without making some kind of manual cascading logic Relying on database cascade deletions is very dangerous. Especially since as the application/org grows, it's easy to lose track of all the things that may get cascaded. There's a good chance you'll find yourself having cascade-deleted data that you never intended to have deleted. Manually implementing logic for "when archiving X, also archive Y and Z" takes more effort, but is a lot safer. When it comes to data. What surprised me most is that github performs irreversible deletions when someone making a repository private. I would have expected them to just create a "is_deleted" column and set that flag to true. I wonder how much of this behavior is motivated by GDPR. Ie, complying with it requires completely deleting data when requested by the user, and they decided the most straight forward way to comply with that requirement is to delete the data immediately when requested.
- zach_garwood 4y ago> I assume that the cascading done on GitHub would be done on a FK constraint, but I'm not really sure how you'd do a "cascading soft delete" without making some kind of manual cascading logic? I'm not at a terminal, so I can't check it out, but could you make a compound foreign key with the soft delete column and use the on update cascade? Something like `alter table stars add foreign key (repo_id, is_deleted) references repos (id, is_deleted) on update cascade;`
- 411111111111111 4y ago> I assume that the cascading done on GitHub would be done on a FK constraint, but I'm not really sure how you'd do a "cascading soft delete" without making some kind of manual cascading logic? Couldn't you just use an on delete trigger for this? I have no experience one the subject however
- nine_k 4y agoAn ON UPDATE trigger for the is_deleted column would do. Some databases also support INSTEAD OF triggers.
- vaishnavsm 4y agoDoesn't ON UPDATE only work for foreign keys? As far as I know, it's used to update the foreign key itself, and not values based on relationships.
- deleted 4y ago[deleted]
- berkes 4y agoGithub is built with MVC. On rails no less. Where problems like soft delete are hard, or even impossible to solve (in scale). Yet there are many architectures beside MVC. Many of them decades old. Proven. Established. Yet unknown to devs who picked up a rails book on day 1 and never looked back (I've been guilty of that for years). This particular problem is a textbook candidate for Command Pattern. The problem of undo is solved naturally in any event-sourced setup (git is even sourced, and moving through history a prime feature). Probably more architectures that I'm less familiar with, solve 'undo' as well. But we are stuck with the web, backends in 2022, being built on MVC frameworks like Rails, where solving such issues is tough and complex. So we are stuck with a huge amount of warning dialogs to 'solve' this. Point being: choose your architecture well, based on your needs and the tradeoffs. Don't just grab the next fancy framework, because that will decide for you, if, and how you solve things like 'soft delete' or 'undo'.
- legedemon 4y agohttps://github.com/rubysherpas/paranoia https://github.com/rubysherpas/paranoia is enough to solve problems at very large scales. There is nothing about Rails or MVC preventing someone from doing this. This is a very common design principle for all kind of ERP and BPM systems: don't ever delete anything.
- berkes 4y agoFirst: soft-delete really doesn't need a library. Paranoia is nice, but almost all of the code and complexity in that gem is to support multiple versions of rails and to let you configure that gem. DIY in this case really is very simple. And far more flexible, performant even, and future-proof. (I've worked on a project where two full-time devs spent days upgrading this gem; this is over 6 years ago). And a few months ago, I worked on a project where they had more code to configure, patch and work around paranoia, than any DIY ever did. My even simpler DIY version not only used 50% of the code we had to override the gem before, it allowed for some custom work that we could not do before. And no: even DIY ain't as simple as you make it seem. Practical issue, that I encountered last year even, was where their "soft delete" was making state-machines very tough. Because in a FSM, "deleted" wants to be state, like anything else. But the "generic soft-delete" conflicts with that. So the project had both. And some fugly glue-code to sync between the FSM and the soft-delete and vice-versa. No suprise that this broke occasionally, making data re-available that people thought gone.
- deleted 4y ago[deleted]
- sriku 4y agoHe did have to type "httpie/httpie" in the box to confirm, no? I'm rather surprised that that didn't snap him out of auto-pilot mode. There ought to have been a DING in the brain seeing that the repo this is being applied to was httpie/httpie? OTOH, I haven't been in such a mode, so I really got no right to comment on this. Best wishes to the team -- that those who saw his post will restar/rewatch the repo -- and (fwiw) thanks for writing it up and making me even more paranoid (in a positive sense) about doing such destructive operations.
- ignoramous 4y agoAll the talk about auto-pilot mode reminds me of this excellent talk on activation energy, waking up yourself from slumber, or flip-flopping between auto-pilot and emergency modes: Mel Robbins, How to stop screwing yourself over, https://www.youtube-nocookie.com/embed/Lp7E973zozc https://www.youtube-nocookie.com/embed/Lp7E973zozc
- decafb 4y agoBy now I've become so accustomed to just copy the bold text from the line above it and paste, that it doesn't break me out anymore. I know I should concentrate and type it out, but in my head it has just become visual noise and a boring exercise.
- deleted 4y ago[deleted]
- sriku 4y agoAha .. perhaps the interface can be changed to prevent copy-paste into that field.
- account42 4y agoBetter would be to not show the repo name directly above the dialog at all so the user actually has to think a bit about what they need to enter. Just re-typing a text shown to you can be done on autopilot as well.