Intent Spec — auto.book_major_service
FULL ID: auto.book_major_service
VERSION: v1.0.0
STATUS: draft
LAST UPDATED: 2026-05-11
DOMAIN: auto
PRIMARY AGENT: AutoServicesAgent
TTBS WEIGHTS: time=0.15 taste=0.20 budget=0.25 safety=0.40
User books a major service — engine work, transmission overhaul, clutch replacement, accident-damage repair, AC compressor work, suspension overhaul, electrical-system diagnostics. Higher cost band (typically ₹5,000–₹2,00,000+), longer turnaround (1-15 days), and SAFETY-dominant TTBS weighting because mis-done major repairs have serious consequences.
Partner exemplars: OEM-authorised workshops (Maruti Authorised, Hyundai Workshop, Tata Motors), Carnation Auto, GoMechanic Major, Spinny Workshops, independent specialist workshops.
SECTION 1 — INTENT IDENTITY
This intent fires for any service that is not a periodic / scheduled service. Goes beyond oil change, filter swap, basic inspection. Distinct from:
auto.book_general_service— periodic / preventive, lower cost, faster turnaroundauto.book_breakdown_assist— emergency on-spot, vehicle dead at roadsideauto.book_battery_replacement— single-part replacementauto.book_paint_job— cosmetic-onlyauto.book_tyre_alignment— single-service
Major service typically involves a diagnostic phase, an itemized quote with multiple line items, a customer-approval gate, and a multi-day workshop stay. The completion contract reflects this longer lifecycle.
SECTION 2 — NATURAL LANGUAGE COVERAGE
CLASSIFIES IN
- "Engine making noise, need overhaul"
- "Clutch replacement for my car"
- "Transmission service / repair"
- "AC compressor not working, needs replacement"
- "Suspension overhaul"
- "Accident repair, body shop work needed"
- "Diagnose why my car is jerking"
- "Major service for my 5-year-old Innova"
- "Engine seized, can it be rebuilt"
- "Electrical fault — wiring problem, need diagnosis"
CLASSIFIES OUT — BORDERLINE NO
- "10K km service" →
auto.book_general_service - "Car broke down right now" →
auto.book_breakdown_assist - "Just a battery swap" →
auto.book_battery_replacement - "Repaint my bumper" →
auto.book_paint_job - "Wheels need alignment" →
auto.book_tyre_alignment
MULTI-INTENT TRIGGERS
- "Major repair + body work" →
auto.book_major_service+auto.book_paint_job(at same workshop when possible) - "Engine work + insurance claim" →
auto.book_major_service+ futureauto.file_insurance_claim(v2; today routes both through major_service with ainsurance_claim_intended=truehint)
SECTION 3 — INPUT (TOMO → PROVIDER)
{
"intent": "auto.book_major_service",
"request_id": "req_01J9Z...",
"user_locale": "en-IN",
"user_currency": "INR",
"user_location": { "lat": 17.4475, "lng": 78.3563, "max_radius_km": 20, "city": "Hyderabad" },
"vehicle": {
"type": "car",
"make": "Toyota",
"model": "Innova Crysta",
"variant": "GX",
"fuel_type": "diesel",
"year_of_manufacture": 2019,
"registration_number_last4": "1234",
"current_odometer_km": 78000,
"is_under_oem_warranty": false
},
"issue": {
"category": "engine_repair", // STRICT ENUM §6
"user_description": "Engine making knocking sound at idle, oil light flickers occasionally",
"is_in_accident": false,
"estimated_severity": "high", // STRICT ENUM §6: low | medium | high | unknown
"tomo_diagnostic_priority": true // user wants formal diagnosis before any work
},
"service_preferences": {
"preferred_window": {
"earliest_drop_off": "2026-05-13T09:00:00+05:30",
"latest_pickup": "2026-05-25T18:00:00+05:30"
},
"max_acceptable_cost_inr": 75000, // user-declared budget ceiling; partner respects
"authorised_only": true,
"loaner_vehicle_required": true,
"insurance_claim_intended": false
},
"ttbs_user_band": {
"time": "flexible",
"taste": "balanced",
"budget": "good",
"safety": "great"
},
"session_context": {
"tomo_session_id": "ses_01J9Z...",
"user_dna_hash": "dna_v3_a7c9..."
}
}
| Field | Type | Constraint | Notes |
|---|---|---|---|
intent |
string | REQUIRED, STRICT ENUM | Always auto.book_major_service |
vehicle.is_under_oem_warranty |
bool | REQUIRED | Steers ranking toward OEM-authorised when true |
issue.category |
enum | REQUIRED, STRICT ENUM §6 | |
issue.user_description |
string | REQUIRED, ≤500 chars | |
issue.estimated_severity |
enum | REQUIRED, STRICT ENUM §6 | |
issue.tomo_diagnostic_priority |
bool | REQUIRED | TRUE: partner must do paid/free diagnosis before any work |
service_preferences.preferred_window.earliest_drop_off |
string | REQUIRED, ISO_DATETIME | |
service_preferences.preferred_window.latest_pickup |
string | REQUIRED, ISO_DATETIME | |
service_preferences.max_acceptable_cost_inr |
int | REQUIRED, ≥0 | Hard cap; partner must surface if estimate exceeds |
service_preferences.authorised_only |
bool | REQUIRED | Filter to OEM-authorised workshops |
service_preferences.loaner_vehicle_required |
bool | REQUIRED | Filter |
service_preferences.insurance_claim_intended |
bool | REQUIRED | Partner steers paperwork accordingly |
Anti-fabrication preamble: Provider may not over-recommend work beyond declared issue. Diagnostic findings must be evidence-backed (photos / video / readings). Estimated cost ranges may not be padded with non-essential work.
SECTION 4 — PROVIDER TOOLS
Tool 1: search_major_service_workshops
PURPOSE: Return up to 15 workshops capable of handling the declared issue category
INPUT: §3
OUTPUT: array<MajorServiceWorkshop> per §5
SLA: p50 ≤ 800ms, p95 ≤ 2000ms, p99 ≤ 4000ms
RATE LIMIT: 60 req/min
IDEMPOTENCY: request_id; 60s cache
RETRY: 1 on 429, 2 on 5xx
Tool 2: create_diagnostic_appointment
PURPOSE: Book a diagnostic visit (with or without commitment to subsequent repair)
INPUT: { request_id, workshop_id, slot_id, vehicle.*, issue.*, contact_phone, loaner_required }
OUTPUT: DiagnosticAppointment per §5
SLA: p50 ≤ 1500ms, p95 ≤ 4000ms
RATE LIMIT: 30 req/min
IDEMPOTENCY: request_id
RETRY: No retry on create
Tool 3: get_diagnostic_report_and_quote
PURPOSE: Pull the post-diagnostic itemized quote partner generated
INPUT: { request_id, diagnostic_id }
OUTPUT: DiagnosticReport per §5
SLA: p50 ≤ 600ms, p95 ≤ 1800ms
RATE LIMIT: 60 req/min
IDEMPOTENCY: diagnostic_id; 5-min cache
RETRY: 1 on 5xx
Tool 4: approve_and_book_repair
PURPOSE: User has reviewed the quote; book the repair (locks parts, schedules bay)
INPUT: { request_id, diagnostic_id, approved_line_item_skus[], declined_line_item_skus[], loaner_required }
OUTPUT: RepairBooking per §5
SLA: p50 ≤ 2000ms, p95 ≤ 5000ms
RATE LIMIT: 30 req/min
IDEMPOTENCY: request_id
RETRY: No retry
Tool 5: cancel_appointment
PURPOSE: Cancel diagnostic or repair pre-intake; honour cancellation policy
INPUT: { request_id, appointment_id, reason_code }
OUTPUT: CancellationResult per §5
SLA: p50 ≤ 800ms, p95 ≤ 2000ms
RATE LIMIT: 30 req/min
RETRY: 1 on 5xx
SECTION 5 — RESPONSE SHAPE
MajorServiceWorkshop
MajorServiceWorkshop:
workshop_id: { type: string, constraint: REQUIRED }
name: { type: string, constraint: REQUIRED }
workshop_type:
type: enum
constraint: REQUIRED, STRICT ENUM §6
values: [oem_authorised, multi_brand_specialist, body_shop, electrical_specialist]
specialisations:
type: array<enum>
constraint: REQUIRED, ≥1 entry, STRICT ENUM §6
values: [engine, transmission, suspension, brakes, ac_system, electrical, body_paint, accident_repair, ev_specialist]
address: { type: string, constraint: REQUIRED }
location: { type: object, shape: { lat, lng }, constraint: REQUIRED }
distance_from_user_km: { type: float, constraint: REQUIRED, 0-50 }
capacity:
next_diagnostic_slot: { type: string, constraint: REQUIRED, ISO_DATETIME }
typical_repair_turnaround_days:
type: object
constraint: REQUIRED
shape:
min: { type: int, constraint: REQUIRED, 1-30 }
max: { type: int, constraint: REQUIRED, 1-60 }
median: { type: int, constraint: REQUIRED, 1-45 }
loaner_vehicle_available: { type: boolean, constraint: REQUIRED }
loaner_per_day_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
diagnostic:
diagnostic_fee_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
diagnostic_fee_waived_if_repair: { type: boolean, constraint: REQUIRED }
typical_diagnostic_hours: { type: float, constraint: REQUIRED, 0.5-8 }
diagnostic_report_includes:
type: array<string>
constraint: REQUIRED, ≥2 entries
example: ["computer_obd_scan", "physical_inspection_photos", "video_walkthrough"]
estimated_cost_range:
low_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
high_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
semantics:
type: string
constraint: REQUIRED
example: "Engine repair for Innova Crysta diesel, ₹40K–₹1.2L depending on actual root cause"
insurance_handling:
cashless_network_partner_for: { type: array<string>, constraint: REQUIRED, may be empty }
handles_claim_paperwork: { type: boolean, constraint: REQUIRED }
insurance_cashless_settlement_days: { type: int, constraint: REQUIRED, 0-60 }
warranty:
parts_warranty_months: { type: int, constraint: REQUIRED, 0-60 }
labour_warranty_months: { type: int, constraint: REQUIRED, 0-12 }
warranty_terms_url: { type: string, constraint: REQUIRED, HTTPS URL }
accreditations:
type: array<enum>
constraint: REQUIRED, may be empty
values: [iso_9001, oem_certified, body_shop_certified, electrical_certified, ev_certified]
ratings:
avg_rating: { type: float, constraint: REQUIRED, 0-5 }
review_count: { type: int, constraint: REQUIRED, ≥0 }
repeat_visit_rate_pct: { type: int, constraint: REQUIRED, 0-100 }
redo_rate_pct_last_90d:
type: int
constraint: REQUIRED, 0-100
semantics: percentage of major repairs that came back within 90 days for redo (lower = better; safety signal)
partner_reference:
source: { type: string, constraint: REQUIRED }
deeplink: { type: string, constraint: REQUIRED, HTTPS URL }
DiagnosticAppointment
DiagnosticAppointment:
diagnostic_id: { type: string, constraint: REQUIRED, immutable }
workshop_id: { type: string, constraint: REQUIRED }
scheduled_start: { type: string, constraint: REQUIRED, ISO_DATETIME }
estimated_diagnostic_completion: { type: string, constraint: REQUIRED, ISO_DATETIME }
diagnostic_fee_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
loaner_arranged: { type: boolean, constraint: REQUIRED }
service_advisor_name: { type: string, constraint: REQUIRED }
service_advisor_phone: { type: string, constraint: REQUIRED, E.164 }
partner_diagnostic_reference: { type: string, constraint: REQUIRED }
DiagnosticReport
DiagnosticReport:
diagnostic_id: { type: string, constraint: REQUIRED }
completed_at: { type: string, constraint: REQUIRED, ISO_DATETIME }
findings:
type: array<Finding>
constraint: REQUIRED, ≥1
shape:
finding_id: { type: string, constraint: REQUIRED }
component: { type: string, constraint: REQUIRED, e.g. "Engine timing chain" }
severity: { type: enum, constraint: REQUIRED, STRICT ENUM §6, values: [advisory, recommended, required_for_safety, immediate] }
evidence:
type: array<EvidenceItem>
constraint: REQUIRED, ≥1
shape:
type: { type: enum, constraint: REQUIRED, STRICT ENUM §6, values: [obd_code, photo, video, sensor_reading, advisor_note] }
url_or_value: { type: string, constraint: REQUIRED }
description: { type: string, constraint: REQUIRED, ≤300 chars }
recommended_line_items:
type: array<LineItem>
constraint: REQUIRED, ≥1
shape:
sku: { type: string, constraint: REQUIRED }
description: { type: string, constraint: REQUIRED }
category: { type: enum, constraint: REQUIRED, STRICT ENUM §6, values: [labour, part, consumable, sublet] }
quantity: { type: int, constraint: REQUIRED, ≥1 }
unit_price_inr: { type: int, constraint: REQUIRED, INR_INTEGER }
total_inr: { type: int, constraint: REQUIRED, INR_INTEGER }
necessity:
type: enum
constraint: REQUIRED, STRICT ENUM §6
values: [advisory, recommended, required_for_safety, mandatory_for_repair]
linked_finding_id: { type: string, constraint: REQUIRED, references findings.finding_id }
totals:
subtotal_inr: { type: int, constraint: REQUIRED, INR_INTEGER }
gst_inr: { type: int, constraint: REQUIRED, INR_INTEGER }
total_inr: { type: int, constraint: REQUIRED, INR_INTEGER }
quote_validity_until: { type: string, constraint: REQUIRED, ISO_DATETIME, ≥48h from completion }
RepairBooking
RepairBooking:
repair_id: { type: string, constraint: REQUIRED, immutable }
diagnostic_id: { type: string, constraint: REQUIRED }
workshop_id: { type: string, constraint: REQUIRED }
approved_line_items: { type: array<string>, constraint: REQUIRED, list of sku }
declined_line_items: { type: array<string>, constraint: REQUIRED, may be empty }
scheduled_start: { type: string, constraint: REQUIRED, ISO_DATETIME }
estimated_completion: { type: string, constraint: REQUIRED, ISO_DATETIME }
loaner_arranged: { type: boolean, constraint: REQUIRED }
total_approved_inr: { type: int, constraint: REQUIRED, INR_INTEGER }
payment_due_at: { type: enum, constraint: REQUIRED, STRICT ENUM §6, values: [50_percent_now_balance_on_pickup, on_pickup, on_completion, insurance_cashless] }
service_advisor_phone: { type: string, constraint: REQUIRED, E.164 }
CancellationResult
CancellationResult:
appointment_id: { type: string, constraint: REQUIRED }
cancelled_at: { type: string, constraint: REQUIRED, ISO_DATETIME }
cancellation_fee_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
refund_amount_inr: { type: int, constraint: REQUIRED, INR_INTEGER, ≥0 }
refund_eta_days: { type: int, constraint: REQUIRED, 0-21 }
FORBIDDEN FIELDS
paid_placement_score,ad_bid,sponsored_rank,promotion_prioritykickback_amount,referral_fee_kickback,_partner_revenue_shareartificial_urgency_text("Engine will fail any moment!" without evidence)ai_generated_photofor workshop / vehicle / diagnostic imagerycommission_padded_priceunnecessary_upsell_line_items— partner-side flag for "we recommended this but it wasn't tied to a finding"
SECTION 6 — CONTROLLED VOCABULARIES
issue.category:
values:
engine_repair: "Engine work — overhaul, head gasket, timing, etc."
transmission_repair: "Gearbox / clutch / transmission"
suspension_overhaul: "Shocks, struts, bushes, alignment after major fix"
ac_system: "AC compressor, condenser, refrigerant, electrical"
electrical_diagnostic: "Wiring, ECU, sensors, battery-not-charging"
accident_repair: "Body work + mechanical after collision"
brake_overhaul: "Master cylinder, calipers, drums, full brake system"
ev_battery_pack: "EV battery pack diagnostic / replacement"
multiple_systems: "Multiple categories — partner determines scope"
issue.estimated_severity:
values:
low: "User thinks it's a minor issue but wants expert opinion"
medium: "Something is wrong, vehicle drives but compromised"
high: "Major symptom — knocking, smoke, brake failure threat, etc."
unknown: "User can't characterise severity"
workshop_type:
values:
oem_authorised: "Vehicle manufacturer's authorised major-service workshop"
multi_brand_specialist: "Independent specialist in this category"
body_shop: "Specialised in accident / body / paint repair"
electrical_specialist: "Specialised in auto-electrical diagnostics"
specialisations:
values:
engine, transmission, suspension, brakes, ac_system, electrical,
body_paint, accident_repair, ev_specialist
finding.severity:
values:
advisory: "Note for future, no action needed now"
recommended: "Should fix in next 6 months"
required_for_safety: "Must fix before safe to drive"
immediate: "Vehicle should not leave workshop without this fix"
line_item.necessity:
values:
advisory: "Optional, future consideration"
recommended: "Should be done with this repair for value"
required_for_safety: "Must be done; safety implication"
mandatory_for_repair: "Cannot complete the declared issue fix without this"
line_item.category:
values:
labour: "Mechanic time"
part: "Replaced part"
consumable: "Oil, fluid, gasket, etc."
sublet: "Sub-contracted work (e.g. machining at external shop)"
evidence.type:
values:
obd_code: "OBD-II fault code with description"
photo: "Photograph of the issue"
video: "Video walkthrough"
sensor_reading: "Readout from diagnostic equipment"
advisor_note: "Service advisor's written observation"
payment_due_at:
values:
50_percent_now_balance_on_pickup: "Half up-front, balance on pickup (common for parts-heavy jobs)"
on_pickup: "Full payment when vehicle handed back"
on_completion: "Full payment after pickup confirmed by user"
insurance_cashless: "Insurance settles directly with partner"
SECTION 7 — TTBS DIMENSIONS
TIME (weight = 0.15):
signals_used:
- capacity.next_diagnostic_slot
- capacity.typical_repair_turnaround_days.median
- distance_from_user_km
weighting:
diagnostic_speed: 0.40
repair_speed: 0.40
distance: 0.20
user_band_handling:
fast: prefer quickest diagnostic + shortest turnaround
balanced: standard
flexible: any in window (the common case for major service)
TASTE (weight = 0.20):
signals_used:
- workshop_type matching user preference (authorised_only=true filters non-OEM out)
- specialisations matching issue.category
- chain familiarity (DNA)
weighting:
type: 0.40
specialisation_match: 0.45
familiarity: 0.15
user_band_handling: standard
BUDGET (weight = 0.25):
signals_used:
- estimated_cost_range.low_inr to high_inr midpoint
- diagnostic.diagnostic_fee_inr (negative if waived_if_repair=true)
- capacity.loaner_per_day_inr (factored if user requires loaner)
weighting:
cost_range: 0.65
diagnostic_fee_net: 0.20
loaner: 0.15
user_band_handling:
ok: prefer cheapest within max_acceptable_cost_inr
good: balance cost vs warranty + redo_rate
great: prefer OEM-authorised + low redo_rate even at premium
SAFETY (weight = 0.40):
signals_used:
- ratings.redo_rate_pct_last_90d (lower = better; weighted heavily)
- accreditations
- warranty.parts_warranty_months
- warranty.labour_warranty_months
- diagnostic.diagnostic_report_includes (more evidence types = higher safety score)
weighting:
redo_rate: 0.35
accreditations: 0.20
warranty: 0.25
diagnostic_quality: 0.20
user_band_handling:
fast: relax warranty floor
balanced: standard
flexible: prioritise lowest redo_rate workshops even at higher cost / longer wait
SECTION 8 — COMPLETION CONTRACT
The major-service intent has TWO completion events:
(a) Diagnostic completed — partner POSTs once when DiagnosticReport is finalised (status="diagnostic_completed"), even if user hasn't approved repair yet. This closes the diagnostic phase of CPRI.
(b) Repair completed — partner POSTs again when vehicle is handed back (status="completed" or terminal failure). This is the billable CPC event.
POST /api/v1/cpc/mcp_provider/<your_partner_id>
Body (repair completion):
{
"intent": "auto.book_major_service",
"external_id": "<repair_id>",
"request_id": "<request_id>",
"diagnostic_id": "<diagnostic_id>",
"amount_inr": 42000, // NET — labour + supplier-margin on parts + sublet markup partner keeps
"gst_inr": 7560, // government — excluded
"tips_inr": 0,
"pass_through_inr": 0, // any third-party sublet partner doesn't keep
"closed_at": "2026-05-20T16:00:00+05:30",
"status": "completed", // STRICT ENUM: completed | cancelled_by_user | cancelled_by_partner | partial_repair | aborted_post_diagnostic
"issue_category": "engine_repair",
"approved_line_items_count": 7,
"declined_line_items_count": 2,
"insurance_settled": false,
"warranty_card_issued": true
}
HMAC, 5-min replay, NET-only commission base. Locked.
SECTION 9 — WIDGET
MajorServiceWidget (planned). Renders diagnostic report inline; user approves/declines line items per-item.
Field mapping:
- MajorServiceWorkshop.name → header
- MajorServiceWorkshop.workshop_type + distance_from_user_km → subline 1
- MajorServiceWorkshop.capacity.typical_repair_turnaround_days.median + loaner_vehicle_available → subline 2
- MajorServiceWorkshop.estimated_cost_range.low/high_inr → "₹40K–₹1.2L" range row
- MajorServiceWorkshop.ratings.redo_rate_pct_last_90d → "Redo rate: X%" pill (color-coded; lower=green)
- MajorServiceWorkshop.warranty.parts/labour → warranty pill
Post-diagnostic:
- DiagnosticReport.findings rendered as expandable cards with evidence (photo/video/OBD)
- DiagnosticReport.recommended_line_items rendered as approve/decline list
- DiagnosticReport.totals updates live as user toggles items
SECTION 10 — CACHING POLICY
| Call | TTL | Rationale |
|---|---|---|
search_major_service_workshops |
120s | Major-service slot churn is slow |
create_diagnostic_appointment |
NO CACHE | Idempotent by request_id |
get_diagnostic_report_and_quote |
5min | Quote validity is anchored to quote_validity_until anyway |
approve_and_book_repair |
NO CACHE | Idempotent by request_id |
cancel_appointment |
NO CACHE | — |
| Workshop static metadata (accreditations, specialisations) | 24h | Static |
SECTION 11 — ERROR CODES
| Code | HTTP | Meaning | Retry |
|---|---|---|---|
INVALID_REQUEST |
400 | Payload malformed | No |
INVALID_AUTH |
401 | Bad creds | No |
RATE_LIMITED |
429 | Throttle | 1, 2s |
INTERNAL_ERROR |
500 | Partner failure | 2, exp |
IDEMPOTENCY_VIOLATION |
409 | request_id reused | No |
SIGNATURE_INVALID |
401 (webhook) | HMAC fail | No |
NO_SLOTS_IN_WINDOW |
200 (empty) | Valid, no diagnostic slots in window | n/a |
ISSUE_OUT_OF_SCOPE |
422 | Partner cannot handle this issue.category | No |
VEHICLE_NOT_SERVICEABLE |
422 | Make/model/year/EV outside partner catalog | No |
QUOTE_EXPIRED |
410 (approve) | quote_validity_until passed | No; UI re-quotes |
LOANER_UNAVAILABLE |
422 (create or approve) | Loaner required but partner can't provide on that date | No (partner may offer alternate date) |
INSURANCE_CLAIM_REJECTED |
422 (approve) | Insurance pre-approval failed; cashless not possible | No (UI surfaces, user picks payment path) |
MID_REPAIR_SCOPE_EXPANSION |
200 (out-of-band; partner POSTs notification to TOMO) | Additional findings post-approval requiring user re-approval | TOMO surfaces to user; not a retry pattern |
CANCELLATION_FEE_DUE |
200 (cancel) | Non-zero fee returned | n/a |
SECTION 12 — SANDBOX → PRODUCTION CHECKLIST
[ ] All five tools implemented; shapes per §5
[ ] At least 3 workshops covering different specialisations (engine, transmission, ac, electrical)
[ ] estimated_cost_range.low/high_inr returned with semantics string explaining the range
[ ] DiagnosticReport.findings include real evidence (OBD scan, photo, video) — not placeholder
[ ] DiagnosticReport.recommended_line_items each linked to a finding_id (no orphan upsells)
[ ] All controlled vocabularies respected
[ ] HMAC signing verified on both diagnostic_completed and repair_completion CPC webhooks
[ ] amount_inr is NET in both webhook events
[ ] No forbidden fields in any responses
[ ] SLA p95 met: search ≤2000ms, create_diagnostic ≤4000ms, get_report ≤1800ms, approve_repair ≤5000ms
[ ] Idempotency tested
[ ] Loaner vehicle workflow tested (when loaner_required=true returns loaner_arranged=true OR LOANER_UNAVAILABLE)
[ ] Insurance cashless workflow tested (when insurance_claim_intended=true)
[ ] Mid-repair scope expansion event tested (user re-approval gate works)
[ ] redo_rate_pct_last_90d field computed from real data (not flat marketing value)
[ ] Compliance docs: GSTIN, OEM authorisation (when claimed), specialist certifications, privacy policy URL
[ ] Service advisor reachable during work-hours; advisor name not generic
SECTION 13 — ANTI-FABRICATION RULES
RULE 1: No paid_placement / ad / kickback. Single occurrence rejects response.
In major-service especially harmful (high-cost decisions).
RULE 2: estimated_cost_range.low_inr to high_inr must reflect realistic
bounds for the issue.category + vehicle make/model/year. Padded
ranges to look competitive at the bottom but inflate at the top
are forbidden. TOMO cross-checks via actual CPC amount_inr
distribution per workshop.
RULE 3: DiagnosticReport.findings MUST be evidence-backed. Each finding
must have ≥1 evidence item (photo / video / OBD / sensor reading
/ advisor note). Findings without evidence are rejected by TOMO ingest.
RULE 4: recommended_line_items must each link to a finding_id. Orphan
line items (recommended without an underlying finding) are
rejected. This prevents upselling unrelated work.
RULE 5: line_item.necessity must be honest. Marking advisory items as
required_for_safety or mandatory_for_repair to scare the user
into approving is forbidden. TOMO samples user post-repair
questionnaires; sustained deviation flags review.
RULE 6: ratings.redo_rate_pct_last_90d must be computed from real return
visits within 90 days for the SAME issue.category. Partners
cannot mask redo rate by reclassifying returns under different
categories. TOMO maintains its own redo-rate ledger from CPC
timestamps.
RULE 7: warranty.parts_warranty_months and labour_warranty_months MUST
be honoured. If partner declines a warranty claim on a TOMO-routed
repair (verified via user dispute), that is a suspension trigger.
RULE 8: accreditations claims (iso_9001, oem_certified, body_shop_certified)
require uploaded certificates during compliance review.
RULE 9: insurance_handling.cashless_network_partner_for[] must reflect
real network agreements with named insurers. Cannot claim
cashless and then bill direct.
RULE 10: AI-generated workshop / vehicle / damage photos forbidden.
All imagery must be real and from current operations.
RULE 11: Mid-repair scope expansions must include new findings + evidence
and re-trigger user approval. Bypassing the re-approval gate
(e.g. just adding line items to invoice) is grounds for
immediate suspension.
RULE 12: No "Top Pick" / "TOMO Recommended" badges. Source-blind TTBS only.
RULE 13: artificial_urgency_text forbidden in any field. Severity-based
language ("required_for_safety", "immediate") is permitted only
when the finding is genuinely safety-critical. Crying-wolf on
severity is grounds for review.
VERSION HISTORY
v1.0.0 — 2026-05-11 — Initial spec. NET commission base in §8. Safety-dominant
TTBS (0.40) — appropriate for major repairs where mis-done
work has serious consequences.