Topics follow the feed, not only the posts - #147
Merged
Conversation
`feeds.category` has always been re-derived on every successful crawl, but topics were gated on `publishedSomethingNew || existingTopics === 0`. That asks the wrong question. `topicsFrom` reads the channel's own categories, title and description as well as its items, so a publisher can change what their feed is about without publishing anything: retag it, rename it, rewrite the standfirst. For a blog that then goes quiet the gate was never true again, and the directory filed it under whatever it happened to be about on the last day it posted. Re-deriving every crawl is affordable because of the diff, not in spite of it. The three reads it needs are already issued whenever auxiliary writes are on, so this adds no round trip; `topicsFrom` is pure computation over a document already parsed; and `keywordDiffStatements` emits nothing when the extracted set matches what is stored, which for a quiet feed is every time. The second test asserts that directly rather than through the rows, because `feed_keywords` carries no timestamp and "rewritten to the same values" is indistinguishable from "left alone" -- the same indistinguishability that hid this cost before. The write cost that forced `CRAWL_AUXILIARY_WRITES=0` is *first* crawls, where every topic is a genuine insert and no diff can help. That is a property of the backlog and is unchanged here; this is inert until that switch goes back on. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feeds.categoryhas always been re-derived on every successful crawl. Topics were not: they were gated onpublishedSomethingNew || existingTopics === 0.That asks the wrong question.
topicsFromreads the channel's own categories, title and description as well as its items, so a publisher can change what their feed is about without publishing anything — retag it, rename it, rewrite the standfirst. For a blog that then goes quiet the gate was never true again, and the directory filed it under whatever it was about on the last day it posted.Why this is affordable
Re-deriving on every crawl is cheap because of the diff, not in spite of it:
topicsFromis pure computation over a document that is already parsed;keywordDiffStatementsemits nothing when the extracted set matches what is stored — which for a quiet feed is every time.The second test asserts that last point directly rather than through the rows, because
feed_keywordscarries no timestamp, so "rewritten to the same values" is indistinguishable from "left alone" — the same indistinguishability that hid this cost in the first place.What this does not change
The write cost that forced
CRAWL_AUXILIARY_WRITES=0in production is first crawls, where every topic is a genuine insert and no diff can help. That is a property of the backlog, not of this gate. This change is inert until that switch goes back on.Tests
Full workspace suite green (11 packages, 0 failures). Two new cases in
packages/ingest/test/recrawl.test.js:🤖 Generated with Claude Code