Going Cold Turkey
What happens when the Claude bill stops being subsidised?
Your AI is only as good as the ticket you hand it. We dig into how vague requirements sabotage both humans and machines, why Behaviour Driven Development (BDD) acceptance criteria act as a clarity multiplier, and how the simple Given-When-Then structure turns fuzzy intent into something AI can reliably execute. If you’re leading teams, working with AI agents, or just tired of reviewing PRs that “technically work” but miss the point, this is your guide to writing tickets that actually get the right thing built.
Suppose you’re about to point your AI agent at a ticket you want implemented…
Give it an empty ticket with just a title, and the odds are high that you’ll get garbage out.
Give it a vague description of the problem, and it’ll go off in unwanted directions; you’ll spend hours going in circles clarifying what you intended.
So how do we keep your AI agent on task? Allow me to introduce Behavior Driven Development (BDD) acceptance criteria.
BDD is an approach to writing structured acceptance criteria that is accessible to technical and non-technical audiences alike. Crucially, it describes the intended *behaviour *of a change, without being prescriptive of the implementation.
Give your AI agent BDD-style acceptance criteria, and it will have everything it needs to ensure the changes it makes will satisfy the expectations of what was originally intended.
BDD focuses on an “articulate before you build” mindset, by giving you a simple framework for expressing acceptance criteria, in the form of:
This structure transforms vague requirements into something concrete, executable, and testable.
The following two examples contrast the difference between a vague ticket and a BDD ticket…
Example of a vague ticket:
Title: Fix user draw validation
Description: Users shouldn't be able to draw if charged off
The same ticket with BDD acceptance criteria:
Title: Prevent charged-off users from taking draws
Given a user has been charged-off in the past
When they attempt to take a new draw
Then they should be blocked from taking a draw, and a fraud validation error message should be returned
Given a user has never been charged-off
When they attempt to take a new draw
Then the draw should proceed normally
The difference?
The vague ticket is a guessing game that leads to:
The BDD ticket:
When you were writing all the code yourself, vague tickets were expensive but survivable — you could fill in the gaps from context in your head (most of the time).
What happens when you drop that ticket into your backlog and come back to it a couple weeks later? How much of that context survived the passage of time? What about if you have to hand that ticket over to a team mate after a couple weeks in your backlog - how much of that important context survived? Increasingly, AI is becoming that team-mate.
When you’re handing tickets to AI, vague tickets become a risk.
AI can’t read your mind. It can’t attend your standup and it can’t ask clarifying questions in Slack (at least not yet). AI agents will make assumptions and fill in the gaps - and it will be wrong in subtle ways that are time-consuming to correct.
This is why some engineers get dramatically better results from AI tools than others. It’s not magic. It’s all about clarity of intent.
A well structured BDD acceptance criteria doesn’t just help AI agents write better code. It *informs *the AI agent on what behaviour to test for, so it can then successfully write the code you’ve asked for. BDD acceptance criteria creates a contract that both humans and machines can execute against.
Here’s a pattern most of us fall into: write the code, then write the tests.
It feels natural. It’s efficient. Unfortunately, this pattern has one massive blind spot: Without BDD, when we bolt on tests after writing the code, we’re operating on a hidden assumption that the code ***already***** correctly behaves as we intended and achieves the desired outcome.**
This is the gap between intention and implementation. It’s where quality slips through the cracks. Without BDD, the post-coding tests we write are great at catching compilation errors, runtime errors, edge cases, and boundary conditions - however they rarely test against acceptance criteria because the language to do so was missing.
Indeed once we get to writing the tests, we’ve already convinced ourselves the code does what we want, and so the tests we write will just assert what the code does.
You’ve probably heard of Test Driven Development (TDD) — writing failing tests first, then writing code to make those tests pass. TDD was specifically designed to solve the blind spot problem we discussed above. But you don’t need to adopt TDD wholesale to benefit from its core insight: writing down intended outcomes before you start building forces clarity.
With BDD’s “articulate before you build” mindset, you have the language to write unit tests that are aligned with your intended outcomes, without requiring you to write tests first.
When writing with BDD, a ticket is no longer just a placeholder or red tape. With BDD, it’s a guidebook. A BDD ticket:
When we skip this, we leave the success criteria trapped in our heads, or worse, we assume that “it’s obvious.” That assumption lets quality slip through the cracks, especially when handing off the work to an AI agent.
Let’s compare another example:
Vague acceptance criteria:
Display an error message when the payment fails.
BDD acceptance criteria:
Title: Handle insufficient funds and expired payment method errors
Given a user has insufficient funds in their account
When they attempt to complete a payment
Then they should see error message "Insufficient funds. Please add money to your account or use a different payment method."
And the payment should not be processed
Given a user's payment method has expired
When they attempt to complete a payment
Then they should see error message "Payment method expired. Please update your payment information."
And they should be redirected to the payment method update page
The BDD version is dramatically more clear. It distinguishes between different failure scenarios, specifies exact error messages, and defines what should happen after the error appears. It gives valuable context about system state and user actions.
And here’s the real kicker…
BDD hands you all the language you need to write a unit test, served up on a plate. It reduces the gap between intent and implementation by helping you focus your test assertions on acceptance criteria (the intended behavior, and the scenarios the behaviours apply to), instead of just the code you wrote.
This is BDD’s real super-power.
When you map each BDD acceptance criterion to at least one unit test, you unlock several benefits:
Something interesting happens when you adopt BDD acceptance criteria: by the time you’ve written four or five criteria in this format, you naturally hit a cognitive limit. You’ll find yourself thinking:
“This ticket is big enough. I can slice the work here.”
You’ll naturally create tickets that are small and manageable. The act of articulating behavior forces you to see the seams where work can be divided.
No. Like any framework, it has limitations.
We still get enormous value from testing facets of our code that don’t neatly fit into acceptance criteria. There will always be edge cases, boundary conditions, and error handling scenarios that weren’t explicitly stated in a ticket but are still worth catching with tests. However, BDD gives us a framework for wrapping these tests in a common language as they arise.
BDD may feel better suited to ‘product’-focused work as it lends itself to being articulated in terms of behaviours. It can feel forced for highly technical chores like database migrations or updating configuration files. Think of BDD as your go-to for changes in system behavior where you can neatly articulate a precondition, a trigger, and an expected outcome.
For purely technical work, don’t force it.
Yes! You can prompt your AI agent to create tickets with BDD language!
As we move toward having AI undertake larger slices of the development lifecycle — scoping, grooming, ticket creation, and execution — there’s plenty of room to guide your AI tool to use BDD language when creating tickets.
In fact, why not ask your AI to attempt a TDD approach when it writes tickets? Have it draft the acceptance criteria first, then propose the implementation approach.
If you’ve made it this far, here’s what to do next:
Try it on your next ticket:
That’s it. You don’t need to rewrite your entire process. Just try it on one ticket and see if it changes the conversation in code review.
Over time, you’ll notice:
That’s the paradigm shift. You don’t need to adopt TDD wholesale or rewrite your entire workflow. Just reframe the way you express intent.
BDD acceptance criteria are simply a tool to bridge intention and implementation, giving your team — and your AI assistants — a shared language to build the right thing, the first time.

I’m a software engineer with experience in C# / .NET, TypeScript, Node.js, AWS, Terraform.
A seasoned micro-services builder, bringing a strong focus on testing, engineering best practices, re-architecting, and a passion for mentoring.
What happens when the Claude bill stops being subsidised?
After 18 months and ~800 incidents, our Rootly classification fields were mostly empty, no one fills in six drop-downs at 2am.
On-call shouldn’t start with archaeology at 2am.
More in AI