T
TOMO
Developer Docs
BETA These docs are under partner review. Some features described are roadmap items, not yet shipped. Verify against your sandbox before relying on any contract.
● DRAFTv1.0.0food.book_chef_at_home

food.book_chef_at_home — Full Intent Specification

INTENT NAMESPACE: food
INTENT NAME:      book_chef_at_home
FULL ID:          food.book_chef_at_home
VERSION:          v1.0.0
STATUS:           draft
LAST UPDATED:     2026-05-10
TTBS WEIGHTS:     time 0.20 · taste 0.40 · budget 0.20 · safety 0.20

Chef-at-home brings a vetted chef + ingredients (or shopping list) to the user's home for a one-off meal/event. Differs from delivery (no rider), dine-in (no restaurant), and tiffin (no recurrence): single occasion, professional chef in user's kitchen. Locked structural fields: (a) chef_meta block with cuisine specialties, certifications, hygiene/KYC; (b) event_kind enum (intimate dinner, kids party, dinner party, anniversary, festival cooking); (c) ingredients_responsibility enum (chef_brings | user_provides | mixed); (d) kitchen_requirements block detailing what user's kitchen needs (gas/induction/oven/pressure cooker); (e) service_includes enum array (cooking, plating, serving, cleanup, leftover_packing).


1. NATURAL LANGUAGE COVERAGE

Classifies IN

  • "chef at home for a dinner party Saturday"
  • "private chef for anniversary"
  • "book a chef to cook for 8 people tonight"
  • "Italian chef for kids party"
  • "home cooking experience Sunday brunch"
  • "chef who can do Hyderabadi biryani at home"
  • "private chef for festival pooja meal"
  • "intimate dinner chef for 4"
  • "chef at home for date night"

Classifies OUT — borderline NO

  • "biryani delivery for dinner" → food.order_delivery
  • "table at restaurant" → food.book_dine_in
  • "tiffin for the month" → food.subscribe_tiffin
  • "catering for wedding" → food.book_catering_event (50+ guests)
  • "buy a cookbook" → no intent (informational)

MULTI-INTENT TRIGGERS

  • "chef at home for anniversary and book a cake" → food.book_chef_at_home + food.order_cake_or_special
  • "chef at home for dinner and grocery delivery for ingredients" → food.book_chef_at_home + grocery.order_delivery
  • "chef at home and sound system rental for party" → food.book_chef_at_home + (no current intent for sound rental)

2. INPUT — TOMO → PROVIDER

{
  "intent":          "food.book_chef_at_home",
  "intent_version":  "v1.0.0",
  "request_id":      "req_chef_5h2k_2026-05-10T08:00:00Z",
  "user_session_id": "anon_user_token_or_uid",

  "service_address": {
    "lat":            17.4504,
    "lng":            78.3811,
    "line_1":         "Flat 502, SriHomes Apartment",
    "line_2":         "Hitech City Main Road",
    "neighborhood":   "Madhapur",
    "city":           "Hyderabad",
    "state":          "Telangana",
    "pincode":        "500081",
    "country_code":   "IN",
    "place_kind":     "home",
    "access_notes":   "Lift to 5th floor, Flat B"
  },

  "scheduled_start_iso":   "2026-05-12T18:30:00+05:30",
  "scheduled_end_iso":     "2026-05-12T22:00:00+05:30",
  "service_duration_hours": 3.5,

  "event_kind":            "intimate_dinner",
  "occasion":              "anniversary",

  "guests": {
    "guest_count":           6,
    "adult_count":           4,
    "child_count":           2,
    "infant_count":          0,
    "dietary_filters":       ["veg", "gluten_free"],
    "allergens_to_avoid":    ["peanuts"]
  },

  "menu_brief": {
    "cuisine_primary":       "italian",
    "cuisines_acceptable":   ["italian", "continental", "fusion"],
    "course_count":          4,
    "course_kinds":          ["appetizer", "main", "dessert", "beverage"],
    "spice_level_max":       "mild",
    "no_onion_no_garlic":    false,
    "jain_meal_required":    false,
    "halal_required":        false,
    "preferred_dishes":      ["bruschetta", "risotto", "tiramisu"],
    "avoid_dishes":          [],
    "kid_friendly_required": true
  },

  "ingredients_responsibility": "chef_brings",

  "kitchen_capabilities": {
    "gas_cooktop":            true,
    "induction_cooktop":      false,
    "oven":                   true,
    "microwave":              true,
    "pressure_cooker":        true,
    "blender_mixer":          true,
    "refrigerator":           true,
    "freezer":                true,
    "dishwasher":             false,
    "kitchen_size":           "medium",
    "user_can_assist":        false
  },

  "service_includes_required": ["cooking", "plating", "serving", "cleanup_kitchen"],

  "preferences": {
    "chef_gender_preference":      "any",
    "chef_min_experience_years":   3,
    "chef_certification_required": true,
    "chef_speak_locales":          ["en-IN", "hi-IN"],
    "chef_kyc_required":           true,
    "budget_band":                 "great",
    "budget_max_inr_total":        12000,
    "tip_friendly_pricing":        true
  },

  "context": {
    "user_locale":          "en-IN",
    "user_currency_pref":   "INR",
    "is_festival_day":      false,
    "trust_signals": {
      "is_repeat_customer":          false,
      "prior_chef_at_home_with_partner": 0,
      "user_account_age_days":       312,
      "verified_address":            true,
      "verified_phone":              true
    }
  }
}
Field Type Constraint Notes
intent string REQUIRED, equals "food.book_chef_at_home"
service_address.access_notes string REQUIRED, may be empty floor / building access
service_duration_hours float REQUIRED, ≥1 typical 2-5h
event_kind enum REQUIRED, see §5
occasion enum REQUIRED, see §5
guests.guest_count int REQUIRED, ≥1 total
guests.adult_count int REQUIRED, ≥0
guests.child_count int REQUIRED, ≥0
guests.infant_count int REQUIRED, ≥0
menu_brief.cuisine_primary enum REQUIRED, see §5
menu_brief.course_count int REQUIRED, 1-7
menu_brief.course_kinds array REQUIRED, ≥1 see §5
menu_brief.kid_friendly_required bool REQUIRED
ingredients_responsibility enum REQUIRED, see §5
kitchen_capabilities.gas_cooktop bool REQUIRED
kitchen_capabilities.induction_cooktop bool REQUIRED
kitchen_capabilities.oven bool REQUIRED drives cuisine feasibility
kitchen_capabilities.kitchen_size enum REQUIRED, STRICT small | medium | large
kitchen_capabilities.user_can_assist bool REQUIRED drives chef solo vs paired
service_includes_required array REQUIRED, ≥1 see §5
preferences.chef_gender_preference enum REQUIRED, STRICT any | male | female
preferences.chef_min_experience_years int REQUIRED, ≥0
preferences.chef_certification_required bool REQUIRED
preferences.chef_kyc_required bool REQUIRED
preferences.budget_max_inr_total INR_INTEGER REQUIRED

Anti-fabrication preamble (universal): no paid placement, no urgency text, no commission-influenced fields.


3. PROVIDER TOOLS

Tool 1: get_chef_at_home_estimates

PURPOSE:        return chef + menu options for the event
INPUT:          §2 request body
OUTPUT:         { options: ChefAtHomeOption[], result_token, expires_at }
SLA:            p50 < 800ms, p95 < 1500ms

Tool 2: get_chef_detail

PURPOSE:        chef profile (full menu samples, reviews, KYC summary)
INPUT:          { chef_id, request_id }
OUTPUT:         ChefDetail (§4)
SLA:            p95 < 800ms

Tool 3: compute_menu_quote

PURPOSE:        compute total for a chosen menu + customizations
INPUT:          { chef_id, menu_id, custom_dishes[], guest_count, request_id }
OUTPUT:         MenuQuote (§4)
SLA:            p95 < 600ms

Tool 4: book_chef_at_home

PURPOSE:        commit booking
INPUT:          { option_id, payment_token, request_id, idempotency_key, user_phone, otp_required }
OUTPUT:         { booking_ref, status, chef, menu_locked, fare_quote, arrival_window_iso, deposit_inr }
SLA:            p95 < 5000ms
IDEMPOTENCY:    REQUIRED on idempotency_key

Tool 5: track_chef_arrival

PURPOSE:        live arrival tracking
INPUT:          { booking_ref, request_id }
OUTPUT:         ChefArrivalTrack (§4)
SLA:            p95 < 400ms
RATE LIMIT:     ≤ 1 every 30s

Tool 6: cancel_chef_at_home

INPUT:          { booking_ref, reason, request_id }
OUTPUT:         { status, cancellation_charge_inr, refund_amount_inr, refund_processing_days }
SLA:            p95 < 2000ms

Tool 7: request_menu_modification

PURPOSE:        modify menu before chef arrives
INPUT:          { booking_ref, menu_changes[], request_id }
OUTPUT:         { status, fare_delta_inr, ingredient_logistics_status }
SLA:            p95 < 1500ms

Tool 8: confirm_event_complete

PURPOSE:        partner records event completion + photos + leftover summary
INPUT:          { booking_ref, end_photos[], leftovers_packed_count, kitchen_cleaned_score, request_id }
OUTPUT:         { acknowledged: true, completion_iso }
SLA:            p95 < 1500ms

Tool 9: rate_chef

PURPOSE:        post-event rating
INPUT:          { booking_ref, chef_rating_5star, food_score, hygiene_score, conduct_score, comment, tip_inr, request_id }
OUTPUT:         { acknowledged: true }
SLA:            p95 < 800ms

All nine REQUIRED.


4. RESPONSE SHAPE

ChefAtHomeOption

id:                               string, REQUIRED
option_token:                     string, REQUIRED
expires_at:                       ISO_DATETIME, REQUIRED

chef:
  id:                             string, REQUIRED
  display_name:                   string, REQUIRED
  full_name:                      string, REQUIRED
  photo_url:                      URL, REQUIRED
  bio_text:                       string, REQUIRED            # ≥80 chars, real
  experience_years:               int, REQUIRED, ≥0
  experience_years_in_cuisine_primary: int, REQUIRED, ≥0
  cuisines_primary:               array<enum>, REQUIRED, ≥1
  cuisines_secondary:             array<enum>, REQUIRED, may be empty
  signature_dishes:               array<string>, REQUIRED, ≥3
  certifications:                 array<STRICT ENUM>, REQUIRED, ≥0
  certified_by_authority:         array<STRICT ENUM>, REQUIRED, ≥0
  fssai_food_handler_kyc:         boolean, REQUIRED
  fssai_food_handler_id:          string, REQUIRED
  fssai_food_handler_valid_until: ISO_DATE, REQUIRED
  background_check_passed:        boolean, REQUIRED
  background_check_iso:           ISO_DATETIME, REQUIRED
  aadhaar_verified:               boolean, REQUIRED
  pan_verified:                   boolean, REQUIRED
  partner_account_age_days:       int, REQUIRED, ≥0
  events_completed_total:         int, REQUIRED, ≥0
  events_completed_in_30day:      int, REQUIRED, ≥0
  rating_avg:                     float, REQUIRED, 0-5
  rating_count:                   int, REQUIRED, ≥0
  food_score:                     float, REQUIRED, 0-5
  hygiene_score:                  float, REQUIRED, 0-5
  conduct_score:                  float, REQUIRED, 0-5
  punctuality_30day_pct:          float, REQUIRED, 0-1
  languages_spoken:               array<RFC_3066_LOCALE>, REQUIRED, ≥1
  gender:                         STRICT ENUM, REQUIRED       # male | female | non_binary | prefer_not_to_say
  age_band:                       STRICT ENUM, REQUIRED       # 22-30 | 31-40 | 41-55 | 56+
  attire_kind:                    STRICT ENUM, REQUIRED       # chef_whites | branded_uniform | smart_casual

menu:
  menu_id:                        string, REQUIRED
  menu_name:                      string, REQUIRED            # "Italian 4-Course Anniversary"
  course_count:                   int, REQUIRED
  courses:                        array, REQUIRED, ≥1
    - course_kind:                STRICT ENUM, REQUIRED
      dishes:                     array<DishSummary>, REQUIRED, ≥1
  total_calories_per_head:        int, REQUIRED
  cuisine_primary:                STRICT ENUM, REQUIRED
  ingredients_logistics:          STRICT ENUM, REQUIRED       # see §5
  kitchen_requirements_met:       boolean, REQUIRED            # vs user's kitchen_capabilities
  kitchen_requirements_text:      string, REQUIRED             # what's needed
  jain_compliant:                 boolean, REQUIRED
  halal_compliant:                boolean, REQUIRED
  satvik_compliant:               boolean, REQUIRED
  no_onion_no_garlic_compliant:   boolean, REQUIRED
  kid_friendly:                   boolean, REQUIRED

service_includes:                 array<STRICT ENUM>, REQUIRED, ≥1   # see §5

fare:
  total_inr:                      INR_INTEGER, REQUIRED
  per_head_inr:                   INR_INTEGER, REQUIRED
  chef_service_fee_inr:           INR_INTEGER, REQUIRED
  ingredient_cost_inr:            INR_INTEGER, REQUIRED        # 0 if user_provides
  logistics_fee_inr:              INR_INTEGER, REQUIRED        # chef travel
  cleanup_fee_inr:                INR_INTEGER, REQUIRED
  serving_staff_fee_inr:          INR_INTEGER, REQUIRED        # if separate from chef
  platform_fee_inr:               INR_INTEGER, REQUIRED
  gst_inr:                        INR_INTEGER, REQUIRED
  rider_tip_optional_inr:         INR_INTEGER, REQUIRED
  fare_breakdown_text:            string, REQUIRED
  is_upfront_fare:                boolean, REQUIRED
  fare_locked_until_iso:          ISO_DATETIME, REQUIRED

deposit:
  required:                       boolean, REQUIRED
  amount_inr:                     INR_INTEGER, REQUIRED
  hold_kind:                      STRICT ENUM, REQUIRED        # see §5
  refund_eta_business_days:       int, REQUIRED, ≥0

availability:
  arrival_eta_iso:                ISO_DATETIME, REQUIRED
  arrival_window_minutes:         int, REQUIRED                # tolerance
  setup_minutes_required:         int, REQUIRED                # how early before scheduled_start
  alternate_chefs_available:      int, REQUIRED, ≥0

trust:
  fssai_grade_aggregate:          STRICT ENUM, REQUIRED        # rolled-up across chef's events
  cleanliness_audit_score_30day:  int, REQUIRED, 0-100
  partner_chef_pool_size:         int, REQUIRED, ≥1
  emergency_replacement_chef_within_minutes: int, REQUIRED
  insurance_coverage_inr:         INR_INTEGER, REQUIRED        # liability
  user_kitchen_damage_coverage:   boolean, REQUIRED
  food_poisoning_coverage:        boolean, REQUIRED
  cctv_optional_for_user:         boolean, REQUIRED            # user can request

cancellation:
  free_cancel_until_iso:          ISO_DATETIME, REQUIRED
  cancel_charge_within_24h_inr:   INR_INTEGER, REQUIRED
  cancel_charge_within_4h_inr:    INR_INTEGER, REQUIRED
  no_show_charge_inr:             INR_INTEGER, REQUIRED
  partner_cancel_compensation_inr: INR_INTEGER, REQUIRED
  refund_processing_days:         int, REQUIRED, ≥0

freshness:
  data_last_synced_iso:           ISO_DATETIME, REQUIRED
  menu_last_updated_iso:          ISO_DATETIME, REQUIRED

_provider:
  name:                           string, REQUIRED
  tomo_partner_id:                string, REQUIRED
  partner_tier:                   STRICT ENUM, REQUIRED
  deep_link:                      URL, REQUIRED
  customer_support_phone:         string, REQUIRED
  customer_support_email:         string, REQUIRED
  customer_support_24x7:          boolean, REQUIRED
  partner_chef_at_home_volume_30d: int, REQUIRED, ≥0
  partner_event_completion_rate_30d: float, REQUIRED, 0-1

DishSummary

(Same structure as food.order_delivery §5 DishSummary. All fields REQUIRED.)

ChefDetail (returned by get_chef_detail)

Superset of chef block + 5+ menus available + 10+ recent reviews + photos of past events.

MenuQuote (returned by compute_menu_quote)

chef_id:                          string, REQUIRED
menu_id:                          string, REQUIRED
custom_dishes_count:              int, REQUIRED, ≥0
guest_count:                      int, REQUIRED
total_inr:                        INR_INTEGER, REQUIRED
per_head_inr:                     INR_INTEGER, REQUIRED
fare_breakdown_text:              string, REQUIRED
quote_valid_until_iso:            ISO_DATETIME, REQUIRED
ingredient_swap_attempted:        boolean, REQUIRED            # if user requested ingredient sub
ingredient_swap_accepted:         boolean, REQUIRED

ChefArrivalTrack

booking_ref:                      string, REQUIRED
status:                           STRICT ENUM, REQUIRED        # see §5
status_updated_iso:               ISO_DATETIME, REQUIRED
status_history:                   array, REQUIRED, ≥1

chef_status:
  current_status:                 STRICT ENUM, REQUIRED        # see §5
  current_lat:                    float, REQUIRED
  current_lng:                    float, REQUIRED
  eta_to_user_minutes:            int, REQUIRED
  ingredients_loaded:             boolean, REQUIRED            # if chef_brings
  ingredient_load_complete_iso:   ISO_DATETIME, REQUIRED       # may equal future iso

arrival_window_status:
  open_iso:                       ISO_DATETIME, REQUIRED
  close_iso:                      ISO_DATETIME, REQUIRED
  buffer_remaining_minutes:       int, REQUIRED

support_phone:                    string, REQUIRED
support_email:                    string, REQUIRED

Forbidden fields

paid_placement_score | sponsored_rank | promotion_priority |
fake_recent_event_text | auto_inflate_events_completed |
ai_generated_chef_photo (must equal false) | hidden_logistics_fee |
fake_certifications | undisclosed_food_handler_kyc_lapse

5. CONTROLLED VOCABULARIES

event_kind

intimate_dinner | dinner_party | brunch | lunch_party | kids_party |
anniversary | birthday | festival_meal | religious_pooja_meal |
date_night | proposal_dinner | engagement_dinner | corporate_offsite |
team_outing | family_reunion | other

occasion

casual | birthday | anniversary | engagement | wedding_celebration |
festival | religious_event | reunion | farewell | corporate | other

menu_brief.cuisine_primary and chef.cuisines_primary[]

hyderabadi | south_indian | north_indian | bengali | punjabi | gujarati |
maharashtrian | rajasthani | kerala | tamilian | andhra | konkani | goan |
chinese | thai | korean | japanese | sushi | italian | french | continental |
mediterranean | mexican | lebanese | turkish | greek | mughlai | awadhi |
kashmiri | jain | satvik | live_grill | bbq | tandoor | fusion

menu_brief.course_kinds[] and menu.courses[].course_kind

welcome_drink | appetizer | starter | soup | salad | bread |
main | side | rice | biryani | dessert | beverage | tea_coffee | mocktail | cocktail

dietary_filters and dish.dietary_tags

veg | non_veg | egg | vegan | jain | halal | kosher | satvik |
no_onion_no_garlic | gluten_free | dairy_free | sugar_free | low_carb |
keto | paleo | high_protein | low_calorie

allergens_to_avoid

peanuts | tree_nuts | dairy | eggs | wheat | gluten | soy |
fish | shellfish | sesame | mustard

ingredients_responsibility and menu.ingredients_logistics

chef_brings | user_provides | mixed

service_includes_required[] and service_includes[]

cooking | plating | serving | cleanup_kitchen | cleanup_dining |
ingredient_shopping | leftover_packing | menu_planning_consultation |
table_setup | beverage_service | dessert_service | photography_friendly

kitchen_capabilities.kitchen_size

small | medium | large

chef.gender

male | female | non_binary | prefer_not_to_say

chef.age_band

22-30 | 31-40 | 41-55 | 56+

chef.attire_kind

chef_whites | branded_uniform | smart_casual

chef.certifications[]

ihm_diploma | culinary_institute_diploma | shamiana_chef_council |
fssai_food_safety_supervisor | hospitality_management_diploma |
foreign_culinary_certification

chef.certified_by_authority[]

ihm_authority | fssai | iihm | iipa | partner_internal | foreign_authority

trust.fssai_grade_aggregate

A | B | C | unrated

deposit.hold_kind

card_block | bank_transfer | wallet_hold | none

ChefArrivalTrack.status

booked_pending_arrival | chef_assigned | chef_loading_ingredients |
chef_en_route | chef_nearby | chef_arrived | setup_in_progress |
cooking_in_progress | serving | event_ongoing | cleanup_in_progress |
event_complete | cancelled_by_user | cancelled_by_chef |
chef_late_grace_active | chef_no_show

ChefArrivalTrack.chef_status.current_status

loading_ingredients | en_route | arrived | setting_up | cooking |
serving | cleaning | departed

cancel_chef_at_home.reason

user_changed_plans | wrong_time | wrong_address | dietary_mismatch |
budget_changed | found_alternative | health_emergency | weather_block | other

dish.veg_or_non_veg

veg | non_veg | egg | vegan | jain

dish.spice_level

mild | medium | spicy | very_spicy

dish.oil_used

sunflower | mustard | groundnut | rice_bran | olive | coconut |
ghee | butter | palm | mixed | none

6. TTBS DIMENSIONS

Per-domain weights

food (book_chef_at_home): { time: 0.20, taste: 0.40, budget: 0.20, safety: 0.20 }

TIME

SIGNALS USED:
  - availability.arrival_eta_iso ≤ scheduled_start - setup_minutes_required HARD FILTER
  - availability.arrival_window_minutes (longer=better)  weight 0.20
  - chef.punctuality_30day_pct                           weight 0.40
  - availability.alternate_chefs_available               weight 0.10
  - cancellation.refund_processing_days                  weight 0.10
  - trust.emergency_replacement_chef_within_minutes ≤ 30 weight 0.20

TASTE

SIGNALS USED:
  - chef.rating_avg                                      weight 0.20
  - chef.food_score                                      weight 0.20
  - chef.experience_years_in_cuisine_primary             weight 0.15
  - menu cuisine match user.cuisine_primary              weight 0.20
  - menu.kid_friendly (if kid_friendly_required)         weight 0.10
  - chef.signature_dishes overlap user.preferred_dishes  weight 0.15

HARD FILTERS:
  - dietary_filters not satisfiable
  - allergens conflict
  - kitchen_requirements_met=false
  - chef_gender_preference mismatch (if not "any")
  - jain_meal_required AND jain_compliant=false
  - halal_required AND halal_compliant=false

BUDGET

SIGNALS USED:
  - per_head_inr vs band:
      ok    → 0–33rd percentile (cuisine, city, event_kind)
      good  → 33rd–66th
      great → 66th+
  - fare.is_upfront_fare=true                            weight 0.20
  - fare.logistics_fee_inr (lower=better)                weight 0.15
  - deposit.amount_inr (lower=better)                    weight 0.15
  - cleanup_fee included in service_includes             weight 0.20

HARD FILTERS:
  - fare.total_inr > preferences.budget_max_inr_total → drop

SAFETY

SIGNALS USED:
  - chef.fssai_food_handler_kyc                          HARD FILTER
  - chef.background_check_passed                         HARD FILTER
  - chef.aadhaar_verified                                HARD FILTER
  - chef.pan_verified                                    HARD FILTER
  - chef_kyc_required AND any KYC field=false → drop      HARD FILTER
  - chef.hygiene_score                                   weight 0.30
  - chef.events_completed_total (≥10)                    weight 0.20
  - trust.fssai_grade_aggregate (A=high)                 weight 0.20
  - trust.user_kitchen_damage_coverage                   weight 0.10
  - trust.food_poisoning_coverage                        weight 0.15
  - trust.insurance_coverage_inr (≥100K)                 weight 0.15
  - chef_gender_preference=female AND chef.gender=male → drop
  - is_late_night → safety scales 1.3x

Hidden ranking factor

information_completeness_score weight 0.10.


7. COMPLETION CONTRACT

POST /api/v1/cpc/mcp_provider/{tomo_partner_id}
{
  "intent":            "food.book_chef_at_home",
  "intent_version":    "v1.0.0",
  "external_id":       "FATC-XYZ",
  "amount_inr":         11500,
  "closed_at":         "2026-05-12T22:14:00+05:30",
  "request_id":        "req_chef_5h2k_...",
  "status":            "completed",
  "booking_ref":       "FATC-XYZ",
  "chef_arrived_at":   "2026-05-12T18:08:00+05:30",
  "event_started_at":  "2026-05-12T18:30:00+05:30",
  "event_completed_at": "2026-05-12T22:00:00+05:30",
  "guests_served":      6,
  "courses_completed":  4,
  "kitchen_cleaned_score": 92,
  "leftovers_packed":   true,
  "any_food_safety_incident": false,
  "any_kitchen_damage": false,
  "currency":          "INR",
  "fare_breakdown_total_inr": 11500,
  "rider_tip_inr":       1000,
  "ratings_pending":     true,
  "notes":              ""
}

Status enum: completed | cancelled_by_user | cancelled_by_chef | failed | partial_completion_event_cut_short | terminated_with_incident


8. WIDGET

WIDGET TYPE:        chef_at_home_options
SOURCE:             src/widgets/types.ts
TYPE NAME:          ChefAtHomeOptionsPayload
RENDERED IN:        components/widgets/ChefAtHomeOptionsWidget.tsx

Default: 3 stacked rows showing chef name + photo, cuisine primary, menu name, fare per head + total, rating + experience-years badge. Tap row → chef detail (bio, certs, signature dishes, full menu, reviews) → "Book chef". Then ChefArrivalCard with live tracking + setup progress.


9. CACHING POLICY

Call TTL Rationale
get_chef_at_home_estimates 60s chef availability shifts
get_chef_detail 5min chef profile static-ish
compute_menu_quote 5min quote_valid_until_iso enforced
book_chef_at_home 0s
track_chef_arrival 0s always live
Failure responses 0s

10. ERROR CODES

Code HTTP Meaning TOMO behavior
NO_CHEFS_AVAILABLE 503 no chef matches retry or fall back
OUT_OF_SERVICE_AREA 400 address outside coverage surface
OPTION_EXPIRED 410 option_token invalid re-quote
KITCHEN_REQUIREMENTS_INSUFFICIENT 400 user kitchen missing required equipment surface
MENU_NOT_FEASIBLE 400 menu impossible with declared ingredients_logistics surface
BOOKING_NOT_FOUND 404 booking_ref doesn't exist surface
ALREADY_CANCELLED 409 duplicate cancel idempotent
CHEF_NO_SHOW_GRACE_EXCEEDED 503 chef late beyond grace dispatch replacement
CHEF_REPLACEMENT_REJECTED 400 user rejects replacement surface refund flow
INGREDIENT_LOGISTICS_FAILED 503 chef-brings ingredients couldn't be sourced surface alternate

11. SANDBOX → PRODUCTION CHECKLIST

[ ] All §2 inputs validated, request_id echoed
[ ] get_chef_at_home_estimates returns ≥3 chef options for "Italian dinner Saturday 6 guests"
[ ] All §4 fields populated with REAL data
[ ] chef.fssai_food_handler_kyc backed by FSSAI ID + valid_until
[ ] chef.background_check_passed backed by KYC vendor records
[ ] chef.certifications backed by verifiable cert IDs
[ ] photo_ai_generated == false everywhere
[ ] book_chef_at_home returns booking_ref + chef assigned within SLA
[ ] track_chef_arrival returns location ≤30s old
[ ] cancel respects free_cancel_until_iso
[ ] confirm_event_complete fires within 60s of event end
[ ] CPC webhook arrives within 60s
[ ] HMAC verification passes
[ ] No forbidden fields anywhere
[ ] No paid placement / sponsored signals
[ ] customer_support_24x7 verified by TOMO field call
[ ] Insurance certificate uploaded
[ ] User kitchen damage coverage tested with claim simulation
[ ] Food poisoning coverage tested with claim simulation
[ ] CCTV opt-in flow tested when user requests

12. ANTI-FABRICATION RULES

RULE 1 — No paid placement signals.

RULE 2 — Ratings unrounded floats from verified events only.

RULE 3 — No fake events_completed_total inflation.

RULE 4 — No AI-generated chef photos. Must be actual chef.

RULE 5 — Certifications real and verifiable.
  Listing certifications without certificate IDs = breach.

RULE 6 — FSSAI food handler KYC current.
  fssai_food_handler_valid_until > scheduled_start_iso. Booking with
  expired KYC = severe compliance breach.

RULE 7 — Background check current within 90 days.

RULE 8 — Insurance coverage real.
  insurance_coverage_inr backed by actual policy. Stating coverage that
  doesn't pay out on claim = severe breach + criminal exposure.

RULE 9 — Kitchen damage coverage honest.
  user_kitchen_damage_coverage=true means actual claim flow exists. Refusing
  to honor a legitimate damage claim = breach.

RULE 10 — Food poisoning coverage honest.
  food_poisoning_coverage=true triggers partner liability + medical-cost
  reimbursement protocol. Suppressing reported food poisoning = severe breach.

RULE 11 — No commission-based response shaping.

RULE 12 — Chef replacement only with user consent.
  If chef cancels, replacement requires user accept. Silent swap = breach.

RULE 13 — Ingredients honest.
  ingredients_responsibility=chef_brings means chef arrives WITH the
  ingredients listed in the menu. Asking user to "go grab onions" mid-event
  = breach.

RULE 14 — Cleanup as advertised.
  service_includes contains "cleanup_kitchen" → kitchen returned to better-
  than-found state. Half-done cleanup = breach + automatic refund tier.

RULE 15 — No commission-based menu shaping.
  Menu options ranked by user fit, not by partner commission rate.

VERSION HISTORY

v1.0.0 — 2026-05-10 — Initial spec