Back in 2015, I started hearing rumors about a project I'll give the codename BOOKS. The lead programmer was a nightmare. The code was overly complicated. Twenty users relied on BOOKS daily, hundreds more used it at least once a month, and none of them were happy.
I had just deployed my fifth application in the last 12 months. My boss came to me and said, "I need you to go fix the BOOKS app." The team lead of BOOKS had already been fired before I arrived -- that was one problem solved.
It took me a couple of weeks to get the lay of the land. All of the rumors were true: the code was overly complicated, the users hated the application because it was tedious to use, and the interface was just as complicated as the code. To cap it off, BOOKS was deployed once a quarter because the changes took so long, which left the users with a backlog of frustrations and zero trust in the developers.
The daily users were led by a woman I'll call the Queen of the Damned. She didn't trust technology, and she didn't trust the developers -- they'd been making her life miserable for three years. My boss, one of the hundreds of regular users, had his own list of features he wanted implemented. Everyone expected me to just roll up my sleeves and start coding, but I knew the tortured codebase would only cause more delays.
I came to a terrible conclusion -- the one the experts warn you never to consider: we needed to rewrite the whole application. Every developer agreed. The Queen and everyone else were rightly skeptical. I'd have to prove it could be done.
I wrote up an analysis of what was wrong with the application as it stood, explained why the code was a nightmare in terms the users and managers could actually follow, and backed it with hard data from previous deployments. Then I spent two hours writing a detailed specification for how the new system would work: what we'd keep, what we'd change, what new ideas we'd bring in. I included every usability fix that would improve life for the daily users and the occasional ones, and explained why a whole new codebase would make all of it easier. I estimated four months to finish.
I scheduled a presentation for the users a month out, and one for management a week after that -- if I couldn't get the users on board, I'd cancel the management meeting entirely. Armed with the specification, I went to work on a prototype.
A month later, I presented the analysis, the specification for the new application, and a working prototype -- having gone the extra mile to import existing data and show off the improved usability that would save everyone real time. There were high-fives from the users. They pushed me to get in front of management as fast as possible. The Queen of the Damned volunteered to come along and vouch for it herself.
Two hours of specification writing, one month to build a demo, and four months later we shipped the new BOOKS codebase to production. It wasn't a big application. It never needed to be as convoluted as the original developer made it. I've followed the same pattern for ten years since. Sometimes it's faster, sometimes slower, but avoiding overcomplication is still the winning move.
Something interesting happened two years ago. Something even more interesting happened two weeks ago.
Two weeks ago, my boss asked me to build a new application, codenamed TUTOR. Nothing about it is big, and there's nothing groundbreaking in it. Since there wasn't a lot of clarity from the managers -- they were describing a pile of clicks, because folders and files are the interface they know, when there's always a better design available -- I wanted to show them a demo of how it would actually work.
It took me about two hours to write a detailed specification. Three hours after that, I had a working demo.
Going from a month to build a demo down to five hours sounds like a stretch. How did I get 53x faster? A little recent history first.
Two years ago, a new kind of tool -- Large Language Models, AI -- landed in the world. I've been vibe coding with LLMs to help manage AWS environments, which is most of what my DevOps work has looked like the last couple of years. Vibe coding often makes a mess, and that mess is what people have started calling AI slop.
Vibe coding and AI slop are both giving LLMs a bad reputation they don't deserve -- both terms really describe the users of the LLM, not the LLM itself. Being fairly new to DevOps myself, I'd been hand-wavy with my instructions: start with a paragraph describing what you want, then keep poking the model with a stick until something works. That process reliably produces AI slop -- code that runs, but isn't maintainable, probably isn't efficient, and no real developer would take pride in. In short, I'd been using the tool wrong.
History lesson over. Back to the story.
How do you avoid AI slop? By writing detailed specifications and following a practice called Research/Plan/Implement, or RPI. I was introduced to RPI by a company called HumanLayer, which has an open-source tool called CodeLayer for interacting with LLMs to build code. CodeLayer runs on Anthropic's Claude Code underneath, and its "commands" for Research, Plan, and Implement are really just prompts that tell Claude what to do at each step. The Research and Plan commands each produce a real document as output; if you've done those right, the Implement command produces working, tested code.
So two weeks ago, I got to work early. Started at 7am. Finished the specification at 9:30am. Fired up CodeLayer and kicked off Research with that specification at 9:45am. By 10:20am, CodeLayer and I had a Plan -- six phases. I started a new session and told it, "Implement Plan 'Site Design' Phase 1," then repeated that for each phase in turn. By 12:38pm, I had a working demo.
It all started with the specification. It was genuinely detailed: every component that needed to be built, how each behaved on mobile versus desktop, all the mock data and how it would be presented. The interactions were a little complicated, so I was specific about each one and how it touched the rest of the application. Following the RPI pattern from there -- Research to understand the requirements, Plan to get specific and break the work into phases, Implement to build each phase -- I got in five hours what had previously taken a month.
That's the power these tools actually have. The lesson is you can't hand an LLM a vague, hand-wavy suggestion of a specification and expect a good result out the other end. Garbage in, garbage out was true for programming long before LLMs existed, and it's just as true now. Ignore that at your own peril.