travel.book_cruise — Full Intent Specification
INTENT NAMESPACE: travel
INTENT NAME: book_cruise
FULL ID: travel.book_cruise
VERSION: v1.0.0
STATUS: draft
TTBS WEIGHTS: time 0.10 · taste 0.35 · budget 0.25 · safety 0.30
LAST UPDATED: 2026-05-14
User books a cruise voyage — domestic Indian coastal (Cordelia Cruises etc.), international (Royal Caribbean, MSC, Norwegian, Carnival, Costa, Princess), or river (Antara on Brahmaputra, Pandaw on Mekong). Multi-night sea travel with cabin accommodation, dining, on-board activities, and port-of-call shore excursions. Distinct from travel.book_package (typically land bundle), travel.book_flight (single segment), and ferry/water-taxi short-hop (not a v1 TOMO intent). Partner exemplars: Cordelia Cruises, MakeMyTrip Cruises, Thomas Cook Cruises, Cruise.com, Costa Cruises direct, Royal Caribbean partners.
1. NATURAL LANGUAGE COVERAGE
Classifies IN
- "cruise from Mumbai"
- "Cordelia cruise to Goa"
- "Mediterranean cruise next year"
- "Caribbean cruise 7 nights"
- "river cruise Brahmaputra"
- "Singapore Penang cruise"
- "Royal Caribbean booking"
- "family cruise with kids' club"
- "cruise wedding"
- "balcony cabin Mediterranean"
Classifies OUT — borderline NO
- "ferry to Elephanta" — out of scope v1
- "yacht charter for the day" — out of scope v1
- "package tour Europe" →
travel.book_package - "hotel in Goa" →
travel.book_hotel - "flight to Singapore" →
travel.book_flight
MULTI-INTENT TRIGGERS
- "cruise + flight to embarkation port" →
travel.book_cruise+travel.book_flight - "cruise + travel insurance" →
travel.book_cruise+finance.buy_travel_insurance - "cruise + visa" →
travel.book_cruise+travel.book_visa_assistance
2. INPUT — TOMO → PROVIDER
{
"intent": "travel.book_cruise",
"intent_version": "v1.0.0",
"request_id": "req_cru_2h4k_2026-05-14T10:00:00+05:30",
"user_session_id": "anon_user_token_or_uid",
"cruise_request": {
"cruise_kind": "ocean",
"departure_port_city": "Mumbai",
"departure_port_country_code": "IN",
"destination_themes": ["coastal_india"],
"destinations_must_include": [],
"departure_window": {
"start": "2026-11-15",
"end": "2026-11-25"
},
"duration_nights_min": 3,
"duration_nights_max": 7,
"party": {
"adult_count": 2,
"children_with_age": [],
"infants_under_2": 0,
"cabins_required": 1
},
"preferences": {
"cabin_kind_acceptable": ["balcony", "ocean_view"],
"deck_preference": "mid",
"dining_plan": "anytime",
"veg_meals_priority": true,
"jain_meals_required": false,
"alcohol_package": "non_alcoholic_package",
"kids_club_required": false,
"casino_acceptable": true,
"smoking_section_acceptable": false,
"wheelchair_accessibility_required": false,
"preferred_cruise_lines": [],
"budget_band": "good",
"budget_max_inr_per_person": 75000,
"budget_max_inr_total": 150000
}
},
"context": {
"user_locale": "en-IN",
"user_currency_pref": "INR",
"trip_purpose": "leisure",
"trust_signals": {
"is_repeat_customer": false,
"user_account_age_days": 312
}
}
}
| Field | Type | Constraint | Notes |
|---|---|---|---|
intent |
string | REQUIRED, equals "travel.book_cruise" |
|
cruise_request.cruise_kind |
enum | REQUIRED, STRICT §6 | ocean / river / expedition |
cruise_request.departure_port_city |
string | REQUIRED | Validated against partner port list |
cruise_request.departure_window |
object | REQUIRED | start, end ISO_DATE |
cruise_request.duration_nights_min/max |
int | REQUIRED, 2-90 | |
cruise_request.party.cabins_required |
int | REQUIRED, ≥1 | |
preferences.cabin_kind_acceptable |
array |
REQUIRED, ≥1, STRICT §6 | inside / ocean_view / balcony / suite |
preferences.deck_preference |
enum | REQUIRED, STRICT §6 | low / mid / high / any |
preferences.dining_plan |
enum | REQUIRED, STRICT §6 | fixed_early / fixed_late / anytime / specialty_only |
preferences.alcohol_package |
enum | REQUIRED, STRICT §6 | none / soft_drinks / non_alcoholic_package / alcoholic_package |
preferences.kids_club_required |
bool | REQUIRED | Hard filter |
preferences.wheelchair_accessibility_required |
bool | REQUIRED | Hard filter |
Anti-fabrication preamble: no paid placement. International cruise lines must show Flag State + Class Society + last-inspection date. Domestic operators must show DG Shipping registration + last seaworthiness certificate.
3. PROVIDER TOOLS
Tool 1: search_cruises
PURPOSE: return cruise voyages matching port + window + duration + cabin
INPUT: §2 request body
OUTPUT: { cruises: CruiseOption[], result_token, expires_at }
SLA: p50 < 2000ms, p95 < 5000ms
RATE LIMIT: ≤ 1/sec
RESULT SET: up to 20 cruises
Tool 2: get_cruise_detail
PURPOSE: full itinerary + ship facilities + cabin photos + dining
INPUT: { cruise_id, request_id }
OUTPUT: CruiseDetail (§5)
SLA: p95 < 2500ms
Tool 3: hold_cabin
PURPOSE: soft-lock cabin for 30 minutes (cruise lines hold longer)
INPUT: { cruise_id, cabin_category_id, party, request_id }
OUTPUT: { hold_id, hold_expires_at, locked_price_inr }
SLA: p95 < 2500ms
Tool 4: confirm_cruise
PURPOSE: confirm + passenger e-docs + boarding passes
INPUT: { hold_id, passenger_passports, payment_method_id, request_id }
OUTPUT: ConfirmedCruise (§5)
SLA: p95 < 6000ms
IDEMPOTENCY: request_id
Tool 5: cancel_cruise
PURPOSE: cancel + tiered refund per cruise-line policy
INPUT: { booking_id, reason_code, request_id }
OUTPUT: CancellationResult (§5)
SLA: p95 < 3500ms
4. RESPONSE SHAPE
CruiseOption
CruiseOption:
cruise_id: { type: string, constraint: REQUIRED, opaque }
cruise_line:
name: { type: string, constraint: REQUIRED }
flag_state: { type: string, constraint: REQUIRED, ISO_3166_2, semantics: "Bahamas, Italy, Malta, India etc." }
classification_society: { type: enum, constraint: REQUIRED, STRICT §6, values: [LR, DNV, ABS, BV, IRS, RINA, ClassNK, CCS, KR, other] }
dg_shipping_registered: { type: boolean, constraint: REQUIRED, semantics: "Mandatory TRUE for Indian-port-of-call domestic cruises" }
last_inspection_date: { type: string, constraint: REQUIRED, ISO_DATE }
fleet_avg_age_years: { type: float, constraint: REQUIRED, ≥0 }
ship:
name: { type: string, constraint: REQUIRED }
year_built: { type: int, constraint: REQUIRED }
year_refurbished: { type: int, constraint: REQUIRED, semantics: "= year_built if never refurbished" }
passenger_capacity: { type: int, constraint: REQUIRED }
crew_count: { type: int, constraint: REQUIRED }
crew_to_passenger_ratio: { type: float, constraint: REQUIRED }
cabin_count: { type: int, constraint: REQUIRED }
deck_count: { type: int, constraint: REQUIRED }
medical_facility_kind: { type: enum, constraint: REQUIRED, STRICT §6, values: [doctor_only, doctor_plus_nurse, mini_hospital] }
voyage:
name: { type: string, constraint: REQUIRED }
departure_port: { type: string, constraint: REQUIRED }
departure_datetime: { type: string, constraint: REQUIRED, ISO_DATETIME }
return_port: { type: string, constraint: REQUIRED }
return_datetime: { type: string, constraint: REQUIRED, ISO_DATETIME }
duration_nights: { type: int, constraint: REQUIRED }
ports_of_call:
type: array<object>
constraint: REQUIRED, may be empty
shape:
port: { type: string, constraint: REQUIRED }
country_code: { type: string, constraint: REQUIRED, ISO_3166_2 }
arrival_at: { type: string, constraint: REQUIRED, ISO_DATETIME }
departure_at: { type: string, constraint: REQUIRED, ISO_DATETIME }
shore_excursion_count_offered: { type: int, constraint: REQUIRED, ≥0 }
cabin_categories:
type: array<object>
constraint: REQUIRED, ≥1
shape:
cabin_category_id: { type: string, constraint: REQUIRED }
cabin_kind: { type: enum, constraint: REQUIRED, STRICT §6 }
deck: { type: enum, constraint: REQUIRED, STRICT §6 }
size_sqft: { type: int, constraint: REQUIRED }
max_occupancy: { type: int, constraint: REQUIRED }
photos: { type: array<string>, constraint: REQUIRED, ≥1, HTTPS URLs }
wheelchair_accessible: { type: boolean, constraint: REQUIRED }
price_per_person_inr: { type: int, constraint: REQUIRED, INR_INTEGER }
pricing_summary:
cheapest_per_person_inr: { type: int, constraint: REQUIRED, INR_INTEGER }
selected_total_for_party_inr: { type: int, constraint: REQUIRED, INR_INTEGER }
port_charges_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
gst_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
tcs_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0, semantics: "Overseas tour TCS §206C(1G)" }
gratuities_per_person_per_day_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
advance_payable_inr: { type: int, constraint: REQUIRED, INR_INTEGER }
balance_due_date: { type: string, constraint: REQUIRED, ISO_DATE }
inclusions: { type: array<enum>, constraint: REQUIRED, STRICT §6, may be empty }
exclusions_text: { type: array<string>, constraint: REQUIRED, ≥1 }
cancellation_policy:
type: array<object>
constraint: REQUIRED, may NOT be empty
shape:
days_before_departure_min: { type: int, constraint: REQUIRED }
days_before_departure_max: { type: int, constraint: REQUIRED }
cancellation_charge_pct: { type: int, constraint: REQUIRED, 0-100 }
on_board:
dining_venues: { type: array<string>, constraint: REQUIRED, ≥1 }
bars_lounges: { type: array<string>, constraint: REQUIRED, may be empty }
kids_club_present: { type: boolean, constraint: REQUIRED }
casino_present: { type: boolean, constraint: REQUIRED }
spa_present: { type: boolean, constraint: REQUIRED }
pool_count: { type: int, constraint: REQUIRED, ≥0 }
theatre_present: { type: boolean, constraint: REQUIRED }
wifi_quality: { type: enum, constraint: REQUIRED, STRICT §6, values: [none, slow_satellite, moderate, high_speed] }
indian_meals_available: { type: boolean, constraint: REQUIRED }
jain_meals_available: { type: boolean, constraint: REQUIRED }
vegetarian_full_menu: { type: boolean, constraint: REQUIRED }
rating:
average_score: { type: float, constraint: REQUIRED, 0.0-5.0 }
review_count: { type: int, constraint: REQUIRED, ≥0 }
partner_reference:
source: { type: string, constraint: REQUIRED }
deeplink: { type: string, constraint: REQUIRED, HTTPS URL }
CruiseDetail
CruiseDetail:
cruise_id: { type: string, constraint: REQUIRED }
day_by_day_plan:
type: array<object>
constraint: REQUIRED, length = duration_nights+1
shape:
day_number: { type: int, constraint: REQUIRED }
title: { type: string, constraint: REQUIRED }
port: { type: string, constraint: REQUIRED, semantics: "Empty when at sea" }
arrival_at: { type: string, constraint: REQUIRED, ISO_DATETIME, semantics: "Empty when at sea" }
departure_at: { type: string, constraint: REQUIRED, ISO_DATETIME, semantics: "Empty when at sea" }
shore_excursions_offered: { type: array<string>, constraint: REQUIRED, may be empty }
dining_highlights: { type: array<string>, constraint: REQUIRED, may be empty }
ship_photos_360_url: { type: string, constraint: REQUIRED, HTTPS URL, semantics: "Empty when no 360 tour" }
required_documents: { type: array<enum>, constraint: REQUIRED, STRICT §6, ≥1 }
visa_advisory_text: { type: string, constraint: REQUIRED, semantics: "Empty when no visa needed" }
health_advisory_text: { type: string, constraint: REQUIRED }
prohibited_items_text: { type: array<string>, constraint: REQUIRED, may be empty }
ConfirmedCruise
ConfirmedCruise:
booking_id: { type: string, constraint: REQUIRED, immutable }
cruise_line_reference: { type: string, constraint: REQUIRED }
ship_name: { type: string, constraint: REQUIRED }
voyage_name: { type: string, constraint: REQUIRED }
departure_datetime: { type: string, constraint: REQUIRED, ISO_DATETIME }
return_datetime: { type: string, constraint: REQUIRED, ISO_DATETIME }
cabin_assignment:
cabin_kind: { type: enum, constraint: REQUIRED, STRICT §6 }
deck: { type: string, constraint: REQUIRED }
cabin_number: { type: string, constraint: REQUIRED }
passengers:
type: array<object>
constraint: REQUIRED, ≥1
shape:
name: { type: string, constraint: REQUIRED }
passport_number_masked: { type: string, constraint: REQUIRED, semantics: "last-4 only" }
nationality: { type: string, constraint: REQUIRED, ISO_3166_2 }
date_of_birth: { type: string, constraint: REQUIRED, ISO_DATE }
total_paid_inr: { type: int, constraint: REQUIRED, INR_INTEGER }
balance_due_inr: { type: int, constraint: REQUIRED, INR_INTEGER }
e_ticket_url: { type: string, constraint: REQUIRED, HTTPS URL }
boarding_pass_url: { type: string, constraint: REQUIRED, HTTPS URL, semantics: "Empty until check-in window opens" }
embarkation_instructions_url: { type: string, constraint: REQUIRED, HTTPS URL }
emergency_contacts:
cruise_line_24_7_phone: { type: string, constraint: REQUIRED, E.164 }
partner_support_phone: { type: string, constraint: REQUIRED, E.164 }
port_agent_phone: { type: string, constraint: REQUIRED, E.164 }
CancellationResult
CancellationResult:
booking_id: { type: string, constraint: REQUIRED }
cancelled_at: { type: string, constraint: REQUIRED, ISO_DATETIME }
refund_amount_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
refund_method: { type: enum, constraint: REQUIRED, STRICT §6, values: [original_payment, bank_transfer, future_cruise_credit] }
refund_eta_days: { type: int, constraint: REQUIRED, 0-90, semantics: "International refunds can take 60+ days" }
cancellation_charge_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
non_refundable_components: { type: array<string>, constraint: REQUIRED, may be empty }
FORBIDDEN FIELDS
paid_placement_score,ad_bid,sponsored_rank,featured_cruise_lineeditor_pick,tomo_recommended,top_choiceinflated_crew_to_passenger_ratio,inflated_review_countai_generated_cabin_photo,staged_dining_photoexpired_classification_society_record,concealed_inspection_overduecommission_padded_pricingurgency_text("Sails next week, only 1 cabin!") unless inventory truly lowfalse_indian_meal_claim— must reflect actual on-board offering
5. CONTROLLED VOCABULARIES
cruise_request.cruise_kind:
values:
ocean: "Ocean / sea cruise"
river: "River cruise (Brahmaputra / Ganges / Mekong / Rhine / Nile)"
expedition: "Expedition (polar / remote / small-ship adventure)"
cruise_request.destination_themes:
values:
coastal_india, mediterranean, caribbean, baltic, scandinavian,
south_east_asia, japan_korea, alaska, hawaii, antarctica, arctic,
galapagos, amazon, ganges, brahmaputra, mekong, rhine, danube, nile
cabin_kind_acceptable / cabin_kind:
values: [inside, ocean_view, balcony, suite, garden_villa_river_expedition_only]
deck_preference / deck:
values: [low, mid, high, any]
dining_plan:
values: [fixed_early, fixed_late, anytime, specialty_only]
alcohol_package:
values: [none, soft_drinks, non_alcoholic_package, alcoholic_package]
classification_society:
values: [LR, DNV, ABS, BV, IRS, RINA, ClassNK, CCS, KR, other]
medical_facility_kind:
values: [doctor_only, doctor_plus_nurse, mini_hospital]
wifi_quality:
values: [none, slow_satellite, moderate, high_speed]
inclusions:
values:
all_meals_main_dining, gratuities_included, wifi_basic, wifi_premium,
soft_drinks, alcohol_select, shore_excursions_select,
speciality_dining_credit, port_charges_included, kids_club_access,
spa_credit
CruiseDetail.required_documents:
values:
passport, visa, vaccination_certificate, health_questionnaire,
travel_insurance, pcr_test_results, photo_id, parent_consent_for_minor
CancellationResult.refund_method:
values: [original_payment, bank_transfer, future_cruise_credit]
6. TTBS DIMENSIONS
TIME (weight = 0.10):
signals_used:
- departure_datetime in window
- duration fits min/max
weighting:
departure_fit: 0.50
duration_fit: 0.50
user_band_handling:
fast: prefer earliest available
balanced: standard
flexible: 14-day window OK
TASTE (weight = 0.35):
signals_used:
- cabin_kind match
- destinations_must_include coverage
- cruise_line preference / DNA repeat
- dining_plan match
- kids_club_required (HARD when TRUE)
- indian_meals_available / jain_meals_available match
- on_board facilities (casino / spa / pool count)
weighting:
cabin_match: 0.20
destination_match: 0.25
line_dna: 0.20
dining_match: 0.15
indian_meals_fit: 0.10
facilities_match: 0.10
BUDGET (weight = 0.25):
signals_used:
- pricing_summary.cheapest_per_person_inr
- pricing_summary.selected_total_for_party_inr
- gratuities_per_person_per_day_inr (often hidden cost)
weighting:
total: 0.55
cheapest_per_person: 0.30
gratuities: 0.15
user_band_handling:
ok: cheapest passing taste + safety
good: balanced
great: suite + premium line regardless of cost
SAFETY (weight = 0.30):
signals_used:
- classification_society in recognized IACS list
- dg_shipping_registered (HARD for IN port-of-call)
- last_inspection_date within 12 months
- fleet_avg_age_years (lower preferred)
- crew_to_passenger_ratio (higher preferred, ≥1:3 floor)
- medical_facility_kind (doctor_plus_nurse floor for ocean / mini_hospital for expedition)
- emergency_contacts complete
- rating.average_score ≥4.0 floor
weighting:
class_society: 0.25
inspection_freshness: 0.20
crew_ratio: 0.15
medical_facility: 0.20
rating_floor: 0.20
user_band_handling:
fast: relax crew_ratio to 1:3.5
balanced: floor 1:3
great: mini_hospital + ≤5yr ship + IACS top-tier class
Locked weights: time 0.10 / taste 0.35 / budget 0.25 / safety 0.30. Taste leads — cruise is fundamentally an experience-fit problem. Safety is non-negotiable HARD filter (class society + DG Shipping + inspection date) before TTBS scoring runs.
7. COMPLETION CONTRACT
POST /api/v1/cpc/mcp_provider/<your_partner_id>
Body:
{
"intent": "travel.book_cruise",
"external_id": "<booking_id>",
"request_id": "<request_id>",
"amount_inr": 6000, // NET partner commission only (5-12% of voyage cost)
"gst_inr": 1080,
"tips_inr": 0,
"pass_through_inr": 95000, // remitted to cruise line (cabin + port + gratuities + meals)
"closed_at": "2026-11-22T11:00:00+05:30",
"status": "completed",
"cruise_line": "cordelia",
"ship_name": "Empress",
"voyage_name": "Mumbai-Goa-Mumbai",
"duration_nights": 3,
"cabin_kind": "balcony",
"passengers": 2
}
User pays full voyage cost. Partner's commission is amount_inr. Cruise-line remittance (cabin + port charges + meals + gratuities) is pass_through_inr. TCS (§206C(1G)) collected at advance-payment stage. HMAC-SHA256.
8. WIDGET
CruiseListingWidget.
Field mapping:
- cruise_line.name + ship.name → header
- voyage.name → subhead
- departure_datetime → "Departs 15 Nov 7 PM"
- duration_nights → "3 nights"
- ports_of_call (top 4) → port chip row
- cabin_kind selected → "Balcony cabin"
- pricing_summary.selected_total_for_party_inr → big price
- inclusions (top 4) → inclusion chips
- rating.average_score + review_count → star pill
- classification_society + flag_state → "Class: DNV · Flag: BS"
- last_inspection_date → "Inspected Mar 2026"
9. CACHING POLICY
| Call | TTL | Rationale |
|---|---|---|
| search_cruises | 5min | Inventory not as volatile as hotels |
| get_cruise_detail | 30min | Detail stable |
| hold_cabin | NO CACHE | Stateful lock |
| confirm_cruise | NO CACHE | Idempotent |
| cancel_cruise | NO CACHE | — |
| Cruise-line / ship static (class, flag, inspection) | 7d | Updated post-inspection |
10. ERROR CODES
| Code | HTTP | Meaning | Retry |
|---|---|---|---|
INVALID_REQUEST |
400 | Malformed | No |
RATE_LIMITED |
429 | Throttle | 1, 2s |
INTERNAL_ERROR |
500 | Partner failure | 2, exp |
SIGNATURE_INVALID |
401 | HMAC fail | No |
NO_CRUISE_MATCH |
200 (empty) | None | n/a |
CABIN_TAKEN |
409 | Hold race-lost | UI re-queries |
HOLD_EXPIRED |
410 | Hold elapsed | UI re-holds |
INSPECTION_OVERDUE |
422 | Ship inspection lapsed; filtered | No |
DG_SHIPPING_NOT_REGISTERED |
422 | IN port-of-call without DG registration | No |
PAYMENT_FAILED |
402 | Gateway declined | No |
VISA_NOT_HELD |
422 | International voyage, visa requirement unmet | No |
PASSPORT_VALIDITY_INSUFFICIENT |
422 | Passport <6mo validity at return date | No |
WHEELCHAIR_NO_CABIN |
422 | No accessible cabin on this voyage | No |
CANCELLED_PAST_POLICY |
410 | Past full-charge stage | No |
VOYAGE_CANCELLED_BY_LINE |
410 | Line cancellation; auto-refund flow | No |
11. SANDBOX → PRODUCTION CHECKLIST
[ ] All five tools implemented
[ ] At least 8 cruise lines in catalog (mix of domestic + international + river)
[ ] Every classification_society in IACS members list (LR/DNV/ABS/BV/IRS/RINA/ClassNK/CCS/KR)
[ ] Every flag_state in ISO 3166-2 with valid maritime registry
[ ] DG Shipping registration verified for Indian port-of-call cruises
[ ] last_inspection_date ≤ 12 months on all ships in catalog
[ ] Crew-to-passenger ratio ≥1:3 enforced floor
[ ] medical_facility_kind floor of doctor_plus_nurse for ocean cruises
[ ] indian_meals_available / jain_meals_available flags audited (sample cruise inspection)
[ ] Wheelchair-accessible cabin availability tested
[ ] TCS §206C(1G) computed correctly at advance payment
[ ] Cancellation policy tested at multiple stages
[ ] HMAC signing verified on test CPC webhook
[ ] amount_inr in CPC is COMMISSION (NET); pass_through_inr is cruise-line remittance
[ ] All controlled vocabularies respected
[ ] No forbidden fields anywhere
[ ] SLA p95 met
[ ] Privacy policy + grievance officer + maritime liability disclosures uploaded
[ ] Customer support: 24×7 cruise helpline + emergency port agent network
[ ] Visa-advisory text validated against current MEA / cruise-destination requirements
12. ANTI-FABRICATION RULES
RULE 1: Classification society must be a current IACS member. Non-IACS
class = ingest reject.
RULE 2: DG Shipping registration verified for Indian port-of-call;
re-checked weekly.
RULE 3: last_inspection_date must reflect a real flag-state or class
inspection (not partner self-attest). Re-verified at every hold.
RULE 4: crew_to_passenger_ratio must reflect official ship manifests;
partner inflating = customer-harm + audit.
RULE 5: medical_facility_kind validated via sample audit on ship
manifests. Partner false-flagging "mini_hospital" without facility
= customer-harm + suspension.
RULE 6: No paid_placement, ad_bid, sponsored_rank, featured_cruise_line.
RULE 7: rating.average_score from completed voyages only; review_count
from verified bookings only.
RULE 8: AI-generated cabin / dining photos forbidden. Real recent photos
required; metadata audited.
RULE 9: indian_meals_available, jain_meals_available, vegetarian_full_menu
flags must reflect actual on-board offering. Sample audits on
maiden voyages. False = customer-harm + suspension.
RULE 10: TCS §206C(1G) computation must match Income Tax Act; under-collect
= regulatory breach.
RULE 11: amount_inr is partner COMMISSION only. Cruise-line remittance is
pass_through_inr. Inflated commission base = audit.
RULE 12: Voyage-line-initiated cancellations trigger automatic full
refund within 7 days (line) + 3 days (partner) regardless of policy.
RULE 13: Required documents (passport / visa / vaccination etc.) must be
the actual line + destination requirements. Misleading = customer
stranded at port + reputational suspension.
RULE 14: Information-completeness score (hidden rank factor weight 0.10)
rewards full §4 shape.
RULE 15: Gratuities-per-person-per-day must be disclosed pre-payment;
hidden gratuities = customer-harm + audit.
RULE 16: Maritime liability disclosures (Athens Convention applicable for
international, Indian maritime law for domestic) must be on
partner site + linked from confirmation email.
VERSION HISTORY
v1.0.0 — 2026-05-14 — Initial spec. IACS classification + DG Shipping
(for IN port-of-call) + 12-month inspection floor.
Crew-to-passenger ≥1:3 floor. Medical-facility
floor doctor_plus_nurse for ocean.
TCS §206C(1G) compliance. Net-commission base.
Indian-meal / Jain-meal flags audited.