A Question Asked Three Times
NewsAgg reached a point recently where the honest answer to “what should the build fleet do here next” is: nothing. Every idea left on its list is stuck behind something only I can do: a one-time maintenance step that would flip roughly twenty already-built features live at once, or a product call about what the aggregator should actually become next. Until one of those happens, shipping anything else onto the pile is just busy-work wearing a commit message. My fleet’s scheduler is built to notice that and say so, rather than invent a feature nobody asked for to look productive. That part worked exactly as designed.
Same night, same repo, three times
What I didn’t expect was for it to say so three separate times in under three hours. A planner session ran at 11:01pm, checked the pipeline’s health, the source list, the corpus freshness, one signal that looked stale (the newest arXiv fetch was almost a day old, verified as a normal weekend gap in arXiv’s own publishing rhythm, not a regression), and concluded: still nothing to build. At 12:32am, a second planner ran the same kind of check, from scratch, and reached the same conclusion. At 1:54am, a third did it again.
None of these were rubber stamps. Each one did real, independent diligence: re-checked the stale-looking signal, re-verified the pipeline was actually healthy rather than just assuming the last check still held. That’s the right instinct in isolation: don’t trust a stale verdict, go look. The problem is that “go look” is exactly what a planner session costs, whether the answer changes or not, and nothing in the scheduling told the third planner that two sessions before it had already spent that cost reaching the identical answer.
The bug wasn’t in the pipeline
Every bug I’ve written about on this site so far has been a mistake in what a system computes: a fallback with the wrong scope, a boundary the code inferred instead of marked. This one is different: nothing computed anything wrong. Three planners each ran a correct process and reached a correct conclusion. The defect is that the fleet has no memory of its own recent verdicts across sessions: a drained repo gets staffed on the same cadence as one that’s actively shipping, so being right about “nothing to build” costs a full planner session every single cycle, indefinitely, until something upstream changes.
That’s a quieter failure mode than the ones I usually catch, because it never shows up as an error. Nothing crashes, nothing produces a wrong answer, no test goes red. The only symptom is compute spent re-deriving a fact that was already true an hour ago, the kind of waste that’s invisible unless someone reads three consecutive session logs back to back and notices they’re the same session.
The fix is restraint, not code
The third planner didn’t leave the check to be run a fourth time. It wrote the pattern itself down as the finding and handed the actual decision to me: either run the one maintenance step that unblocks the twenty waiting features (which makes the repeated checks moot, because there’d be real work again), or pause this repo’s turn in the fleet’s rotation until it genuinely needs a human call. Both are mine to make, not the fleet’s, which is why the session surfaced the choice instead of picking one. No code shipped today, on purpose. That’s the correct output of a system that would rather cost me three redundant sessions than one that silently ships filler to look busy.
The lesson points at a part of the system I hadn’t looked at yet: a component that’s good at saying “no” honestly still needs somewhere to put that “no,” or the next check starts from zero instead of from what was already known. Being right isn’t free just because it isn’t wrong.