web: Atom feed omits the required id and updated elements #94

Closed
opened 2026-07-04 17:50:25 +00:00 by rosa · 1 comment
Owner

get_user_atom (crates/web/src/handlers/users.rs:534-591) builds the feed and each entry without calling .id(...) or .updated(...), so atom_syndication's builders emit empty ones.

id and updated are mandatory on both feed and entry in RFC 4287. Feed validators reject the output, and some readers will refuse or mis-handle the feed (entries without stable ids also break read-state tracking).

Suggested fix:

  • Feed id: the profile URL. Feed updated: the newest entry's publication instant (or now if empty).
  • Entry id: the post's permalink URL. Entry updated: the post's publication (or last-modified, if available) timestamp.

The RSS counterpart (get_user_rss) is fine.

`get_user_atom` (`crates/web/src/handlers/users.rs:534-591`) builds the feed and each entry without calling `.id(...)` or `.updated(...)`, so `atom_syndication`'s builders emit empty ones. `id` and `updated` are mandatory on both `feed` and `entry` in RFC 4287. Feed validators reject the output, and some readers will refuse or mis-handle the feed (entries without stable ids also break read-state tracking). **Suggested fix:** - Feed `id`: the profile URL. Feed `updated`: the newest entry's publication instant (or now if empty). - Entry `id`: the post's permalink URL. Entry `updated`: the post's publication (or last-modified, if available) timestamp. The RSS counterpart (`get_user_rss`) is fine.
Author
Owner

This was generated by AI during triage.

Agent Brief

Category: bug
Summary: The Atom feed emits an empty <id> and an epoch-defaulted <updated> on both the feed and every entry, violating RFC 4287.

Current behavior:
FeedData::to_atom_string builds the feed and its entries without setting id or updated. atom_syndication's builders then emit their defaults — an empty <id></id> and <updated>1970-01-01T00:00:00+00:00</updated> — on both the feed element and each entry. id and updated are mandatory on feed and entry per RFC 4287; validators reject the output and some readers mis-handle it. Entries lacking stable ids also break read-state tracking. The RSS renderer (FeedData::to_rss_string) is unaffected.

Note: the report cites the old location in the users handler, but the code has since been refactored into FeedData::to_atom_string — the bug moved with it and is otherwise unchanged.

Desired behavior:
The rendered Atom document carries a non-empty id and a real updated timestamp on the feed and on every entry:

  • Feed id = the blog/profile URL (FeedData::blog_url).
  • Feed updated = the most recent entry's publication instant, falling back to the current time when there are no entries.
  • Entry id = the post's permalink (the entry's url).
  • Entry updated = the post's publication timestamp. FeedData/FeedEntry carry no separate last-modified field, so published is the correct source; do not add a new field for this.

Key interfaces:

  • FeedData::to_atom_string — set id/updated on the entry builder and the feed builder. The data it needs (blog URL, per-entry permalink, per-entry published_at) is already present on FeedData/FeedEntry; no new inputs are required.
  • FeedData / FeedEntry — no shape change expected.

Acceptance criteria:

  • The rendered feed element has a non-empty id equal to the blog URL and an updated equal to the newest entry's publication instant.
  • With no entries, the feed's updated is a current timestamp (not the Unix epoch).
  • Every rendered entry has a non-empty id equal to its permalink and an updated equal to its publication timestamp.
  • A test asserts these id and updated values on both the feed and an entry (the existing round-trip test passes today despite the bug because empty ids parse cleanly — the new assertions must fail against the current code and pass after the fix).
  • The RSS output is unchanged.

Out of scope:

  • The entry <content> element, which currently uses an out-of-line src=<permalink> rather than embedding the post HTML (as RSS does). That is a separate discrepancy, not part of this issue.
  • Any change to to_rss_string or the RSS output.
  • Adding a last-modified field to the post/entry model.
> *This was generated by AI during triage.* ## Agent Brief **Category:** bug **Summary:** The Atom feed emits an empty `<id>` and an epoch-defaulted `<updated>` on both the feed and every entry, violating RFC 4287. **Current behavior:** `FeedData::to_atom_string` builds the feed and its entries without setting `id` or `updated`. `atom_syndication`'s builders then emit their defaults — an empty `<id></id>` and `<updated>1970-01-01T00:00:00+00:00</updated>` — on both the feed element and each entry. `id` and `updated` are mandatory on `feed` and `entry` per RFC 4287; validators reject the output and some readers mis-handle it. Entries lacking stable ids also break read-state tracking. The RSS renderer (`FeedData::to_rss_string`) is unaffected. Note: the report cites the old location in the users handler, but the code has since been refactored into `FeedData::to_atom_string` — the bug moved with it and is otherwise unchanged. **Desired behavior:** The rendered Atom document carries a non-empty `id` and a real `updated` timestamp on the feed and on every entry: - Feed `id` = the blog/profile URL (`FeedData::blog_url`). - Feed `updated` = the most recent entry's publication instant, falling back to the current time when there are no entries. - Entry `id` = the post's permalink (the entry's `url`). - Entry `updated` = the post's publication timestamp. `FeedData`/`FeedEntry` carry no separate last-modified field, so published is the correct source; do not add a new field for this. **Key interfaces:** - `FeedData::to_atom_string` — set `id`/`updated` on the entry builder and the feed builder. The data it needs (blog URL, per-entry permalink, per-entry `published_at`) is already present on `FeedData`/`FeedEntry`; no new inputs are required. - `FeedData` / `FeedEntry` — no shape change expected. **Acceptance criteria:** - [ ] The rendered feed element has a non-empty `id` equal to the blog URL and an `updated` equal to the newest entry's publication instant. - [ ] With no entries, the feed's `updated` is a current timestamp (not the Unix epoch). - [ ] Every rendered entry has a non-empty `id` equal to its permalink and an `updated` equal to its publication timestamp. - [ ] A test asserts these `id` and `updated` values on both the feed and an entry (the existing round-trip test passes today despite the bug because empty ids parse cleanly — the new assertions must fail against the current code and pass after the fix). - [ ] The RSS output is unchanged. **Out of scope:** - The entry `<content>` element, which currently uses an out-of-line `src=<permalink>` rather than embedding the post HTML (as RSS does). That is a separate discrepancy, not part of this issue. - Any change to `to_rss_string` or the RSS output. - Adding a last-modified field to the post/entry model.
rosa closed this issue 2026-07-05 00:49:46 +00:00
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#94
No description provided.