This is article 3 in a series about building PlannerCritic, an open-source engine where one LLM writes a plan and a second LLM reviews it. Article 1 covers the 157-goal field test. Article 2 is about the critic severity bug. This one is about the most uncomfortable thing the field test revealed: the planner has a structural problem that no model upgrade fixes.
132 concrete blockers across 63 strict goals. Three defect families. I tried gpt-4o. Same pattern. The fix is deterministic validation, not more parameters.
By the 10th strict goal, I noticed it. By the 50th, I could predict the failure before the critic printed it. By the 100th, I stopped being surprised and started being annoyed.
The planner kept making the same three mistakes. Not occasionally. Not randomly. Every single strict goal that failed did so because of one of three defect families.
Unverified dependencies (57 blockers): The plan declares a precondition that no earlier task establishes. The planner knows what should be true. It doesn't arrange the steps to make it true.
The plan says "cutover 100% of traffic" but no earlier task verifies that the 10% and 50% stages were stable.
Unsafe sequencing (46 blockers): Tasks are ordered before their hard prerequisites. The cutover runs before the verification. The backup completes after the migration.
Weak rollback (18 blockers): High-blast-radius steps lack rollback. The planner includes rollback on routine steps but omits it on cutover, teardown, and failback.
The rollback exists but it is not credible. Switching back to single-write does not undo the data inconsistencies that dual-write may have introduced.
I tested it both ways — gpt-4o planner with mini critic, and gpt-4o for both roles.
That was the moment I stopped blaming the model size. The planner wasn't dumb. That was the annoying part. It was plausible. It knew the right steps. It just couldn't close the dependency graph or enforce the ordering.
The revision loop is designed to converge. The critic reports blockers. The planner revises.
But the planner tends to fix one blocker and introduce another. It reshuffles task order without closing the dependency gap. It adds rollback to the wrong task.
After 2 revisions — the median across 33 strict goals — the planner stops making meaningful changes. The convergence detector fires. The engine escalates.
The loop works as designed. The planner is the bottleneck. I kept expecting the revision loop to converge. It didn't, because the planner can't fix a structural problem by rewriting the prose.
Worth being clear about what failed here. The critic reliably found the same blockers across revisions — the failure was the planner's inability to structurally repair, not the critic's judgment. That's a different defect from the one in Article 2, where the critic's severity calibration was the problem.
The highest-leverage fix is a precondition closer: a deterministic linter that runs after the planner produces a draft and verifies that every precondition is actually established by an earlier task. If a task says "requires replica_verified," there must be a prior task that produces it.
This single pass would eliminate 64 of 132 blockers (48%) without asking the LLM to get smarter.
