Engineering

How the refusal actually happens.

The home page argues that SafePlate stops the order rather than advising on it. This page is the mechanism behind that claim, for the readers who want it before they believe it.

The enforcement path

Five steps, and one of them can say no.

The check sits in the order flow, not beside it. That is the whole design: a system that advises can be ignored under pressure, and a system that blocks cannot.

  1. 01

    A cover declares

    An allergen profile is attached to a seat, not to a note on the ticket. It can be entered by a server, self declared by the guest, or read off a Passport QR at the till.

  2. 02

    A server taps a dish

    The item is decomposed against the canonical ingredient ontology. Menu items carry mapped ingredients; ingredients carry FSA-14 codes and any operator defined triggers.

  3. 03

    The check runs

    Every candidate item is checked against every declared profile on the cover before it can join the bill. The check is synchronous. Nothing is queued and nothing is checked afterwards.

  4. 04

    The mode decides

    Strict blocks outright and no manager can override it. Moderate allows a PIN override, timestamped with a logged reason. Advisory prompts for a verbal confirmation and logs that too.

  5. 05

    The kitchen inherits it

    The ticket carries the allergen itself, not a free text note. The kitchen display shows which cover it belongs to, and a chef acknowledgement is recorded against it.

The rule everything else follows from

If the allergen check cannot run, the item cannot be added.

An unreachable allergen service returns a refusal, not a pass. A check that times out is a check that failed, and a check that failed is not an all clear. This is why the till behaves the same on a bad network as on a good one, and it is the behaviour the load test in the next section was built to try to break.

It is also the least convenient possible default. Failing open would make the product feel faster and every outage invisible. That trade is available to every competitor and it is the one thing this system will not do.

369,262
requests across the run
1
request that failed
17,067
canonical ingredients
6,438
confirmed by a person

The shape of it

Six services, one of which is allowed to refuse.

Separated so the check has its own failure domain. An outage in reporting, in the kitchen display or in the ingredient database cannot turn a block into a pass, because none of them is the thing that decides.

gateway
Edge routing and auth for every client
core
Tenancy, menus, covers, bills, audit
allergen
The check itself. The only service that can say no
epos
Square and Access EVO connectors behind one interface
fooddb
Canonical ingredient ontology and dish mapping
kds-service
Kitchen display state and chef acknowledgements

Alongside them: four client applications, a dashboard, two till surfaces and a kitchen display, all reading the same engine. Postgres for state, Redis for cache and pub/sub, object storage for menu and ingredient imagery.

EPOS connectors

One interface, and the till never knows the difference.

Every till integration implements the same connector contract: connect, pull the menu, observe the order, and refuse an addition. Square authenticates through OAuth and Access EVO through an API key, and above that seam the enforcement path is identical.

That is what makes a third integration a connector rather than a rewrite, and it is why the roadmap can name quarters for Lightspeed and Toast without qualifying them.

  • SquareLive, OAuth
  • Access EVOLive, API key
  • LightspeedQ3 2026
  • ToastQ4 2026

On the handset

Three signals, because one model guessing is not a safety feature.

Vision and rules

Apple Vision identifies the plate; the labels run through the same 282 ingredient patterns and 254 synonyms the backend uses.

A trained classifier

FastViT-T8, trained across 101,000 food images then fine tuned to predict all fourteen regulated allergens.

Retrieval

MobileCLIP matched against 10,574 labelled dishes, which is what covers the allergens with too little training data to learn.

It runs entirely on the device and never says a dish is safe: it reports what it detected and defers to the till. The rarest allergens still have measured accuracy gaps, disclosed in the app where a guest can read them.

Ask harder questions.

Architecture documents, the connector contract, the audit findings and the load test method are all written down. If you are evaluating this technically, say so and I will send them instead of summarising them.

Request the technical pack