Recipes & Production — how a dish becomes the ingredients it consumed¶
What this covers. A restaurant doesn't sell flour and eggs; it sells a carbonara. But the stock behind that carbonara is flour and eggs, and they have to leave inventory at a real cost. This chapter is about the food layer that sits on top of the stock books: the recipe that says what a dish is made of, why recipes are versioned so the cost of a sale made in March is still computable in June, how a sold dish is unpacked down to the raw materials it actually used (using the recipe version that was in force on the day it sold), what a prep item is — formally, a semi-finished good: a thing you make in advance and keep in stock, like peeled carrots or a base sauce — and why its yield emerges from its own recipe instead of being typed in. It ends with production (making a prep item is just two ordinary stock movements, posted at the batch's actual quantities) and theoretical-vs-actual variance (what the recipes say you should have used versus what the count says you actually did), and what happens when a recipe turns out to have been wrong — a correction document, never a rewrite of history. Throughout, keep one thing in mind: a recipe is far more than the parts list this chapter leans on — it is the company's recipe knowledge base (§1).
1. A recipe is the company's recipe knowledge base¶
A recipe is the company's recipe knowledge base — far more than a parts list. It is the durable, versioned record of how a thing is made, and it does several jobs at once:
- The parts and quantities — the structured ingredients: per portion, 110 g spaghetti, 45 g guanciale, 1 egg, 18 g pecorino — plus the packaging it ships in.
- How to actually make it — free-form preparation steps, plating and packaging instructions, photos, and notes: the craft a bare parts list can't hold.
- The evidence every food calculation reads — the very same recipe is what the nutrition, shelf-life, and allergen logic reads to reach its answers (see Food attributes); the richer the recipe, the better those answers.
- How cooks learn and are checked — a new cook learns a dish from its recipe and is attested on it (answering questions about its details), and a cook preparing a batch opens the recipe on a tablet to remind themselves of the method.
This chapter is about the one facet the stock books depend on: the structured ingredients, which form a bill of materials (BOM) — the manufacturing term for a list naming the parts of a product and how much of each, the same idea a car factory uses to say "one car = four wheels, one engine, one chassis." The recipe's other roles — the how-to-make-it craft, the training, the food-calculation evidence — are the same artifact serving the wider operation; they live in Menu & catalog and Food attributes.
Why does the stock side care about recipes at all? Because of the one-way boundary explained in Sales & consumption: the selling side reports "12 carbonaras sold," but it has no idea what a carbonara is made of. A dish, by itself, depletes nothing. Its recipe is the only thing that knows the dish became 1.32 kg of spaghetti and 12 eggs leaving stock. So the recipe is the bridge between "a dish was sold" and "these ingredients left, at this cost." Get the recipe wrong and the food-cost number is wrong.
2. Why recipes are versioned — the problem they create for the books¶
Here is the trap, and it's the reason almost everything in this chapter is shaped the way it is.
A recipe is not a fixed fact — it changes over time. The cheeseburger sold on 1 March used a different patty than the one sold on 1 June; somebody changed the dough hydration in April; a supplier swap nudged the cheese in May. That's normal. But now think about re-costing a past sale. A delivery platform back-reports a March order in July. An auditor restates last quarter. A variance review asks "what did that 1 March carbonara actually cost us?" If the books only ever stored the current recipe, every one of those questions would be answered with the June recipe — and produce a number that is wrong, and worse, unreproducible: ask again next month and you'd get yet another answer.
So the rule is:
The cost of a past sale must be computable forever, from the recipe that was actually in force on the day of that sale.
The way the domain guarantees this is a principle worth naming: immutable by reference. Once a recipe version is in force, it is never edited in place. Changing a recipe doesn't overwrite the old one — it creates a new version, and the old version stays exactly as it was, quantities and costs and all. Re-costing a March sale looks up the version that was active in March and walks a recipe that can never change underneath it. The past is frozen because nothing ever writes over it; it only gets superseded by something newer.
This is the same instinct as the stock ledger itself (see Stock ledger): you never edit history, you only add to it. Recipes obey the same discipline.
3. How versioning works: draft, then activate¶
Each recipe version is its own record. There is no separate "history" file — the history simply is the set of versions that belong to the same owner (a dish, or a prep item). A version has a lifecycle with exactly two states, and only one move between them:
- Draft. Freely editable. You can rewrite the ingredients, the portion sizes, anything. A draft has no effect on the books — nothing is ever unpacked through a draft. It's a sketch.
- Active. When you activate a draft, you stamp it with an effective date — the business date from which this version becomes the truth — and from that moment it is the recipe in force for any date in its window. There is no third state and no "retired": a version is taken out of service purely by a later version becoming active after it.
The first version may simply establish the recipe. Every later version must carry a short change note: what materially changed since the previous version, such as "supplier pasta changed," "portion resized," or "packaging added." The note is not part of the cooking method; it is the version timeline's audit trail, so an operator can understand why the recipe changed without diffing the whole card.
When a version goes active, the parts that drive the numbers lock. The locked set is precisely the parts that determine cost and yield: the ingredient list, the packaging, and the portion count / portion size. The reason is exactly the immutability principle from §2 — if those could change after the fact, a past unpacking would silently re-cost, and the whole guarantee would collapse. What doesn't move the numbers stays editable even on an active version: the description, the prep steps, photos, cooking time, and the version's change note. You can fix a typo in step three of the method without minting a new version. But to change a single gram of an ingredient, you make a new version — duplicate the active one into a fresh draft, edit it, and activate it on a new date.
One active version per owner per date — the timeline rule¶
There can be at most one recipe in force for a given owner on a given date. This sounds obvious but it's load-bearing: it's what makes "the recipe on date D" a question with exactly one answer rather than an ambiguous set. If two versions could claim the same effective date, "re-cost the March sale" would be undefined. So a version's effective date is unique per owner, and if you try to activate a second version on a date that's already taken, the system refuses.
Activation is also ordered: a new version's effective date must be strictly after the effective date of the latest version already in force for the same owner. You always publish past the end of the timeline — you never slip a version in between two already-published ones — so the timeline stays a clean, append-only run of windows: each active version owns the stretch of dates from its effective date up to (but not including) the next version's effective date.
The effective date may lie in the past — and why¶
Notice what the ordering rule does not say: it does not say the new effective date must be in the future. It must come after the latest active version's date — but it may well be before today. If the latest version went active effective 15 May and today is 20 June, you may activate the next version effective 1 June (in the past, but after 15 May); what you may not do is activate it effective 1 May, before the version already in force.
Why allow back-dating at all? Because the most common real failure runs backwards: a dish starts selling before its recipe is recorded. A new item is rushed onto the menu on Friday; the recipe gets written up the following Wednesday. Every Friday-through-Tuesday sale of it is now a sold dish with no recipe in force on its sale date — a hard close-blocker (§9): those sales are held, uncosted, because a sold dish must never cost nothing. The resolution is exactly a back-dated activation: write the recipe now and activate it effective on or before the first sale. The held sales resolve a version, unpack normally, and the close can proceed.
Back-dating is safe because of one property the next sections build: consumption already on the books is never re-exploded. Every posted depletion is pinned to the recipe version that explained it (§5), so activating a version into the past changes nothing that has already been computed — it only gives an answer to dates that had none, and governs explosions from here on. One accepted consequence follows: if some sales inside the back-dated window had already posted against an older version, they stay pinned to that older version; the books don't churn just because a better-dated recipe arrived later.
Worked example — resolving the recipe on a date¶
The dish "Roast Carrot Plate" has three published versions:
| Version | Effective from | Window it governs |
|---|---|---|
| v1 | 2026-01-10 | 10 Jan – 1 Mar (exclusive) |
| v2 | 2026-03-01 | 1 Mar – 15 May (exclusive) |
| v3 | 2026-05-15 | 15 May – onward |
The rule for "which version governs date D" is: the active version whose effective date is the greatest value still ≤ D. So:
- A sale on 20 Feb resolves v1 — the most recent version at or before that date.
- A sale on 1 Mar resolves v2 — the boundary day belongs to the newer version (the test is "effective date ≤ D").
- A sale on 1 Jun resolves v3.
The uniqueness and ordering rules above are what guarantee this lookup always returns exactly one version. This is the same "recipe actuality" rule the catalog uses (see Menu & catalog).
4. The recipe is a tree — and there are two ways to nest¶
An ingredient line points at one of two things, and never both:
- an item — flour, oil, a bought-in good, or a stocked prep item like dough. If the item is a plain material, the line is a leaf: there's nothing further to break down. If the item has its own recipe (a prep item does — §6), the line is a live link: every explosion resolves that item's recipe by date, with the same greatest-effective-date-≤-D lookup as §3; or
- a pinned version of another recipe — not "the dough recipe" in general but "dough, v7": one specific, frozen version row.
Because a line can point into another recipe — which has its own lines, which can point deeper still — a recipe is really a tree that bottoms out in raw items. A dish references a dough; the dough references a starter; the starter references flour and water. Walking that whole tree down to the raw leaves is what manufacturing calls a bill-of-materials explosion — "exploding" the dish into the full flat list of raw materials behind it. (A line is not allowed to reference the very recipe being edited, so a recipe can't trivially point at itself and loop.)
The two modes propagate changes differently¶
The choice between the two reference kinds is not cosmetic — it decides what happens when a child recipe changes:
- An item reference follows the child as it evolves. The line names the item, not any version of its recipe — so when the prep cook publishes a new version of the dough recipe, every dish whose line says "dough" picks it up automatically at its next explosion, with no edit to the dish at all. One child edit, propagated everywhere, by construction.
- A pinned reference is a frozen snapshot. The parent names "dough v7" and means exactly v7, forever. If dough moves on to v8, the parent keeps reading v7 until somebody re-versions the parent to point at the newer child. The activated parent plus the exact child versions it names form a snapshot that, top to bottom, cannot change — which is the whole point of pinning.
Which to use when? The guidance is simple:
- A stocked prep item is referenced as an item. The consumption unpacking stops at it anyway (§7) — it depletes as itself, at its own cost — and the live link keeps the dish's rolled-up cost (and nutrition, allergens, and shelf life — §11) tracking the prep recipe as it evolves, with no parent edits.
- A pinned nested version is for non-stocked sub-compositions where the snapshot is the intent — a sauce assembled to order, a spice mix that exists only inside this one dish. There is no stocked item for the walk to stop at, so the sub-recipe is genuinely part of the dish's published recipe — and it should be frozen together with it.
There's one courtesy the activation step handles for pinned references: while you're still authoring, a draft parent is allowed to point at draft children (you draft a whole nested recipe family together). Activation won't publish a parent that still references an unpublished child, so — with your explicit go-ahead — it activates the whole referenced draft subtree together, on the same effective date, in one step. If activating one recipe would quietly drag others live with it, the system stops and shows you exactly what would publish before you commit.
5. Unpacking a sold dish — date-correct explosion¶
Now put §3 and §4 together. When a sale of a dish comes through the front door (the sales ticket of Sales & consumption), the stock side must turn "12 carbonaras" into the actual raw quantities that left stock. That transformation is the explosion, and it must be date-correct — it must use the recipe that was in force on the sale's business date, not the one in force today.
The steps:
- Resolve the root recipe for the dish on the sale's business date — the §3 lookup, the greatest effective date ≤ that day.
- Pin that resolved version onto every stock movement the explosion produces. This is the linchpin of reproducibility: each consumption movement records which exact recipe version explained it, so a later recipe edit — or a back-dated activation (§3) — can never re-explain a movement already on the books. Re-open the movement years later and it still points at the version it was costed against.
- Walk the tree down to its leaves — pinned branches exactly as published, item references resolved by the same business date (§4). At each level, scale the child quantities by how much of the parent was requested, recurse into any nested recipe lines (the walk stops at a stocked prep item — §7), and collect a flat list of raw-item quantities. Leaves that turn out to be the same material are merged into one line.
- Convert to base units at the leaf. Every quantity that enters the books is in that item's base unit — grams, milliliters, or each — so the explosion is where recipe quantities (which may be written in any sensible unit) get converted down to the base the ledger speaks (see Units of measure).
Because version rows are immutable, the flattened result of walking a version on a given business date can be computed once and reused for every line in a run — it changes only when a new version (of the root, or of a date-resolved child) takes effect.
Worked example. 12 carbonaras sold. The recipe in force on the sale date is, per portion, 110 g spaghetti, 45 g guanciale, 1 egg, 18 g pecorino. The explosion yields 1.32 kg spaghetti, 540 g guanciale, 12 eggs, 216 g pecorino — and posts each as a consumption movement, removing it from stock at what that ingredient is currently worth, every movement pinned to the recipe version that explained it.
This is the same dish that, on the selling side, was just "12 carbonaras." The recipe is what made it twelve eggs.
6. Prep items — things you make and stock in advance¶
So far a recipe explodes all the way down to raw items in one sale. But real kitchens don't work that way for everything. You don't peel a carrot per plate at service — you peel a tub of carrots in the morning and keep them ready. You don't mix dough per pizza — you make a batch and portion it. That prepped, stocked, made-in-advance thing is a prep item (formally, a semi-finished good).
A prep item is something with three properties at once:
- it is producible — you make it (you make dough; you do not "make" raw flour);
- it is stocked — it's a perpetually tracked item, with an on-hand quantity and a cost, counted at close like any other stock (see Item model & policies for what "stocked" means precisely); and
- it has its own recipe — a recipe attached to it (not to a dish) that says what goes into making a batch.
That combination — producible AND stocked — is what makes something a prep item. Note what it is not keyed on: it is not decided by a category named "Prep items." A label like that is a name someone typed, and behavior must never hinge on a typed name (you could rename the category, or spell it differently, and silently break the logic). Prep-item-ness is derived from the stable facts — do you make it, do you stock it — not from what bucket it's filed under.
A prep item's output emerges from its recipe header¶
A prep item's recipe says how much one batch makes. Its header carries a portion count (how many portions a batch yields) and a portion size (how big one portion is). The batch output is simply:
output = portion count × portion size
The portion-size unit must be dimensionally compatible with the prep item's own base unit — a prep item measured in mass can't declare a volume portion. (Dimensions — mass vs volume vs count — never auto-convert into one another; see Units of measure.) These header fields are part of the locked set on an active version, precisely because they are the denominator of the prep item's unit cost, as the next section shows.
7. Yield is emergent, not a typed-in factor¶
This is the most important costing idea in the chapter, and the one most inventory systems get wrong.
When you prep a raw ingredient, it loses mass. You buy 124 g of whole carrots and, after peeling, you have 100 g of edible peeled carrot. This is the difference between as-purchased (AP) — what you bought and paid for — and edible portion (EP) — what's actually usable after prep. The classic costing rule is EP cost = AP cost ÷ yield%: because some of what you paid for is now peel in the bin, the surviving edible part must carry the full purchase cost, so it costs more per gram than the raw ingredient did. Cost at the as-purchased price and you systematically understate food cost — you pretend the peel was free.
The naive fix that many systems reach for is a yield-percentage field on each ingredient: "carrots, 81% yield, type it in." This domain deliberately does not do that. Instead:
Yield emerges from the prep item's own recipe. It isn't stored; it's computed from ingredients and output.
The reasoning: the moment a prep item has its own recipe (§6), the recipe already contains everything a yield factor would have told you. The ingredients are right there; the output is right there; the yield is just one divided by the other. A typed-in yield factor would be a second statement of the same fact — and two sources of truth that can drift apart is strictly worse than one that can't. So:
yield = prep-item output ÷ Σ(its ingredients, in base units)prep-item unit cost = Σ(ingredient costs) ÷ output
The unit cost already embeds the yield — nothing to type, nothing to keep in sync, nothing to get wrong. And when a parent recipe uses a prep item, it consumes it one-for-one: one gram of "peeled carrot" in a dish is one gram of the prep item, at the prep item's cost. No factor at the point of use, because the cost already carries it.
The recipe editor can price this before anything is posted. Any recipe version, including a draft, can be previewed at a warehouse and date without recording history: stocked rows price at that warehouse's current average cost, non-stocked rows price through their active sub-recipe or latest receipt reference price, and pinned sub-recipes price their frozen tree scaled to the row quantity. For a prep recipe, the editor's cost per output unit is the theoretical full recipe cost divided by declared output — useful for authoring and margin work, but distinct from what a production posting later puts into the pool.
Worked example — Peeled Carrots (124 g → 100 g, 81% yield)¶
Model "Peeled Carrots" as a prep item (producible, stocked, measured in grams) with its own recipe:
- Input: 124 g whole carrots. Say the warehouse's average cost for whole
carrots is €0.0020 / g → ingredient cost =
124 × 0.0020 = €0.2480. - Output: portion count 1, portion size 100 g → output = 100 g of peeled carrot.
- Emergent yield:
100 g ÷ 124 g = 0.806… ≈ 81%. Nobody typed this. It falls straight out of "we put in 124, we got 100." - Prep-item unit cost:
€0.2480 ÷ 100 g = €0.00248 / g. Notice this is higher than the €0.0020/g raw cost — the 24 g of peel-loss has been correctly rolled into the 100 g that survived. That uplift is the yield, now expressed as cost.
Now the dish — "Roast Carrot Plate" — uses 80 g of peeled carrot. Its recipe references the Peeled-Carrots prep item one-for-one:
- 80 g of peeled carrot ×
€0.00248 / g= €0.1984 of carrot cost in the dish.
And here's the key consequence: because the prep item is stocked, the dish explosion (§5) stops at it. It posts an 80 g consumption of peeled carrot at the prep item's cost and does not keep going down into whole carrots. The peeling already happened — and was already costed — back when the prep item was produced. Descending again would count the carrots twice — and would deplete whole carrots the kitchen never touched while the batch of peeled carrots it actually drew down sat untouched on the books. (This is the rule Sales & consumption §4 referred to: the unpacking stops at a stocked prep item.)
The operator chooses how deep to model¶
The very same plate could instead list raw carrots directly in the dish recipe. That's simpler to author — but then the dish explodes straight down to whole carrots, and the 19% peel-loss never shows up as recipe cost; it only surfaces later as count-driven variance (§9). Modeling Peeled Carrots as a prep item buys accuracy (yield captured right in the recipe, prep tracked as real stock); putting raw carrots in the dish buys simplicity. Both are legitimate. The depth of decomposition is a deliberate operator decision, not a system rule.
8. Production — making a prep item is two movements¶
How does a batch of peeled carrots actually come into stock? Not through any special "manufacturing" mechanism. Production is just the ordinary stock engine plus a recipe — a pair of stock movements through a virtual staging point called production (one of the non-physical counterparty locations the ledger uses; see Scope & locations).
For one batch of Peeled Carrots:
- Consume the ingredients. A movement carries 124 g of whole carrots out of the warehouse and into production — at the warehouse's average cost, €0.2480.
- Yield the output. A movement carries 100 g of peeled carrots out of production and back into the warehouse — and that 100 g lands carrying the full rolled-up ingredient cost: €0.2480 over 100 g, i.e. €0.00248/g.
The ingredient value flows through into the output value; quantity is neither invented nor destroyed — it's conserved across a pair of balanced movements, exactly the double-sided discipline the stock ledger uses for everything (see Stock ledger).
A production run records a session, output-first. One document captures the whole prep session — "this morning we prepped: peeled carrots 300 g, sauce 5 L" — with one line per item made, and the recorded output is the anchor: ingredients default from the active recipe scaled to what actually came out. If the card declares a 100 g batch from 124 g of whole carrots, recording 300 g of peeled defaults 372 g of carrots in. The operator may instead state the ingredients by hand — today's carrots are old and peel at 78%, not 81% — and the posted pair then carries the stated numbers, so the cost is honest by construction: cost = stated ingredients ÷ recorded output. The recipe is not weakened by this — it remains the standard every batch is measured against — and the month's count variance (§9) stays honest: if production were forced to post the recipe's theoretical quantities, every real-world deviation would silently pile up as unexplained shrinkage at the count.
The document is a process, so it starts as a draft. A run is written by a person, and in a real operation the cook who writes the sheet is rarely the person who signs it off at the end of the shift. So a session opens as a draft: freely editable, holding as much or as little as the shift has managed to write down, and touching no stock at all. Posting is the gesture that asserts it, and it asserts the session whole — every line's move-pair or none. If any line cannot resolve honestly (the item has no recipe card, no version is active on that date, the card declares no output), nothing posts and the document stays a draft with the reason named against each line; the operator activates the card or states the ingredients by hand and posts again. A line with stated ingredients posts with no recipe at all — which is how a kitchen records production from day one, before any cards are authored. Book stock is never among the reasons a post is refused: the batch was already made, so the draw posts even when the book cannot cover it — the ingredient pool goes negative at its own price, and the missing receipt or the next count settles the debt (the book never refuses a fact; see Invariants). A draft dated inside a period blocks that period's close until it is posted, re-dated, or thrown away (see Period close), so a captured shift can never quietly become shrinkage. Once posted the session is frozen: corrections reverse the whole document and record a corrected one — the same correct-by-contra discipline as everywhere else.
What the shift measured is a sighting, not a posting instruction. Alongside the output lines, a session may record what it actually got through, at document level: "flour, 12 kg total." That measurement stays with the document forever — a draft reopened the next morning must not lose it, and a posted session shows the comparison for good — but the books never read it. Two comparisons fall out, and neither is stored and neither blocks anything:
per line ingredients entered on the line vs what the recipe would have derived
per session Σ line ingredients (theoretical) vs what the shift measured (actual)
If the operator wants the books to carry the measured usage, they say so plainly — by editing the lines' ingredients until the totals agree — and post that. An unreconciled variance is simply left standing: the document keeps both numbers side by side, and the missing quantity turns up at the next count as ordinary shrinkage, with this session as the obvious place to look. That is count-wins (§9) doing its job, not a hole: nothing is invented on the books from a number nobody committed to.
One deliberate accounting distinction sits underneath all of this. The editor's recipe cost preview is the theoretical full cost of the recipe, including expensed leaves, because it answers "what does this recipe cost to make?" A production run capitalizes only the stocked ingredients it actually consumes into the output pool. Any expensed leaves have already hit profit-and-loss where their treatment says they belong, so pushing them into the produced item would double-count them.
Trim-loss is implicit. Output (100 g) weighs less than the ingredients (124 g), but the output carries their full cost — so the 24 g of peel needs no separate entry. Its value simply lands in the 100 g that survived, which is exactly where the EP/AP rule (§7) says it belongs. (Logging the trim as an explicit waste movement to the scrap location is a possible later refinement; the cost result is the same either way.)
The payoff of treating production this way: stockable prep items, commissary prep (a central warehouse that makes batches for several restaurants — its batches reach each restaurant's own stores by explicit transfer; see Scope & locations), and a forward production plan all fall out of one primitive — a consume-then-yield pair — instead of each needing its own bespoke machinery.
Where a batch draws from — the production floor is a storage location¶
Recording a batch always posts the full move-pair above: ingredients out, output in. The trade calls this backflushing — the ingredients are deducted on the strength of the recorded output rather than issued by hand. It is forgiving by construction. Even a wrong recipe still yields correct books: the count-wins reconciliation absorbs the drift, and the variance report points at the recipe that caused it, so recipes can start rough and converge over a few close cycles.
What varies is not whether the ingredients post but where they leave from. A warehouse holds its stock in one or more storage locations — the walk-in, the dry store, the kitchen table (see Scope & locations). A session may name the storage location it drew from, and the consumption then leaves that spot; naming none draws from the warehouse's default. The yield always lands at the default, because that is where finished prep is stored and issued from.
A site that has physically separated its prep gives that floor a storage location of its own and works the shift as an ordinary walk of goods:
shift opens relocate dry store → kitchen table raw goods walk over
day production run kitchen table → production ingredients, at pool cost
production → dry store the yield, same value
leftovers relocate kitchen table → dry store unused raw walks back
end of shift count the kitchen table — usually all zeros, a clean table
Nothing here is a separate accounting regime. A relocation neither creates nor destroys value; the warehouse still prices its stock as one pool, so which storage location holds a kilo of flour never changes what that kilo is worth. The floor takes part in the period close like any other storage location — its own full count, its own differences — and the close will not run until it has been counted.
That makes the two kinds of error legible separately, which is the whole point of working this way. What the cooks actually used against what the recipe says they should have used is answered by the run's own facts: the session records the real ingredients, and a shift that has not been signed off sits in draft where the close can see it. What quietly disappeared from the floor — a spill, a handful grabbed for staff food, a bag walked off — is answered by the floor's own count, as an ordinary shortage. It is shrinkage in one storage location, told apart from recipe error by where it surfaced, and it needs no special counterparty to say so.
9. Theoretical vs actual — what you should have used vs what you did¶
Recipes give you the theoretical side of food cost; physical counts give you the actual side. Comparing the two is one of the most valuable things an inventory system does, because the gap between them is where waste, over-portioning, and theft hide.
- Theoretical usage = for every sale in the period, the dish's quantity times its date-correct explosion (§5) — i.e. what should have been consumed for perfectly portioned plates with zero waste and zero loss. It is built entirely from recipes and sales.
- Actual usage = what the books say really left, derived from counts: opening count + everything received + transfers in − closing count. This is the truth event of the period close (see Period close).
- Variance =
theoretical − actual, reported three ways: in quantity, in money, and as a percent. - Unexplained =
variance − logged waste. Once you subtract the waste someone actually recorded (a dropped tray, a spoiled batch), what's left is the operationally interesting residue — the over-portioning, the mis-invoicing, the shrink nobody wrote down.
Worked example. The recipes say a month of carrot-plate sales should have used 40 kg of whole carrots (theoretical). The count says 44 kg actually left (actual). Variance = −4 kg, roughly −€8 at €0.0020/g. Logged waste for the month was 1 kg (a spoiled crate). Unexplained = 3 kg — three kilos of carrots that left stock for no recorded reason. That's the number worth a manager's attention.
The recipe layer's whole job in this calculation is to make the theoretical term reproducible and date-correct — which is precisely what versioning (§2–§3) and pinned explosions (§5) buy you. The actual term comes from the count-and-close machinery in Period close. And the two only line up honestly if every sold dish had a recipe on its sale date — which is why a sold dish with no active recipe is a hard close-blocker: it is quarantined and surfaced for a human to fix — typically by writing the recipe and activating it back-dated to cover the sale dates (§3) — never silently exploded to zero cost (a sold dish must never cost nothing).
10. When the recipe was wrong — correcting posted journals¶
Two recipe failures look alike and are nothing alike. A missing recipe already has its path: the sold lines are quarantined and the produced session stays in draft, the operator writes the recipe and activates it back-dated to cover the dates, and the held work posts normally, on its true dates (§3, §9). A wrong recipe is different: the lines did post, the books balanced — against the wrong explosion. Weeks later somebody notices the carbonara card said 30 g of guanciale when the kitchen has always plated 45. What is on the books is not shrinkage; it is an error in posted journals, and it deserves a correction, not a shrug.
The fix begins the same way: record the corrected version and activate it back-dated to when the error began. That alone changes nothing on the books — posted movements never re-explode; nothing ever cascades from a recipe edit (§5's pinning guarantees it). Instead, the operator asks for a recipe correction: a document that computes, per affected line, the difference between what the correct recipe would have consumed and what the wrong one did:
delta = explode(correct version) − explode(wrong version), per line, per item.
Which lines participate is derived, never flagged. A sales line is always a pure explosion, so it is always in scope. A production line joins only when its recorded ingredients equal the wrong version's explosion — an operator who stated them by hand made an assertion of their own, and an assertion is not a wrong explosion. Corrections already posted net into every new delta, so a fix-of-the-fix posts only the residual.
Posting has two regimes, split by whether the affected dates are still open:
- Open dates. The delta posts as ordinary consumption on the original business dates. The book's projection corrects itself, and the upcoming count's variance for those items collapses toward zero — the error is explained before it ever reads as shrinkage.
- Closed dates. The stock on hand is already right — count-wins settled it at the close — so a quantity correction would double-count. Instead the correction posts a net-zero reclassification pair in the current open period: a consumption entry and an equal shrinkage reversal. On-hand does not move; a euro of cost moves within cost of goods sold, from unexplained shrinkage to explained consumption, attributed to the restaurant that earned it. The consumption leg mirrors the journals it corrects: a sales-sourced delta posts against the customer side, a production-sourced one against the production counterparty. Closed periods are never restated — standard accounting practice corrects an immaterial error in the current period — and their frozen snapshots stay frozen.
In both regimes total cost of goods is unchanged. Count-wins guaranteed the total was right all along — whatever really left stock was already charged; the correction buys back explanation and attribution. Money follows the same modesty: the exact as-if is a quantity idea. Within an open period the close's one blended cost re-spreads value anyway, and for closed dates the reclass prices at today's average — the same convention a late sale follows.
Worked example. The card said 30 g of guanciale; the kitchen always plated 45. 200 plates sold in May → the delta is
200 × 15 g = 3 kgof guanciale the books never charged to sales. If May is still open: 3 kg of consumption posts on the May sale dates, and the coming count no longer shows a 3 kg mystery. If May is closed: the close already charged those 3 kg to shrinkage (the count saw them gone). The correction posts, in June, a consumption of 3 kg-worth (at today's average — say €18/kg → €54) and a shrinkage reversal of the same €54. June's on-hand is untouched; the books now say "€54 of guanciale was eaten by guests, not lost" — same total cost, honest story.
11. One explosion, four answers¶
A closing note on why the explosion is worth getting right beyond cost. The same date-correct walk down the recipe tree (§5) that produces leaf consumption and cost also produces three more roll-ups off the very same traversal: a dish's nutrition, its allergens, and its shelf-life safety cap (the soonest any component expires). All four ride one engine, and a single change anywhere in the tree refreshes all four together — so a recipe edit can never leave the cost current but the nutrition stale, or vice versa. The prep item's output weight (§6) does double duty here: it's the denominator of unit cost and the per-portion basis for nutrition. The food attributes are taught in their own chapter — Food attributes — but they are the same tree, walked the same way.
See also¶
- Sales & consumption — the sale that triggers the explosion, and the front door it comes through; where the unpacking stops at a stocked prep item.
- Period close — the period close and the actual side of theoretical-vs-actual variance this layer feeds.
- Stock ledger — the journal every consumption and production movement is recorded in; the never-edit-history discipline recipes share.
- Scope & locations — warehouses, restaurants, and the virtual production location the move-pair runs through.
- Item model & policies — what makes an item stocked and producible, the two facts that define a prep item.
- Menu & catalog — dishes, items, recipes, and the "recipe actuality" rule (§3 here).
- Units of measure — base units, dimensions, and the convert-to-base edge the explosion crosses.
- Costing & valuation — the average cost each consumed ingredient is priced at, and how ingredient cost rolls into a produced batch.
- Food attributes — nutrition, allergens, and shelf-life as roll-ups on this same explosion.
- Glossary — recipe, recipe version, recipe actuality, prep item, EP/AP yield, and unit terms.