Mandate

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)

line cap€800
order cap€1,000
weekly cap€4,000
hard limit, even with a yes€8,000
never delegatedallergen change · new product · substitute that breaks a preference
unknown allergen recordhold
meat originprefer Finnish

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.

Kitchen screenUI
Request pageUI
Chat with the agentchat
Your own agentMCP
Any programREST

applyOps(state, ops)

  1. The order service checks every line against the mandate and the approval.
  2. 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.
  3. An outside agent's request never counts as an approval, whatever its key says.

Written to the log

whothe person or agent that asked
doorwhich of the five it came through
whatthe change, with its reason
livestreamed to every open screen

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

delivery dateproductquantityunitunit pricestock unknownrules the chef accepted breakingtimestamps

One real approval, waiting on the live app

d97dd52a4a21…26e879e0b4f

sign-off · mandate version 1

beforeThe chef was asked to sign off version 7 of a buffet plan.
changeA line was added: puff pastry, 13 packs, for the Christmas tarts.
resultThe version-7 approval was voided, with that difference recorded, and a new one is waiting.
at commitPrices and stock are quoted again. If the fingerprint moved, nothing is ordered and the chef is asked again.

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.

Gemini 3.5 Flash-LiteReads the request, the chat and the explanations: what, how much, for when.reads
Gemini 3.8 FlashProposes a menu from a sentence, and re-reads a request the first pass wasn't sure about.suggests
Gemini Decision 1Scores substitutes: how well a swap fits the dish, whether it breaks a hard rule, how likely it's Finnish. Falls back to a recorded replay, then to rules.can only hold
The mandate's checksPlain code, no model. Decides ordered, waiting or refused for every line; the full list of checks is on How it works.decides

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

  1. Match the words against Finnish and English names and the brand
  2. Map kitchen words to catalogue words: "cow" to beef, "steak" to beef cuts, about 50 such words
  3. Handle Finnish word forms and compounds, plurals, and fix typos to the nearest known word
  4. 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

  1. Valio Aimo's product record says yes or no
  2. No record: unknown, and the line waits for the chef (about 59% of products have none)
  3. Web facts found by Exa are shown beside it, cited by barcode. They never clear a hold.

Product photos, best match first

  1. A page with the product's own barcode
  2. The same product in another pack size, labelled "Pack may differ"
  3. The brand's image, labelled "Brand image"
  4. 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.