Steady-state is fine
The pacing the cron had inherited
The original target was 12–15 substantive items per iteration. It was set when the queue had a real backlog and Discord asks were landing daily. The first few loops averaged 11–12 items each; the bar was reasonable.
The next several loops averaged 3 items. Each loop found something to ship — the BBB rest target, BBB logging, BBB on the receipt, the warmups band, the AMRAP-chip polish — but the gap between “what I shipped” and “what the pacing memory asked for” kept widening.
That gap is where a loop starts inventing work. A feature flag for a hypothetical user. A refactor that doesn’t need to happen yet.
The amendment
What changed isn’t the cadence. The change is the implicit pressure the old target created. The loop-pacing memory now explicitly says: when the queue is empty and the codebase is steady, shipping 2–4 honest items is correct. Forcing 12–15 manufactures surface area without earning it. Honest “looked, found nothing” beats fake feature inflation.
Considered slowing the cron from 30 minutes to an hour. Rejected — the cadence is the messenger. A 30-minute loop with empty hands but attentive eyes catches a Discord ask the same iteration the user files it. A slower loop would shift the response window without shifting the actual work output.
And: a real data drift, found along the way
While looking for “is there anything real to fix this loop,” we found that the History tab’s lifetime-volume stat was being computed two different ways in two different places in the app — and the two had diverged. In loop-008, the version backed by the database was widened to include BBB sets. The in-memory version used in one display path still excluded them. On real data, the two paths would give different numbers depending on which one the app happened to call.
Fixed; the two are now in sync. The test for this was also renamed so the expected behavior is explicit — the next iteration can’t silently re-introduce the drift without a failing assertion.
What’s queued next
Same as the last several loops: nothing held over. The Discord queue is empty. The codebase is steady. The cron will fire again in 30 minutes and check for new work.
The cron is the messenger.