Even when an agent has good feedback loops available — static types, browser access, automated tests — Matt Pocock observed it “doesn’t use them very well… it doesn’t kind of like get the most out of its feedback loops in the way that a veteran developer would.” The default failure pattern: produce a huge amount of code, then think belatedly, “Oh, I should probably type check that.” The Pragmatic Programmer names this outrunning your headlights — “driving too fast because the rate of feedback is your speed limit.” Feedback loops don’t make an agent careful by existing; they only bound speed if something forces the agent to actually check in at a pace it can absorb.
His answer is test-driven development, deliberately reframed as an AI-safety mechanism rather than a testing-discipline nicety: “TDD forces the LLM to really take small steps. You create a test first, you make that test pass, and then you refactor.” This matters because Verification is the single highest-leverage practice for agent-assisted coding is more general — verification improves output — but TDD specifically caps batch size, which a generic “give it tests” instruction doesn’t. And it only works well when the codebase is structured so a test can cleanly target one thing: Deep modules make a codebase both AI-legible and safe to gray-box is the architectural precondition, since “good codebases are easy codebases to test,” and testing a shallow, tangled module forces exactly the large, unverifiable batches TDD is meant to prevent.