Catering management · build status
Recipes, allergens, costing, production and the service gate. The ledger below is the authority; this page is generated from it.
M1 – M16 · 16 slices
15 complete · 1 in progress
M17 – M18 · 2 slices
2 complete
X1 – X6 · 8 slices
2 complete · 3 in progress · 3 not started
| Slice | Name | Status | The ledger’s note |
|---|---|---|---|
| Phase A — the event production spine | |||
| M1 | Foundation | complete | Schema, mise_rw role, migration tooling, health fingerprint, token symlinks, app shell |
| M2 | Company, identity, audit | complete | Persona, polymorphic auth, sessions, cloned roles, append-only audit. Isolation proved for read AND write |
| M3 | Kitchens and capability | complete | Counted named resources, capacity windows, storage bands. UI: list + create + add resource |
| M4 | Products and suppliers | complete | Unit conversion, dated prices, declared allergens with source, nutrition, carbon |
| M5 | Recipes and the resolver | complete | Nested sub-recipes, per-step yield, cycle guard, recipe_ingredients() |
| M6 | Costing functions | complete | Proved against an independent Python oracle — 37 assertions, every figure agrees |
| M7 | Dishes and menus | complete | Dish↔recipe, equipment rules per (dish × style), menu structure |
| M8 | ★The Allergen Chain | complete | Derived through nesting, ingredient_declaration() as marked-up spans, both labelling regimes, review dates |
| M9 | Clients, functions, service moments | complete | Enquiries, tastings, options with expiry, service moments, guest requirements |
| M14 | ★The Service Gate | complete | Six legs, all real functions. No stub remains. not_assessed now means "there is nothing to assess" rather than "not built". The sixth is dietary (D-034): a certify requirement inside its supplier lead time blocks the price and names itself |
| M10 | ★The Kitchen Playbook | complete | Facts with provenance (who, when, which job, how) and expiry derived from a volatility class — 5 years structural, 6 months personnel. Blocking facts refuse the gate. Discrepancies keep both values. A correction is a FUNCTION that lists every gate verdict which consumed the old value |
| M12 | BEO and versions | partial | Quote versions are immutable once issued and carry the gate verdict. A separate BEO document with a ten-second diff is not built |
| M13 | Production planning | complete | Backward scheduling from serves_at, prep list ≠ pack list, batches with lot traceability and trace_lot(), cold-chain legs with a reason per leg. ★ The Pass — the full-bleed gloved-hand surface. 16 assertions |
| M15 | Purchasing and stock | complete | Purchase orders, goods receipt with lot and expiry, an append-only signed movement ledger with no stored balance, stock counts that post adjustments, purchase_requirement() from the resolver, and theoretical-vs-actual with its causes separated. 17 assertions |
| M16 | Crew and labour | complete | One labour engine for quote and timesheet. Double-booking refused by a Postgres exclusion constraint, proved by raw insert bypassing the API. 22 assertions |
| M11 | ★The Costing Spine | complete | Rate cards, quote versions with per-line VAT in basis points, contract with an enforced final-numbers deadline, settlement, variance attributed to causes that sum exactly. Screens for both. 16 assertions |
| Phase A′ — settlement and compliance | |||
| M17 | Settlement | complete | Built with M11 |
| M18 | HACCP | complete | Task-shaped, not document-shaped. A missing record counts as a failure, a CCP on a recipe step generates its own check, and a batch is not closed until its checks are. 21 assertions |
| Cross-product couplings and the site | |||
| Phase B–D | Ordering, service floor, analytics | not started | Specified in 05 |
| X1 | event.clinic reader | unblocked and live | Reader, snapshot model, sync check and exception lifecycle all built and tested. Q-011 is answered: event.clinic built app.event_participant_summary() and the supplier-principal mechanism, and Mise is identified by the database role it connects as (session_user), impersonating no tenant. Measured this session: the engaged event returns rows as mise_rw, an unengaged one returns none. D-017 and D-019 held throughout |
| X2 | Estate | partial | GET /api/venues/:id joins the venue, its spaces, Estate's booking diary and Mise's own kitchen record. Reads Estate defensively and returns estateReadable: false rather than an empty array when its schema differs |
| X3 | Procurevent bidding | partial | Bid requests, requirements, responses and the submission gate all built. A bid cannot be submitted without a Service Gate evaluation — a database constraint, not a convention. No transport to Procurevent: Q-005 |
| X4 | Verbunk crew | not started | The agency crew kind and agency_worker_ref exist to receive it. Q-007 |
| X5 | VELA weddings | partial | The inbound receiver stores verbatim then processes, and turns a guest list into seat-level requirements. It refuses to guess which sitting a requirement belongs to. No transport: Q-007 |
| X6 | Truss dock contention | not started | Same database, so the cheapest of the six |
| Site | Marketing site | complete | 5 pages, same tokens, served on 4322 |
scripts/
that exits 0 against the code as committed; a slice whose script has not
exited 0 in a single run is not complete here, whatever else was built.
Exit 2 means BLOCKED — nothing was measured, which is not a pass.
./scripts/verify-all.sh local
# 1 · API worker (Hyperdrive → local Postgres) cd ~/Documents/mise/api && npm run dev # :8801 # 2 · console app cd ~/Documents/mise/app && npm run dev # :5181 # 3 · marketing site (optional) cd ~/Documents/mise/site && npm run dev # :4322 # prove the tree before believing any status above cd ~/Documents/mise && ./scripts/verify-all.sh local
Mise uses hash routing, so every link below is a genuine deep link — it survives a reload and can be pasted to someone else.
/#/functions/<id>/beo, /#/quotes/<id>, /#/settlements/<id>)