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