Planned Autonomous Restaurant and Culinary Operations Intelligence Platform (TODO Phase 68)
This document is the technical specification for the Annapurna domain — the planned Oshun platform for commercial food-service operations. It translates the Phase 68 roadmap into precise type definitions, state machines, API contracts, persistence schemas, and invariants that implementation teams can build against. The document is organized to serve two reading modes: a top-down scan for understanding the domain's shape, and a reference lookup for the exact definition of a specific type, enum, or rule.
Every type, field, enum value, state, transition, event, API family, and
requirement in this document is traceable to one of three design sources:
DOMAINS/annapurna/features.md, DOMAINS/annapurna/architecture.md, or
TODOS/phase-68.md. Nothing is invented; nothing is described as implemented,
because no Annapurna code exists in the monorepo yet.
Status#
Planned domain — design-level specification. No workspace packages exist
yet: there is no libs/annapurna/, no apps/annapurna/, and no
services/annapurna/ directory, and no package.json declares an
@annapurna/* package anywhere in the monorepo. The only Annapurna artifacts
present are the design documents in DOMAINS/annapurna/ and the published HTML
under docs/releases/v1/domains/annapurna/.
This document is therefore a planned/design-level technical specification, not a description of running code. Every type, field, enum value, state, transition, event, API family, and requirement below is grounded in one of three design sources and is cited as such:
DOMAINS/annapurna/features.md— the Phase 68 feature specification.DOMAINS/annapurna/architecture.md— the planned workspace topology and domain boundaries.TODOS/phase-68.md— the Phase 68 task list ("Annapurna - Autonomous Restaurant & Culinary Operations Intelligence Platform"), the authoritative task-level source for package structure, schema columns, types, enums, and events.
Where features.md and the phase doc differ in granularity, the phase doc is
treated as authoritative for package structure and column lists, and features.md
is authoritative for the three frozen core domain objects and the four hard
requirements. Items the phase doc enumerates but features.md does not are
labelled (planned, phase-68) to keep the provenance explicit. When packages
are implemented, this document must be rewritten against the real code with
concrete persistence schemas and test gates.
Domain Identity#
Annapurna (अन्नपूर्णा) is the Hindu goddess of food, nourishment, and abundance — from the Sanskrit anna ("food") and purna ("complete"): "she who provides complete nourishment." The domain is the planned Oshun platform for commercial food-service operations: menu engineering, kitchen automation and robotics, front-of-house, autonomous and human delivery, ghost kitchens, multi-unit chains and franchises, commissaries, procurement, food safety, workforce, restaurant finance, customer intelligence, and sustainability.
Source: features.md opening section; phase-68.md Phase 68 header.
Core Pillars#
The phase doc organizes the domain around six capability pillars that together
span the full commercial food-service lifecycle — from recipe science through to
autonomous delivery and multi-unit management. Each pillar maps to one or more
planned @annapurna/* packages.
The phase doc frames the domain around six pillars (phase-68.md, "Core
Pillars"):
- Culinary Intelligence — world cuisine mastery, flavor science, menu engineering, recipe innovation, nutritional and dietary intelligence.
- Restaurant Design & Operations — restaurant spaces across concepts (fine dining through ghost kitchen), FOH/BOH management, POS, reservations, staff scheduling.
- Kitchen Automation & Robotics — robotic cooking, automated mise en place, vision-based quality control, IoT kitchen monitoring, automated cleaning.
- Autonomous Delivery — self-driving ground vehicles, delivery drones (via the Oya domain), route optimization, thermal packaging, mixed-fleet orchestration.
- Multi-Unit Intelligence — franchise management, central kitchen / commissary, menu consistency across locations, performance benchmarking.
- Supply Chain & Food Safety — fresh procurement, perishable inventory, HACCP compliance, farm-to-table traceability (via the Asase domain).
Planned Package Prefix and Workspace Shape#
The domain's workspace shape is fixed by Phase 68 before any code is written, so that TypeScript path mappings and ESLint module-boundary rules can be configured without retrofitting.
- Libraries:
@annapurna/*(phase-68.md§68.1.1.25, path mappings totsconfig.base.json). - Cross-domain contracts:
@contracts/annapurna, planned aslibs/contracts/annapurna/(phase-68.md§68.1.1.23). - ESLint module-boundary scope tag:
scope:annapurna(phase-68.md§68.1.1.26).
The planned libs/annapurna/* packages (phase-68.md §68.1.1.2 – §68.1.1.22)
are: core, culinary, menu, kitchen, robotics, restaurant, foh,
boh, delivery, ghost, chain, commissary, supply, safety, staff,
finance, customer, apps, ai, sustainability, integration —
twenty-one libraries — plus libs/contracts/annapurna/. The application suite
(Customer app, Kitchen Management app, Delivery Fleet app) is planned to live
inside libs/annapurna/apps/ (phase-68.md §68.18), not as standalone
apps/annapurna/* projects.
Technology Stack#
The domain is polyglot by design, with each language chosen to match the performance and runtime characteristics of its concern. TypeScript handles orchestration and APIs where developer velocity matters; Rust handles robotics and navigation where determinism and safety matter; Python handles ML models where the scientific ecosystem matters; C/C++ handles embedded firmware where bare-metal control matters.
The table below summarizes the planned language and technology assignments
(phase-68.md, "Technology Stack").
| Concern | Planned technology |
|---|---|
| Orchestration, APIs, business logic, POS, dashboards | TypeScript |
| Autonomous vehicle navigation, real-time path planning, kitchen robotics control | Rust |
| ML/AI models (food-quality computer vision, flavor prediction, demand forecasting, menu optimization) | Python |
| Embedded systems (delivery-vehicle firmware, kitchen-robot controllers, IoT sensors) | C / C++ |
| Real-time kitchen management runtime | Node.js with native modules |
| Relational persistence | PostgreSQL |
| Time-series telemetry (kitchen sensors, order time-series) | PostgreSQL with TimescaleDB hypertables |
| Real-time order tracking, kitchen-display state | Redis |
| Order event streaming across kitchen, delivery, and business systems | Kafka |
| Kitchen robotics and delivery-vehicle autonomy stack | ROS2 |
| Customer app, driver/robot monitoring app | React Native |
| Real-time order status, kitchen display, delivery tracking transport | WebSocket |
| Recipe similarity, flavor-profile matching, customer-preference embeddings | pgvector extension |
| ORM and migrations | Drizzle ORM |
Source: phase-68.md "Technology Stack" and §68.1.2.11 – §68.1.2.15.
Core Domain Objects#
Three core domain objects anchor every package; they are the frozen contract
every Phase 68 feature builds on (features.md, "Domain Foundation"). They are
specified here exactly as defined in this domain's design docs.
The three objects are frozen — meaning their field sets and invariants do not
change without a deliberate domain design revision — because every other package
in Annapurna reads or writes them. A change to MenuItem, RestaurantOrder, or
IngredientLot is a breaking change for the entire domain.
Branded Identifier Types#
All entity references use branded string ID types so that, for example, a
MenuItemId cannot be passed where an OrderId is expected. Branded IDs
prevent a class of runtime bugs where identifiers of different entity types are
accidentally interchanged — a mistake that is otherwise only caught at query
time.
type RestaurantId = string;
type MenuItemId = string;
type OrderId = string;
type IngredientLotId = string;
type StaffMemberId = string;
The phase doc additionally calls for branded IDs VehicleId, TableId, and
RecipeId with factory functions, alongside RestaurantId, MenuItemId,
OrderId, and StaffId (phase-68.md §68.2.1.9). The five IDs listed above
are the ones the core domain objects in this domain's docs reference directly;
VehicleId, TableId, and RecipeId are (planned, phase-68).
Source: specifications.md core types; features.md @annapurna/core entity
models; phase-68.md §68.2.1.9.
MenuItem#
A sellable item on a restaurant's menu. This is the primary revenue object in the domain: it carries the price, the allergen declaration, and the derived margin that menu engineering optimizes against.
interface MenuItem {
id: MenuItemId;
restaurantId: RestaurantId;
name: string;
category: 'appetizer' | 'main' | 'dessert' | 'drink' | 'special' | 'bundle';
price: number;
currency: string;
allergens: string[];
grossMarginPercent?: number;
}
The table below describes each field, its type, whether it is required, and its meaning in the domain.
| Field | Type | Required | Meaning |
|---|---|---|---|
id |
MenuItemId |
Required | Stable branded identifier for the menu item. |
restaurantId |
RestaurantId |
Required | Owning restaurant; the multi-tenancy scope key for the item. |
name |
string |
Required | Display name of the dish. |
category |
literal union | Required | One of six categories — see the MenuItem category enum below. |
price |
number |
Required | The current selling price. |
currency |
string |
Required | ISO currency code the price is denominated in. |
allergens |
string[] |
Required | Allergens present in the item. Computed as the union of recipe-ingredient allergens plus shared-equipment cross-contact risk; it is never narrower than the ingredient set (features.md @annapurna/culinary, allergen propagation). |
grossMarginPercent |
number |
Optional | Gross margin percentage. The field menu engineering reads and writes; it is derived from costed recipe ingredients against the current price, never hand-entered (features.md, "Domain Foundation"). |
Three domain invariants govern MenuItem beyond the type definition:
allergensis the union of recipe-ingredient allergens and cross-contact risk, and never narrower than the ingredient set.grossMarginPercentis always reproducible for any historical date because price changes are versioned (hard requirement 3).- For
category: 'bundle'items, the bundle composes other items; bundle margin is computed from component costs and the bundle inherits the union of component allergens (features.md@annapurna/menu, bundles).
RestaurantOrder#
A customer order against a restaurant. The order object is the primary operational object: every kitchen, delivery, and FOH workflow is driven by advancing an order through its status graph.
interface RestaurantOrder {
id: OrderId;
restaurantId: RestaurantId;
channel: 'dine_in' | 'takeaway' | 'delivery' | 'catering' | 'ghost_kitchen';
status:
| 'created'
| 'confirmed'
| 'in_prep'
| 'ready'
| 'served'
| 'delivered'
| 'cancelled';
items: MenuItemId[];
}
The table below describes each field and its role in the order lifecycle.
| Field | Type | Required | Meaning |
|---|---|---|---|
id |
OrderId |
Required | Stable branded identifier for the order. |
restaurantId |
RestaurantId |
Required | Owning restaurant; multi-tenancy scope key. |
channel |
literal union | Required | The fulfilment channel — see the RestaurantOrder channel enum. The channel determines which fulfilment path the order takes and which apps observe it (features.md, "Domain Foundation"). |
status |
literal union | Required | The order's lifecycle status — see the RestaurantOrder status state machine. |
items |
MenuItemId[] |
Required | The menu items on the order. |
IngredientLot#
A received batch of one ingredient — the unit of traceability. The lot is the object that connects a supplier delivery to a finished dish: every step from receiving through consuming an ingredient is tracked against a lot ID, making it possible to answer "which orders were affected by a recall?" in constant time.
interface IngredientLot {
id: IngredientLotId;
ingredientName: string;
supplierId: string;
receivedAt: string;
expiryDate?: string;
traceabilityStatus: 'pending' | 'verified' | 'hold' | 'recalled';
}
The table below describes each field and how it participates in the safety lifecycle.
| Field | Type | Required | Meaning |
|---|---|---|---|
id |
IngredientLotId |
Required | Stable branded identifier for the lot. |
ingredientName |
string |
Required | The ingredient this lot is a batch of. |
supplierId |
string |
Required | The supplier the lot was received from. |
receivedAt |
string |
Required | Timestamp the lot was received. |
expiryDate |
string |
Optional | Expiry/use-by date, when the ingredient carries one. Lots approaching expiryDate are surfaced for use-first or markdown; expired lots are blocked from consumption (features.md @annapurna/supply, inventory and expiry). |
traceabilityStatus |
literal union | Required | The lot's safety lifecycle state — see the IngredientLot traceabilityStatus state machine. |
Enumerations#
The enumerations in this section define the exact set of legal values for the enum-typed fields on the three core domain objects. Each enum value carries a specific operational meaning that determines how the system routes work, enforces safety rules, or classifies output.
MenuItem category#
The six category values classify what kind of item a MenuItem is. The bundle
value is architecturally important: bundle items have derived margin and
inherited allergens rather than directly assigned values.
Source: specifications.md MenuItem.category; features.md "Domain
Foundation".
| Value | Meaning |
|---|---|
appetizer |
A starter course item. |
main |
A main-course item. |
dessert |
A dessert-course item. |
drink |
A beverage. |
special |
A limited or seasonal item outside the standing menu. |
bundle |
A composite item that composes other MenuItems; margin and allergens are derived from its components. |
RestaurantOrder channel#
The five channel values determine the fulfilment path an order takes and which
applications and services observe it. For example, a ghost_kitchen order
bypasses FOH entirely and is routed to the delivery fleet; a dine_in order is
routed to the kitchen display and the server's section.
Source: specifications.md RestaurantOrder.channel; features.md "Domain
Foundation".
| Value | Meaning |
|---|---|
dine_in |
Consumed on the restaurant premises; observed by FOH and kitchen-display surfaces. |
takeaway |
Collected by the customer for off-premise consumption. |
delivery |
Fulfilled by the delivery channel (@annapurna/delivery) to a customer address. |
catering |
A catering order. |
ghost_kitchen |
A delivery-only order routed through ghost-kitchen operations (@annapurna/ghost); typically normalized from a third-party marketplace. |
RestaurantOrder status#
The seven status values form the order lifecycle state machine. The terminal
state differs by channel: dine_in ends at served, while delivery and
ghost_kitchen end at delivered. cancelled is terminal and reachable from
any non-terminal state. See the state-machine section for the full legal
transition graph.
Source: specifications.md RestaurantOrder.status; features.md "Domain
Foundation" and @annapurna/core order state machine.
| Value | Meaning |
|---|---|
created |
The order has been created but not yet confirmed. Initial state. |
confirmed |
The order is accepted and committed for preparation. |
in_prep |
The order is being prepared in the kitchen. |
ready |
Preparation is complete; the order awaits service or dispatch. |
served |
The order has been served to the guest. Terminal status for dine_in. |
delivered |
The order has been handed off to the customer. Terminal status for delivery and ghost_kitchen. |
cancelled |
The order was cancelled. Terminal status, reachable from any non-terminal state. |
IngredientLot traceabilityStatus#
The four traceability status values track a lot through its safety lifecycle.
Only verified lots are available for consumption; hold and recalled lots
are hard-blocked. The recalled state is terminal — there is no path from
recalled back to any usable state.
Source: specifications.md IngredientLot.traceabilityStatus; features.md
"Domain Foundation" and @annapurna/safety traceabilityStatus lifecycle.
| Value | Meaning |
|---|---|
pending |
The lot has been received but its safety verification is not yet complete. Initial state. |
verified |
Supplier documentation and a receiving temperature check have passed; the lot is cleared for consumption. |
hold |
The lot has been quarantined by a manager action or a failed inspection. May not be consumed. |
recalled |
A recall notice has named the lot or its supplier. May not be consumed. Terminal state. |
Domain Event Names#
Six typed domain-event names form the @annapurna/core event contract. These
are the events other packages — and downstream Oshun domains — subscribe to.
They are the primary integration surface of the domain: anything that needs to
react to something happening in Annapurna does so by subscribing to one of these
six events.
Six typed domain-event names are defined as the @annapurna/core event contract
(features.md @annapurna/core, event contracts): order.created,
order.status_changed, lot.received, lot.recalled, menu.price_changed,
incident.logged. See the Domain Events section for payloads.
The phase doc additionally enumerates Kafka event-bus events OrderPlaced,
OrderConfirmed, FoodReady, PickedUp, Delivered, InventoryLow,
EquipmentAlert, and VehicleDispatched (phase-68.md §68.1.3.7). These are
(planned, phase-68) bus-level events; the canonical typed domain-event names
this domain commits to are the six @annapurna/core events.
State Machines#
The two state machines below are the most operationally significant behavioral
contracts in the domain. The order state machine governs every revenue
transaction; the lot traceability state machine governs every food-safety
decision. Both are owned by @annapurna/core.
RestaurantOrder status state machine#
@annapurna/core is the single authority for the seven-status order transition
graph. It rejects illegal transitions and stamps each transition with actor and
timestamp (features.md @annapurna/core, order state machine). No other
package may change order status directly — they must go through the state
machine.
States: created, confirmed, in_prep, ready, served, delivered,
cancelled.
Initial state: created.
Forward progression (features.md "Domain Foundation"):
created → confirmed → in_prep → ready → served → delivered. The status
advances through these values in order; the order state machine rejects illegal
skips such as created → served (features.md @annapurna/core, order state
machine).
Cancellation: cancelled is reachable from any non-terminal state.
Terminal states by channel (features.md "Domain Foundation"):
| Channel | Terminal status |
|---|---|
dine_in |
served |
delivery |
delivered |
ghost_kitchen |
delivered |
| any channel | cancelled (terminal once reached) |
For the delivery channel, the order advances to delivered only on confirmed
customer handoff (features.md @annapurna/delivery, last-mile timing).
Each transition is stamped with the acting actor and a timestamp; this is the audit basis for order history.
IngredientLot traceabilityStatus state machine#
@annapurna/safety owns the IngredientLot traceabilityStatus lifecycle
(features.md @annapurna/safety, traceabilityStatus lifecycle). The
ownership by @annapurna/safety is deliberate: safety transitions must be
governed by the package that enforces HACCP and food-safety rules, not scattered
across receiving or supply packages.
States: pending, verified, hold, recalled.
Initial state: pending — entered on receipt of the lot.
Transitions:
The table below lists every legal transition, the state it starts from, the
state it moves to, and the event that triggers it. The recalled terminal state
can be reached from any non-terminal state because a recall notice may arrive at
any point in a lot's lifecycle.
| From | To | Trigger |
|---|---|---|
pending |
verified |
A passed receiving temperature check and valid supplier documentation. |
pending / verified |
hold |
A manager action, or a failed inspection. |
pending / verified / hold |
recalled |
A recall notice names the lot or its supplier. |
Terminal state: recalled.
Consumption invariant: hold and recalled lots may not be consumed by any
order (features.md "Domain Foundation"; hard requirement 2 and
@annapurna/safety). A temperature reading outside its threshold raises an
alert and may itself trigger a hold transition (features.md
@annapurna/safety, temperature logs).
Robotic station state (planned, phase-68)#
Every robotic station exposes a safety-stop that halts motion immediately and
transitions the station to a stopped state requiring explicit operator
clearance to resume (features.md @annapurna/robotics, safety-stop). A
station with no wired safety-stop cannot be commissioned, and a robot may not
start a food cycle while a calibration is overdue (features.md
@annapurna/robotics, calibration and cleaning cycles). When robotic capacity
is saturated or a station is stopped, orders fall back to a manual prep queue
rather than stalling (features.md @annapurna/robotics, queueing and
fallback). The exact station-state enum is not enumerated in the design docs and
must be defined when @annapurna/robotics is implemented.
Hard Requirements (Platform Invariants)#
Four platform requirements constrain every package and are non-negotiable
(features.md, "Hard Requirements"; specifications.md, "Requirements"). They
are acceptance criteria for the domain as a whole.
These four requirements are not feature flags or policy settings — they are structural invariants. Any package implementation that does not satisfy all four is incomplete, regardless of how many other features it delivers. They exist because food-service operations carry real public-health and legal consequences that cannot be addressed after the fact.
- Immutable food-safety records. Food-safety and allergen records — HACCP logs, temperature readings, sanitation checks, inspection results — become read-only the moment they are signed off. Corrections are appended as new records that reference the original; the original is never edited or deleted.
- Lot-to-order traceability. Every
IngredientLotmust be linked forward to theMenuItems it was consumed in and theRestaurantOrders those items were served on. A recall must resolve, from a lot ID, to the exact list of affected orders and guests. - Versioned menu pricing. Every
MenuItemprice change retains the prior price, the cost assumptions in effect at the time, and the timestamp.grossMarginPercentis always reproducible for any historical date. - Robotic safety controls. Every robotic kitchen workflow exposes a safety-stop, a manual-override path, and an append-only incident log. A robot may not run a station without these wired.
Package Specifications#
Each package below is a planned @annapurna/* library. The behaviour described
is the acceptance contract for that package when it is implemented; all of it is
(planned, phase-68) unless it restates a frozen core object or hard
requirement.
Each section follows the same structure: a one-sentence role statement, the
features the package owns (as described in features.md), and the additional
phase-68 implementation detail drawn from phase-68.md. The phase-68 detail is
additive — it narrows the feature description to specific algorithms, data
targets, or numeric tolerances — and is prefixed with "Phase-68 detail" to keep
the two layers of specification distinct.
@annapurna/core#
Foundation package: the primitives every other package depends on. This package must be implemented first; every other package imports from it.
- Entity models. Restaurant, brand, location, kitchen, station,
MenuItem, recipe,IngredientLot, supplier,RestaurantOrder, reservation, staff member, guest, table, inventory record, invoice, delivery, and compliance record. Each carries a stable branded ID type (RestaurantId,MenuItemId,OrderId,IngredientLotId,StaffMemberId). - Event contracts. The six typed domain events
order.created,order.status_changed,lot.received,lot.recalled,menu.price_changed, andincident.logged, which other packages and downstream domains subscribe to. - Order state machine. The single authority for the seven-status
RestaurantOrdertransition graph; rejects illegal transitions and stamps each transition with actor and timestamp. - Multi-tenancy. All entities are scoped by
restaurantId; a brand groups restaurants for a chain. Queries are tenant-isolated by default.
Phase-68 type detail (phase-68.md §68.2.1 – §68.2.2): the core type set is
planned to include Restaurant, KitchenStation, MenuItem, Order,
DeliveryVehicle, Table, Reservation, StaffMember, Recipe,
Ingredient, FlavorProfile, CuisineType, CookingTechnique,
DietaryRequirement, and NutritionalData, each with a Zod schema. The enum
detail the phase doc fixes:
- Restaurant concept (
phase-68.md§68.2.1.1): fine dining, casual dining, fast-casual, QSR, ghost kitchen, food truck, pop-up, cafe, bakery, bar/lounge. - KitchenStation name (
phase-68.md§68.2.1.2): grill, saute, fry, pastry, cold/garde manger, pizza, wok, sushi, prep, plating, dishwash. - Table real-time status (
phase-68.md§68.2.1.6): available, occupied, reserved, cleaning, blocked. - StaffMember role (
phase-68.md§68.2.1.8): chef, sous chef, line cook, prep cook, server, bartender, host, busser, dishwasher, manager, delivery. - DeliveryVehicle class (
phase-68.md§68.2.1.5): sidewalk robot, road robot, delivery drone, bicycle, motorcycle, car. - Dietary tags on
MenuItem(phase-68.md§68.2.1.3): vegan, vegetarian, gluten-free, halal, kosher, keto, paleo.
@annapurna/culinary#
Culinary intelligence: turning recipes into executable, costed, allergen-aware production. This is the knowledge-intensive package in the domain — it encodes flavor science, non-linear scaling rules, and allergen propagation logic that cannot be naively derived from simple CRUD on recipe records.
- Recipe model and scaling. Recipes hold ingredient quantities per yield;
scaling recomputes quantities for a target cover count and rounds to practical
pack sizes. Scaling must handle non-linear behaviour — spices do not scale
linearly, leavening adjusts differently, and cooking times change with volume
(
phase-68.md§68.3.1.4). - Flavor pairing and substitutions. A substitution graph proposes
replacements when an ingredient lot is on
holdor out of stock, ranked by flavor compatibility and allergen safety. A substitution that introduces a new allergen is rejected, not down-ranked. - Allergen propagation. An item's
allergensarray is computed as the union of its recipe ingredients' allergens plus shared-equipment cross-contact risk; it is never narrower than the ingredient set. - Nutrition and prep planning. Per-portion nutrition is rolled up from ingredients; prep plans and mise-en-place lists are generated per station from the day's forecasted order mix.
- Batch cooking. Recipes sharing prep steps are grouped into batches sized to equipment capacity and the forecasted demand window.
Phase-68 detail (phase-68.md §68.3): a world-cuisine taxonomy of 250+ regional
cuisines, a master recipe database structured for 10,000+ recipes, a recipe
standardization engine (home → commercial format), recipe versioning, a
sub-recipe/component system, a flavor-compound database of 1,000+ aroma
compounds, a flavor-pairing engine on shared aroma chemistry, taste-balance and
texture/temperature-contrast planners, a Maillard optimizer, fermentation
intelligence, a molecular-gastronomy toolkit, spice-blend formulation, and a
mother-sauce/derivative system. The CookingTechnique enum is planned at 500+
techniques organized by heat method — dry heat, moist heat, no heat,
combination, and molecular (phase-68.md §68.2.2.5).
@annapurna/menu#
Menu engineering: deciding what to sell, at what price, and what to cut. The menu-engineering matrix is the analytical centerpiece of this package; the quadrant classification tells operators exactly what action to take for every item on the menu, derived from actual sales and cost data rather than intuition.
-
Menu-engineering matrix. Every
MenuItemis classified each period on two axes — popularity (unit sales versus menu average) and profitability (grossMarginPercentversus menu average) — into one of four quadrants:Quadrant Popularity Margin Recommended action Stars High High Protect and feature. Plowhorses High Low Re-engineer cost or raise price carefully. Puzzles Low High Reposition, rename, or re-plate. Dogs Low Low Candidate for removal. -
Price testing. A price test changes one item's
pricefor a defined cohort or period and measures the unit-sales and margin delta against a control. The test holds the prior price as the control baseline and respects the versioned-pricing requirement so every test is reproducible. -
Contribution margin. Per-item contribution (price minus plate cost) and menu-mix-weighted total contribution drive recommendations; recommendations cite the cost assumptions used.
-
Seasonal and regional menus. Items carry availability windows; regional localization swaps items and prices per location while preserving allergen and costing logic.
-
Bundles.
category: 'bundle'items compose other items; bundle margin is computed from component costs, and a bundle inherits the union of component allergens.
Phase-68 detail (phase-68.md §68.4): a menu pricing engine (food-cost
percentage targets, psychological .95/.99 endings, anchor and decoy
pricing), a menu-layout optimizer, an AI menu-description generator, dynamic
pricing (time-of-day, demand-based, surge), and a food-costing engine. The phase
doc fixes target food-cost percentages by category — proteins 30–35%, sides
20–25%, desserts 20–25%, beverages 15–20% (phase-68.md §68.4.2.1) — and
defines food-cost variance as theoretical food cost (POS sales × recipe cost)
versus actual food cost (purchases − inventory change) (phase-68.md
§68.4.2.3).
@annapurna/kitchen (planned, phase-68)#
Kitchen design, equipment, and workflow management (phase-68.md §68.1.1.5).
The phase doc places commercial-kitchen design under §68.5.2: a workflow-based
layout engine (receiving → storage → prep → cooking → plating → service),
menu-driven equipment specification, Type I/Type II ventilation design,
refrigeration specification, plumbing specification (three-compartment sink,
handwash stations, grease interceptor), electrical load planning, kitchen-
flooring specification, and an equipment maintenance scheduler.
@annapurna/restaurant#
Restaurant and dining-space intelligence. This package is the bridge between the built environment (owned by Cybele) and the operational use of that space — it models how tables, stations, and equipment are arranged to serve the volume and concept the restaurant targets.
- Kitchen layout. Station placement is checked against safety clearances, equipment footprints, and traffic-flow lanes; the planner flags clearances below code minimums rather than silently accepting them.
- Dining-room layout. Table mix and capacity are modeled against target
cover counts; the planner reports seated capacity and turn potential per
layout. The phase doc fixes spacing targets per concept tier — fine dining
15–20 sq ft/seat, casual 12–15, QSR 8–12 (
phase-68.md§68.5.1.2). - Equipment dependencies. Each station declares energy and water dependencies so layout changes surface utility-load and plumbing impacts.
Phase-68 detail (phase-68.md §68.5.1): a restaurant concept-design engine,
biophilic restaurant design (consuming @seshat/harmony and @athena/biome
patterns), layered lighting design, an acoustics designer with RT60 targets by
concept (fine dining 0.5–0.8 s, casual 0.6–1.0 s — phase-68.md §68.5.1.5),
open-kitchen design, bar/lounge design, outdoor-dining design, restroom design,
and food-truck/pop-up design.
@annapurna/robotics#
Kitchen automation and robotic cooking — governed by hard requirement 4. This package compiles recipes into robot instruction sets, orchestrates multi-robot kitchen coordination, and enforces the safety prerequisites that must be wired before any station can be commissioned. The Rust control layer, the safety-stop, the incident log, and the fallback queue are all non-negotiable.
- Recipe-to-robot translation. A recipe is compiled into an ordered robot instruction set for a station; instructions reference calibrated tool offsets and timings.
- Safety-stop. Every robotic station exposes a safety-stop that halts motion immediately and transitions the station to a stopped state requiring explicit operator clearance to resume. A station with no wired safety-stop cannot be commissioned.
- Manual override. An operator can pre-empt a robot mid-cycle and complete the step by hand; the override is recorded with actor, station, and reason.
- Incident log. Collisions, aborts, calibration failures, and overrides are written to an append-only incident log; entries are never edited.
- Calibration and cleaning cycles. Stations run scheduled calibration and cleaning cycles; a robot may not start a food cycle while a calibration is overdue.
- Queueing and fallback. When robotic capacity is saturated or a station is stopped, orders fall back to a manual prep queue rather than stalling.
Phase-68 detail (phase-68.md §68.6): robotic controllers for wok, grill/
plancha, fryer, pizza assembly, sushi assembly, salad/bowl assembly, beverage
preparation, and pastry/dessert assembly; a multi-robot kitchen orchestrator
that synchronizes dish completion for a table; an automated cleaning/
sanitization cycle verified by ATP bioluminescence sensor; automated ingredient
dispensing (accuracy ±1 g for spices, ±5 g for proteins/vegetables —
phase-68.md §68.6.2.1); and kitchen IoT and vision systems (plate QC against
reference photos, vision-based food-safety monitoring, cooking-completion
detection). The robotic-cooking and navigation control layers are planned in
Rust (phase-68.md "Technology Stack").
@annapurna/foh#
Front-of-house operations. FOH is the guest-facing half of the restaurant: it owns the reservation-to-departure arc, the table and server assignments, and the service-timing visibility that keeps courses flowing without the kitchen stacking up behind a slow handoff.
- Reservations and waitlist. Reservations hold a party size, time, and table preference; the waitlist estimates wait from current table turns and promotes parties as tables free.
- Seating and host workflow. Seating assigns parties to tables honoring server-section balance; the host view shows table status (open, seated, dirty, reserved).
- Service timing. Order flow tracks course pacing per table; servers are
alerted when a table's
RestaurantOrdersits inin_preporreadybeyond a per-course threshold. - Guest notes, complaints, tips, handoff. Guest notes persist across visits; complaints are logged against an order; tips are attributed per server; shift handoff transfers open tables and notes to the incoming server.
Phase-68 detail (phase-68.md §68.7): a touchscreen POS system (modifier
selection, split checks, void/comp authorization, tip management,
cash/card/mobile payment, gift cards); a kitchen display system (KDS) with
station ticket routing and green/yellow/red timing colour-coding; multi-channel
order aggregation across dine-in POS, web, mobile app, phone, and third-party
platforms; an order-throttling system; tableside QR ordering; and a self-service
kiosk.
@annapurna/boh (planned, phase-68)#
Back-of-house operations — prep, cooking, plating, cleaning, and inventory
(phase-68.md §68.1.1.9). The phase doc does not give @annapurna/boh its own
numbered subsection; back-of-house behaviour is distributed across
@annapurna/culinary (prep, batch cooking), @annapurna/robotics (cooking,
plating, cleaning automation), and @annapurna/supply (inventory). This package
is the planned home for non-robotic back-of-house workflow.
@annapurna/delivery#
Delivery and last-mile operations for the delivery order channel, plus the
autonomous-vehicle fleet. This package closes the delivery loop: from the moment
a kitchen marks an order ready, through packaging selection, dispatch, route
optimization, and confirmed guest handoff that advances the order to
delivered.
- Packaging. Packaging is selected per item to hold temperature and structural integrity for the estimated transit time.
- Dispatch and routing. Orders are dispatched to drivers and batched when drop-offs are geographically close and within a freshness window; routing optimizes the batched stop sequence.
- Last-mile timing. Promised delivery time combines prep time, dispatch
wait, and route ETA; the order advances to
deliveredonly on confirmed handoff. - Delivery quality. Late, cold, or incomplete deliveries are logged and feed driver and packaging quality metrics.
Phase-68 detail (phase-68.md §68.8): autonomous ground-delivery vehicles
(sidewalk robot, road robot, multi-meal pod), an autonomous navigation stack on
ROS2 (HD maps, GPS/RTK, LiDAR + camera sensor fusion, pedestrian and obstacle
detection), a multi-stop path-planning engine, thermal compartment management
(hot food >60 °C, cold food <5 °C, frozen <−18 °C — phase-68.md §68.8.1.4),
customer authentication at handoff (PIN, QR, facial recognition), fleet
management, charging infrastructure planning, a delivery-robot safety system
(emergency stop, collision response, zone speed limits), delivery-drone
integration via the Oya domain, a delivery dispatch optimizer, a multi-order
batching engine, delivery-time estimation, and delivery quality scoring.
@annapurna/ghost#
Ghost kitchen and cloud-kitchen operations for the ghost_kitchen order
channel. Ghost kitchens are the most capital-efficient restaurant format — high
output per square foot, no FOH costs — but they require careful station
allocation and brand separation to prevent one brand's peak demand from starving
another's.
- Cloud-kitchen brands. One physical kitchen runs multiple delivery-only brands; each brand has its own menu, and orders carry the brand identity.
- Station allocation. Shared stations are allocated across brands by forecasted demand to avoid one brand starving another at peak.
- Marketplace channels. Orders arriving from third-party marketplaces are
normalized into
RestaurantOrderwithchannel: 'ghost_kitchen'and tracked through the standard status graph.
Phase-68 detail (phase-68.md §68.9): a ghost-kitchen facility designer
(multi-brand kitchen, shared-equipment optimization), a virtual-brand creator, a
brand-performance analyzer per virtual brand, a shared-kitchen resource
optimizer that prevents cross-contamination between brand concepts, a
ghost-kitchen location optimizer, and a kitchen-as-a-service model that rents
stations to external brands.
@annapurna/chain#
Multi-unit and franchise management. A chain's central challenge is maintaining brand standards across many independently operated or franchised locations while still allowing the local adaptation that makes individual restaurants viable. This package provides the publishing, deviation-tracking, and portfolio- reporting tooling that makes that balance possible at scale.
- Brand standards. Recipes, menus, and procedures are published from the brand to member restaurants; per-location deviations are tracked as exceptions.
- Franchise reporting. Sales, prime cost, and compliance roll up from each franchised location to the brand; franchisees see their own data, the franchisor sees the portfolio.
- Expansion playbooks. Opening a new unit follows a templated checklist spanning layout, equipment, hiring, and menu localization.
Phase-68 detail (phase-68.md §68.10): a multi-unit dashboard aggregating KPIs
across locations, a menu-consistency enforcer that detects deviation from POS
and food-cost variance, a centralized procurement system, a franchise-management
system (franchisee onboarding, royalty calculation, brand-compliance audits),
new-location analysis (site selection, cannibalization analysis), and a
store-opening playbook with milestone tracking.
@annapurna/commissary#
Central kitchen and commissary operations. A commissary allows a chain or high-
volume operator to produce components centrally at scale — on tilt kettles,
combi ovens, and mixers — and distribute them to restaurants, so that each
location maintains quality without replicating the full production effort.
Critically, traceability must survive the transfer from commissary to
restaurant: each IngredientLot reference must travel with the prepped goods.
- Central production. The commissary produces prepped components in bulk; production batches are sized to aggregate downstream restaurant demand.
- Transfer orders. Prepped goods move to restaurants on transfer orders;
each transfer carries
IngredientLotreferences so traceability survives the hop from commissary to restaurant. - Quality consistency. Commissary output is QA-checked so every restaurant receives the same spec.
Phase-68 detail (phase-68.md §68.11): central-kitchen production planning,
batch-recipe management at commissary scale (recipes scaled for 50/100/500-
gallon batches on tilt kettle, combi oven, and mixer), commissary-to-location
distribution with temperature-controlled transport, sous vide and cook-chill
production, and a commissary HACCP plan.
@annapurna/supply#
Procurement, inventory, and ingredient cost management. This package is the
entry gate for ingredients: every IngredientLot starts here when goods are
received. It is also the cost engine: ingredient prices flowing through this
package are what make grossMarginPercent accurate across the menu.
- Procurement and vendor scoring. Purchase plans are generated from par levels and forecasted demand; vendors are scored on price, fill rate, on-time delivery, and quality rejection rate.
- Receiving. Received goods create
IngredientLotrecords inpending; receiving captures quantity, temperature, and supplier documentation, which must pass before the lot moves toverified. - Inventory and expiry. Stock counts reconcile against system quantities;
lots approaching
expiryDateare surfaced for use-first or markdown, and expired lots are blocked from consumption. Perishables are managed FEFO (first-expiry-first-out —phase-68.md§68.12.2.2). - Costing. Ingredient costs feed recipe plate costs and therefore
grossMarginPercent; cost changes are versioned alongside menu prices. - Traceability and waste. Each lot's consumption is recorded against menu items and orders (hard requirement 2); waste is tracked by lot and reason.
Phase-68 detail (phase-68.md §68.12): a food-service supplier database
(broadline distributors, specialty purveyors, local farms), automated purchasing
from par levels, cross-supplier price comparison, a receiving-inspection
workflow, farm-to-table sourcing integration consuming @asase/crops, a
perpetual inventory system, shelf-life management by ingredient category (fresh
produce 1–7 days, proteins 2–5 days, dairy 5–14 days — phase-68.md
§68.12.2.3), waste categorization, and inventory valuation (beginning
inventory + purchases − ending inventory = COGS).
@annapurna/safety#
Food safety, HACCP, and compliance — governed by hard requirement 1, and owner
of the IngredientLot traceabilityStatus lifecycle. This package is the
compliance backbone of the domain. It enforces immutability on signed-off
records, owns all transitions in the lot safety lifecycle, and executes the
recall response that links a lot ID to the exact orders and guests affected.
- HACCP plans. Hazard analysis and critical control points are modeled per
recipe and process; each critical control point declares a monitored limit.
Hazard analysis covers biological, chemical, and physical hazards per Codex
Alimentarius / FDA guidelines (
phase-68.md§68.13.1.1). traceabilityStatuslifecycle. The package owns theIngredientLotpending → verified → hold → recalledtransitions: receipt createspending; a passed receiving check and supplier documentation move it toverified; a manager action or failed inspection moves it tohold; a recall notice moves it torecalled.holdandrecalledlots are barred from consumption.- Temperature logs and thresholds. Cold storage, hot holding, and cook
temperatures are logged against thresholds — cold-chain at or below the safe
ceiling, hot holding at or above the safe floor, cook temperature meeting the
per-product minimum. A reading outside its threshold raises an alert and may
trigger a
hold. - Immutability after signoff. Once a HACCP log, temperature reading, sanitation check, or inspection result is signed off it is read-only; a correction is a new appended record referencing the original.
- Recalls. A recall names lots or suppliers, transitions matching lots to
recalled, and resolves through lot-to-order traceability to the exact affected orders and guests. - Allergen controls and audit trails. Allergen handling procedures are tracked per station; every safety record carries an immutable audit trail of who recorded it and when.
Phase-68 detail (phase-68.md §68.13): a HACCP plan builder, a temperature-
monitoring system with continuous IoT logging and instant deviation alerts, a
health-inspection readiness system, employee-health tracking, an allergen-
management protocol with a per-item allergen matrix and colour-coded prep
equipment, a cleaning-and-sanitization schedule with ATP swab validation, pest-
control management, and a food-recall response system driven by lot tracking.
@annapurna/staff#
Workforce management and labor planning. Labor is typically the second-largest
cost center in a restaurant after food; scheduling is therefore both an
operational and a financial problem. This package integrates demand forecasts
from @annapurna/ai with skill coverage rules to produce schedules that are
both adequately staffed and within budget.
- Scheduling. Shifts are scheduled against forecasted demand and labor-cost targets; the scheduler respects skill coverage so every station has a qualified worker.
- Skills and training. Staff carry skill and certification records; training completion gates assignment to skill-restricted stations.
- Labor cost. Scheduled labor cost is projected and compared to the labor-cost-percentage target; overruns are flagged before the schedule is published.
Phase-68 detail (phase-68.md §68.14): a demand-based scheduling engine
(servers per section, cooks per station, break compliance, overtime control),
tip management and pooling, kitchen-brigade management, training-program
management with recertification, labor-cost analytics (covers per labor hour,
revenue per labor hour), and a kitchen skills matrix tracking competency per
cook per station.
@annapurna/finance#
Restaurant financial intelligence. This package translates the operational records produced by supply, staff, and sales into the financial statements operators and investors use to evaluate performance. The core calculation is the margin reconciliation: comparing theoretical food cost (derived from recipes) against actual food cost (derived from inventory movements) to surface waste and shrinkage that would otherwise be invisible.
- COGS and prime cost. Cost of goods sold is rolled up from consumed
IngredientLotcosts; prime cost combines COGS and labor and is reported against target. - P&L and cash flow. Per-location profit and loss and cash-flow projections are built from sales, prime cost, and operating expenses.
- Margin reconciliation. Actual food cost is reconciled against theoretical cost derived from recipe costing, surfacing waste and shrinkage.
Phase-68 detail (phase-68.md §68.15): a restaurant P&L engine (revenue by
channel and daypart, COGS by food/beverage/packaging, labor by role, EBITDA), a
prime-cost tracker with a target band of 55–65% of revenue depending on concept
(phase-68.md §68.15.1.2), break-even analysis per restaurant, cash-flow
management, a new-restaurant financial model (years 1–5), and delivery-channel
profitability analysis (revenue per order − food cost − packaging − platform
commission − delivery cost = net margin).
@annapurna/customer#
Guest CRM and analytics. Guest data is the long-run competitive asset for a restaurant: understanding who comes back, why they leave, what they prefer, and what their allergens are makes personalized service possible at scale. This package also closes the demand loop: aggregate guest behavior feeds the forecasts that drive scheduling, procurement, and batch cooking.
- Guest profiles and loyalty. Guest profiles carry visit history, preferences, and allergen flags; loyalty tracks points and rewards across visits and channels.
- Feedback. Feedback and complaints are tied to orders and items, feeding menu-engineering and quality signals.
- Lifetime value and demand forecasting. Guest lifetime value is computed from visit frequency and spend; aggregate guest behaviour feeds the demand forecasts that drive scheduling, procurement, and batch cooking.
Phase-68 detail (phase-68.md §68.16): a customer data platform unifying a
360-degree profile from POS, online orders, app usage, loyalty, feedback, and
social media; a segmentation engine using RFM (recency, frequency, monetary)
analysis; a personalized recommendation engine; churn prediction with win-back
campaigns; and a customer-lifetime-value calculation (visit frequency × average
check × expected relationship duration).
@annapurna/sustainability#
Waste, sourcing, and environmental signals. This package quantifies the environmental cost of restaurant operations and surfaces the data operators need to reduce it — waste by cause, sourcing quality, and per-item carbon and water estimates derived from ingredient provenance.
- Food-waste reduction. Waste logged by
@annapurna/supplyis analyzed by cause (spoilage, over-prep, plate waste) and feeds par-level and batch-size corrections. - Sustainable sourcing. Supplier and ingredient sourcing attributes (local,
certified, seasonal) are tracked per
IngredientLot. - Carbon and water signals. Per-menu-item carbon and water estimates are derived from ingredient sourcing and surfaced for menu decisions.
Phase-68 detail (phase-68.md §68.17): a food-waste tracking engine with CO2e
impact and surplus-food donation management, a per-menu-item carbon-footprint
calculation, a sustainable-sourcing scorecard (local percentage, organic
percentage, MSC/ASC seafood certification), an energy-efficiency tracker (energy
per cover, per square foot, per revenue), a single-use packaging-reduction
planner with a reusable-container deposit/return program, and a water-
conservation tracker.
@annapurna/ai#
AI and ML engine supporting other packages — not a standalone product surface.
This package provides the predictive layer that makes the rest of the domain
proactive. Its outputs are always consumed by another package: demand forecasts
feed @annapurna/staff and @annapurna/supply; menu optimization feeds
@annapurna/menu; quality anomaly detection feeds @annapurna/safety. It does
not expose user-facing surfaces directly.
- Demand forecasting. Forecasts order volume and item mix per location and
daypart; consumed by scheduling, procurement, and batch cooking. Forecasts
carry confidence intervals for safety stock (
phase-68.md§68.19.1.1). - Menu optimization. Recommends price, placement, and removal moves from the menu-engineering matrix and price-test results.
- Quality anomaly detection. Flags anomalies in temperature logs, delivery timing, and food-cost variance for human review.
Phase-68 detail (phase-68.md §68.19): a demand-forecasting model conditioned
on weather, events, holidays, and promotions; a food-quality vision model that
classifies plate presentation; a customer recommendation model (collaborative
filtering plus content-based on flavor profiles); a dynamic pricing model; a
kitchen-efficiency optimizer; a review sentiment analyzer; delivery-route
optimization ML; and food-trend prediction. ML models are planned in Python
(phase-68.md "Technology Stack").
@annapurna/apps#
The application suite — planned as libs/annapurna/apps/ (phase-68.md
§68.1.1.19, §68.18). This package houses all three end-user applications: the
guest-facing customer app, the kitchen and management apps used by staff, and
the fleet monitoring and courier apps used by the delivery operation.
- Restaurant OS. The operational console for a single restaurant — orders, tables, kitchen, and staff in one view.
- Kitchen display. Station-level display of in-prep and ready orders, driven by the order state machine.
- Manager app. Sales, prime cost, labor, and safety dashboards per location and across a chain.
- Customer app. Guest-facing reservations, ordering, and loyalty.
Phase-68 detail (phase-68.md §68.18): a Customer app (iOS/Android) with menu
browsing, allergen filtering, real-time order tracking, in-app reservation
booking, a loyalty interface, and an AR menu preview; a Kitchen Management app
(KDS tablet app, kitchen-manager dashboard, prep-management app); and a Delivery
Fleet app (fleet monitoring dashboard, human-courier app, robot remote-operation
teleoperation interface). The customer and monitoring apps are planned in React
Native (phase-68.md "Technology Stack").
@annapurna/integration#
Cross-domain integration hub. Annapurna does not duplicate facts owned elsewhere; it links to them. Each integration point below exists because an adjacent Oshun domain is the single source of truth for a subject that Annapurna needs but should not re-model. The integration package owns the adapter layer that translates between domain contracts.
- Hestia. Consumer recipe and nutrition data feeds Annapurna menus; Annapurna operational data informs Hestia restaurant-grade techniques. The boundary is the point of sale: household cooking is Hestia; commercial food-service is Annapurna.
- Demeter and Asase. Agriculture and ingredient supply-chain facts; Annapurna procurement links to them rather than re-modeling supply. Asase is authoritative for farm-level traceability; Annapurna picks up the chain at the receiving dock.
- Brigid. Industrial kitchen automation equipment and maintenance;
@annapurna/roboticsintegrates with Brigid for equipment-level concerns. Brigid owns the hardware layer; Annapurna owns the food-service-specific control and safety layer on top. - Cybele. Restaurant real estate and kitchen/facility construction;
@annapurna/restaurantlinks space intelligence to Cybele. Cybele owns the built environment; Annapurna owns the operational use of that space. - Maat. Financial rollups;
@annapurna/financefeeds Maat for cross-domain financial reporting.
Phase-68 detail (phase-68.md §68.20): a Hestia recipe adapter and meal-
planning bridge; an Asase farm-to-restaurant supply-chain adapter consuming
@asase/crops, @asase/quality, and @asase/cold-chain, plus an Asase retail
migration that absorbs @asase/retail QSR capability into @annapurna/chain; a
Brigid kitchen-automation adapter (@brigid/factory, @brigid/robotics),
refrigeration adapter (@brigid/hvac), and energy adapter (@brigid/energy);
an Oya aerial-delivery adapter and a ground-vehicle expansion proposal; and
adapters for Seshat (@seshat/harmony biophilic design), Athena
(@athena/studio, @athena/marketplace furniture), Freya (restaurant
textiles), Maat (@maat/finance, @maat/compliance, @maat/workforce), and
Psyche (voice/chatbot customer interaction). The phase doc requires a minimum of
200 integration test cases across all cross-domain adapters (phase-68.md
§68.20.5.6).
Planned API Surface#
The phase doc fixes the API-gateway architecture and transport set
(phase-68.md §68.1.3). All endpoints below are (planned, phase-68).
The multi-transport design reflects the different latency and interaction patterns in the domain: REST for standard CRUD operations, GraphQL for complex menu queries with multiple filter axes, WebSocket for the real-time order tracking that kitchen displays and customer apps depend on, gRPC for the high-frequency internal calls between robotic and delivery services, and Kafka for the event bus that decouples producers from consumers across the domain.
API gateway and transports#
- A route-based API gateway dispatching to per-area microservices (
phase-68.md§68.1.3.1). - REST endpoints for menu CRUD, order management, and delivery tracking
(
phase-68.md§68.1.3.2), formalized in an OpenAPI 3.1 specification (phase-68.md§68.1.3.8). - A GraphQL schema for complex menu queries with allergen filtering,
nutritional search, and availability (
phase-68.md§68.1.3.3). - A WebSocket server for real-time order status — kitchen display, customer
tracking, and delivery-vehicle position streaming (
phase-68.md§68.1.3.4). - gRPC service definitions for internal communication — kitchen robotics,
delivery-vehicle dispatch, and inventory updates (
phase-68.md§68.1.3.5). - A Kafka event bus for domain events (
phase-68.md§68.1.3.7). - Prometheus metrics for order throughput, kitchen efficiency, delivery
times, and vehicle utilization (
phase-68.md§68.1.3.9), and distributed tracing with OpenTelemetry across all services (phase-68.md§68.1.3.10).
API families#
The API families below group the planned endpoints by operational area. Each family maps to the packages that own the underlying domain objects.
Restated from features.md, "Planned API Surface", and grouped by package area:
- Culinary and supply — menu, recipe, ingredient, inventory, supplier, and procurement APIs.
- Operations — order, kitchen-display, prep, service, delivery, and customer APIs.
- Workforce — staff scheduling, skill, labor-cost, and payroll-integration APIs.
- Safety — APIs for HACCP plans, inspections, allergens, temperature logs, recalls, and traceability.
- Business — finance, analytics, loyalty, chain/franchise, commissary, and sustainability APIs.
Authentication and roles#
Authentication middleware enforces role-based access. The seven roles below are
the complete set; no request may access a tenant-scoped resource without
carrying one of these roles, and all entity queries are tenant-isolated by
restaurantId.
The phase doc fixes the role set (phase-68.md §68.1.3.6): customer, server,
chef, manager, driver, franchisee, admin. All entity queries are
tenant-isolated by restaurantId (@annapurna/core multi-tenancy).
Domain Events#
The @annapurna/core event contract defines six typed domain events
(features.md @annapurna/core). These events are the integration surface that
other packages — and other Oshun domains — subscribe to. Each event carries the
minimal payload needed to react to the change; full entity data is fetched
separately by subscribers that need it.
Payloads are derived from each event's stated purpose and the core domain
objects; exact payload schemas must be fixed when @annapurna/core is
implemented.
| Event | Trigger | Payload (planned) |
|---|---|---|
order.created |
A RestaurantOrder is created. |
The new order's OrderId, restaurantId, channel, and items. |
order.status_changed |
The order state machine transitions a RestaurantOrder. |
The OrderId, prior status, new status, acting actor, and timestamp. |
lot.received |
An IngredientLot is received and created in pending. |
The IngredientLotId, ingredientName, supplierId, and receivedAt. |
lot.recalled |
A recall transitions an IngredientLot to recalled. |
The IngredientLotId and the recall reference (lot or supplier named by the notice). |
menu.price_changed |
A MenuItem price is changed. |
The MenuItemId, prior price, new price, the cost assumptions in effect, and the timestamp (per hard requirement 3). |
incident.logged |
A robotic incident — collision, abort, calibration failure, or override — is recorded. | The station, incident type, acting actor where applicable, and timestamp; written to the append-only incident log. |
Phase-68 Kafka bus events (phase-68.md §68.1.3.7), (planned, phase-68):
OrderPlaced, OrderConfirmed, FoodReady, PickedUp, Delivered,
InventoryLow, EquipmentAlert, VehicleDispatched.
Persistence#
Persistence is planned on PostgreSQL with the pgvector extension, TimescaleDB
hypertables for telemetry, Redis for real-time state, and Drizzle ORM for schema
migrations (phase-68.md §68.1.2). All schemas below are (planned, phase-68);
concrete column types, indexes, and partitioning must be fixed when the schema
is implemented.
The persistence stack is split by data access pattern: relational PostgreSQL for durable, queryable records; TimescaleDB hypertables for high-frequency append- only telemetry; pgvector for similarity search; and Redis for the mutable real-time state that kitchen displays and delivery trackers read on every update.
Relational schemas (PostgreSQL, Drizzle ORM)#
The phase doc enumerates ten core relational schemas, each corresponding to a
major entity group in the domain. The table below lists each schema and the key
fields the phase doc calls out; exact column types, indexes, and constraints are
(planned, phase-68) and must be specified during implementation.
The phase doc enumerates ten core relational schemas (phase-68.md §68.1.2.1 –
§68.1.2.10):
| Schema | Key fields called out by the phase doc |
|---|---|
| restaurants | location, concept, capacity, hours, zones (dining, bar, patio, private); spatial data. |
| menus | items, categories, modifiers, allergens, dietary tags, pricing tiers, availability windows, seasonal rotation. |
| recipes | ingredients with quantities and units, preparation steps, cooking parameters, plating instructions, costing, nutritional data, allergen flags. |
| orders | order items, modifiers, timestamps (placed, confirmed, preparing, ready, picked-up, delivered), channel (dine-in, takeout, delivery, platform), payment. |
| inventory | ingredients, par levels, shelf life, lot tracking, FEFO ordering, waste logging, supplier, cost. |
| kitchen equipment | type, model, location, maintenance schedule, IoT sensor endpoints, calibration records. |
| delivery vehicles | type (robot, drone, human), status, location, battery/fuel, capacity, assigned orders, maintenance. |
| staff | role, certifications, availability, shift schedule, performance metrics, training progress. |
| customers | profile, dietary preferences, allergens, order history, loyalty points, feedback. |
| suppliers | contact, products, pricing, delivery schedule, quality rating, certifications. |
Time-series telemetry (TimescaleDB hypertables)#
Kitchen sensors and delivery vehicles generate high-frequency append-only data that is better served by a time-series store than standard relational rows. Two hypertable families are planned for this purpose.
Two hypertable families (phase-68.md §68.1.2.11 – §68.1.2.12):
- Kitchen IoT telemetry — equipment temperature, humidity, energy, and cooking parameters.
- Delivery-vehicle telemetry — GPS, speed, battery, compartment temperature, and obstacle events.
Vector and cache layers#
Two additional persistence layers complement the relational store: pgvector handles similarity search for recipes and flavor profiles, and Redis holds the mutable real-time state that changes on every order transition.
- pgvector — recipe-similarity search, flavor-profile matching, and
customer-preference embeddings (
phase-68.md§68.1.2.13). - Redis — real-time order state, kitchen-display-system state, delivery
tracking, and menu availability (
phase-68.md§68.1.2.14).
Seed data#
Seed data is planned for world-cuisine categories, base ingredients, common
allergens, equipment types, and cooking techniques (phase-68.md §68.1.2.16).
Validation Rules, Invariants, and Constraints#
The rules below are the complete set of domain-level invariants derived from this domain's design docs. They supplement the four hard requirements and apply to every package in the domain. An implementation that satisfies all rules below and all four hard requirements satisfies the domain contract.
Consolidated from this domain's design docs:
- Tenant isolation. Every entity is scoped by
restaurantId; queries are tenant-isolated by default (@annapurna/coremulti-tenancy). - Legal order transitions only. The
@annapurna/coreorder state machine rejects illegalRestaurantOrderstatus transitions (for examplecreated → served) and stamps every accepted transition with actor and timestamp. - No consumption of held or recalled lots.
IngredientLots inholdorrecalledmay not be consumed by any order; expired lots (pastexpiryDate) are also blocked from consumption. - Allergen union floor. A
MenuItem.allergensarray is never narrower than the union of its recipe ingredients' allergens plus cross-contact risk; a substitution that introduces a new allergen is rejected. - Bundle allergen inheritance. A
category: 'bundle'item inherits the union of its component items' allergens. - Immutable safety records. Signed-off food-safety records (HACCP logs, temperature readings, sanitation checks, inspection results) are read-only; corrections are appended records referencing the original.
- Forward lot traceability. Every
IngredientLotis linked forward to theMenuItems it was consumed in and theRestaurantOrders those items were served on; a recall resolves from a lot ID to the exact affected orders and guests. - Versioned pricing. Every
MenuItemprice change retains the prior price, the cost assumptions in effect, and the timestamp;grossMarginPercentis reproducible for any historical date. - Robotic safety prerequisites. A robotic station cannot be commissioned without a wired safety-stop, and a robot may not start a food cycle while a calibration is overdue; collisions, aborts, calibration failures, and overrides are written to an append-only incident log.
- Append-only logs. The robotic incident log and the safety audit trails are append-only — entries are never edited.
Acceptance Criteria#
The architecture doc names the verification suites expected of the
implementation (architecture.md, "Verification Expectations"). Each suite
below is the acceptance gate for its package; passing the suite is the minimum
bar for marking the corresponding package complete.
- Recipe-scaling tests — including a 4-portion recipe scaled to 50 portions
producing correct totals within ingredient pack granularity (
features.md@annapurna/culinary, recipe model and scaling). - Menu-profitability tests.
- Food-safety traceability tests.
- Allergen tests.
- Order-flow tests against the seven-status state machine.
- Delivery-routing tests.
- Staff-scheduling tests.
- Robotic-kitchen safety tests.
The phase doc additionally fixes a minimum of 200 integration test cases across
all cross-domain adapters (phase-68.md §68.20.5.6).
Configuration and Environment Inputs#
The design docs do not enumerate named environment variables. The configuration
surface implied by the planned stack and topology, all (planned, phase-68):
- PostgreSQL connection (with pgvector and TimescaleDB extensions enabled).
- Redis connection for real-time order, KDS, and delivery-tracking state.
- Kafka broker configuration for the domain event bus.
- ROS2 runtime configuration for kitchen robotics and delivery-vehicle autonomy.
- Per-restaurant tenancy configuration keyed by
restaurantId, and brand grouping for chains. - Cross-domain integration endpoints for Hestia, Asase, Brigid, Oya, Cybele, Maat, Seshat, Athena, Freya, and Psyche.
- Role-based access configuration for the seven roles (customer, server, chef, manager, driver, franchisee, admin).
Concrete environment-variable names must be defined when the packages are implemented.
Domain Boundaries#
Annapurna owns commercial food-service operations. Adjacent ownership is fixed
by architecture.md, "Boundaries", and phase-68.md, "Distinction from
Adjacent Domains". The boundaries below define where Annapurna ends and an
adjacent domain begins; the reason each boundary exists is stated alongside it.
- Hestia owns home cooking, recipe intelligence, nutrition, and smart-kitchen experiences for the household. The Hestia/Annapurna boundary is the point of sale: a household preparing a meal is Hestia; a business selling that meal is Annapurna. The boundary exists so that consumer recipes and commercial recipes do not accumulate duplicated ownership in two domains.
- Demeter and Asase own agriculture and ingredient production / supply-chain facts. Annapurna procurement starts where Asase ends — from processed ingredients to plated food and delivery to the customer. The boundary exists so that farm-level traceability has one authoritative source.
- Brigid owns generic industrial automation equipment and maintenance; Annapurna adds food-service-specific kitchen automation and robotics on top. The boundary exists so that equipment-level maintenance records are not duplicated between Brigid and the food-service layer.
- Cybele owns restaurant real estate and kitchen/facility construction. The boundary exists so that space and construction data have one authoritative source; Annapurna links to Cybele rather than maintaining a parallel model of the same physical spaces.
- Oya owns aerial-drone management; Annapurna adds food-specific ground delivery vehicles and consumes Oya for aerial delivery. The boundary exists so that general drone fleet management is not duplicated inside the delivery package.
Implementation Status#
There is no current libs/annapurna/*, apps/annapurna/*, or
services/annapurna/* implementation; this document is a planned/design-level
specification only. When packages are created, each package section above
becomes the acceptance contract for its package, and this document and
architecture.md must be rewritten against the real code with concrete
persistence schemas (column types, indexes, partitioning), service contracts,
integration fixtures, and test gates.