What happens when the safety mechanism that protects your posting schedule becomes the exact thing that will get your account flagged?
That is the problem I ran into with floor_catchup(). The function exists for a good reason: if you fall behind your target posting cadence because of a quiet hours gate, a failed draft, or a slot that got skipped, it adds catch up variance to pull volume back toward the daily floor. Keeps the account healthy over a week. Works great in steady state.
During account warm up it is a liability.
Warm up is the period where a new or recovering account deliberately stays below its long term posting target. The whole point is to look like a cautious new user, not a bot that missed a week and is now firing at full speed to compensate. If floor_catchup() runs while WARMUP_ENABLED = True, it sees the gap between current volume and the floor and helpfully injects catch up posts. The account spends warm up posting like it is already warm. That is the opposite of what warm up is supposed to do.
The fix is almost embarrassingly simple. At the top of floor_catchup(), I added a guard:
if config.WARMUP_ENABLED:
return 0
Return zero. Do not compute the gap. Do not add volume. Exit immediately.
The tradeoff is explicit: you accept that the account will under post against its floor during warm up. You are choosing that deliberately. A floor exists to prevent the account from going silent; during warm up, going a little quieter than the long term target is not a bug, it is the intent. The ceiling guard introduced in P4 already enforces an upper bound on warm up volume. This patch neutralizes the lower bound pressure that was working against it.
Testing this required two distinct paths. I added test_variance_warmup.py with six tests: three verify that floor_catchup() returns 0 across various gap sizes when WARMUP_ENABLED is set, and three verify that the existing catch up math runs normally when warm up is off. The second group is not redundant with the pre existing test_post_floor.py suite, it is a regression guard. The last thing I want is a future refactor that breaks the warm up branch while all the steady state tests still pass, leaving me with no signal until I notice the account behaving oddly. All 14 tests pass.
One thing I would do differently: the configuration check should probably be more granular. Right now WARMUP_ENABLED is a single boolean that mutes the entire catch up mechanism. A cleaner model would distinguish between the warm up phase and the post warm up ramp: once an account graduates from warm up, there is a period where you might want partial catch up (say, 50% of the normal floor gap) rather than snapping immediately to full catch up volume. The current binary works, but the transition out of warm up is abrupt in ways that a graduated ramp would smooth out.
The broader lesson is that steady state and warm up are genuinely different operating modes and they need separate logic, not just parameter tweaks. Anywhere the account's normal self regulation assumes it is already at cruise speed, you need to check whether that assumption holds during warm up. floor_catchup() was the fifth place I found this assumption embedded. I doubt it will be the last.
Top comments (0)