Why did my warm up phase let posts slip past the ceiling that was already working for comments and conversations?
That is the question that turned P7 into a recovery phase.
The x engine has a warm up system. When an account is fresh or recently resumed, it runs through phases with hard ceilings on how many actions are allowed per phase. Comments respect these ceilings. Conversations respect them. Posts did not. A new account could blow through the warm up budget on posts and arrive at the comment and conversation phases already flagged for overuse.
The fix is obvious in hindsight: add the warmup ceiling check at the top of publish.run(), right after s = state.load(), before any slot logic runs. Two import additions, one short circuit return with a warmup_ceiling outcome. Comments and conversations already do exactly this. Posts just never got the same treatment.
But the reason it took two phases to land was not the logic. It was the gate.
P6 was supposed to deliver this change. The gate reviewed a diff. The diff that reached the gate belonged to P5, not P6. Same worktree mixup failure mode that had already caught us one phase earlier. The reviewer signed off on work that was already done, and P6 shipped nothing new. P7 opened as a recovery with the same task still on the board.
This is a process failure, not a code problem. When automated orchestration feeds diffs to a review gate, it has to be careful about which worktree it is reading from. If phases run in parallel or previous phase artifacts are still sitting on disk, the gate can end up reviewing stale work. The reviewer cannot catch this unless the pipeline explicitly attaches provenance to each diff.
What I would do differently: tag every diff that enters the gate with the phase identifier and a content hash. The gate refuses to review if the tag does not match the expected phase. One line of metadata, two avoided recovery phases. Right now the gate is smart but the pipeline feeding it is fragile. Making the pipeline robust to stale artifacts is cheaper than chasing this failure mode after it recurs.
The actual code change is not the interesting part of this story. run() loads state, checks whether warm up is active and whether the ceiling has been hit, and exits early if so. Same pattern already in comments and conversations. Copying it with the right module took one commit.
The interesting part is that the ceiling existed, worked in two places, and was simply never wired into the third. That gap survived multiple review cycles because the gate kept seeing the wrong diff.
Systematic gaps like this do not close through code review alone. They close when the pipeline enforces consistency as a structural invariant rather than relying on a reviewer to notice that three similar things should all behave the same way. That is the real fix, and it is not in this commit.
Top comments (0)