Inside Mandate
What happens between the chef's words and an order.
This page opens the system up. Each section shows one mechanism on real data from the deployed app: how the rules are stored, how one line is decided, and why no model and no outside agent can approve an order.
01 · The mandate
The chef writes a sentence. The app stores it as limits.
This is the sample hotel's mandate, as the agent reads it from the live app. The sentence is what the chef sees; the fields are what the checks use.
In the chef's words
Order alone up to €800 a line and €1,000 an order, €4,000 a week. Never change an allergen. Ask me before any new product or any substitute I haven't seen.
As the checks read it · Hotel Rautatientori (fictional)
Seven sample kitchens each have their own mandate: a care home that must stay lactose-free, a central kitchen that orders only from its tender list and requires Finnish meat, fish and milk.
02 · One gate
Every change, from every door, goes through one function.
The Kitchen screen, the request page, the chat and outside agents all call the same tool handlers. Those handlers change state in one place, applyOps, and an order is checked twice on the way.
applyOps(state, ops)
- The order service checks every line against the mandate and the approval.
- The state function checks it again: the plan version and the terms must match the approval, and only lines the mandate allows go through without one.
- An outside agent's request never counts as an approval, whatever its key says.
Written to the log
A retry can't order twice: each commit carries a key built from the plan, its version and its terms, and the same key returns the same receipt.
03 · One line
Every line can show its working, with a source for each step.
The milk for the Christmas buffet's rice porridge, exactly as the Why drawer returned it from the deployed app.
Dish: rice porridge, ingredient: milk
the buffet's recipe
Need 10.5 l
computed from guests and portions
10.5 l ÷ 1 l per pack → 11 packs
catalogue pack size
€1.56 a pack → €17.16
Valio Aimo price, cached from the live API
Availability: Valio Aimo doesn't state a quantity
a very large stock number means "unknown", never "in stock"
Waits for the chef a requirement the product's record doesn't confirm
the mandate
04 · The approval
A yes covers the exact terms the chef saw. Change one, and it's void.
An approval is tied to a fingerprint of the order: a SHA-256 hash over the delivery date and every line. It's also tied to the plan's version, the mandate's version and an expiry.
Inside the fingerprint
One real approval, waiting on the live app
d97dd52a4a21…26e879e0b4f
sign-off · mandate version 1
05 · The models
Models read and suggest. Only the rules let a line through.
Gemini turns words into structure and scores substitutes. Its output can add a reason to hold a line; nothing it returns can release one.
06 · Retrieval
From a chef's words to a Valio Aimo product, in Valio Aimo's units.
The catalogue holds 17,546 products, each named in Finnish and English by Valio Aimo. Search is by words, built to read a chef: English, kitchen slang and typos. There is no vector search.
How a word finds a product
- Match the words against Finnish and English names and the brand
- Map kitchen words to catalogue words: "cow" to beef, "steak" to beef cuts, about 50 such words
- Handle Finnish word forms and compounds, plurals, and fix typos to the nearest known word
- Not confident enough: no guess, the agent asks
The buffet's ham, from guests to packs
140 guests × 135 g portion
÷ 0.7 yield: bone and cooking loss
= 27 kg to buy
→ 4 × 7 kg Valio Aimo sells it in 7 kg lots
Allergens: one source of truth
- Valio Aimo's product record says yes or no
- No record: unknown, and the line waits for the chef (about 59% of products have none)
- Web facts found by Exa are shown beside it, cited by barcode. They never clear a hold.
Product photos, best match first
- A page with the product's own barcode
- The same product in another pack size, labelled "Pack may differ"
- The brand's image, labelled "Brand image"
- A category icon, labelled "No photo"
Price and availability come live from Valio Aimo's hackathon API for the products on a plan, cached, with five supply states: known, unknown, out, undeliverable and blocked.
07 · The agent door
Any agent can plan. Only the chef can say yes.
Mandate's tools are open over MCP and REST, with a scoped key per agent. Of the 20 tools, an outside agent's key lists 17: approving and changing the mandate need scopes it doesn't have.
An outside agent can
- Read the kitchens, their mandates and open plans
- Search products, quote prices, look up facts
- Propose a menu, plan an event, place an order
- Hand the chef a link to approve or review. A link points; it grants nothing.
It can't
- Approve: its lines always wait for the chef
- Change the mandate or accept a menu
- Try anyway unnoticed: the attempt is refused and written to the log, and Operations shows it
The chef's own assistant is different
When the chef connects their own assistant with their own key, it can ask them to approve right in the conversation. The terms are shown, and only an explicit yes counts, recorded with the assistant's name. Anything that needs a sign-off still goes to the app.
08 · Valio Aimo's view
Valio Aimo sees every kitchen's demand and exceptions as they happen.
The Operations screen reads the same log as the kitchens. Postgres pushes each change to every open screen, so a kitchen's order shows up on Valio Aimo's side within a second.
Problems
One card per cause, consequence first: "Christmas ham: 28 kg short for 1 kitchen". Held lines are grouped by the decision they wait on, across kitchens.
Orders
Each plan in four stages: asked, changed and why, signed on which terms, ordered.
Demand
For each delivery day: what every kitchen ordered, signed and still proposes.
Forecast simulated
Two weeks ahead, starting from Valio Aimo's availability answers, with stated estimates for weekday draw, Christmas and restocking. Labelled on screen as a model, not live stock.