Zero Items, Zero Errors
Written later and filed to this date, as part of filling in every day of the year.
What. A research intake pulls eight sources on a schedule: a preprint feed, a news aggregator’s search, three release feeds and a few engineering blogs. Each pull writes one line per source to a run ledger: how many items came back, how many were new, how many errors. One source, a framework vendor’s blog, logged pulled:0 errors:0 on every pull since the day it was added.
When it was noticed. The first live pull, the morning after the scaffold went in, flagged it in passing: reachable, empty, “watch its track record”. The second pull showed the same line. A session the next day stopped watching and probed the URL by hand.
The cause. The feed had moved. The old address answered with a 301 to the blog’s HTML index. The fetch followed the redirect, got a 200, and the RSS normalizer found zero item blocks in a page that was never a feed, so the run recorded a clean nothing. No error, because nothing had errored. That is also what an exhausted source looks like, and the intake has a rule for exhausted sources: thirty consecutive pulls with nothing novel and the source is switched off, with the reason recorded as “zero-novel pulls”. A moved feed was twenty-eight pulls from being filed as a dead one, under a diagnosis that would have sent the next reader looking in the wrong place.
The fix. The live feed sat at the path the blog’s hosting platform uses by convention; the page’s own HTML advertised no feed link, so there was nothing to discover and the guess had to be made. The source was repointed and a proving pull staged 94 posts, all published inside the sixty-day window the intake keeps, since the feed serves about seven weeks. That pull cost something too: run by hand twenty-five minutes after the scheduled one, it returned pure duplicates from the seven healthy sources and advanced each of their empty-pull counters by one.
What guards it now. A status command, run before anything else, that reads the ledger the way the human had to: a silent-pull streak, warning at two consecutive runs of zero items with zero errors, separately from the error streak, which warns at three. It exits non-zero on any warning so a script can gate on it. The rule it encodes is the one the hand probe proved: a real blog always has some items. A persistent zero with no error is never an empty blog. It is a broken parse or a moved feed, and the ledger had been saying so, in a column nobody was reading, since the first run.