|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| - id: airline.price_rename
|
| drift_type: schema
|
| domain: airline
|
| from_version: v1
|
| to_version: v2
|
| description: "field 'price' renamed to 'total_fare_inr'; 'currency' removed"
|
| mutation:
|
| rename: {price: total_fare_inr}
|
| remove: [currency]
|
| detection_hints:
|
| - total_fare_inr
|
| - price
|
| - rename
|
|
|
| - id: airline.pax_required
|
| drift_type: schema
|
| domain: airline
|
| from_version: v2
|
| to_version: v3
|
| description: "booking now requires 'passenger_count' field"
|
| mutation:
|
| require_new_field: [passenger_count]
|
| detection_hints:
|
| - passenger_count
|
| - MISSING_PASSENGER_COUNT
|
| - passenger
|
|
|
| - id: cab.fare_breakdown
|
| drift_type: schema
|
| domain: cab
|
| from_version: v2
|
| to_version: v3
|
| description: "field 'fare_inr' replaced by nested 'fare_breakdown' with base/surge/tolls/gst"
|
| mutation:
|
| remove: [fare_inr]
|
| require_new_field: [fare_breakdown, total_inr]
|
| detection_hints:
|
| - fare_breakdown
|
| - base
|
| - surge
|
| - tolls
|
| - gst
|
|
|
| - id: restaurant.items_shape_bump
|
| drift_type: schema
|
| domain: restaurant
|
| from_version: v2
|
| to_version: v3
|
| description: "each item in 'items' now requires a 'modifiers' list (empty allowed)"
|
| mutation:
|
| require_new_field: [modifiers]
|
| detection_hints:
|
| - modifiers
|
| - INVALID_ITEMS_SHAPE
|
| - items
|
|
|
| - id: hotel.gst_field
|
| drift_type: schema
|
| domain: hotel
|
| from_version: v2
|
| to_version: v3
|
| description: "hotel.book now requires 'gst_number' when total_with_tax > 7500"
|
| mutation:
|
| require_new_field: [gst_number]
|
| detection_hints:
|
| - gst_number
|
| - MISSING_GST_NUMBER
|
| - GST_REQUIRED
|
|
|
|
|
|
|
| - id: airline.booking_window_shrink
|
| drift_type: policy
|
| domain: airline
|
| from_version: v1
|
| to_version: v2
|
| description: "same-day bookings rejected after 14:00 IST (was: same-day always allowed)"
|
| mutation:
|
| time_window_shrink: {same_day_cutoff_hour_ist: 14}
|
| detection_hints:
|
| - BOOKING_WINDOW_CLOSED
|
| - booking_window
|
| - "14:00"
|
| - same-day
|
|
|
| - id: cab.school_hours_mini_reject
|
| drift_type: policy
|
| domain: cab
|
| from_version: v1
|
| to_version: v2
|
| description: "vehicle_class=mini during 07:00-09:00 IST now auto-rejects with policy_error"
|
| mutation:
|
| policy_flag_flip: {mini_reject_school_hours: true}
|
| detection_hints:
|
| - SCHOOL_HOURS_MINI_REJECTED
|
| - school_hours
|
| - mini
|
| - "07:00"
|
|
|
| - id: restaurant.min_order_bump
|
| drift_type: policy
|
| domain: restaurant
|
| from_version: v1
|
| to_version: v2
|
| description: "minimum order amount increased from 199 to 299"
|
| mutation:
|
| numeric_bump: {min_order_inr: 299}
|
| detection_hints:
|
| - MIN_ORDER_NOT_MET
|
| - min_order
|
| - "299"
|
|
|
| - id: hotel.cancel_window_shrink
|
| drift_type: policy
|
| domain: hotel
|
| from_version: v1
|
| to_version: v2
|
| description: "free cancellation window shrunk from 24h to 6h before check-in"
|
| mutation:
|
| time_window_shrink: {cancel_window_hours: 6}
|
| detection_hints:
|
| - CANCEL_WINDOW_EXPIRED
|
| - cancel_window
|
| - 6h
|
| - 24h
|
|
|
| - id: cab.vehicle_class_expand
|
| drift_type: policy
|
| domain: cab
|
| from_version: v1
|
| to_version: v2
|
| description: "vehicle_class enum expanded to include 'suv' and 'infant_seat_sedan'"
|
| mutation:
|
| enum_expand:
|
| vehicle_class: [mini, sedan, suv, infant_seat_sedan]
|
| detection_hints:
|
| - vehicle_class
|
| - suv
|
| - infant_seat_sedan
|
| - VEHICLE_CLASS_UNAVAILABLE
|
|
|
|
|
|
|
| - id: airline.baggage_tnc_rewrite
|
| drift_type: tnc
|
| domain: airline
|
| from_version: v1
|
| to_version: v2
|
| description: "free cabin allowance reduced from 7kg to 5kg; announced via side-channel notice"
|
| mutation:
|
| tnc_text_swap: {cabin_allowance_kg: 5}
|
| side_channel_notice_append: "Baggage T&C updated: free cabin allowance is now 5kg (was 7kg)."
|
| detection_hints:
|
| - cabin_allowance
|
| - 5kg
|
| - 7kg
|
| - baggage
|
|
|
| - id: cab.surge_policy_tnc
|
| drift_type: tnc
|
| domain: cab
|
| from_version: v1
|
| to_version: v2
|
| description: "surge may now apply retroactively if ride is extended; side-channel notice"
|
| mutation:
|
| tnc_text_swap: {surge_retroactive: true}
|
| side_channel_notice_append: "Surge policy updated: retroactive surge may apply if ride is extended."
|
| detection_hints:
|
| - surge
|
| - retroactive
|
| - surge_retroactive
|
|
|
| - id: restaurant.veg_filter_semantic
|
| drift_type: tnc
|
| domain: restaurant
|
| from_version: v2
|
| to_version: v3
|
| description: "veg_only=True now excludes egg-based dishes (previously included)"
|
| mutation:
|
|
|
|
|
|
|
|
|
|
|
| tnc_text_swap: {veg_only_excludes_egg: true, veg_only: "semantics_egg_excluded"}
|
| side_channel_notice_append: "Semantics update: veg_only=True now excludes egg-based dishes."
|
| detection_hints:
|
| - veg_only
|
| - egg
|
| - semantic
|
|
|
| - id: hotel.early_checkin_tnc
|
| drift_type: tnc
|
| domain: hotel
|
| from_version: v1
|
| to_version: v2
|
| description: "early check-in before 12:00 now billed at 50% of nightly rate; side-channel"
|
| mutation:
|
| tnc_text_swap: {early_checkin_fee_pct: 50}
|
| side_channel_notice_append: "Early check-in before 12:00 now costs 50% of nightly rate."
|
| detection_hints:
|
| - early_checkin
|
| - 50%
|
| - "12:00"
|
| - nightly
|
|
|
| - id: airline.reschedule_tnc
|
| drift_type: tnc
|
| domain: airline
|
| from_version: v2
|
| to_version: v3
|
| description: "reschedule fee previously waived; now 10% of fare + side-channel text"
|
| mutation:
|
| tnc_text_swap: {reschedule_fee_pct: 10}
|
| side_channel_notice_append: "Reschedule fee policy updated: 10% of fare applies."
|
| detection_hints:
|
| - reschedule
|
| - 10%
|
| - fare
|
|
|
|
|
|
|
| - id: airline.convenience_fee_append
|
| drift_type: pricing
|
| domain: airline
|
| from_version: v1
|
| to_version: v2
|
| description: "hidden 199 INR convenience fee added at booking; search estimate unchanged"
|
| mutation:
|
| fee_append: {convenience_fee_inr: 199}
|
| detection_hints:
|
| - convenience_fee
|
| - "199"
|
| - hidden
|
|
|
| - id: cab.toll_unbundle
|
| drift_type: pricing
|
| domain: cab
|
| from_version: v1
|
| to_version: v2
|
| description: "tolls previously included; now a separate line item on booking, not estimate"
|
| mutation:
|
| pricing_restructure: {toll_bundled: false}
|
| detection_hints:
|
| - toll
|
| - tolls
|
| - unbundle
|
|
|
| - id: hotel.resort_fee_append
|
| drift_type: pricing
|
| domain: hotel
|
| from_version: v1
|
| to_version: v2
|
| description: "500 INR/night resort fee added at booking; not shown in nightly_rate"
|
| mutation:
|
| fee_append: {resort_fee_inr: 500}
|
| detection_hints:
|
| - resort_fee
|
| - "500"
|
| - resort
|
|
|
|
|
|
|
| - id: payment.auth_scope_upgrade
|
| drift_type: auth
|
| domain: payment
|
| from_version: v1
|
| to_version: v2
|
| description: "token_v1 now returns 401; requires token_v2 with scope=payments:write:v2"
|
| mutation:
|
| auth_scope_bump: {required_scope: "payments:write:v2"}
|
| token_version_bump: {accepted_token_version: v2}
|
| detection_hints:
|
| - AUTH_SCOPE_INSUFFICIENT
|
| - scope
|
| - token_v2
|
| - "payments:write:v2"
|
|
|
| - id: payment.mfa_required
|
| drift_type: auth
|
| domain: payment
|
| from_version: v1
|
| to_version: v2
|
| description: "transactions > 5000 INR now require mfa_code; auth_error with MFA_REQUIRED (payment v1 → v2, alternative auth-tightening to auth_scope_upgrade triggered by amount rather than scope)"
|
| mutation:
|
| policy_flag_flip: {mfa_required: true}
|
| numeric_bump: {mfa_threshold_inr: 5000}
|
| detection_hints:
|
| - MFA_REQUIRED
|
| - mfa_code
|
| - mfa
|
| - "5000"
|
|
|