Intent Spec Template — TOMO Partner Integration
This is the canonical template every TOMO intent specification follows. It is duplicated per-intent under docs/intents/<domain>.<intent>.md and filled in completely.
Authoring rule (locked 2026-05-09 by founder): Every field is REQUIRED. There is no "optional." If a partner cannot surface a field, that partner cannot list that intent on TOMO. TOMO Intelligence requires complete signal — incomplete listings are not a soft choice, they are a rejection condition.
This is harder for partners than industry-standard contracts. That is intentional. TOMO sets the bar; partners that meet it deliver users a maximum-information experience.
REQUIRED SECTIONS PER INTENT
Every <domain>.<intent>.md file MUST contain these 13 sections, in order, with full depth.
1. INTENT IDENTITY
2. NATURAL LANGUAGE COVERAGE — what user phrasings classify into this intent
3. INPUT — exact JSON shape TOMO sends to the provider
4. PROVIDER TOOLS — what the partner MUST implement
5. RESPONSE SHAPE — every field in every object the partner returns
6. CONTROLLED VOCABULARIES — fixed enums, no free text
7. TTBS DIMENSIONS — how TOMO ranks across providers source-blind
8. COMPLETION CONTRACT — what the partner POSTs when intent closes
9. WIDGET — which TOMO chat widget renders the result
10. CACHING POLICY — TTLs per call type
11. ERROR CODES — exhaustive list, no free-text errors
12. SANDBOX → PRODUCTION CHECKLIST — what reviewers verify
13. ANTI-FABRICATION RULES — forbidden fields, behaviors, signals
SECTION 1 — INTENT IDENTITY
INTENT NAMESPACE: <domain> // mobility | food | travel | etc.
INTENT NAME: <verb_object> // book_hotel | order_delivery | book_ride
FULL ID: <namespace>.<name> // travel.book_hotel
VERSION: v1.0.0
STATUS: draft | live | deprecated
LAST UPDATED: YYYY-MM-DD
TTBS WEIGHTS: time, taste, budget, safety // sum to 1.0; locked per domain
SECTION 2 — NATURAL LANGUAGE COVERAGE
Three lists with at least 8 entries each:
CLASSIFIES IN — user phrasings that route to this intent CLASSIFIES OUT — borderline NO — phrasings that look similar but go elsewhere MULTI-INTENT TRIGGERS — phrasings that fan out to this AND another intent
This section is read by the SLM training pipeline. It directly influences automobnxt-slm/dataset/*.jsonl and services/engine/intentClassifier.ts.
SECTION 3 — INPUT (TOMO → PROVIDER)
Full JSON request body shape. Every field documented in a table:
| Field | Type | Constraint | Notes |
|---|
Field constraints use these markers:
REQUIRED— must be present + non-nullSTRICT ENUM— must match controlled vocabulary in §6ISO_DATE— ISO 8601 date (YYYY-MM-DD)ISO_DATETIME— ISO 8601 datetime with timezone offsetINR_INTEGER— whole rupees, no decimals, no formattingRFC_3066_LOCALE— e.g.en-INISO_3166_2— country code, alwaysINfor v1
Anti-fabrication preamble (every intent): "TOMO will never inject paid_placement signals, urgency text, or commission-influenced fields into this payload. Provider may not reject the request based on TOMO's commission rate."
SECTION 4 — PROVIDER TOOLS
For each tool the partner must implement, document:
TOOL NAME: <verb_object>
PURPOSE: one-sentence description
INPUT SHAPE: reference to §3 or sub-shape
OUTPUT SHAPE: reference to §5
SLA: p50, p95, p99 latencies
RATE LIMIT: requests TOMO will send per (user, partner)
IDEMPOTENCY: how the partner deduplicates retries
RETRY: what TOMO does on what error code
A typical commerce intent has 3-4 tools: search_*, get_*, create_*, optionally cancel_*.
SECTION 5 — RESPONSE SHAPE
The big one. Every field of every returned object. Format:
ObjectName:
field_name:
type: string | int | float | boolean | enum<...> | object | array<...>
constraint: REQUIRED | STRICT ENUM | URL | ISO_DATETIME | INR_INTEGER | etc.
semantics: one-sentence meaning
example: "Taj West End"
null_handling: REJECTED # always — no nulls allowed under strict-required regime
Authoring rule for §5: under strict-required, every field listed MUST be in every response. Partners that don't have the data must collect it, derive it, or contract a third-party data provider. There is no "skip this if you don't have it" path.
If a field is genuinely impossible for any partner (e.g., a hotel can't have a "trip distance" field — that's a ride property), the field doesn't appear in the spec at all.
Forbidden fields are listed at the end of §5 explicitly so partner reviewers can grep for them in test responses.
SECTION 6 — CONTROLLED VOCABULARIES
Every enum field gets a fixed list. Free text is forbidden where structure is possible.
Format:
field_path:
values:
value1: "human-readable description"
value2: "..."
resolution_order: how partners map their internal vocabulary to ours
Vocabulary changes require a spec version bump (v1.0.0 → v1.1.0) so partners get a heads-up.
SECTION 7 — TTBS DIMENSIONS
Four sub-sections. For each:
TIME:
signals_used: [field paths from §5]
weighting: how each signal contributes
user_band_handling: how user's "fast vs flexible" preference shifts ranking
TASTE:
signals_used: [...]
weighting: ...
user_band_handling: ...
BUDGET:
signals_used: [...]
weighting: ...
user_band_handling: ok / good / great spectrum
SAFETY:
signals_used: [...]
weighting: ...
user_band_handling: ...
Per-domain weights are locked in server/lib/domain-agent-map.ts. The intent spec restates them for clarity.
User can shift via DNA-weighting (silent personalization). Partners cannot influence weights through any spec field.
SECTION 8 — COMPLETION CONTRACT
The HMAC-signed POST partner sends to /api/v1/cpc/mcp_provider/{tomo_partner_id} when the intent closes (success or terminal failure).
Mandatory fields, signing scheme, replay window, retry behavior. Locked in server/routes/cpc.ts + server/lib/cpcWebhookClient.ts.
SECTION 9 — WIDGET
The TOMO chat widget that renders this intent's results. Reference to:
- Source file:
src/widgets/types.ts - Type:
<WidgetName>Payload - Rendering rules: how Listing fields map to widget fields
Widget contracts are locked. Partners do not influence widget design.
SECTION 10 — CACHING POLICY
| Call | TTL | Rationale |
|---|
TTLs balance partner load vs data freshness. Pricing/availability calls cache short (30-60s). Static metadata (descriptions, photos) caches long (5-60min). Failure responses NEVER cache.
SECTION 11 — ERROR CODES
Exhaustive table. Free-text errors forbidden — every error must map to a code from this list.
| Code | HTTP Status | Meaning | TOMO retry behavior |
|---|
Universal codes (apply to every intent):
INVALID_REQUEST— payload malformedRATE_LIMITED— partner-side throttleINTERNAL_ERROR— partner-side failureINVALID_AUTH— bad credentialsSIGNATURE_INVALID— HMAC verification failed (CPC webhook only)
Intent-specific codes documented per intent.
SECTION 12 — SANDBOX → PRODUCTION CHECKLIST
Concrete, testable list. Reviewer (TOMO admin) ticks each before flipping status: live.
[ ] All required input fields validated
[ ] All response fields populated with real data (no test fixtures)
[ ] Controlled vocabularies respected (no free-text drift)
[ ] HMAC signing verified on test CPC webhook
[ ] Forbidden fields absent from all responses
[ ] SLA latency p95 met during 100-call sandbox test
[ ] Compliance docs uploaded and approved (intent-specific list)
[ ] Privacy policy URL live and accessible
[ ] Customer support contact verified (email + phone)
Intent-specific items append to this list.
SECTION 13 — ANTI-FABRICATION RULES
The hardest section. Rules that protect users from partner manipulation. Each rule is enforced at TOMO ingest:
RULE: No paid_placement_score, ad_bid, sponsored_rank, promotion_priority,
kickback_amount, referral_fee_kickback, _partner_revenue_share fields
anywhere in any response. TOMO ingest scans for these field names AND
semantic equivalents (lowercased, snake_case'd). Listing rejected if found.
RULE: No artificial_urgency_text ("Only 1 left! Act fast!") unless backed
by a numeric inventory.rooms_left field with value <= 3. Partner
cannot fabricate scarcity.
RULE: review_score values must be unrounded floats from raw user reviews.
No "rounded up to 4.5 for marketing" — TOMO checks recent scores
against historical distribution.
RULE: ... (intent-specific rules per spec)
VERSION HISTORY
Per-intent file maintains a changelog:
v1.0.0 — 2026-05-09 — Initial spec
v1.1.0 — YYYY-MM-DD — Added <field>; partners must update by YYYY-MM-DD
v2.0.0 — YYYY-MM-DD — Breaking change: <description>; partners must re-verify
Major version bumps require all live partners to re-verify within 30 days or get suspended.
HOW PARTNERS CONSUME THIS
- Read
_TEMPLATE.mdonce — understand the shape - Read the specific
<domain>.<intent>.mdfor each intent they want to serve - Implement the tools in §4 returning the shape in §5
- Test against TOMO sandbox (creds issued at
/business/tier1signup) - POST signed CPC webhook from §8 on every closed intent
- Submit to TOMO admin for production review (§12)
- Get
status: liveflag — start receiving traffic
No phone calls. No human onboarding. The spec is the contract.
HOW TOMO CONSUMES THIS
domain-agent-map.tsreferences intent IDs from this catalog- SLM training data (
automobnxt-slm/dataset/*.jsonl) generated from §2 phrasings intentClassifier.tsroutes user input → intent ID- Provider's manifest declares which intent IDs they serve
- Orchestrator dispatches in parallel to all enabled providers serving the intent
- Response merger validates against §5 schema; rejects malformed listings
- TTBS scorer uses §7 to rank source-blind
- Widget from §9 renders the merged result
- CPC ledger validates §8 webhook on close
- Admin reviewer uses §12 checklist to gate production access
This template is the contract for the contract. Every intent doc is graded against this template before it's added to the live catalog.