###################################

PROJECTS


// Prototypes, Experiments & Notes


###################################

RSS to Atom Feed Comparison Notes

Task 1: GUID/ID Matching ✅

Status: All match perfectly!

PostRSS <guid>Atom <id>Match
bookclubhttps://alabut.com/writing/bookclubhttps://alabut.com/writing/bookclub
photobrainstorminghttps://alabut.com/writing/photobrainstorminghttps://alabut.com/writing/photobrainstorming
mudfunhttps://alabut.com/writing/mudfunhttps://alabut.com/writing/mudfun
shelterislandhttps://alabut.com/writing/shelterislandhttps://alabut.com/writing/shelterisland

Why this matters: Feed readers use these IDs to detect duplicates. Matching IDs ensure a smooth transition without duplicate posts.

How it works: The <data class="u-uid" value="..."> in your HTML maps to Atom <id> via Granary, which matches your RSS <guid>.


Task 2: Feed-Level Description ⚠️

Status: Granary limitation - confirmed not supported

RSS has:

<description>Writing by Al Abut, a product designer and startup veteran.</description>

Atom should have (but doesn’t):

<subtitle>Writing by Al Abut, a product designer and startup veteran.</subtitle>

HTML has:

<p class="p-summary">Writing by Al Abut, a product designer and startup veteran.</p>

Investigation results:

Action items:


Task 3: Is Feed Description Needed? 🤔

Answer: Optional, not critical

Findings:

Recommendation:


Task 4: Other Field Comparisons ✅

Feed-Level Fields:

FieldRSSAtomMatchNotes
Title<title>Al Abut</title><title>Al Abut</title>Perfect match
Link<link>https://alabut.com/</link><link rel="alternate" href="https://alabut.com/" />Same URL, different structure (normal)
IDN/A (RSS doesn’t have feed ID)<id>https://alabut.com/projects/microformats/mainfeed/static/</id>⚠️Atom ID is the static page URL, not site root. This is expected for Granary-generated feeds.
Description<description>Writing by...</description>Missing <subtitle>Known Granary limitation (see Task 2)
Language<language>en-us</language>xml:lang="en-US"Same language, different format (normal)
UpdatedN/A<updated>2025-12-05T22:33:00+00:00</updated>N/AAtom requires this (uses most recent entry date)
AuthorN/A<author><name>Al Abut</name><uri>https://alabut.com/</uri></author>N/AAtom has author, RSS doesn’t (normal)

Key insight: The Atom feed ID being the static page URL is actually correct for Granary - it identifies the source HTML page. This won’t cause issues with feed readers.

⚠️ Important for production: When moving to /feeds folder, the feed <id> should point to your production feed URL (e.g., https://alabut.com/feeds/main), not the test static page.

Entry-Level Fields (Example: “bookclub” post):

FieldRSSAtomMatchNotes
ID/GUID<guid>https://alabut.com/writing/bookclub</guid><id>https://alabut.com/writing/bookclub</id>Perfect match (critical for duplicates)
Title<title>The Non-Designer's Design Book</title><title>The Non-Designer's Design Book</title>Perfect match
Link<link>https://alabut.com/writing/bookclub</link><link rel="alternate" href="https://alabut.com/writing/bookclub" />Same URL, different structure (normal)
Summary/Description<description>Revisiting a 90's classic...</description><summary>Revisiting a 90&#39;s classic...</summary>Same content, HTML entity encoding difference (normal)
Date Published<pubDate>Fri, 05 Dec 2025 22:33:00 GMT</pubDate><published>2025-12-05T22:33:00+00:00</published>Same moment, different format (RSS uses RFC 822, Atom uses ISO 8601/RFC 3339)
Date UpdatedN/A<updated>2025-12-05T22:33:00+00:00</updated>N/AAtom requires both published and updated (uses same value here, which is fine)
Content<content:encoded> (HTML escaped)<content type="html"> (CDATA)Same HTML, different encoding (both work in readers)
AuthorN/A<author> (empty URI)N/AAtom has author element but empty (inherits from feed level)

Date format explanation:

Content encoding explanation:


Additional Atom-Specific Elements (Not in RSS)

These Atom elements don’t exist in RSS but are not migration blockers:

ElementPurposeExampleNotes
<link rel="alternate" href=".../static/" />Points to HTML source pagehttps://alabut.com/projects/microformats/mainfeed/static/Informational - shows where Granary gets the feed from. Keep HTML page private to avoid feed readers showing users a choice between HTML and Atom feeds.
<link rel="ostatus:conversation">ActivityPub/OSTatus conversation thread IDhttps://alabut.com/writing/bookclubFor Mastodon/compatibility - not needed for RSS migration
<link rel="self"> (in entries)Canonical URL of the entryhttps://alabut.com/writing/bookclubShould match entry’s alternate link (it does)
Empty <author> in entriesInherits from feed-level authorEmpty URI, inherits nameRSS doesn’t have per-entry authors, so this is fine

Key takeaway: These are Atom/ActivityPub enhancements. Feed readers that support Atom will use them, but they don’t affect duplicate detection or migration compatibility.


Key Concepts Learned

GUID/ID Matching

Feed Descriptions

Granary Conversion


Summary: Critical vs. Nice-to-Have

✅ Critical for Invisible Migration (All Match!)

These fields must match exactly to prevent duplicate posts in feed readers:

  1. Entry ID/GUID ✅ - All 4 posts match perfectly
  2. Entry Title ✅ - All 4 posts match perfectly
  3. Entry Link ✅ - All 4 posts match perfectly
  4. Entry Published Date ✅ - All dates match (different formats, same moment in time)
  5. Entry Content ✅ - HTML content matches (different encoding, same result)

Result: Your Atom feed is ready for migration from a duplicate-prevention standpoint!

⚠️ Format Differences (Normal, Not Issues)

These are expected differences between RSS and Atom formats. Feed readers handle both correctly:

📝 Nice-to-Have (Not Blocking)

These would be nice for parity but won’t cause issues if missing:

  1. Feed Description/Subtitle ⚠️ - Granary limitation, doesn’t affect duplicate detection
  2. Feed Language ✅ - Present in both (different format, same value)
  3. Feed Updated Date - Atom-only field (uses most recent entry date)

🎯 Migration Readiness Assessment

Status: ✅ READY FOR MIGRATION

All critical fields match. The format differences are normal and expected. Feed readers will:

Next Steps:

  1. ✅ Field comparison complete
  2. ⏭️ Test with live URL (when ready)
  3. ⏭️ Set up redirect from RSS to Atom
  4. ⏭️ Monitor for any issues after switch

Production Migration Checklist

When moving from test (/projects/microformats/mainfeed/static/) to production (/feeds/):

Feed Structure

Note: Keep HTML pages private/test-only to avoid feed readers auto-discovering them and showing users a choice between HTML and Atom feeds.

Feed ID Considerations

Current (test): <id>https://alabut.com/projects/microformats/mainfeed/static/</id> Production should be: <id>https://alabut.com/feeds/main</id> (or your chosen feed URL)

Why this matters: The feed ID is a stable identifier. If it changes between test and production, some feed readers might see it as a “new” feed. However, since you’re redirecting from the old RSS URL, this should be fine - readers will follow the redirect and get the new feed ID.

Redirect Strategy

Static vs Dynamic Template

Recommended approach: Use static HTML first, convert to Astro template later

Why static first:

When to convert to Astro:

Alternative: Convert to Astro now if you’re confident, but adds complexity during migration validation.