domain: deleting the published property on a live post leaves it Published but invisible #87

Open
opened 2026-07-04 06:04:45 +00:00 by rosa · 0 comments
Owner

Found during triage of #53.

Location: crates/domain/src/models/micropub.rs (MicropubUpdate::apply_to, the published branch)
Severity: Correctness — silent invisibility

Problem

A Micropub update with delete: ["published"] on a Published post resolves published_at to None while the status stays Published. Post::is_live requires published_at.is_some_and(|p| p <= now), so the post silently drops out of public view, listings, and webmention dispatch while still reporting itself as Published. The current resolution behavior is codified by the clear_published_unsets_it unit test.

Why #53 doesn't cover this

The #53 fix is deliberately transition-based: it defaults published_at only when a status change to Published leaves it unset, and never counteracts a delete operation the client explicitly specified (Micropub update semantics define what the specified operations do; re-adding a property the client just deleted would contradict the request).

So this case needs its own semantics decision. Options:

  1. Reject — a Published post must carry a publish date; a delete of published without also leaving the published state is an invalid request.
  2. Honor literally — the post goes dark (today's behavior). If chosen, it should at least be a documented, intentional outcome rather than an accident.
  3. Reinterpret — e.g. treat it as reverting the post to draft. Probably the most surprising option.

Failure scenario

Publish a post via Micropub (published_at set), then send an update deleting the published property with no other changes. The post remains Published but is_live is false forever; only the author sees it, and no un-publish webmentions go out.

Found during triage of #53. **Location:** `crates/domain/src/models/micropub.rs` (`MicropubUpdate::apply_to`, the `published` branch) **Severity:** Correctness — silent invisibility ## Problem A Micropub update with `delete: ["published"]` on a Published post resolves `published_at` to `None` while the status stays `Published`. `Post::is_live` requires `published_at.is_some_and(|p| p <= now)`, so the post silently drops out of public view, listings, and webmention dispatch while still reporting itself as Published. The current resolution behavior is codified by the `clear_published_unsets_it` unit test. ## Why #53 doesn't cover this The #53 fix is deliberately transition-based: it defaults `published_at` only when a status change to Published leaves it unset, and never counteracts a `delete` operation the client explicitly specified (Micropub update semantics define what the specified operations do; re-adding a property the client just deleted would contradict the request). So this case needs its own semantics decision. Options: 1. **Reject** — a Published post must carry a publish date; a `delete` of `published` without also leaving the published state is an invalid request. 2. **Honor literally** — the post goes dark (today's behavior). If chosen, it should at least be a documented, intentional outcome rather than an accident. 3. **Reinterpret** — e.g. treat it as reverting the post to draft. Probably the most surprising option. ## Failure scenario Publish a post via Micropub (`published_at` set), then send an update deleting the `published` property with no other changes. The post remains `Published` but `is_live` is false forever; only the author sees it, and no un-publish webmentions go out.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rosa/vernier#87
No description provided.