Tokens in staff/available. A drink holds one for the whole brew.
Split across the three order_* transitions in the model's own proportion.
Sets every abandon_* rate. Waiting customers are three places in the net — one queue per drink — not a colour on a card.
— triple arrivals for the first two hours, then quiet.
Why the barista has to be held
Making a drink is two firings, not one: start_X takes an order, its ingredients
and a barista; finish_X produces the drink and gives the barista back. In between,
a token sits in brewing_X and that barista is unavailable.
If making a drink were a single firing, the barista would be seized and released in the same instant — never observably busy — and no amount of staffing could change the answer. That is not a detail of the implementation; it is the difference between a model that can answer this question and one that cannot.
A prerequisite is not an accelerant
start_X also consumes beans, milk, a cup and a barista, and the usual rate law multiplies
every input into the firing rate. That is right for chemistry and wrong for a café: it made a bigger
pantry brew faster, favoured the latte over the cappuccino for using more milk, and made two drinks in
progress finish each other early. Those arcs are marked kinetic: false, so they still gate
the firing and are still consumed by it — they just leave the rate alone.
The queue is one place per drink for the same reason. With a single fungible queue, which drink got made was settled by whichever recipe's ingredients multiplied out largest; the shop could serve more espressos than anyone ordered and never make a cappuccino at all. Now demand sets the pace and everything else sets permission.
The queue itself is a prerequisite too. While picking an order up scaled with the number of people waiting — exactly as giving up does — the two cancelled, and precisely one customer in six walked out however many baristas were on and however short the queue was. Patience was a coin flip rather than a function of the wait, so "how many baristas do I need to stop losing people" had no answer. A barista does not pick orders up faster because more people are waiting, and once the model says so, the walkout column responds to the staffing slider.
Waiting on is the row that says what the shop was short of, and for how much of the day. It is not the same question as Ran out: a resource consumed as fast as it is delivered is refilled and drained all day and never reads as empty. The milk was in that state, and the only visible symptom was a table that made no sense — idle baristas, and half the customers gone.
Which engine answers
The discrete one. A queue with three baristas is exactly the regime where noise decides the outcome, so the answer is an average over independent runs rather than a smooth curve. The continuous solver has no firing instant, so it cannot test a capacity or a guard at all — asked about a model that has them, it refuses instead of quietly answering an easier question.