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.
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.
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.
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.
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.
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