⚙ Under the hood — the full engine chain fires
match_ingredient ("tomatoes")
3 candidates:
roma · $2.10/lb
5x6 · $1.60/lb
cherry · $3.40/lb
→
convert(2 each → g)
needs an
each→weight fact
none in kitchen memory
assume 150g/each ⚠
→
yield_lookup ("tomato, diced")
none found
assume 92% ⚠POLICY TBD yield on 'each'-quantified lines may double-count trim (an each is bought whole)
→
cost_recipe()
totals all 8 lines
plate cost
$5.02 ± 0.31
COST + LEDGER: 8 entries — 2 material, 6 auto-resolved
// ledger entry — the tomato assumption
{ line: "tomatoes 2",
assumed: { match: "roma", each_g: 150 },
candidates: ["roma","5x6","cherry"],
plate_cost_delta: "$0.08 – $0.31",
status: "MATERIAL" } // → will be asked
Shape illustrative — regenerate from frozen fixtures after the schema session.
The full rigor runs HERE, invisibly. The conversion engine fires inside every costing.