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.
● LIVEv1.0.0mobility.book_intracity_ride

mobility.book_intracity_ride — Full Intent Specification

INTENT NAMESPACE: mobility
INTENT NAME:      book_intracity_ride
FULL ID:          mobility.book_intracity_ride
VERSION:          v1.0.0
STATUS:           live
LAST UPDATED:     2026-05-09
TTBS WEIGHTS:     time 0.40 · taste 0.10 · budget 0.30 · safety 0.20

1. NATURAL LANGUAGE COVERAGE

Classifies IN

  • "ride to airport"
  • "cab to HITEC City"
  • "auto to MG Road"
  • "book me a Rapido to Banjara Hills"
  • "I need a cab right now to Apollo Hospital"
  • "Uber to home"
  • "ola to office"
  • "bike taxi to RGI airport"
  • "EV cab to Gachibowli"

Classifies OUT — borderline NO

  • "self-drive car for the weekend" → mobility.book_self_drive
  • "Goa to Mumbai cab" → mobility.book_intercity_ride
  • "rental scooter for the day" → mobility.book_two_wheeler_rental
  • "outstation cab to Tirupati" → mobility.book_outstation_package
  • "I want to drive to office tomorrow" → no intent (informational; NOT a TOMO action)

MULTI-INTENT TRIGGERS

  • "ride to airport tomorrow morning, also order coffee" → mobility.book_intracity_ride + food.order_delivery
  • "book cab to airport, pickup at 4 AM" + flight context → may chain mobility.book_airport_transfer

2. INPUT — TOMO → PROVIDER

{
  "intent":          "mobility.book_intracity_ride",
  "intent_version":  "v1.0.0",
  "request_id":      "req_4r8t1k_2026-05-09T08:14:00Z",
  "user_session_id": "anon_user_token_or_uid",

  "pickup": {
    "lat":            17.4435,
    "lng":            78.3772,
    "address":        "HITEC City Main Road, Madhapur",
    "neighborhood":   "Madhapur",
    "city":           "Hyderabad",
    "pincode":        "500081",
    "country_code":   "IN",
    "place_kind":     "office",
    "instructions":   "Pickup gate B"
  },

  "drop": {
    "lat":            17.2403,
    "lng":            78.4294,
    "address":        "Rajiv Gandhi International Airport",
    "neighborhood":   "Shamshabad",
    "city":           "Hyderabad",
    "pincode":        "500409",
    "country_code":   "IN",
    "place_kind":     "airport",
    "instructions":   "Terminal 1 departures"
  },

  "intent_kind":         "asap",
  "scheduled_for_iso":   "2026-05-09T08:14:00+05:30",

  "party": {
    "passenger_count":  1,
    "luggage_pieces":   2,
    "luggage_size":     "checkin"
  },

  "preferences": {
    "vehicle_kinds_acceptable":   ["sedan", "suv", "hatchback", "ev_sedan"],
    "budget_band":                "good",
    "budget_max_inr":              700,
    "max_eta_minutes":             8,
    "ac_required":                 true,
    "female_driver_required":      false,
    "ev_only":                     false,
    "wheelchair_accessible_required": false,
    "child_seat_required":         false,
    "pet_friendly_required":       false,
    "no_pool":                     true,
    "carry_pet":                   false,
    "max_seat_capacity_min":       4
  },

  "route_context": {
    "estimated_distance_km":   28.5,
    "estimated_duration_min":  47,
    "involves_toll":           true,
    "toll_count":              1,
    "involves_highway":        true,
    "weather_celsius":         28,
    "rain_probability_pct":    20,
    "current_aqi":             142,
    "is_late_night":           false,
    "is_surge_window":          false
  },

  "context": {
    "user_locale":          "en-IN",
    "user_currency_pref":   "INR",
    "trip_purpose":         "airport_dropoff",
    "trust_signals": {
      "is_repeat_customer":          true,
      "prior_rides_with_partner":    37,
      "user_account_age_days":       312,
      "fastag_present":              true,
      "fastag_balance_inr":          245
    }
  }
}
Field Type Constraint Notes
intent string REQUIRED, equals "mobility.book_intracity_ride"
pickup.country_code ISO_3166_2 REQUIRED, always IN
pickup.place_kind enum REQUIRED, see §6
drop.place_kind enum REQUIRED, see §6
intent_kind enum REQUIRED, STRICT asap | scheduled
party.luggage_size enum REQUIRED, STRICT none | handbag | backpack | cabin | checkin | oversized
preferences.vehicle_kinds_acceptable array REQUIRED, ≥1 see §6
preferences.no_pool bool REQUIRED rejects shared rides if true
route_context.involves_toll bool REQUIRED
route_context.toll_count int REQUIRED, ≥0
route_context.current_aqi int REQUIRED, ≥0
route_context.is_late_night bool REQUIRED
route_context.is_surge_window bool REQUIRED
context.trip_purpose enum REQUIRED, see §6
context.trust_signals.fastag_present bool REQUIRED
context.trust_signals.fastag_balance_inr INR_INTEGER REQUIRED 0 if no FASTag

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


3. PROVIDER TOOLS

Tool 1: get_ride_estimates

PURPOSE:        return ride options with fares + ETAs across vehicle kinds
INPUT:          §2 request body
OUTPUT:         { options: RideOption[], result_token, expires_at }
SLA:            p50 < 400ms, p95 < 1000ms
RATE LIMIT:     ≤ 2/sec per user

Tool 2: book_ride

PURPOSE:        commit a ride
INPUT:          { ride_option_id, payment_token, request_id, idempotency_key, user_phone, otp_required }
OUTPUT:         { ride_ref, status, driver, vehicle, fare_quote, otp_for_driver }
SLA:            p95 < 4000ms
IDEMPOTENCY:    REQUIRED on idempotency_key

Tool 3: track_ride

PURPOSE:        live ride state + driver location
INPUT:          { ride_ref, request_id }
OUTPUT:         RideTrack (§5)
SLA:            p95 < 400ms
RATE LIMIT:     ≤ 1 every 5s

Tool 4: cancel_ride

PURPOSE:        cancel
INPUT:          { ride_ref, reason, request_id }
OUTPUT:         { status, cancellation_charge_inr, refund_amount_inr }
SLA:            p95 < 2000ms

Tool 5: update_ride_drop

PURPOSE:        change drop mid-ride (add stop or modify)
INPUT:          { ride_ref, new_drop, additional_stops[], request_id }
OUTPUT:         { revised_fare_inr, revised_eta_minutes, status }
SLA:            p95 < 1500ms

Tool 6: rate_ride

PURPOSE:        post-ride rating
INPUT:          { ride_ref, rating_5star, comment, tip_inr, request_id }
OUTPUT:         { acknowledged: true }
SLA:            p95 < 800ms

Tool 7: share_trip_status

PURPOSE:        return a tokenized URL the user can share for live trip tracking
INPUT:          { ride_ref, recipient_phone_optional, request_id }
OUTPUT:         { share_url, expires_at }
SLA:            p95 < 500ms

All seven REQUIRED.


4. RESPONSE SHAPE

RideOption (returned by get_ride_estimates)

id:                               string, REQUIRED
ride_option_token:                string, REQUIRED         # opaque, used in book_ride
expires_at:                       ISO_DATETIME, REQUIRED

vehicle_kind:                     STRICT ENUM, REQUIRED    # see §6
vehicle_class:                    STRICT ENUM, REQUIRED    # see §6
display_label:                    string, REQUIRED         # "Uber Premier", "Ola Sedan"
seat_capacity:                    int, REQUIRED, ≥1
luggage_capacity:                 STRICT ENUM, REQUIRED    # see §6

eta:
  pickup_minutes:                 int, REQUIRED
  trip_minutes:                   int, REQUIRED
  total_minutes:                  int, REQUIRED            # pickup + trip
  drivers_within_radius_count:    int, REQUIRED, ≥0
  closest_driver_km:              float, REQUIRED, ≥0

fare:
  total_inr:                      INR_INTEGER, REQUIRED
  base_inr:                       INR_INTEGER, REQUIRED
  per_km_inr:                     float, REQUIRED
  per_minute_inr:                 float, REQUIRED
  surge_multiplier:               float, REQUIRED, ≥1.0    # 1.0 if no surge
  surge_reason:                   STRICT ENUM, REQUIRED    # see §6 ("none" if no surge)
  toll_inr:                       INR_INTEGER, REQUIRED
  toll_count:                     int, REQUIRED, ≥0
  late_night_inr:                 INR_INTEGER, REQUIRED    # 0 if not late night
  airport_pickup_charge_inr:      INR_INTEGER, REQUIRED    # 0 unless airport
  airport_drop_charge_inr:        INR_INTEGER, REQUIRED    # 0 unless airport
  highway_charge_inr:             INR_INTEGER, REQUIRED    # 0 unless highway
  state_border_charge_inr:        INR_INTEGER, REQUIRED    # 0 if same-state
  parking_charge_inr:             INR_INTEGER, REQUIRED    # 0 if not relevant
  platform_fee_inr:               INR_INTEGER, REQUIRED
  gst_inr:                        INR_INTEGER, REQUIRED
  rider_tip_optional_inr:         INR_INTEGER, REQUIRED    # default 0; user-driven
  fare_breakdown_text:            string, REQUIRED          # human-readable
  is_upfront_fare:                boolean, REQUIRED          # true = locked
  fare_locked_until_iso:          ISO_DATETIME, REQUIRED

vehicle_amenities:
  ac:                             boolean, REQUIRED
  music_on_demand:                boolean, REQUIRED
  charging_port:                  boolean, REQUIRED          # USB-A or USB-C
  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      # see §6
  wheelchair_accessible:          boolean, REQUIRED
  oxygen_supply_for_emergency:    boolean, REQUIRED          # ambulance-grade only

vehicle_meta:
  age_years:                      int, REQUIRED
  fuel_kind:                      STRICT ENUM, REQUIRED      # see §6
  ev_battery_charge_pct:          int, REQUIRED, 0-100       # 0 if not EV
  emission_norm:                  STRICT ENUM, REQUIRED      # see §6
  registration_state_code:        string, REQUIRED            # "TS"
  vehicle_class_certification:    STRICT ENUM, REQUIRED      # commercial_yellow_plate | private | etc.
  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      # see §6
  commercial_aggregator_permit_number: string, REQUIRED
  vehicle_color:                  string, REQUIRED            # for visual ID

driver_meta:
  driver_id:                      string, REQUIRED
  display_name:                   string, REQUIRED            # first name
  photo_url:                      URL, REQUIRED
  rating_avg:                     float, REQUIRED, 0-5
  rides_completed_total:          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      # 18-25 | 26-35 | 36-50 | 51+
  experience_years_driving:       int, REQUIRED, ≥0

driver_kyc:
  dl_verified:                    boolean, REQUIRED
  dl_number_masked:               string, REQUIRED            # "TG**1234"
  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            # required by Motor Vehicle Act

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

route_quality:
  estimated_distance_km:          float, REQUIRED
  estimated_duration_min:         int, REQUIRED
  surge_zones_passed_through:     int, REQUIRED, ≥0
  highway_kms:                    float, REQUIRED
  inner_road_kms:                 float, REQUIRED
  toll_passes:                    array, REQUIRED, may be empty
    - toll_name:                  string, REQUIRED
      toll_amount_inr:            INR_INTEGER, REQUIRED
      fastag_supported:           boolean, REQUIRED
      cash_accepted:              boolean, REQUIRED

cancellation:
  free_cancel_within_minutes:     int, REQUIRED                # post-booking grace window
  cancel_charge_after_grace_inr:  INR_INTEGER, REQUIRED
  no_show_charge_inr:             INR_INTEGER, REQUIRED
  driver_cancel_compensation_inr: INR_INTEGER, REQUIRED        # if driver cancels late, what user gets

fastag_check:
  toll_count_on_route:            int, REQUIRED, ≥0
  fastag_required:                boolean, REQUIRED
  estimated_toll_total_inr:       INR_INTEGER, REQUIRED
  user_fastag_balance_sufficient: boolean, REQUIRED            # derived from §2 input

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

RideTrack (returned by track_ride)

ride_ref:                         string, REQUIRED
status:                           STRICT ENUM, REQUIRED        # see §6
status_updated_iso:               ISO_DATETIME, REQUIRED
status_history:                   array, REQUIRED, ≥1
  - status:                       STRICT ENUM, REQUIRED
    iso:                          ISO_DATETIME, REQUIRED

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               # "•• 1234"

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         # see §6

eta:
  to_pickup_minutes:              int, REQUIRED                  # 0 if past pickup
  to_drop_minutes:                int, REQUIRED
  revised_fare_inr:               INR_INTEGER, REQUIRED          # if route changed
  detour_minutes:                 int, REQUIRED                  # 0 if no detour

ride_safety:
  on_route:                       boolean, REQUIRED
  unusual_stop_detected:          boolean, REQUIRED
  unusual_speed_detected:         boolean, REQUIRED
  trip_share_active:              boolean, REQUIRED
  trip_share_url:                 URL, REQUIRED                  # always present, may be unused

fastag:
  next_toll_distance_km:          float, REQUIRED                # 9999 if no upcoming toll
  next_toll_amount_inr:           INR_INTEGER, REQUIRED          # 0 if none
  user_fastag_balance_sufficient_for_remaining_tolls: boolean, 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_driver_rating | partner_paid_for_top_listing

5. CONTROLLED VOCABULARIES

vehicle_kind (preferences + RideOption)

auto | bike_taxi | hatchback | sedan | suv | premium_sedan | premium_suv |
ev_hatchback | ev_sedan | ev_suv | electric_3wheeler |
shared_hatchback | shared_sedan | luxury_sedan | luxury_suv |
xl_van | wheelchair_accessible_van

vehicle_class

economy | comfort | premium | luxury | xl | xl_premium | shared

RideOption.luggage_capacity

small | medium | large | xl

pickup.place_kind and drop.place_kind

home | office | airport | railway | metro_station | bus_terminal |
hotel | restaurant | mall | hospital | clinic | school | college |
gym | salon | event_venue | religious_place | grocery | pharmacy |
park | landmark | other

party.luggage_size

none | handbag | backpack | cabin | checkin | oversized

preferences.vehicle_kinds_acceptable

Same enum as vehicle_kind above.

preferences.female_driver_required / ac_required / ev_only etc.

booleans (no enum)

RideOption.fare.surge_reason

none | rain | weekend_evening | morning_peak | late_night | major_event |
festival | airport_demand | city_event | rider_shortage

route_context.is_late_night

boolean. Definition: pickup_local_time between 22:30 and 05:30.

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 | stage_carriage | private | tourist | aggregator_permit

vehicle_meta.vehicle_class_certification

commercial_yellow_plate | aggregator_white_with_yellow_strip | private | tourist | tempo_traveller

vehicle_amenities.child_seat_kind

none | infant | toddler | booster | universal

driver_meta.age_band

18-25 | 26-35 | 36-50 | 51+

RideTrack.status

searching_driver | driver_assigned | driver_arriving | arrived |
otp_required | trip_started | en_route | nearby_drop |
completed | cancelled_by_user | cancelled_by_driver | failed

RideTrack.location.status

heading_to_pickup | at_pickup | trip_in_progress | nearby_drop | reached_drop

cancellation.reason (in cancel_ride input)

user_changed_mind | wrong_vehicle | wrong_address | driver_too_far |
driver_unresponsive | safety_concern | no_longer_needed | found_alternative |
emergency

context.trip_purpose

commute_to_work | commute_to_home | airport_dropoff | airport_pickup |
hospital_visit | shopping | dining_out | event | religious | leisure |
emergency | other

merchant_id resolution

N/A — driver+vehicle is the listing unit, no cross-partner dedup necessary at the ride level.


6. TTBS DIMENSIONS

Per-domain weights (locked)

mobility: { time: 0.40, taste: 0.10, budget: 0.30, safety: 0.20 }

TIME

SIGNALS USED:
  - eta.pickup_minutes                              weight 0.50
  - eta.drivers_within_radius_count                 weight 0.10
  - eta.closest_driver_km                           weight 0.10
  - route_quality.estimated_duration_min            weight 0.20
  - is_surge_window                                 penalty 0.10

USER BAND HANDLING:
  - "asap" → pickup_minutes weight up to 0.60
  - max_eta_minutes HARD FILTER → drop options exceeding

TASTE

SIGNALS USED:
  - driver_meta.rating_avg                          weight 0.40
  - vehicle_meta.age_years (newer = better)         weight 0.20
  - vehicle_amenities.ac (if ac_required)           HARD FILTER
  - vehicle_amenities match w/ user prefs           weight 0.30
  - languages_spoken match w/ user_locale           weight 0.10

BUDGET

SIGNALS USED:
  - fare.total_inr vs band:
      ok    → auto / hatchback / shared
      good  → sedan / hatchback / EV
      great → premium_sedan / premium_suv / luxury
  - surge_multiplier (lower = better)               weight 0.20
  - upfront_fare locked (yes = better)              weight 0.10

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

USER BAND HANDLING:
  - persistent "ok" users see budget_band defaults boosted
  - emergency trip_purpose deweights budget

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 (aggregator|contract|tourist) HARD FILTER
  - safety_features.sos_button_in_app               weight 0.15
  - safety_features.trip_share_supported            weight 0.15
  - safety_features.cctv_in_cab                     weight 0.10
  - safety_features.driver_drowsiness_detection     weight 0.10
  - vehicle_meta.fitness_certificate_valid_until_iso > now+30d weight 0.10
  - driver_meta.female_driver
      (boosted if female_driver_required)           weight 0.20
  - is_late_night → safety weight scales 1.5x

HARD FILTERS:
  - female_driver_required → drop male drivers
  - wheelchair_accessible_required → drop non-wheelchair
  - child_seat_required → drop without seat
  - ev_only → drop non-EV

Hidden ranking factor

information_completeness_score weight 0.10.

FASTag check

If route_context.involves_toll AND user_fastag_balance_sufficient = false, TOMO surfaces a top-up CTA before booking. Locked behavior; not a TTBS dimension.


7. COMPLETION CONTRACT

POST /api/v1/cpc/mcp_provider/{tomo_partner_id}
X-TOMO-Timestamp: <ms>
X-TOMO-Signature: sha256=<hex>

{
  "intent":            "mobility.book_intracity_ride",
  "intent_version":    "v1.0.0",
  "external_id":       "UBER-RIDE-XYZ",
  "amount_inr":         480,
  "closed_at":         "2026-05-09T09:02:00+05:30",
  "request_id":        "req_4r8t1k_...",
  "status":            "completed",
  "ride_ref":          "UBER-RIDE-XYZ",
  "started_at":        "2026-05-09T08:21:00+05:30",
  "completed_at":      "2026-05-09T09:02:00+05:30",
  "distance_traveled_km": 28.7,
  "duration_minutes":   41,
  "promised_eta_minutes": 47,
  "actual_eta_minutes":   41,
  "currency":          "INR",
  "fare_breakdown_total_inr": 480,
  "rider_tip_inr":       0,
  "ratings_pending":     true,
  "notes":              ""
}

Status enum: completed | cancelled_by_user | cancelled_by_driver | failed | rerouted_with_extra_charge


8. WIDGET

WIDGET TYPE:        ride_options
SOURCE:             src/widgets/types.ts
TYPE NAME:          RideOptionsPayload
RENDERED IN:        components/widgets/RideOptionsWidget.tsx

Default: 3 stacked rows showing vehicle_kind, ETA, fare, key amenities. Tap row → confirmation card → "Book". Then RideTrackingCard with live driver location.


9. CACHING POLICY

Call TTL Rationale
get_ride_estimates 30s surge + driver positions move fast
track_ride 0s always live
book_ride 0s
cancel_ride 0s
update_ride_drop 0s
Failure responses 0s

10. ERROR CODES

Code HTTP Meaning TOMO behavior
NO_DRIVERS_AVAILABLE 503 none in radius retry with delay or fall back to other partners
OUT_OF_SERVICE_AREA 400 pickup or drop outside coverage surface to user
OPTION_EXPIRED 410 ride_option_token invalid re-quote
PAYMENT_DECLINED 402 gateway rejection surface
OTP_FAILED 401 OTP-at-pickup mismatch surface
RIDE_NOT_FOUND 404 ride_ref doesn't exist surface
ALREADY_CANCELLED 409 duplicate cancel idempotent return
DRIVER_UNRESPONSIVE 503 driver assigned but not moving offer reassign
SURGE_EXCEEDED_BUDGET 400 new surge pushed over budget_max re-quote with new band
FASTAG_INSUFFICIENT 400 route requires FASTag, balance low surface top-up CTA

11. SANDBOX → PRODUCTION CHECKLIST

[ ] All §2 inputs validated, request_id echoed
[ ] get_ride_estimates returns ≥3 options for "HITEC City → RGI airport, 1 passenger, 2 bags"
[ ] All §4 required fields populated with REAL data
[ ] driver_kyc + vehicle_meta truthful + verifiable on demand
[ ] background_check_passed=true backed by partner's KYC vendor
[ ] fitness_certificate + insurance + PUC + permit numbers all valid
[ ] book_ride returns ride_ref + driver assignment within SLA
[ ] track_ride returns driver location ≤5s old
[ ] cancel_ride respects free_cancel_within_minutes window
[ ] update_ride_drop computes revised fare correctly
[ ] CPC webhook arrives within 60s of ride completion
[ ] HMAC verification passes
[ ] No forbidden fields anywhere
[ ] Trip share URL works for ≥2h post-completion
[ ] SOS button tested with TOMO ops monitoring
[ ] No paid placement / sponsored signals
[ ] customer_support_24x7 verified by TOMO field call
[ ] Aggregator permit certificate uploaded
[ ] State permit covers all cities partner serves

12. ANTI-FABRICATION RULES

RULE 1 — No paid placement signals
RULE 2 — No fake driver ratings
  rating_avg = unrounded float from real ride feedback. TOMO samples 1% rides.
RULE 3 — No fake driver photos / AI photos
  photo_url must show same driver who arrives. TOMO field-tests.
RULE 4 — Vehicle plate must match the actual vehicle dispatched
  plate_masked at booking → must match vehicle that arrives. Mismatch = breach.
RULE 5 — Fare displayed must be honored
  is_upfront_fare=true means fare_locked_until_iso. Any post-trip price hike
  (other than legitimate detour) = breach.
RULE 6 — Driver KYC claims must be verifiable
  TOMO ops can request KYC docs for any driver_id at any time. Failure to
  produce within 48h = breach.
RULE 7 — SOS / panic features must function
  Self-declared CCTV/SOS/panic features tested in sandbox; failures block
  production approval.
RULE 8 — No surge gaming
  surge_multiplier > 1.0 requires surge_reason ∈ valid enum. TOMO checks
  surge against same-time-same-area data on partner's own app via 1% audit.
RULE 9 — Cancel charges must match displayed
  free_cancel_within_minutes window enforced server-side. Charging within
  the window = breach.
RULE 10 — No commission-based response shaping
  Same trip on TOMO and on partner's app must yield same fare.

VERSION HISTORY

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