Structure Drift Detection
Vendors sometimes change their changelog page structure or feed format without notice. A heading selector that worked last month might break. An RSS feed might switch to Atom.
Watch Changelog computes a cheap hash of the feed or page shape and compares it to the last known structure. When the hash changes, we flag the source for investigation.
What We Hash
Section titled “What We Hash”For each source, we compute a SHA-256 hash of:
- adapterType: rss, atom, github, or html
- contentType: HTTP Content-Type header (if available)
- itemKeys: A stable sorted list of feed field names or HTML selectors
Example for an RSS feed:
{ "adapter": "rss", "content": "application/rss+xml", "keys": ["description", "link", "pubDate", "title"]}Example for an HTML changelog:
{ "adapter": "html", "content": "text/html", "keys": [".changelog-entry h3", ".changelog-entry .date", ".changelog-entry a"]}The hash is stored in ChangelogSource.structureHash.
When Structure Changes
Section titled “When Structure Changes”When we fetch a source and the computed hash differs from structureHash:
- We set
structureChangedAtto the current timestamp - We store the new hash
- The source is flagged for manual review
This does not automatically mark the source as degraded. It is a signal that the adapter might need updates.
Database Fields
Section titled “Database Fields”model ChangelogSource { // ... structureHash String? // SHA-256 hex of structure shape structureChangedAt DateTime? // When we detected the hash changed // ...}Implementation
Section titled “Implementation”The structure hash helper is in lib/changelog/structure-hash.ts:
computeStructureHash({ adapterType: "rss", contentType: "application/rss+xml", itemKeys: ["title", "link", "pubDate", "description"]})// Returns: "a3f8b2..." (SHA-256 hex)The fetch job (not in this pass) will call this helper and compare the result to the stored hash.
Learn about Health and Billing to understand how degraded sources are handled.