deleted

A  deleted  is a post that has been removed. It may still have a permalink, for purposes of returning an HTTP 410 Gone status code, and a simple static HTML h-entry tombstone saying something like "This post is gone", and a  with a non-empty value, perhaps the actual datetime of deletion (consider privacy concerns).

Why
There are numerous reasons you may want to delete a post, indicate to others that you want any copies deleted, and hoping they will delete it from their servers eventually.

Maybe you changed your mind, maybe you decided to retract your comment for further consideration, maybe you decided you did not intend to continue a discussion, etc.

How to
How to handle deleted posts, i.e. implementation details:

How to publish
When a post is deleted by the user, implementations should:
 * send a webmention to all URLs that were in the post
 * delete any POSSE copies of that post (perhaps with a delay, or "Confirm Delete" user prompt, or both). See POSSE Delete for details.

When a user (re)loads a permalink of a deleted post:
 * When the permalink of a post that has been deleted is requested, implementations should return:
 * HTTP 410 Gone
 * an HTML h-entry with prose noting the post has been deleted, and at least a link to the home page, or recent posts. You may want to consider returning a link to "nearby" (by date, topic) posts, if you're comfortable disclosing that kind of contextual information about the post that was deleted. This helps users because often posts that are deleted are subsequently "replaced" by new posts. It would be nice if those new related posts were discoverable from the deleted permalink. You could also include the date the post was deleted, marked up with . See Tombstoning brainstorm for more details.

When a user (or reader) (re)loads your stream/feed (and you have recently deleted a post):
 * When the primary stream/feed of a site that has recently deleted posts is requested, implementations should return:
 * Tombstone posts in that stream/feed for each of the recently deleted posts, with a  property set to a non-empty value, or even better, specifically the date (and time) of deletion (taking into consideration privacy considerations). See Tombstoning brainstorm for more details.

How to receive deleteds

 * When a webmention is received and the URL returns a 410 Gone HTTP Status code, implementations should:
 * remove (or tombstone, e.g. by replacing author with "user" and content with "this comment was deleted by the author" or similar) any existing copies of that URL and any syndicated content from it from site receiving the webmention.

Naming
We could informally refer to this indieweb delete protocol as the Pilgrim Protocol  in honor of Mark Pilgrim who was a strong advocate for proper use of the 410 Gone HTTP Status code, and who one day suddenly deleted his presence (indie and otherwise) from the web.

DO NOT
What not to do:

301 302 Redirect
DO NOT simply redirect deleted posts to your home page.

This is bad usability, e.g. "especially for people who tend to open a bunch of links in background tabs while reading a twitterbookica stream, then start reading those tabs, and wonder why/when they opened the homepage of some news site..." - grawity in IRC, 2013-176 unlogged.

404 Not Found
DO NOT simply return a 404 not found for deleted posts.

Publishers should not return and display a 404 page for deleted posts because: "The 410 (Gone) status code SHOULD be used if the server knows, through some internally configurable mechanism, that an old resource is permanently unavailable and has no forwarding address."

404 Discussion
Issue: 404 should be a valid response code for delete.

Reasons why we MUST NOT treat 404 as a delete:
 * Vagueness. 404 is vague and could mean any number of things (including a delete). Given its vagueness and the destructive nature of delete, it is better not to interpret it as a delete, because it very well might not mean a delete.
 * Server error. A server mistake or proxy misconfiguration could cause 404s for URLs (happens all the time), and if that were to somehow cause deletes across the web that would be a very bad thing.
 * Simpler design. A simpler protocol is better, and one way to do something is simpler than two. We already have 410 which, meaning "permanently unavailable" (RFC2616 10.4.5), in otherwords, deleted. No need to confuse publishers/consumers with another way of doing deletes (whether 404 or something else).

IndieWeb Examples
Examples of indieweb sites publishing deleted posts.

Ben Werdmuller
has implemented deleted posts support in Known (when it was idno) on his site werd.io since 2013-06-25 (per edit history of deleted).

Deleted posts are replaced (for now) with a very simple message in the form of an h-entry with a p-name and summary that explain the problem. A link is also provided to the homepage.

Example URL of a deleted post:
 * http://werd.io/view/51c94f6ebed7de537c45de63
 * as of 2016-05-02 this post returns a 410 but then immediately redirects via a 302

Aaron Parecki
has implemented deleted posts support in p3k on his site aaronparecki.com since at least 2014-08-03.

Deleted posts are replaced with a simple message in the form of an h-entry with a p-name of "Deleted" and content of "This post has been deleted." as well as returning HTTP 410. This allows consumers of this post that don't understand the HTTP status code to treat it as an update, replacing the contents of the post with the deleted text.

Example URL of a deleted post:
 * http://aaronparecki.com/notes/2014/08/03/1
 * as of 2016-05-02 this post generates a 301 instead of a 410

Ben Roberts
has impletement deleted posts support in postly on his site ben.thatmustbe.me.

postly does not currently track the date / time a post is deleted, only that it is "deleted" (does not delete from database in order to allow "un-delete"). Changing this to store the date of deletion would not be complex at all, though it is not an interest of mine. In my experience you start to get in to the question of, do i track when it was undeleted? Do I track re-deleted times? etc. It gets needlessly complex.

Example URL of a deleted post
 * https://ben.thatmustbe.me/note/2015/9/16/24/
 * as of 2016-05-02 this post returns a 410 but then immediately redirects via a 302

gRegor Morrill
implemented support on gregorlove.com as of 2014-07-01, though it broke when I switched CMS on 2015-07-12. Deleted posts are working again as of 2016-05-01.

HTTP 410 is returned along with a default h-entry with name "Deleted" and content "This post has been deleted."
 * http://gregorlove.com/2016/05/this-is-a-test-note/
 * http://gregorlove.com/2014/06/note-to-self-watch-generation-1/ First deleted post, manually re-created after fixing on 2016-05-01

bear
has implemented deleted posts support in kaku on his site bear.im since 2016-05-01.

Deleted posts are replaced with a "This post has been deleted" page and sets .

Example URL of a deleted post:
 * https://bear.im/bearlog/2016/123/testing-delete

Tantek
has implemented (some) deleted posts support in Falcon on his site tantek.com since 2016-05-08.

Deleted posts are replaced with a "This post is gone." page and sets .

Examples
 * http://tantek.com/2016/128/t2 - formerly a note
 * http://tantek.com/2018/308/t1 - deleted comment on Jeremy's Testing webmentions post

Tombstones with "dt-deleted" set are provided in his homepage h-feed of updates.

Deleted posts are completely removed from his Atom feed (until he figure out how to publish Atom entry tombstones in a way which is "correct" and preferably consumed/handled by feed readers).

j4y_funabashi
has implemented deleted posts in aruna on his site since 2016-10-17. Deleted posts are currently not shown in my feeds but I might change this to a tombstone in the future. The post's permalink shows a tombstone, e-content is replaced with "This post has been deleted" and dt-published is replaced with dt-updated which shows the date-deleted.

e.g https://j4y.co/p/20161005121412_57f4ee949fc72

Jacky Alcine
has deletion functionality in Koype. However, this deletion is not permanent. It's closer to how archiving works (removing it completely from anyone but the site's owner view). There's no information about the prior post nor is any sort of tombstoning is doen.

Reader Examples
Examples of readers that support removing of deleted posts:

SimplePie
Per https://unicyclic.com/mal/2016-05-06-deleted_post_support_in_dobrado_indieweb, SimplePie looks for a deleted property inside h-entry and if it finds one, it sets the content and title to empty strings which triggers a reader view deletion.
 * Experimental support: not pushed this change to official SimplePie yet, but you can test deleting a post and watching it get removed from a feed at unicyclic.com/indieweb. (no PuSH support, updates only occur once per hour.)

Flickr
Flickr shows a page saying something like "This photo has been removed by the user." on photo post permalinks of photos deleted by users.

What HTTP status error code does Flickr return for deleted photo posts?

Twitter
Twitter shows a generic error page eg https://twitter.com/tfadp/status/185901564131688448 with a 404 for deleted posts. However, it does send a delete notification through the stream API

Status deletion notices (delete) These messages indicate that a given Tweet has been deleted. Client code must honor these messages by clearing the referenced Tweet from memory and any storage or archive, even in the rare case where a deletion message arrives earlier in the stream that the Tweet it references.

gnip
Gnip maps the twitter deletions to an Activity Streams 1 delete discussion example

HTML meta http-equiv for status
If for some reason you are unable to configure your web server / content host to return a 410 response (e.g. GitHub pages), perhaps a meta http-equiv could work. Since the status code is returned in code explicitly as a "Status:" header, we can simply use meta http-equiv:

No known servers support this, but there's no reason they couldn't, i.e.:
 * HTTP Servers should read the  of an HTML document before serving it, and use meta http-equiv Status for the status code to return in the HTTP Response Header, if one hasn't been set by other means of configuration (e.g. in .htaccess).

It's probably a good idea to put that meta tag in the HTML you return for deleted comments in addition to returning the 410 status code.

Adding http-equiv parsing to uf2 parsing sounds like it might be a good strategy:

From irc http://indiewebcamp.com/irc/2014-04-09: 10:56 it would be great if the http-equiv was included in the result of microformats parsers, like how "rels" is ... 10:57 example: https://gist.github.com/aaronpk/10297489

Captured:
 * http://microformats.org/wiki/microformats2-parsing-brainstorming#Add_meta_http-equiv_to_microformats2_parsing_model

See the meta http-equiv status HTML extension specification for updates and details.

Tombstoning
Even though a deleted post returns an HTTP status code of 410, it could also be useful to communicate the date of the deletion and/or a helpful human-friendly message, perhaps indicating why the post was deleted.

Such tombstone information (date deleted, deletion message) could be private (kept as a note for the author/deleter) or public.

A deleted post could publish this information with:
 * an h-entry with at minimum:
 * for the deletion date. (the original dt-published date could be kept too)
 * for the deletion message.

Plain text deleted post
A plaintext tombstone for a deleted post could look like: "I deleted a post. 15th May 2015, 13:06+01:00. Author Name."

With microformats:

 I deleted a post. 15th May 2015 13:06 Amy Guy

Time of deletion
By adding a  it would be possible to detect that the tombstone is a tombstone and when it became a tombstone thus distinguishing tombstones easily from non-tombstones and making it possible to handle and present them in special ways.

Date of deletion
In 's new version of p3k, it keeps track of the date the post was deleted, and also writes a "deleted" entry to the changelog stream. This means a deleted post knows the date it was deleted, and the delete action itself has a permalink.

Notifying Responses

 * send a webmention to all responses to the post (so the responses can update their reply-context, per reply-context CRUD, possibly notify the responder so they can update or delete their response).
 * Note: this is subject to the issues documented re: reply-context CRUD

Upstream Downstream Confusion
Regarding sending webmentions to responses to a post:
 * This sounds like an experimental addition to me, webmentions are only sent upstream – never downstream. Sending webmentions downstream can, especially in the case of updates, have side-effects for those not expecting such webmentions. I would say that one should _not_ do this. Pelle Wessman 04:43, 8 May 2016 (PDT) [06:03am]


 * This use of upstream/downstream makes no sense to me. Because AFAIK both are done "normally". An original post sends *downstream* webmentions to e.g. every link mentioned in the content body, person-tags etc. a *reply* post sends *upstream* webmention to the original post it is in reply to. so a *reply* post that itself has links inside its content sends BOTH *upstream* webmention(s) to the links it is in reply to (e.g. multi-reply) AND sends downstream webmentions to the links in its content. so this statement makes no sense: "webmentions are only sent upstream – never downstream." Tantek 06:12, 8 May 2016 (PDT)


 * "things a post mentions" -> upstream, "things mentioning a post" -> downstream. That's at least how I've been looking at things. Pelle Wessman


 * threads have a notion of order and thus up/down. because threads have a notion of order and thus up/down. and an original post is at the top, and thus everything it mentions is "downstream". responses are the only things that send webmentions "upstream" because they are a response to something that came before. Tantek 06:12, 8 May 2016 (PDT)


 * lets skip the specific terms of "upstream" and "downstream" then as that apparently adds confusion maybe due to language barriers or through something else, and lets talk about the difference between things a page mentions and things mentioning a page instead. I find the distinction between the two to be valuable and so far my impression is that webmentions has been focused on pinging things a page mentions rather than things mentioning a page Pelle Wessman 06:16, 8 May 2016 (PDT)


 * This is perhaps the core issue — I see no distinction in those two expressions things a page mentions and things mentioning a page. Pages link to pages, period, and any such link is worthy of a webmention. Tantek 06:19, 8 May 2016 (PDT)

Threaded Comments Problems

 * "Delete" could cause some issues on threaded comment implementations. If a whole discussion starts based on one Webmention, a delete could result in a) deleting a whole discussion thread or b) destroying the context be deleting one of the root-element. An example of threaded Webmentions: http://notizblog.org/2013/06/20/5231/#comments --Matthias Pfefferle
 * The way threaded forums like Hackernews and Reddit handle this could be a good solution. When there is a post that is deleted, it will turn into a grey placeholder that says "deleted" with no author information or timestamp, but all threaded replies below still appear. This way readers know there used to be something there in case part of the discussion no longer makes sense. Aaronparecki.com 07:20, 26 June 2013 (PDT)
 * What Aaron suggests (e.g. "turn into a grey placeholder that says "deleted" with no author information or timestamp") is perfectly fine. Hence the "shoulds" in the spec. Tombstoning rather than deleting is perfectly fine. I'll clarify in the How To accordingly. Tantek 17:43, 26 June 2013 (PDT)
 * +1

Three Cases

 * Www.sandeep.io 03:24, 26 June 2013 (PDT): Based on my experience there are three cases from a webmention receivers perspective : (how is this an issue? - these were real-world cases that were not handled at the time, and one of them is yet unsolved -Www.sandeep.io 10:09, 28 June 2013 (PDT))
 * Deletion of source post
 * Change in rel type from source to target
 * This is closer to an update, or perhaps a move? This should be explicitly described in "update" handling (will do so). Tantek 17:43, 26 June 2013 (PDT)
 * unlinking from source to target.
 * This also feels like an update variant. I'll update (heh) accordingly. Tantek 17:43, 26 June 2013 (PDT)
 * This happened yesterday on sandeep.io. Received two webmentions from the same resource, one from its canonical URL and one from an alternative archive/date-based URL. There is no good way to delete such webmentions remotely, yet. -- Www.sandeep.io 16:25, 27 June 2013 (PDT)
 * One way to solve this might be to look for rel="canonical" and use that as source instead of the URL that was sent as source in the webmention.

No Plans To Implement

 * No plans to implement storing deleted content/URLs
 * "I don't have plans to implement" is not an excuse to screw up a protocol.
 * consider keeping tombstones for deleted URLs as a part of cool URIs don't change.
 * Another technique is to simply keep a list of deleted URLs and check those to return a 410. This could even be done in an .htaccess file that sets the response code to 410.
 * Yet another technique is to simply keep a recent (past month?) cache list of deleted URLs and check those to return a 410. That should be good enough for real-time deletes to work, and if those URLs eventually expire from that cache and start returning 404s later that's ok because anyone who cared about the deleted semantic already took care of it.

Discussion

 * A (practical) workaround that I've figured out (to avoid the extra work needed for responding with a 410 and also avoiding a 404) is to simply change the content of my comment to "This post has been delete." and sending a webmention for updating the comment. -Www.sandeep.io 20:01, 7 July 2013 (PDT)
 * Avoids extra work needed for responding with a 401. -Www.sandeep.io 20:01, 7 July 2013 (PDT)
 * Avoids sending a 404. -Www.sandeep.io 20:01, 7 July 2013 (PDT)
 * Does not require the target to implement tombstoning. -Www.sandeep.io 20:01, 7 July 2013 (PDT)
 * Interestingly, it gives the commenter (content-owner) more control over explaining the intent of the delete (for example: "I retracted this post because it was very rude and inappropriate.") than if it were tombstoned by the target. -Www.sandeep.io 20:01, 7 July 2013 (PDT)
 * For non-comment responses (like, repost, mention), I will unlink target from source and send a webmention resulting in a delete. -Www.sandeep.io 01:24, 8 July 2013 (PDT)
 * This leads me to believe that update might be enough and we could skip the concept of delete altogether? -Www.sandeep.io 20:01, 7 July 2013 (PDT)