A defined workflow beat every clever prompt I wrote
When I started ParkEase I spent a lot of energy on prompts. Long ones. "You are a senior engineer who…", step lists, examples, warnings in capitals. They helped for about one session.
The thing that actually changed the quality of the AI's output wasn't a better prompt. It was a workflow the AI couldn't talk its way around: fixed phases, named gates, and a rule that skipping one had to be said out loud. Here's why that works better, and three times it caught something I'd have shipped.
Why prompts don't scale
A prompt is a request. The model weighs it against everything else in its context, including its own momentum toward "done". Late in a long session, "remember to run the security review" competes with a nearly finished feature and a model that would very much like to report success.
A workflow is different in three ways:
- It's the same every time. I don't have to remember to ask for tests; the build phase is "tests first".
- It's specific at the moment it matters. The verification instructions load when the agent is about to claim it's done, not 40,000 tokens earlier.
- It produces evidence, not assurances. The ship phase is a table: each line has a command, an output, a pass.
A prompt gets you "I've thoroughly tested this". A gate gets you the test output.
Three times a gate caught it
- The palette that failed accessibility. The design gate made the AI render three visual directions before building screens; I picked one, called Wayfinder. It came with a vivid cobalt and a vivid green. A token test then computed every colour pair against white: the vivid cobalt measured 4.10:1, the green 3.77:1, both under the 4.5:1 minimum for normal text. Fourteen-pixel button labels would have failed. The fix was a two-tier palette: darker tones for anything with text on it, the vivid ones only for map pins and large fills that carry their own label. Now a palette change that breaks contrast fails a test before anyone sees it.
- The checkout page that could run another user's code. Payments open Razorpay's checkout in a WebView. The first version built the checkout page by putting the booking details, including the space title, into a script block. Space titles are written by owners. Then a test tried the nasty case, a title containing
</script><script>…, and it broke out of the block. That's cross-user script injection, in the payment path. The fix wasn't better escaping; it was never putting another user's text into a document we build at all. The values now travel through the WebView's typed channel. - The security control that protected nothing. An earlier version of that same checkout file exported an origin allowlist, with a test proving it was all-Razorpay. It was never wired to the WebView. The security review pass caught it. The comment it left behind is the most useful sentence in the file: A control that is defined, tested and unused is worse than no control: the test reads as assurance and there is none.
None of these needed a smarter model. They needed a step where someone, or something, was required to look.
What a workflow costs
It isn't free. Every gate is tokens, and gates that dispatch separate reviewer agents are a lot of tokens. I learned that the expensive way (post 14). And it adds latency: a two-line fix still passes through verify.
The trade is worth it for one reason. With AI, producing code is cheap and trusting it is expensive. A workflow moves effort from the cheap side to the expensive side.
Next: a 1,550-line file of mistakes. How learnings.md gave an AI with no memory a memory, and the entries that saved the most time.
ParkEase is a peer-to-peer parking marketplace for India, built solo with Claude Code. Code: https://github.com/Deonkar/parkease
Comments
No comments yet. Start the discussion.