mobility.book_chauffeur_hourly — Full Intent Specification
INTENT NAMESPACE: mobility
INTENT NAME: book_chauffeur_hourly
FULL ID: mobility.book_chauffeur_hourly
VERSION: v1.0.0
STATUS: draft
LAST UPDATED: 2026-05-10
TTBS WEIGHTS: time 0.30 · taste 0.20 · budget 0.20 · safety 0.30
Chauffeur-hourly is a single-city block-time booking — driver + vehicle dedicated to user for N hours with multiple stops, free wait between stops, and a flexible loose itinerary. It differs from intracity (one-trip), intercity (cross-city), and outstation (multi-day). Locked structural shape: (a) block_kind enum (4h_40km / 8h_80km / 12h_120km / etc.); (b) per-hour and per-km overage rates; (c) free wait between stops; (d) live itinerary edits supported mid-block; (e) user can extend block from inside chat without re-quote.
1. NATURAL LANGUAGE COVERAGE
Classifies IN
- "chauffeur for full day in Bangalore"
- "book a driver for 4 hours"
- "rent cab with driver for 8 hours today"
- "personal chauffeur for the morning"
- "8-hour cab booking for client visits"
- "chauffeur driven sedan from 10am to 6pm"
- "hire cab + driver for shopping day"
- "8/80 chauffeur package today"
- "executive car with driver for the afternoon"
Classifies OUT — borderline NO
- "ride to office" →
mobility.book_intracity_ride - "Hyderabad to Bangalore cab" →
mobility.book_intercity_ride - "Goa 4N5D package" →
mobility.book_outstation_package - "self-drive car for the day" →
mobility.book_self_drive - "airport transfer with meet and greet" →
mobility.book_airport_transfer
MULTI-INTENT TRIGGERS
- "chauffeur for 8 hours and book lunch reservation in Indiranagar" →
mobility.book_chauffeur_hourly+food.book_dine_in - "chauffeur today and book a salon" →
mobility.book_chauffeur_hourly+lifestyle.book_salon - "chauffeur for 4 hours, three meetings around city" →
mobility.book_chauffeur_hourly(single intent)
2. INPUT — TOMO → PROVIDER
{
"intent": "mobility.book_chauffeur_hourly",
"intent_version": "v1.0.0",
"request_id": "req_chf_5j8t_2026-05-10T08:00:00Z",
"user_session_id": "anon_user_token_or_uid",
"block_kind": "8h_80km",
"city": {
"lat": 12.9716,
"lng": 77.5946,
"address": "Bangalore",
"city": "Bangalore",
"state_code": "KA",
"country_code": "IN"
},
"pickup_location": {
"lat": 12.9352,
"lng": 77.6245,
"address": "Hilton Embassy Golf Links",
"neighborhood": "Domlur",
"city": "Bangalore",
"pincode": "560071",
"state_code": "KA",
"country_code": "IN",
"place_kind": "hotel",
"instructions": "Lobby entrance"
},
"stops_planned": [
{
"lat": 12.9698,
"lng": 77.7500,
"address": "Manyata Tech Park, Hebbal",
"stop_kind": "office",
"expected_minutes": 90
},
{
"lat": 12.9783,
"lng": 77.6408,
"address": "UB City Mall, Bangalore",
"stop_kind": "lunch",
"expected_minutes": 75
},
{
"lat": 12.9117,
"lng": 77.6473,
"address": "Forum Mall, Koramangala",
"stop_kind": "shopping",
"expected_minutes": 60
}
],
"scheduled_start_iso": "2026-05-10T10:00:00+05:30",
"scheduled_end_iso": "2026-05-10T18:00:00+05:30",
"billed_hours": 8,
"billed_km_included": 80,
"party": {
"passenger_count": 2,
"luggage_pieces": 1,
"luggage_size": "handbag",
"minor_count": 0,
"senior_count": 0
},
"preferences": {
"vehicle_kinds_acceptable": ["sedan", "premium_sedan", "suv"],
"budget_band": "great",
"budget_max_inr": 5500,
"ac_required": true,
"female_driver_required": false,
"ev_only": false,
"wheelchair_accessible_required": false,
"child_seat_required": false,
"max_seat_capacity_min": 4,
"driver_must_speak_locales": ["en-IN", "hi-IN", "kn-IN"],
"professional_attire_required": true,
"include_bottled_water": true
},
"city_context": {
"is_business_district": true,
"expected_total_distance_km": 65,
"involves_metro_zones": true,
"is_event_day": false,
"weather_celsius": 26,
"rain_probability_pct": 15,
"current_aqi": 78
},
"context": {
"user_locale": "en-IN",
"user_currency_pref": "INR",
"trip_purpose": "business_meetings",
"trust_signals": {
"is_repeat_customer": true,
"prior_chauffeur_with_partner": 3,
"user_account_age_days": 312,
"fastag_present": false,
"fastag_balance_inr": 0
}
}
}
| Field | Type | Constraint | Notes |
|---|---|---|---|
intent |
string | REQUIRED, equals "mobility.book_chauffeur_hourly" |
|
block_kind |
enum | REQUIRED, see §5 | drives base fare structure |
city.state_code |
string | REQUIRED | |
pickup_location.place_kind |
enum | REQUIRED | |
stops_planned |
array | REQUIRED, may be empty | tentative; can be modified live |
stops_planned[].stop_kind |
enum | REQUIRED, see §5 | |
stops_planned[].expected_minutes |
int | REQUIRED, ≥0 | |
scheduled_start_iso |
ISO_DATETIME | REQUIRED | |
scheduled_end_iso |
ISO_DATETIME | REQUIRED | must be > start; matches block_kind hours |
billed_hours |
int | REQUIRED, ≥1 | |
billed_km_included |
int | REQUIRED, ≥0 | matches block_kind km |
preferences.driver_must_speak_locales |
array |
REQUIRED, ≥1 | |
preferences.professional_attire_required |
bool | REQUIRED | drives uniform/grooming filter |
preferences.include_bottled_water |
bool | REQUIRED | |
city_context.is_business_district |
bool | REQUIRED | |
city_context.is_event_day |
bool | REQUIRED | event days reshuffle availability |
Anti-fabrication preamble (universal): no paid placement, no urgency text, no commission-influenced fields.
3. PROVIDER TOOLS
Tool 1: get_chauffeur_estimates
PURPOSE: return chauffeur block options across vehicle kinds
INPUT: §2 request body
OUTPUT: { options: ChauffeurOption[], result_token, expires_at }
SLA: p50 < 500ms, p95 < 1200ms
RATE LIMIT: ≤ 1/sec per user
Tool 2: book_chauffeur_block
PURPOSE: commit a chauffeur block
INPUT: { option_id, payment_token, request_id, idempotency_key, user_phone, otp_required }
OUTPUT: { booking_ref, status, driver, vehicle, fare_quote, block_handover_iso }
SLA: p95 < 4000ms
IDEMPOTENCY: REQUIRED on idempotency_key
Tool 3: track_chauffeur_block
PURPOSE: live state with stops progress + free-wait counter
INPUT: { booking_ref, request_id }
OUTPUT: ChauffeurBlockTrack (§4)
SLA: p95 < 400ms
RATE LIMIT: ≤ 1 every 10s
Tool 4: cancel_chauffeur_block
PURPOSE: cancel
INPUT: { booking_ref, reason, request_id }
OUTPUT: { status, cancellation_charge_inr, refund_amount_inr }
SLA: p95 < 2000ms
Tool 5: add_or_modify_stop
PURPOSE: add a stop or modify an existing stop mid-block
INPUT: { booking_ref, stop_index_or_new, stop_lat, stop_lng, stop_address, stop_kind, expected_minutes, request_id }
OUTPUT: { revised_total_distance_km, revised_estimated_fare_inr, status }
SLA: p95 < 1500ms
Tool 6: extend_block
PURPOSE: extend block while in progress
INPUT: { booking_ref, additional_hours, request_id }
OUTPUT: { revised_billed_hours, revised_fare_inr, additional_km_included, status }
SLA: p95 < 1500ms
Tool 7: rate_chauffeur_block
PURPOSE: post-block rating
INPUT: { booking_ref, rating_5star, comment, tip_inr, request_id }
OUTPUT: { acknowledged: true }
SLA: p95 < 800ms
Tool 8: share_block_status
PURPOSE: tokenized share URL
INPUT: { booking_ref, recipient_phone_optional, request_id }
OUTPUT: { share_url, expires_at }
SLA: p95 < 500ms
All eight REQUIRED.
4. RESPONSE SHAPE
ChauffeurOption (returned by get_chauffeur_estimates)
id: string, REQUIRED
option_token: string, REQUIRED
expires_at: ISO_DATETIME, REQUIRED
block_kind: STRICT ENUM, REQUIRED
vehicle_kind: STRICT ENUM, REQUIRED
vehicle_class: STRICT ENUM, REQUIRED
display_label: string, REQUIRED
seat_capacity: int, REQUIRED, ≥1
luggage_capacity: STRICT ENUM, REQUIRED
availability:
pickup_eta_minutes: int, REQUIRED # against scheduled_start
drivers_within_radius_count: int, REQUIRED, ≥0
alternate_block_kinds_offered: array<STRICT ENUM>, REQUIRED, may be empty
fare:
total_inr: INR_INTEGER, REQUIRED
base_block_inr: INR_INTEGER, REQUIRED # for the included hours/km
per_hour_overage_inr: INR_INTEGER, REQUIRED
per_km_overage_inr: float, REQUIRED
included_hours: int, REQUIRED
included_km: int, REQUIRED
free_wait_minutes_per_stop: int, REQUIRED # standard 30 min
per_minute_wait_overage_inr: INR_INTEGER, REQUIRED
driver_allowance_inr: INR_INTEGER, REQUIRED # 0 typically for hourly within city
ac_charge_inr: INR_INTEGER, REQUIRED
late_night_charge_inr: INR_INTEGER, REQUIRED
parking_charge_inr: INR_INTEGER, REQUIRED # passed-through actuals
toll_inr: INR_INTEGER, REQUIRED # passed-through actuals
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
vehicle_amenities:
ac: boolean, REQUIRED
music_on_demand: boolean, REQUIRED
charging_port: boolean, REQUIRED
wifi_in_cab: boolean, REQUIRED
bottled_water: boolean, REQUIRED
newspaper: boolean, REQUIRED
pet_friendly: boolean, REQUIRED
child_seat_available: boolean, REQUIRED
child_seat_kind: STRICT ENUM, REQUIRED
wheelchair_accessible: boolean, REQUIRED
privacy_partition: boolean, REQUIRED # premium/luxury feature
reading_light: boolean, REQUIRED
oxygen_supply_for_emergency: boolean, REQUIRED
vehicle_meta:
age_years: int, REQUIRED
fuel_kind: STRICT ENUM, REQUIRED
ev_battery_charge_pct: int, REQUIRED, 0-100
emission_norm: STRICT ENUM, REQUIRED
registration_state_code: string, REQUIRED
vehicle_class_certification: STRICT ENUM, REQUIRED
comprehensive_insurance: boolean, REQUIRED
insurance_valid_until_iso: ISO_DATE, REQUIRED
fitness_certificate_valid_until_iso: ISO_DATE, REQUIRED
puc_valid_until_iso: ISO_DATE, REQUIRED
permit_kind: STRICT ENUM, REQUIRED # contract_carriage | aggregator | tourist
commercial_aggregator_permit_number: string, REQUIRED
vehicle_color: string, REQUIRED
driver_meta:
driver_id: string, REQUIRED
display_name: string, REQUIRED
photo_url: URL, REQUIRED
rating_avg: float, REQUIRED, 0-5
rides_completed_total: int, REQUIRED, ≥0
chauffeur_blocks_completed: int, REQUIRED, ≥0
partner_account_age_days: int, REQUIRED, ≥0
languages_spoken: array<RFC_3066_LOCALE>, REQUIRED, ≥1
female_driver: boolean, REQUIRED
age_band: STRICT ENUM, REQUIRED
experience_years_driving: int, REQUIRED, ≥0
professional_attire_compliant: boolean, REQUIRED
business_etiquette_certified: boolean, REQUIRED # partner-internal certification
hospitality_training_certified: boolean, REQUIRED # for premium tier
driver_kyc:
dl_verified: boolean, REQUIRED
dl_number_masked: string, REQUIRED
dl_valid_until_iso: ISO_DATE, REQUIRED
rc_verified: boolean, REQUIRED
aadhaar_verified: boolean, REQUIRED
pan_verified: boolean, REQUIRED
background_check_passed: boolean, REQUIRED
background_check_iso: ISO_DATETIME, REQUIRED
badge_id_displayed: boolean, REQUIRED
safety_features:
sos_button_in_app: boolean, REQUIRED
trip_share_supported: boolean, REQUIRED
in_app_chat_supported: boolean, REQUIRED
in_app_call_supported: boolean, REQUIRED
emergency_contact_alerts: boolean, REQUIRED
cctv_in_cab: boolean, REQUIRED
panic_alert_to_local_police: boolean, REQUIRED
driver_drowsiness_detection: boolean, REQUIRED
speed_limit_governing: boolean, REQUIRED
privacy_compliance_signed: boolean, REQUIRED # NDA-grade for executives
cancellation:
free_cancel_within_minutes: int, REQUIRED # before block_starts
cancel_charge_after_grace_inr: INR_INTEGER, REQUIRED
cancel_charge_within_2h_inr: INR_INTEGER, REQUIRED
no_show_charge_inr: INR_INTEGER, REQUIRED
driver_cancel_compensation_inr: INR_INTEGER, REQUIRED
early_release_refund_policy: STRICT ENUM, REQUIRED # see §5
freshness:
data_last_synced_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_24x7: boolean, REQUIRED
in_app_chat_supported: boolean, REQUIRED
partner_chauffeur_volume_30d: int, REQUIRED, ≥0
ChauffeurBlockTrack (returned by track_chauffeur_block)
booking_ref: string, REQUIRED
status: STRICT ENUM, REQUIRED
status_updated_iso: ISO_DATETIME, REQUIRED
status_history: array, REQUIRED, ≥1
block_progress:
started_iso: ISO_DATETIME, REQUIRED
scheduled_end_iso: ISO_DATETIME, REQUIRED
hours_consumed: float, REQUIRED, ≥0
hours_remaining: float, REQUIRED, ≥0
km_consumed: float, REQUIRED, ≥0
km_remaining: float, REQUIRED # may be negative if overage
overage_charge_inr_so_far: INR_INTEGER, REQUIRED, ≥0
current_stop_index: int, REQUIRED, ≥-1 # -1 = between stops
free_wait_remaining_at_stop_minutes: int, REQUIRED, ≥0
driver:
driver_id: string, REQUIRED
display_name: string, REQUIRED
phone_masked: string, REQUIRED
photo_url: URL, REQUIRED
rating_avg: float, REQUIRED, 0-5
in_app_chat_supported: boolean, REQUIRED
in_app_call_supported: boolean, REQUIRED
vehicle:
vehicle_kind: STRICT ENUM, REQUIRED
display_label: string, REQUIRED
color: string, REQUIRED
plate_masked: string, REQUIRED
location:
current_lat: float, REQUIRED
current_lng: float, REQUIRED
heading_degrees: float, REQUIRED, 0-360
speed_kmh: float, REQUIRED, ≥0
location_updated_iso: ISO_DATETIME, REQUIRED
status: STRICT ENUM, REQUIRED
eta:
to_next_stop_minutes: int, REQUIRED # 0 if at stop
to_block_end_minutes: int, REQUIRED
revised_total_fare_inr: INR_INTEGER, REQUIRED
ride_safety:
on_route: boolean, REQUIRED
unusual_stop_detected: boolean, REQUIRED
trip_share_active: boolean, REQUIRED
trip_share_url: URL, REQUIRED
support_phone: string, REQUIRED
support_email: string, REQUIRED
Forbidden fields
paid_placement_score | sponsored_rank | promotion_priority |
artificial_demand_text | fake_recent_booking_text |
auto_inflate_chauffeur_blocks_completed | partner_paid_for_top_listing |
fake_business_etiquette_certified | hidden_overage_inr
5. CONTROLLED VOCABULARIES
block_kind
4h_40km | 6h_60km | 8h_80km | 10h_100km | 12h_120km | full_day_24h_300km
vehicle_kind
sedan | premium_sedan | luxury_sedan | suv | premium_suv | luxury_suv |
xl_van | wheelchair_accessible_van | ev_sedan | ev_premium_sedan
vehicle_class
economy | comfort | premium | luxury | xl
ChauffeurOption.luggage_capacity
small | medium | large | xl
pickup_location.place_kind
home | office | hotel | airport | restaurant | mall | hospital | event_venue | landmark | other
stops_planned[].stop_kind
office | meeting | client_visit | hotel | restaurant | lunch | dinner |
shopping | mall | spa | salon | event | medical | bank | religious_place |
sightseeing | other
vehicle_meta.fuel_kind
petrol | diesel | cng | lpg | ev_full | hybrid | bs6_petrol | bs6_diesel
vehicle_meta.emission_norm
bs3 | bs4 | bs6 | ev | unknown_legacy
vehicle_meta.permit_kind
contract_carriage | aggregator_permit | tourist
vehicle_meta.vehicle_class_certification
commercial_yellow_plate | aggregator_white_with_yellow_strip | tourist | luxury_charter
vehicle_amenities.child_seat_kind
none | infant | toddler | booster | universal
driver_meta.age_band
21-30 | 31-40 | 41-55 | 56+
cancellation.early_release_refund_policy
no_refund_after_block_start | pro_rata_unused_hours |
flat_50pct_unused_hours | flat_70pct_unused_hours
ChauffeurBlockTrack.status
scheduled | driver_assigned | driver_arriving | arrived_at_pickup |
otp_required | block_started | en_route_to_stop | at_stop_with_user |
at_stop_waiting | en_route_to_next | nearby_block_end |
block_completed | extended | cancelled_by_user | cancelled_by_driver |
early_release | failed
ChauffeurBlockTrack.location.status
heading_to_pickup | at_pickup | at_stop_with_user | at_stop_waiting |
trip_in_progress | nearby_block_end
cancel_chauffeur_block.reason
user_changed_mind | wrong_vehicle | wrong_address | driver_too_far |
driver_unresponsive | safety_concern | weather_block |
no_longer_needed | found_alternative | emergency
context.trip_purpose
business_meetings | corporate_events | sales_visits | client_pitches |
shopping_day | wedding_event | family_outing | sightseeing |
medical_visit | religious_pilgrimage | leisure | other
6. TTBS DIMENSIONS
Per-domain weights (locked; chauffeur override)
mobility (chauffeur_hourly): { time: 0.30, taste: 0.20, budget: 0.20, safety: 0.30 }
TIME
SIGNALS USED:
- availability.pickup_eta_minutes ≤ 10 HARD FILTER (corporate use, must be on time)
- availability.alternate_block_kinds_offered weight 0.10
- cancellation.refund_processing_days weight 0.10
- driver_meta.business_etiquette_certified (on-time discipline) weight 0.20
- free_wait_minutes_per_stop (≥30 min) weight 0.20
USER BAND HANDLING:
- "starts in 1 hour" → tighten pickup_eta filter
- "schedule next week" → relax
TASTE
SIGNALS USED:
- vehicle.year_of_manufacture (newer = better) weight 0.15
- vehicle_amenities match w/ user prefs weight 0.25
- vehicle_amenities.privacy_partition (executive) weight 0.10
- vehicle_amenities.bottled_water + newspaper weight 0.10
- driver_meta.professional_attire_compliant weight 0.15
- driver_meta.hospitality_training_certified weight 0.15
- languages_spoken match user_locale + business locales weight 0.10
HARD FILTERS:
- ac_required + ac=false → drop
- professional_attire_required + driver compliance=false → drop
BUDGET
SIGNALS USED:
- fare.total_inr vs band:
ok → sedan / hatchback (rare in chauffeur)
good → sedan / suv
great → premium_sedan / luxury_sedan / luxury_suv
- fare.is_upfront_fare=true weight 0.20
- fare.included_hours covers requested block weight 0.15
- fare.included_km vs city_context.expected_total_distance_km weight 0.20
- fare.per_hour_overage_inr (lower=better) weight 0.15
- fare.free_wait_minutes_per_stop (higher=better) weight 0.15
HARD FILTERS:
- fare.total_inr > preferences.budget_max_inr → drop
USER BAND HANDLING:
- business_meetings purpose deweights ok options
SAFETY
SIGNALS USED:
- driver_kyc.background_check_passed HARD FILTER
- driver_kyc.dl_verified HARD FILTER
- vehicle_meta.comprehensive_insurance HARD FILTER
- vehicle_meta.permit_kind in (contract_carriage|aggregator|tourist) HARD FILTER
- safety_features.sos_button_in_app weight 0.10
- safety_features.cctv_in_cab weight 0.10
- safety_features.privacy_compliance_signed (executive) weight 0.20
- driver_meta.business_etiquette_certified weight 0.15
- driver_meta.female_driver
(boosted if female_driver_required) weight 0.20
- driver_meta.chauffeur_blocks_completed (≥30) weight 0.15
- vehicle_meta.fitness_certificate_valid_until_iso > scheduled_end HARD FILTER
- is_late_night_block → safety scales 1.3x
HARD FILTERS:
- female_driver_required → drop male drivers
- wheelchair_accessible_required → drop non-wheelchair
Hidden ranking factor
information_completeness_score weight 0.10.
7. COMPLETION CONTRACT
POST /api/v1/cpc/mcp_provider/{tomo_partner_id}
X-TOMO-Timestamp: <ms>
X-TOMO-Signature: sha256=<hex>
{
"intent": "mobility.book_chauffeur_hourly",
"intent_version": "v1.0.0",
"external_id": "OLA-CHF-XYZ",
"amount_inr": 5200,
"closed_at": "2026-05-10T18:14:00+05:30",
"request_id": "req_chf_5j8t_...",
"status": "completed",
"booking_ref": "OLA-CHF-XYZ",
"block_started_at": "2026-05-10T10:08:00+05:30",
"block_ended_at": "2026-05-10T18:00:00+05:30",
"billed_hours": 8,
"actual_hours": 7.87,
"billed_km_actual": 78,
"stops_visited": 3,
"wait_overage_minutes": 12,
"wait_overage_charge_inr": 60,
"currency": "INR",
"fare_breakdown_total_inr": 5200,
"rider_tip_inr": 0,
"ratings_pending": true,
"notes": ""
}
Status enum: completed | cancelled_by_user | cancelled_by_driver | failed | early_release | extended_and_completed
8. WIDGET
WIDGET TYPE: chauffeur_block_options
SOURCE: src/widgets/types.ts
TYPE NAME: ChauffeurBlockOptionsPayload
RENDERED IN: components/widgets/ChauffeurBlockOptionsWidget.tsx
Default: 3 stacked rows showing block_kind label, vehicle_kind, fare with per-hour-overage + free-wait callouts, key amenities, business-etiquette badge. Tap row → confirmation card with full block breakdown including overage rates → "Book". Then ChauffeurTrackingCard with stops progress + free-wait countdown + extend block button.
9. CACHING POLICY
| Call | TTL | Rationale |
|---|---|---|
get_chauffeur_estimates |
60s | demand moves slower than ride-hail |
track_chauffeur_block |
0s | always live |
book_chauffeur_block |
0s | |
cancel_chauffeur_block |
0s | |
add_or_modify_stop |
0s | |
extend_block |
0s | |
| Failure responses | 0s |
10. ERROR CODES
| Code | HTTP | Meaning | TOMO behavior |
|---|---|---|---|
NO_DRIVERS_AVAILABLE |
503 | none with required block_kind | retry or fall back |
OUT_OF_SERVICE_AREA |
400 | city not covered | surface |
OPTION_EXPIRED |
410 | option_token invalid | re-quote |
BLOCK_NOT_FOUND |
404 | booking_ref doesn't exist | surface |
ALREADY_CANCELLED |
409 | duplicate cancel | idempotent return |
EXTENSION_BLOCKED |
409 | driver unavailable beyond block_end | surface alternate |
STOP_OUT_OF_RANGE |
400 | new stop > 25km from current location | reject or re-quote |
WAIT_OVERAGE_LIMIT |
400 | extended free-wait beyond 60 min | surface charge |
PAYMENT_DECLINED |
402 | gateway rejection | surface |
OTP_FAILED |
401 | OTP-at-pickup mismatch | surface |
WEATHER_BLOCK |
503 | weather closure | suggest reschedule |
11. SANDBOX → PRODUCTION CHECKLIST
[ ] All §2 inputs validated, request_id echoed
[ ] get_chauffeur_estimates returns ≥3 options for all block_kinds
[ ] All §4 required fields populated with REAL data
[ ] driver_kyc + vehicle_meta truthful + verifiable
[ ] business_etiquette_certified backed by partner training records
[ ] hospitality_training_certified backed by training records
[ ] book_chauffeur_block returns booking_ref + driver assignment within SLA
[ ] track_chauffeur_block returns location ≤10s old + stops progress accurate
[ ] add_or_modify_stop handles ≥3 stops with correct fare recalc
[ ] extend_block honors driver availability check
[ ] cancel respects free_cancel_within_minutes
[ ] CPC webhook arrives within 60s of block completion
[ ] HMAC verification passes
[ ] No forbidden fields anywhere
[ ] SOS button tested with TOMO ops monitoring
[ ] Trip share URL works for ≥4h post-completion
[ ] No paid placement / sponsored signals
[ ] customer_support_24x7 verified by TOMO field call
[ ] Aggregator permit certificate uploaded
[ ] Privacy compliance NDA verifiable for executive tier
12. ANTI-FABRICATION RULES
RULE 1 — No paid placement signals.
RULE 2 — No fake driver ratings.
RULE 3 — No fake chauffeur_blocks_completed inflation.
TOMO compares stated count against partner's CPC ledger; mismatch >5% = breach.
RULE 4 — No fake business_etiquette_certified.
Claim must be backed by partner training program docs verifiable by TOMO ops.
RULE 5 — Vehicle plate must match dispatched vehicle.
RULE 6 — Fare displayed must be honored.
is_upfront_fare=true means fare_locked_until_iso. Per-hour overage and
per-km overage are the ONLY legitimate post-block increases (and must be
audit-trail-linked to actual hours_consumed and km_consumed in track payload).
RULE 7 — Free wait minutes honored.
free_wait_minutes_per_stop cannot be reduced retroactively. Charging within
the stated free window = breach.
RULE 8 — Driver KYC + permit claims must be verifiable.
RULE 9 — Cancel charges must match displayed thresholds.
RULE 10 — No commission-based response shaping.
RULE 11 — Professional attire must be evident.
professional_attire_compliant=true requires uniformed driver. TOMO ops
field-tests with photo evidence at random.
RULE 12 — Privacy compliance is real.
privacy_compliance_signed=true requires NDA-grade contract with driver +
partner. Sharing executive trip details with marketing or third parties =
severe breach.
RULE 13 — Stop additions cannot extend block silently.
add_or_modify_stop that pushes block past scheduled_end_iso must explicitly
trigger an extend_block call with user consent.
VERSION HISTORY
v1.0.0 — 2026-05-10 — Initial spec