Catering management · build status

Mise

Recipes, allergens, costing, production and the service gate. The ledger below is the authority; this page is generated from it.

generated 2026-08-03 19:22 UTC tree 2782722 (uncommitted changes present) 26 slices from docs/BUILD-LEDGER.md

Overall

73%complete
19 complete4 in progress3 not started 26 total

Phases

Phase A — the event production spine

M1 – M16 · 16 slices

15 complete · 1 in progress

Phase A′ — settlement and compliance

M17 – M18 · 2 slices

2 complete

Cross-product couplings and the site

X1 – X6 · 8 slices

2 complete · 3 in progress · 3 not started

Every module

SliceNameStatusThe ledger’s note
Phase A — the event production spine
M1FoundationcompleteSchema, mise_rw role, migration tooling, health fingerprint, token symlinks, app shell
M2Company, identity, auditcompletePersona, polymorphic auth, sessions, cloned roles, append-only audit. Isolation proved for read AND write
M3Kitchens and capabilitycompleteCounted named resources, capacity windows, storage bands. UI: list + create + add resource
M4Products and supplierscompleteUnit conversion, dated prices, declared allergens with source, nutrition, carbon
M5Recipes and the resolvercompleteNested sub-recipes, per-step yield, cycle guard, recipe_ingredients()
M6Costing functionscompleteProved against an independent Python oracle — 37 assertions, every figure agrees
M7Dishes and menuscompleteDish↔recipe, equipment rules per (dish × style), menu structure
M8The Allergen ChaincompleteDerived through nesting, ingredient_declaration() as marked-up spans, both labelling regimes, review dates
M9Clients, functions, service momentscompleteEnquiries, tastings, options with expiry, service moments, guest requirements
M14The Service GatecompleteSix 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
M10The Kitchen PlaybookcompleteFacts 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
M12BEO and versionspartialQuote versions are immutable once issued and carry the gate verdict. A separate BEO document with a ten-second diff is not built
M13Production planningcompleteBackward 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
M15Purchasing and stockcompletePurchase 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
M16Crew and labourcompleteOne labour engine for quote and timesheet. Double-booking refused by a Postgres exclusion constraint, proved by raw insert bypassing the API. 22 assertions
M11The Costing SpinecompleteRate 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
M17SettlementcompleteBuilt with M11
M18HACCPcompleteTask-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–DOrdering, service floor, analyticsnot startedSpecified in 05
X1event.clinic readerunblocked and liveReader, 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
X2EstatepartialGET /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
X3Procurevent biddingpartialBid 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
X4Verbunk crewnot startedThe agency crew kind and agency_worker_ref exist to receive it. Q-007
X5VELA weddingspartialThe 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
X6Truss dock contentionnot startedSame database, so the cheapest of the six
SiteMarketing sitecomplete5 pages, same tokens, served on 4322

What “done” means here

Done means a verification script exited zero on the committed tree. Not that somebody opened the screen and it looked right, and not that an agent reported success. Every slice marked complete above has a script in 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.

Run every gate at once:
./scripts/verify-all.sh local

Run it locally

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

Screens with data

Screen
Open at
What is on it
Dashboard
landing
http://localhost:5181/#/
Company-wide counts and the next service moments
Functions
list + detail
http://localhost:5181/#/functions
Every booked function; detail screens hang off each row
Enquiries
list + detail
http://localhost:5181/#/enquiries
Enquiry pipeline with options and their expiry
Tastings
list
http://localhost:5181/#/tastings
Scheduled tastings against enquiries
Orders
list + detail
http://localhost:5181/#/orders
Drop-off and online orders — Phase B, mostly empty
Channels
empty by design
http://localhost:5181/#/channels
Ordering channels — Phase B, not started
Menus
list + detail
http://localhost:5181/#/menus
Menu structure; each menu opens its own detail
Dishes
list + detail
http://localhost:5181/#/dishes
Dishes with equipment rules per (dish × style)
Recipes
list + detail
http://localhost:5181/#/recipes
Nested sub-recipes, per-step yield, the cycle guard
Products
list
http://localhost:5181/#/products
Suppliers, dated prices, declared allergens with source
Kitchens
list
http://localhost:5181/#/kitchens
Counted named resources, capacity windows, storage bands
Equipment
list
http://localhost:5181/#/equipment
Equipment and the rules that bind it to dishes
Playbook
signature
http://localhost:5181/#/playbook
★ Facts with provenance and expiry derived from a volatility class
Crew
list
http://localhost:5181/#/crew
One labour engine for quote and timesheet; double-booking refused by the DB
Production
list + detail
http://localhost:5181/#/production
Backward scheduling, prep ≠ pack, batches with lot traceability
Stock
list
http://localhost:5181/#/stock
Append-only movement ledger with no stored balance
Compliance
list
http://localhost:5181/#/compliance
HACCP as tasks; a missing record counts as a failure
Clients
list
http://localhost:5181/#/clients
Client records behind the enquiries
System
diagnostic
http://localhost:5181/#/system
Health fingerprint and configuration
★ The Pass
needs an id
open from Production → a batch
Full-bleed gloved-hand service surface. Leaves the shell entirely and needs a service-moment id — open it from a function's detail screen
BEO / quote / settlement detail
needs an id
open from Functions
All three are id-addressed (/#/functions/<id>/beo, /#/quotes/<id>, /#/settlements/<id>)