Palate

The Instrument Room

What each kind of dish is made of

Every dish in the corpus carries 18 measured flavor dimensions. Group them by what kind of dish they are — the one label in this corpus that partitions cleanly — and ask how each group departs from the corpus average.

The expected result is ten distinct profiles. The actual result is that only three kinds of dish have a fingerprint at all.

2026-07-26T21:02:58.956539 image/svg+xml Matplotlib v3.11.0, https://matplotlib.org/ funk fermented salinity marine briny heat° pungent allium° smoke° umami earthy citrus sourness herbaceous bitterness spicy aromatic fruity floral sweetness nutty richness main n=1473 soup n=179 appetizer n=113 sauce/condiment n=24 salad n=97 drink n=73 dessert n=160 bread n=58 snack n=60 side n=108 -0.9 -0.8 -0.8 -2.1 -1.6 +1.2 -2.1 -1.6 -1.4 -1.3 +1.3 +1.8 -1.2 -0.8 -1.2 -1.1 -0.8 -0.8 −2 −1 0 1 2 SD from the corpus average above average below average What each kind of dish is made of Every one of 2,345 dishes carries 18 measured flavor dimensions. Each cell is that category's average, in standard deviations from the whole corpus — so 0 is “ordinary” and the colour is a departure, not a level. Rows and columns are ordered by similarity, not alphabetically. Only cells past ±0.75 SD are labelled. Sampling noise is about ±0.40 SD for the smallest group (sauce/condiment, n=24) and ±0.05 for the largest (main, n=1473) — so pale cells are not findings. ° heat, smoke and pungent allium are presence-only channels: they are drawn, so the fingerprint is whole, but they carry no printed value and nothing here ranks dishes on them. Palate corpus v17, 2,345 dishes (~40% written for the project) · piece8_dish_anatomy.py · 18 analysis dimensions, never the 6-spoke display hexagon
Each cell is that category's average in standard deviations from the whole corpus, so 0 is 'ordinary' and colour is a departure, not a level. Rows and columns ordered by similarity.

Most dishes are the average dish

Measured as the root-mean-square departure across all 18 dimensions, the categories fall off a cliff:

How far the category's average profile sits from the corpus average, across all 18 dimensions.
kind of dishdistinctiveness (RMS z)n
drink1.0073
dessert0.98160
bread0.8058
salad0.4097
sauce/condiment0.4024
side0.33108
snack0.3160
soup0.20179
appetizer0.19113
main0.191473

Drink, dessert and bread have a signature. Everything else is close to ordinary, and soup and appetizer are as featureless as main — which is the real finding, because main is 63% of the corpus and therefore is the average by construction. Soup and appetizer have no such excuse. They are simply not a flavor category; they are a serving format.

A dessert is defined by what is missing

The strongest departures in the whole grid, restricted to channels the engine can make a magnitude claim on:

kind of dishdimensionSD from corpus averagen
drinksalinity-2.1373
drinkrichness-2.0973
dessertsweetness+1.84160
dessertsalinity-1.63160
drinkumami-1.6273
dessertumami-1.40160
dessertfloral+1.31160
dessertherbaceous-1.26160
breadumami-1.2558
drinksweetness+1.2173

Seven of the ten biggest departures point downward. What marks a dessert is not mainly the sugar — it is the absence of the savory axis: umami, salinity and herbaceous all sit more than a standard deviation below average. A dessert is defined by what has been taken out at least as much as by what was put in. Dessert is also the corpus’s floral pole, which is vanilla, citrus zest and rosewater rather than a fruit effect.

Mirepoix is not 2 : 1 : 1

The classic teaching is two parts onion to one carrot to one celery, by weight. Of 2,345 recipes, 52 list all three vegetables with a weight. Their median proportion is about 1.4 : 1.5 : 1 — carrot slightly ahead of onion — and only 5 of the 52 carry as much onion as carrot and celery combined, which is what 2:1:1 actually implies.

2026-07-26T21:02:59.357554 image/svg+xml Matplotlib v3.11.0, https://matplotlib.org/ what you're taught 2 : 1 : 1 what 52 recipes do 1.38 : 1.50 : 1 onion 2.00 carrot 1.00 celery 1.00 onion 1.38 carrot 1.50 celery 1.00 0.5x 1x 2x 4x 8x onion, as a multiple of the celery weight 1x 2x 4x 8x 16x carrot, as a multiple of the celery weight taught: 2 : 1 : 1 median carrot 1.50x median onion 1.38x 25 5 4 3 one circle = one exact proportion 1 recipe 5 recipes 25 recipes Mirepoix is not 2 : 1 : 1 The taught proportion is 2 parts onion to 1 carrot to 1 celery, by weight. Of 2,345 recipes, 52 list all three vegetables with a weight. Their median proportion is about 1.4 : 1.5 : 1 — carrot slightly ahead of onion. Only 5 of the 52 carry as much onion as carrot and celery combined. Weights are the engine's unit conversion: a bare “1 onion” becomes 110 g, a carrot 60 g, a celery stalk 40 g. Most lines are bare counts (“1 onion, 2 carrots, 2 stalks celery”), so the ratios are lumpy: 17 distinct proportions across the 52 recipes, 25 of them on a single one. Onion means the bulb — scallion, spring onion, shallot and leek are excluded, as are onion powder, onion flakes and celery seed (10 ingredient names, 179 lines, that a plain substring search would have counted). Palate corpus v17 (~40% written for the project); excluding those, n=27 and both medians are unchanged · piece8_dish_anatomy.py
Each circle is one exact proportion; area is how many recipes share it. The taught 2:1:1 is marked.

Read the caveat on that chart before quoting the ratio. The distribution is severely quantized — 17 distinct proportions across 52 recipes, with 25 of them on a single coordinate — because almost every line is a bare count (“1 onion, 2 carrots, 2 stalks celery”) converted by standard piece weights. The robust claim is therefore about what recipes say, not what cooks weigh: the most common mirepoix instruction in this corpus is one onion, two carrots and two stalks of celery, which fails 2:1:1 under any sensible set of piece weights.

Honest limitations

  • Three dimensions are drawn but never ranked. Heat, smoke and pungent allium are presence-only channels in this engine — they reliably separate has-it from hasn’t and nothing finer — so they appear in the grid (dropping them would misrepresent the vector) marked with a degree sign, carry no printed value, and are excluded from every ranked list above.
  • Sampling noise is about ±0.40 SD for the smallest group (sauce/condiment, n=24) and ±0.05 for the largest (main, n=1,473). Pale cells are not findings.
  • The mirepoix ratio is hostage to unit conversion — see above. The count claim survives; the precise mass ratio is our arithmetic as much as the corpus’s.
  • ~40% of the corpus is project-authored. For mirepoix, excluding those leaves n=27 and both medians are unchanged.

Reproduce this

Deterministic, offline, no model calls. Every number on this page is read from the script’s results file — the page cannot state a number the script didn’t produce.

python analysis/instrument_room/scripts/piece8_dish_anatomy.py
python analysis/instrument_room/scripts/piece8_figures.py

Input: prototype/web/src/data/sample_corpus_v17.json (read-only). Every number on this page is in analysis/instrument_room/results/piece8_dish_anatomy.json.