Decision Tables: Making Maya's Brain Explicit

July 28, 2026 · 19 min read

GreenBox has 1,000 subscribers across Perth and is opening in Melbourne. The team has grown to fifteen people, and the codebase has been restructured around bounded contexts. But the substitution logic that matches produce to boxes still lives in the founder’s head – and that’s about to become a problem.

Every Tuesday at 5am, Maya’s alarm goes off. She makes a coffee, opens the farm availability spreadsheet, and starts matching supply to demand. Which farms have what. Which subscribers get which box. What to do when Dave’s zucchini crop falls short and she needs a substitute that works for customers who are vegan, or allergic to nightshades, or just really hate beetroot.

This has worked fine for a year. Maya’s brain is the substitution engine. She knows that when zucchini is short, you swap in green beans unless it’s winter, in which case you swap in broccoli unless the customer has flagged a preference against brassicas, in which case you swap in sweet potato unless the box is a small box and sweet potato would push the weight over the limit.

She does this for a thousand subscribers. Every Tuesday. In her head.

Now GreenBox is opening Melbourne. Anika has joined the team to handle Melbourne operations. She’s sharp, organised, and excited about the role. She also has zero farming experience. She doesn’t know which farms are reliable, which produce substitutes well for what, or which customers will email Sam in a fury if they get kale instead of spinach.

Maya can’t be the substitution engine for two cities. The maths doesn’t work. Perth matching takes her three hours. Melbourne will take another two. That’s five hours of manual work before sunrise every Tuesday. And if Maya’s sick? If she’s on a plane? If she’s on holiday?

The business depends on the contents of one person’s head. That’s not a staffing problem. That’s a survival risk.

The Example Map that broke

Anika’s first instinct is a good one. She’s read the earlier posts in this series. She knows about Example Mapping. She suggests they sit down and map out the substitution rules.

They set up the session. Yellow card: “Substitute produce when a farm can’t supply.” They start writing rules on blue cards and examples on green cards.

The first rule is simple enough: “When a produce item is short, substitute a similar item from the same category.” Green card: zucchini short, substitute green beans. Green card: apples short, substitute pears. Easy.

Then the conditions start multiplying.

What about the season? Green beans are a great zucchini substitute in summer, but they’re not available in winter. Blue card: “Substitution must be in season.”

What about allergens? A customer with a nightshade allergy can’t get capsicum as a tomato substitute. Blue card: “Substitution must respect allergen flags.”

What about customer preferences? Some customers have marked “no beetroot” in their profile. Blue card: “Substitution must respect stated preferences.”

What about the price band? A small box at $25 a week can’t have $8 worth of cherries substituted in when the missing item was $3 worth of carrots. Blue card: “Substitution must fit within the box price band.”

What about box size? A large box has room for a bulky substitute like pumpkin. A small box doesn’t. Blue card: “Substitution must fit the box size constraints.”

What about farm reliability? Dave overpromises his zucchini yield every spring. Maya knows to order 20% less than he offers. Rachel’s carrots are always exactly as promised. Blue card: “Supply estimates should be adjusted for farm reliability history.”

Twenty minutes in, Anika has six rules and five or six conditions per rule. She starts writing green card examples for the combinations.

Zucchini short, summer, no allergens, no preferences, small box: substitute green beans. Zucchini short, summer, no allergens, no preferences, large box: substitute green beans. Zucchini short, winter, no allergens, no preferences, small box: substitute broccoli. Zucchini short, winter, nightshade allergy, no preferences, small box: substitute broccoli. (Same answer – nightshades aren’t relevant for zucchini.) Zucchini short, winter, no allergens, “no brassicas” preference, small box: substitute sweet potato. Zucchini short, winter, no allergens, “no brassicas” preference, large box: substitute sweet potato.

The green cards pile up. Thirty examples and they still haven’t covered tomatoes, apples, or leafy greens. Every produce item has its own substitution tree, and every tree branches on the same five or six conditions.

Anika sits back and looks at the wall. “This isn’t working. We’re going to need hundreds of cards.”

She’s right. Example Mapping is brilliant for stories with a handful of rules and a few conditions each. When the conditions multiply – when you’ve got five or six independent variables and each combination produces a different outcome – Example Mapping produces a card explosion. You end up with hundreds of green cards, and even then you’re not sure you’ve covered every combination.

The tool isn’t wrong. It’s just the wrong tool for this particular problem shape.

Charlotte introduces decision tables

Charlotte has been watching from the doorway. She’s seen this pattern before – complex multi-condition logic that Example Mapping can’t efficiently capture.

“You need a decision table,” she says.

A decision table is a structured way to express every combination of conditions and what should happen for each one. Instead of free-form examples on cards, you build a table where the columns are conditions and actions, and each row is a complete rule.

The format is simple:

Condition 1 Condition 2 Condition 3 Action
Value Value Value Do this
Value Value Value Do that

Every combination of conditions has a row. Every row has an unambiguous action. No gaps. No “it depends.” The table forces completeness.

Charlotte draws the structure for zucchini substitutions:

Season Allergens Preferences Box Size Price Band Substitute
Summer None None Small Standard Green beans
Summer None None Large Standard Green beans
Summer None No legumes Small Standard Yellow squash
Summer None No legumes Large Standard Yellow squash
Summer Nightshade None Small Standard Green beans
Summer Nightshade None Large Standard Green beans
Winter None None Small Standard Broccoli
Winter None None Large Standard Broccoli
Winter None No brassicas Small Standard Sweet potato
Winter None No brassicas Large Standard Pumpkin
Winter Nightshade None Small Standard Broccoli
Winter Nightshade No brassicas Small Standard Sweet potato
Any Any Any Any Premium Asparagus (seasonal)

“Each row is a complete rule,” Charlotte explains. “You read left to right: if the season is summer, and there are no allergens, and no preferences, and it’s a small box, and it’s standard price band – the substitute is green beans. No ambiguity. No ‘it depends.’ Every combination has an answer.”

Maya looks at the table. “This is what I do in my head every Tuesday.”

“Exactly. And now it’s on paper where Anika can see it, the developers can implement it, and the LLM can generate exhaustive code from it.”

Building the table together

Maya and Anika spend the next two days building decision tables for the twelve most commonly substituted produce items. It’s not quick work. Each item has its own table, and each table has between twenty and forty rows.

The process is collaborative in a way that matters. Maya provides the domain knowledge – she knows that pumpkin is too heavy for a small box, that customers who say “no brassicas” usually mean they don’t like the taste rather than having an allergy, that asparagus is a premium substitute that only works in certain price bands.

Halfway through the first day, they hit Mrs Patterson.

Tom has built the initial table structure with five columns: Season, Allergens, Preferences, Box Size, and Price Band. Maya looks at it and shakes her head.

“Where’s the customer preference column?”

“That’s ‘Preferences,’” Tom says, pointing. “No legumes, no brassicas, no nightshades.”

“Those are category preferences. I mean specific customer preferences. Like Mrs Patterson.”

Tom looks blank. Anika looks blank.

“Mrs Patterson hates beetroot,” Maya says. “She’s never flagged it as an allergy or a category preference. She just hates it. I know this because she emailed Sam eight months ago and I’ve kept it in my head ever since. If the system substitutes beetroot into her box, she’ll be upset. And she’s been subscribed since week three – she’s one of our most loyal customers.”

Tom frowns. “So we need a column for… individual customer dislikes?”

“We need the table to handle the case where a customer has an implicit preference that isn’t captured by category flags. Mrs Patterson isn’t the only one. There are a dozen subscribers whose preferences I carry around in my head.”

Charlotte, listening from the doorway, nods. “That’s exactly the kind of thing the table should force you to confront. What happens when you substitute beetroot for a customer who hasn’t flagged anything but who you know hates it?”

They add a “Customer Flag” column – a boolean that marks whether the customer has any individually recorded preference. If the flag is set, the system checks a separate preferences table before applying the standard substitution. If not, standard rules apply. It adds rows to every table, but it captures something that lived only in Maya’s memory.

“Mrs Patterson’s beetroot just added a dimension to twelve decision tables,” Tom says.

“Mrs Patterson’s beetroot just made the system honest about what it doesn’t know,” Charlotte replies.

Anika challenges with other edge cases. “What if the customer is vegan AND allergic to nuts AND in the small box AND it’s winter? What do we substitute for the capsicum?”

Maya pauses. “I… honestly don’t know. I’ve never had that exact combination.”

They look at each other. That’s the point. The decision table forces them to confront every combination, including the ones Maya has never encountered. In her head, those combinations would produce a gut-feel answer or a five-minute scramble on a Tuesday morning. In the table, they produce a deliberate, recorded decision.

They decide: for that particular combination, the substitute is sweet potato. They write it down. Row 34 of the capsicum table.

“How often does this combination actually come up?” Anika asks.

“Maybe once a quarter,” Maya says. “But when it does, I spend ten minutes agonising over it. Now it’s a lookup.”

Charlotte checks in at the end of day two. The team has twelve decision tables with a total of about three hundred rows. That sounds like a lot, but each table is self-contained – the zucchini table doesn’t reference the tomato table. And each row is a simple, readable rule.

Dave visits the office on Thursday to drop off a sample crate from a new cherry variety he’s trialling. Maya shows him the decision tables on her screen. Row 7 of the zucchini table: “Adjust Dave’s supply estimates by -20% based on historical over-promising.”

Dave stares at the screen for a long time. His face is unreadable.

“You’ve put my forty years of farming into a spreadsheet,” he says finally. “I don’t know whether to be flattered or offended.”

“Both is fine,” Maya says.

Dave leans closer. He reads a few more rows. “This one’s wrong. You’ve got butternut pumpkin as a summer substitute for zucchini, but I don’t grow butternut in summer. Too hot. You want Kent pumpkin.”

Maya corrects the row. Dave watches her type.

“Huh,” he says. “Quicker than calling you at five in the morning, I suppose.”

Feeding it to the LLM

This is where decision tables and LLMs form a powerful combination. LLMs are exceptionally good at implementing decision tables. The table is a complete, unambiguous specification. Every input combination maps to exactly one output. There are no judgement calls, no “use your best judgement,” no ambiguity for the LLM to fill with plausible-sounding guesses.

Priya takes the zucchini decision table and feeds it to the LLM with this prompt:

Here is a decision table for zucchini substitutions. Each row specifies a combination of conditions (season, allergens, customer preferences, box size, price band) and the correct substitute. Generate a Go function that takes these conditions as inputs and returns the correct substitute. Include unit tests that cover every row of the table.

The LLM generates a function and a table-driven test suite. Every row of the decision table becomes a test case. Priya runs the tests. They all pass. She reviews the code – it’s a straightforward series of conditional checks that mirror the table exactly.

“That’s it?” Kai asks, looking over her shoulder. “That handles all of Maya’s substitution logic for zucchini?”

“For zucchini, yes. Every combination. Every edge case. Including the vegan-nut-allergic-small-box-winter case that Maya’s never actually seen.”

They repeat the process for all twelve produce items. Each table generates a function and a comprehensive test suite. The total substitution engine is about a thousand lines of Go code with four hundred test cases.

Decision Tables 12 produce items, ~300 rows
LLM Generates code
Substitution Engine ~1,000 lines Go
Test Suite ~400 test cases, all pass

Compare this to what would have happened without the decision tables. Priya would have prompted the LLM with something like: “Write a substitution engine for a produce box company.” The LLM would have generated plausible code based on common-sense assumptions about produce substitution. Some of those assumptions would match Maya’s expertise. Many wouldn’t. The edge cases – the ones that only come up once a quarter but cause customer complaints when handled wrong – would be missed entirely.

The decision table doesn’t just help the LLM write correct code. It guarantees completeness. Every combination is specified. Every combination is tested. There is nowhere for bugs to hide.

Anika runs Melbourne independently

The following Tuesday, Anika runs the Melbourne matching for the first time. She enters the farm availability data. The substitution engine handles the matching. Where manual review is needed – a new farm whose reliability isn’t yet established, a produce item not covered by the tables – the system flags it for Anika’s attention.

She finishes in forty minutes. Not the five hours Maya was dreading. Not the three hours it takes Maya to do Perth manually. Forty minutes, because the decision tables captured the hard thinking, and the code does the mechanical work.

Maya reviews Anika’s output. Two minor adjustments – an unusual beetroot variety that the table classified as “root vegetable” but that Maya thinks belongs in “salad greens” for substitution purposes. They update the table. They regenerate the code. The test suite catches the change and confirms the new behaviour.

“This is how it should work,” Charlotte says. “The tables evolve as you learn. The code follows the tables. The tests confirm the code matches the tables. The humans make the decisions. The machines execute them.”

The emotional beat

It would be easy to tell this story as “technology replaces expert.” Maya’s knowledge, extracted into tables, implemented in code, run by someone who’s been at the company for a fortnight. A textbook automation narrative.

But that’s not what happened.

On Wednesday morning, Maya sends a message to the team Slack: “For the first time in a year, I woke up at 7am on a Tuesday. Not 5am. 7am. Anika handled Melbourne. The engine handled the matching. I reviewed the output over breakfast instead of building it from scratch in the dark.”

That evening, Maya sits on the couch in Fremantle while Nadia reads beside her. She picks up her phone and texts her mum.

“Is this how you felt when you sold the farm?”

Her mum responds twenty minutes later, while Maya is brushing her teeth. “No. This is how I felt when you left.”

Maya reads it three times, standing in the bathroom with toothpaste on her lips. Her mum doesn’t mean it as a wound. She means: the hardest letting go isn’t giving up the thing. It’s watching someone else carry it forward and knowing they’ll carry it differently than you would.

She’s relieved. Not threatened. Her knowledge isn’t being replaced – it’s being captured so the business doesn’t depend on her being awake at 5am every Tuesday. So that when she goes on holiday, the boxes still go out. So that when Melbourne grows to five hundred subscribers, Anika doesn’t have to become another Maya.

Maya still makes the hard calls. The tables cover the known combinations, but farming is unpredictable. When a freak hailstorm wipes out three farms’ lettuce crops on a Monday night, Maya is the one who works out the emergency substitution plan. The system handles the routine. Maya handles the exceptions. That’s the right division of labour.

“I used to think my value was in doing the matching,” Maya says. “But actually, my value was in knowing what the right matches are. Now the team knows that too.”

When to use decision tables vs Example Mapping

Charlotte draws the distinction clearly.

Example Mapping is the right tool when a story has a few rules, each with a few conditions. The card-based format handles this beautifully – you can see the rules, the examples, and the questions at a glance. If your Example Map fits on a table with room to spare, you don’t need a decision table.

Decision tables are the right tool when the conditions multiply. When you’ve got four, five, six independent variables and the combinations explode. When you find yourself writing the same Example Map card over and over with small variations. When completeness matters – when every combination needs a defined answer, not just the common ones.

The signals that you need a decision table:

  • Your Example Mapping session produces more than twenty green cards and you’re not done yet
  • Every green card looks like the one before it with one condition changed
  • Domain experts say things like “it depends on…” more than twice in the same rule
  • You’re worried about missed edge cases in production

The signals that Example Mapping is still the right tool:

  • The story has three or four rules with a few examples each
  • The conditions are simple and mostly independent
  • The common cases cover 90% of real-world usage
  • You need shared understanding more than exhaustive specification

In practice, the team often starts with Example Mapping and discovers during the session that they need a decision table. Anika’s zucchini session is the textbook example – it started as Example Mapping and the card explosion told them to switch tools.

“Don’t treat them as competing techniques,” Charlotte says. “Example Mapping is discovery. Decision tables are specification. You often need discovery first to understand the shape of the problem, and then specification to nail down every case.”

Sam’s shared inbox now has eighty-plus emails per week. She’s created a spreadsheet of common questions and template responses – copy, paste, send. Jas looks at Sam’s spreadsheet and designs a FAQ page based on the top ten questions. When it goes live, support volume drops thirty percent. Most customers just needed to know when their box arrives and how to skip a week. Sam: “The best support is the support you don’t need.” The FAQ page costs almost nothing to build. It saves Sam five hours a week.

Maintaining the tables

Decision tables aren’t a one-off artefact. They’re living documents.

When GreenBox onboards a new farm that grows something they’ve never substituted before – say, dragon fruit – Maya and Anika sit down and write a new decision table. It takes an afternoon. The LLM generates the code and tests. The substitution engine grows.

When a customer complains that they got kale instead of silverbeet and they hate kale, Sam flags it. Anika checks the table. Row 17 of the leafy greens table says kale is a valid substitute for silverbeet with no stated preferences. They add a condition: if the customer has previously complained about a substitute, flag it for manual review. New row. New code. New test.

The tables are the single source of truth for substitution logic. Not the code – the tables. The code is generated from the tables. If the code and the tables disagree, the tables win.

Charlotte insists on this discipline. “The moment you start editing the code directly instead of updating the table first, you’ve lost the connection between the business logic and the implementation. The table is the specification. The code is the implementation. Keep them in sync or you’ll end up where you started – with the logic in someone’s head.”

What the team learned

Decision tables solved a specific, concrete problem: capturing Maya’s substitution expertise in a form that scales. But the underlying lesson is broader.

Complex multi-condition logic is everywhere in business software. Pricing rules. Eligibility checks. Routing logic. Approval workflows. Anywhere you hear “it depends on…” more than twice, there’s a decision table waiting to be written.

LLMs are extraordinarily good at implementing decision tables because the specification is exhaustive and unambiguous. There’s no gap for the LLM to fill with assumptions. Every input maps to exactly one output. The generated code is correct by construction – and the generated tests prove it.

The combination of human domain expertise, structured decision tables, and LLM-generated implementation is powerful. The humans decide what should happen. The table captures those decisions completely. The LLM turns the table into code. Nobody is guessing. Nobody is assuming. Nobody is getting a 5am alarm because the matching engine is between their ears.

The decision tables captured what GreenBox does. But they don’t capture why it does things that way. As the team grows and more decisions pile up, knowing the reasoning behind those decisions becomes critical. That’s the next problem Charlotte tackles – and it starts when a new developer asks a simple question that nobody can answer: “Why does the payment system charge on delivery day instead of signup day?”

That’s Architecture Decision Records (coming 18 August).

Questions or thoughts? Get in touch.