I run a small agent on a little server. Every morning it scrapes a handful of AI labs’ blogs and writes me a digest. It had been working for weeks. Then one day I read the source pages alongside its output, and found that it had fetched one site dozens of times and silently left that site out of the report.
The header said fetched 4 sources, all OK. The body never mentioned the missing one. It did not appear in the results, in a “no updates” list, or in a “failed” list. It simply vanished. The agent was not lying on purpose. It had quietly decided that the site’s articles fell outside a time window, dropped them, and never accounted for that decision anywhere.
This is the failure mode that makes unattended loops dangerous. The danger is not a crash, because you would notice a crash. The danger is a confident success that is not one.
A loop that cannot tell you what it did not do will eventually drop something and report success.
Two missing guardrails
The bug had two halves, and both were about accounting rather than scraping.
A shared rule leaked across items. The window logic said “expand the lookback if there are fewer than three articles,” but it was evaluated globally. One prolific source filled the quota, so every other source got cut, including the one with real updates. The fix was to judge each source on its own.
There was no coverage contract. Nothing forced the agent to account for every source. The fix was to make it place each source into exactly one bucket — included, no updates, or fetch failed — and to end with a self-check line confirming that the counts add up. If the counts do not add up, the agent goes back and fixes the report before sending it.
The lesson
Neither fix made the agent better at scraping. Both fixes made it honest about its own coverage. That is the real content of loop engineering: the scraping is the easy part, and the guardrail that catches a silent omission is the work.
The cheap version of any recurring agent reports what it found. The trustworthy version reports what it found and proves that it looked everywhere it was supposed to look.