# Annapurna Domain - Technical Specifications

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

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

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

### `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 `MenuItem`s; 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 `MenuItem`s it was consumed in and the `RestaurantOrder`s 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.** `IngredientLot`s 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
  `MenuItem`s it was consumed in and the `RestaurantOrder`s 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.
