Domain · Specifications

Annapurna Domain - Technical Specifications

yet: there is no libs/annapurna/, no apps/annapurna/, and no

17sections45 minread

On this page

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"):

  1. Culinary Intelligence — world cuisine mastery, flavor science, menu engineering, recipe innovation, nutritional and dietary intelligence.
  2. Restaurant Design & Operations — restaurant spaces across concepts (fine dining through ghost kitchen), FOH/BOH management, POS, reservations, staff scheduling.
  3. Kitchen Automation & Robotics — robotic cooking, automated mise en place, vision-based quality control, IoT kitchen monitoring, automated cleaning.
  4. Autonomous Delivery — self-driving ground vehicles, delivery drones (via the Oya domain), route optimization, thermal packaging, mixed-fleet orchestration.
  5. Multi-Unit Intelligence — franchise management, central kitchen / commissary, menu consistency across locations, performance benchmarking.
  6. 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 to tsconfig.base.json).
  • Cross-domain contracts: @contracts/annapurna, planned as libs/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.

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

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.

typescript
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:

  • allergens is the union of recipe-ingredient allergens and cross-contact risk, and never narrower than the ingredient set.
  • grossMarginPercent is 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.

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

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

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.

  1. 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.
  2. Lot-to-order traceability. Every IngredientLot must be linked forward to the MenuItems it was consumed in and the RestaurantOrders those items were served on. A recall must resolve, from a lot ID, to the exact list of affected orders and guests.
  3. Versioned menu pricing. Every MenuItem price change retains the prior price, the cost assumptions in effect at the time, and the timestamp. grossMarginPercent is always reproducible for any historical date.
  4. 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, and incident.logged, which other packages and downstream domains subscribe to.
  • Order state machine. The single authority for the seven-status RestaurantOrder transition 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 hold or 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 allergens array 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 MenuItem is classified each period on two axes — popularity (unit sales versus menu average) and profitability (grossMarginPercent versus 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 price for 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 RestaurantOrder sits in in_prep or ready beyond 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 delivered only 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 RestaurantOrder with channel: '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 IngredientLot references 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 IngredientLot records in pending; receiving captures quantity, temperature, and supplier documentation, which must pass before the lot moves to verified.
  • Inventory and expiry. Stock counts reconcile against system quantities; lots approaching expiryDate are 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).
  • traceabilityStatus lifecycle. The package owns the IngredientLot pending → verified → hold → recalled transitions: receipt creates pending; a passed receiving check and supplier documentation move it to verified; a manager action or failed inspection moves it to hold; a recall notice moves it to recalled. hold and recalled lots 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 IngredientLot costs; 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/supply is 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/robotics integrates 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/restaurant links space intelligence to Cybele. Cybele owns the built environment; Annapurna owns the operational use of that space.
  • Maat. Financial rollups; @annapurna/finance feeds 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/core multi-tenancy).
  • Legal order transitions only. The @annapurna/core order state machine rejects illegal RestaurantOrder status transitions (for example created → served) and stamps every accepted transition with actor and timestamp.
  • No consumption of held or recalled lots. IngredientLots in hold or recalled may not be consumed by any order; expired lots (past expiryDate) are also blocked from consumption.
  • Allergen union floor. A MenuItem.allergens array 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 IngredientLot is linked forward to the MenuItems it was consumed in and the RestaurantOrders those items were served on; a recall resolves from a lot ID to the exact affected orders and guests.
  • Versioned pricing. Every MenuItem price change retains the prior price, the cost assumptions in effect, and the timestamp; grossMarginPercent is 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.