openapi: 3.1.0
info:
  title: Compass Food Technologies DaaS API
  version: 1.0.0
  description: |
    Compass DaaS public API v1. Restaurant discovery, enrichment, and dietary
    fit decisioning backed by deterministic VeganScore v3 and the locked
    30-code reason taxonomy.

    This spec mirrors the locked API contract at
    `docs/plans/compass-daas-api-contract-v0-2026-04-30.md` (v0.2.5).
    Schema changes here MUST be reflected in the contract first.
  contact:
    name: Compass Food Technologies
    url: https://compassfoodtechnologies.com
  license:
    name: Proprietary
    identifier: LicenseRef-Proprietary
servers:
  - url: https://api.compassfoodtechnologies.com
    description: Production (custom domain live)
  - url: https://daas-api-veganmapai-1a8b7.a.run.app
    description: Staging
security:
  - CompassApiKey: []
x-runtime-limitations:
  malformedApplicationJson: |
    When the request `Content-Type` is `application/json` and the body is not valid JSON, the request may be rejected by the Firebase / Google Cloud Functions runtime before it reaches the Compass API. In that case, the response does not follow the Compass `application/problem+json` envelope. Clients SHOULD send well-formed JSON. Compass guarantees the `application/problem+json` envelope only for errors raised by the Compass API itself.
x-internal-route-runbook: docs/ops/compass-daas-internal-routes-2026-05-08.md
tags:
  - name: public
    description: Public health and dataset introspection
  - name: search
    description: Natural-language restaurant discovery
  - name: enrich
    description: Restaurant matching and enrichment
  - name: decision
    description: Conservative dietary fit decisions
  - name: changes
    description: Enterprise change feed
paths:
  /v1/health:
    get:
      tags: [public]
      summary: Public API health check
      description: |
        Returns a lightweight public health response for uptime checks and
        deployment verification. This endpoint is intentionally unauthenticated.
      operationId: getHealth
      security: []
      responses:
        '200':
          description: API health status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HealthResponse'
              example:
                status: ok
                version: 1.0.0
                timestamp: '2026-05-04T09:30:00.000Z'
  /v1/metadata:
    get:
      tags: [public]
      summary: Public dataset metadata
      description: |
        Returns public, cacheable dataset metadata and capability discovery
        for Compass DaaS. The restaurant total reflects the searchable corpus
        and the remaining fields summarize current deterministic scoring
        coverage, country coverage, supported enum values, available regions,
        and model versions for verification and agent integrations.
      operationId: getMetadata
      security: []
      responses:
        '200':
          description: Public dataset metadata
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MetadataResponse'
              example:
                datasetVersion: '2026-05-04'
                totalRestaurants: 374041
                totalWithVeganScore: 360000
                lastUpdated: '2026-05-04T09:30:00.000Z'
                coverageByCountry:
                  US: 374041
                averageVeganScore: 72
                scoringVersion: v3.0-deterministic
                cuisineDistribution:
                  Vegan: 18250
                  Italian: 14600
                api_version: v1
                supported_enums:
                  diets:
                    - strict_vegan
                    - vegetarian
                    - pescatarian
                    - gluten_free
                    - halal
                    - kosher
                    - low_fodmap
                  decisions: [fit, not_fit, unknown]
                  confidences: [high, medium, low]
                  risk_flags:
                    - cross_contamination_risk
                    - limited_evidence
                    - stale_data
                    - third_party_unverified
                    - user_report_only
                    - language_barrier
                  evidence_tiers: [A, B]
                  evidence_types:
                    - menu_item
                    - review_signal
                    - external_source
                    - user_report
                    - restaurant_declared
                available_regions:
                  - us
                model_versions:
                  scoring: v3.0-deterministic
                  embedding_model: voyage-4-large-512d-v1
        '304':
          description: Cached metadata is still current for the supplied ETag
        '500':
          $ref: '#/components/responses/InternalError'
  /v1/search:
    post:
      tags: [search]
      summary: Natural-language restaurant search
      description: |
        Returns ranked restaurant results for a free-text query. Embeds the
        query with Voyage `voyage-4-lite` 512d and searches the Qdrant
        `restaurants_v2` collection. Conservative `unknown` decisions appear
        in `match_for_profile` when evidence is insufficient. When `location`
        is supplied, Compass returns only results with coordinates inside the
        requested radius; if `radius_m` is omitted, the default radius is
        5,000 meters.
      operationId: searchRestaurants
      parameters:
        - $ref: '#/components/parameters/CompassMode'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SearchRequest'
      responses:
        '200':
          description: Search results (rich or fast mode)
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/XRateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/XRateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/XRateLimitReset'
            X-RateLimit-IP-Remaining:
              $ref: '#/components/headers/XRateLimitIPRemaining'
            X-RateLimit-IP-Reset:
              $ref: '#/components/headers/XRateLimitIPReset'
            X-Usage-ThisMonth:
              $ref: '#/components/headers/XUsageThisMonth'
            X-Usage-Limit:
              $ref: '#/components/headers/XUsageLimit'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/UpstreamUnavailable'
  /v1/restaurants/{compass_place_id}:
    get:
      tags: [search]
      summary: Get one restaurant by Compass restaurant ID
      description: |
        Returns the legacy DaaS restaurant detail payload for a stable
        `compass_place_id` UUID or the public `compass_id` returned by Search
        and Enrich. This route remains public in v1 for direct record
        inspection after search/enrichment workflows. Responses are tier-filtered
        and do not expose Google Places, Foursquare, pipeline, raw review, or
        provider-cost fields.
      operationId: getRestaurantByCompassPlaceId
      parameters:
        - name: compass_place_id
          in: path
          required: true
          schema:
            type: string
          description: Stable `compass_place_id` UUID or public `compass_id` returned by Search/Enrich.
      responses:
        '200':
          description: Restaurant detail payload
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/XRateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/XRateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/XRateLimitReset'
            X-RateLimit-IP-Remaining:
              $ref: '#/components/headers/XRateLimitIPRemaining'
            X-RateLimit-IP-Reset:
              $ref: '#/components/headers/XRateLimitIPReset'
            X-Usage-ThisMonth:
              $ref: '#/components/headers/XUsageThisMonth'
            X-Usage-Limit:
              $ref: '#/components/headers/XUsageLimit'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RestaurantLookupResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/RestaurantNotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
  /v1/changes:
    get:
      tags: [changes]
      summary: Enterprise restaurant change feed
      description: |
        Returns restaurant create/update/delete events after an ISO 8601
        `since` timestamp. The endpoint is part of the public v1 contract but
        requires Enterprise tier at runtime.
      operationId: getRestaurantChanges
      parameters:
        - name: since
          in: query
          required: true
          schema:
            type: string
            format: date-time
          description: Include changes after this timestamp. Maximum lookback is 30 days.
        - name: type
          in: query
          required: false
          schema:
            type: string
            enum: [created, updated, deleted]
          description: Optional change-type filter.
        - name: page
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            default: 1
        - name: pageSize
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
      responses:
        '200':
          description: Change feed page
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/XRateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/XRateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/XRateLimitReset'
            X-RateLimit-IP-Remaining:
              $ref: '#/components/headers/XRateLimitIPRemaining'
            X-RateLimit-IP-Reset:
              $ref: '#/components/headers/XRateLimitIPReset'
            X-Usage-ThisMonth:
              $ref: '#/components/headers/XUsageThisMonth'
            X-Usage-Limit:
              $ref: '#/components/headers/XUsageLimit'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChangesResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/EnterpriseOnly'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
  /v1/enrich/restaurant:
    post:
      tags: [enrich]
      summary: Match and enrich a restaurant record
      description: |
        Matches a customer-provided restaurant by direct `compass_id` lookup,
        or by `name + address` / `name + google_place_id` against the Compass
        index, and returns enrichment data. Not decision-bearing; no `decision`
        or `recommended_user_text`.
      operationId: enrichRestaurant
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EnrichRequest'
      responses:
        '200':
          description: Enrichment result (matched or unmatched)
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/XRateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/XRateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/XRateLimitReset'
            X-RateLimit-IP-Remaining:
              $ref: '#/components/headers/XRateLimitIPRemaining'
            X-RateLimit-IP-Reset:
              $ref: '#/components/headers/XRateLimitIPReset'
            X-Usage-ThisMonth:
              $ref: '#/components/headers/XUsageThisMonth'
            X-Usage-Limit:
              $ref: '#/components/headers/XUsageLimit'
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/EnrichResponseMatched'
                  - $ref: '#/components/schemas/EnrichResponseUnmatched'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          $ref: '#/components/responses/MatchFailed'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
  /v1/decision/restaurant-fit:
    post:
      tags: [decision]
      summary: Conservative dietary fit decision
      description: |
        Returns `fit | not_fit | unknown` for a (user_profile, restaurant)
        pair. `unknown` is the locked conservative posture when evidence is
        insufficient, conflicting, or stale (>180 days). `unknown` is never
        an error.
      operationId: decideRestaurantFit
      parameters:
        - $ref: '#/components/parameters/CompassMode'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DecisionRequest'
      responses:
        '200':
          description: Decision response
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/XRateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/XRateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/XRateLimitReset'
            X-RateLimit-IP-Remaining:
              $ref: '#/components/headers/XRateLimitIPRemaining'
            X-RateLimit-IP-Reset:
              $ref: '#/components/headers/XRateLimitIPReset'
            X-Usage-ThisMonth:
              $ref: '#/components/headers/XUsageThisMonth'
            X-Usage-Limit:
              $ref: '#/components/headers/XUsageLimit'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DecisionResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/RestaurantNotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  securitySchemes:
    CompassApiKey:
      type: apiKey
      in: header
      name: X-Compass-API-Key
      description: |
        API key issued at signup. Prefix is scoped:
        `cmp_test_` (Sandbox), `cmp_live_` (paid), `cmp_int_` (internal).
  parameters:
    CompassMode:
      name: X-Compass-Mode
      in: header
      required: false
      schema:
        $ref: '#/components/schemas/Mode'
      description: |
        Search response mode and Decision credit-cost selector:
        `fast` or `rich` (default).
  headers:
    RetryAfter:
      description: Seconds to wait before retrying after a per-minute or IP rate-limit response.
      schema:
        type: integer
        minimum: 1
      example: 60
    XRateLimitLimit:
      description: Monthly Compass credit quota limit for the key as a decimal string, or `unlimited` for Enterprise keys.
      schema:
        type: string
      examples:
        paid:
          value: '1000'
        enterprise:
          value: unlimited
    XRateLimitRemaining:
      description: Remaining monthly Compass credits after the current accepted request, as a decimal string, or `unlimited`.
      schema:
        type: string
      examples:
        paid:
          value: '999'
        enterprise:
          value: unlimited
    XRateLimitReset:
      description: ISO 8601 timestamp when the monthly API quota resets.
      schema:
        type: string
        format: date-time
      example: '2026-06-01T00:00:00.000Z'
    XRateLimitIPRemaining:
      description: Remaining requests in the current per-IP window.
      schema:
        type: integer
        minimum: 0
      example: 299
    XRateLimitIPReset:
      description: ISO 8601 timestamp when the current per-IP rate-limit window resets.
      schema:
        type: string
        format: date-time
      example: '2026-05-07T13:05:30.000Z'
    XUsageThisMonth:
      description: Compass credits used by the key in the current monthly quota window.
      schema:
        type: string
      example: '2'
    XUsageLimit:
      description: Monthly usage limit for the key as a decimal string, or `unlimited`.
      schema:
        type: string
      examples:
        paid:
          value: '1000'
        enterprise:
          value: unlimited
  schemas:
    Diet:
      type: string
      description: |
        Accepted user-profile preference input. Launch-strength evidence is
        strongest for vegan and vegan-friendly workflows; safety-sensitive or
        religious-diet inputs are handled conservatively and do not imply public
        certification/free-from facts.
      enum:
        - strict_vegan
        - vegetarian
        - pescatarian
        - gluten_free
        - halal
        - kosher
        - low_fodmap
    Decision:
      type: string
      enum: [fit, not_fit, unknown]
    Confidence:
      type: string
      enum: [high, medium, low]
    Mode:
      type: string
      enum: [fast, rich]
      default: rich
    RiskFlag:
      type: string
      enum:
        - cross_contamination_risk
        - limited_evidence
        - stale_data
        - third_party_unverified
        - user_report_only
        - language_barrier
    EvidenceTier:
      type: string
      enum: [A, B]
    EvidenceType:
      type: string
      enum:
        - menu_item
        - review_signal
        - external_source
        - user_report
        - restaurant_declared
    EvidenceWeight:
      type: string
      enum: [primary, supporting]
    ParaphraseMethod:
      type: string
      enum: [automatic, manual, none]
    ReasonCode:
      type: string
      description: |
        Locked reason code taxonomy v0.2.2 (30 codes). Implementation MUST
        only emit values from this list. New codes require an explicit
        contract revision.
      enum:
        # 7.1 Vegan-related (6)
        - VEGAN_MENU_CONFIRMED
        - VEGAN_OPTIONS_MENTIONED
        - NO_VEGAN_EVIDENCE_FOUND
        - VEGETARIAN_ONLY_NOT_STRICT_VEGAN
        - VEGAN_MENU_FULL_RESTAURANT
        - VEGAN_FRIENDLY_PARTIAL
        # 7.2 Cross-contamination (5)
        - FRYER_CONTAMINATION_RISK
        - SHARED_GRILL_RISK
        - SHARED_PREP_SURFACE_RISK
        - DEDICATED_VEGAN_PREP_CONFIRMED
        - CROSS_CONTAMINATION_UNKNOWN
        # 7.3 Allergen (7)
        - DAIRY_PRESENT_IN_RELEVANT_DISHES
        - NUT_PRESENT_IN_RELEVANT_DISHES
        - NUT_ALLERGY_RISK_UNKNOWN
        - GLUTEN_RISK_HIGH
        - GLUTEN_FREE_OPTIONS_AVAILABLE
        - ALLERGEN_INFO_UNAVAILABLE
        - DECLARED_ALLERGEN_FREE
        # 7.4 Source quality (8)
        - MENU_OUTDATED
        - REVIEW_SIGNAL_POSITIVE
        - REVIEW_SIGNAL_NEGATIVE
        - REVIEW_SIGNAL_CONFLICTING
        - SOURCE_CONFIDENCE_LOW
        - SOURCE_CONFIDENCE_HIGH
        - RESTAURANT_VERIFICATION_RECOMMENDED
        - DATA_FRESHNESS_POOR
        # 7.5 Behavior (4)
        - INSUFFICIENT_EVIDENCE
        - HIGH_CONFIDENCE_DECISION
        - EDGE_CASE_FLAGGED
        - USER_PROFILE_AMBIGUOUS
    SourceFreshness:
      type: object
      required:
        [oldest_signal_age_days, newest_signal_age_days, recommended_refresh]
      properties:
        oldest_signal_age_days:
          type: integer
          minimum: 0
        newest_signal_age_days:
          type: integer
          minimum: 0
        recommended_refresh:
          type: boolean
    Evidence:
      type: object
      required: [evidence_id, type, source, weight, tier]
      properties:
        evidence_id:
          type: string
        type:
          $ref: '#/components/schemas/EvidenceType'
        source:
          type: string
          format: uri
        excerpt:
          type: string
          maxLength: 500
        weight:
          $ref: '#/components/schemas/EvidenceWeight'
        tier:
          $ref: '#/components/schemas/EvidenceTier'
        paraphrase_method:
          $ref: '#/components/schemas/ParaphraseMethod'
    SearchUserProfile:
      type: object
      additionalProperties: false
      properties:
        diet:
          $ref: '#/components/schemas/Diet'
        exclude_cross_contamination:
          type: boolean
        dietary_rules:
          type: array
          items:
            type: string
    DecisionUserProfile:
      type: object
      additionalProperties: false
      description: |
        Decision-only profile input for supported dietary preferences and
        stricter cross-contamination handling.
      properties:
        diet:
          $ref: '#/components/schemas/Diet'
        exclude_cross_contamination:
          type: boolean
        dietary_rules:
          type: array
          items:
            type: string
    Address:
      type: object
      required: [street, city, state, postal_code, country]
      properties:
        street:
          type: string
          nullable: true
        city:
          type: string
          nullable: true
        state:
          type: string
          nullable: true
        postal_code:
          type: string
          nullable: true
        country:
          type: string
          nullable: true
    Coordinates:
      type: object
      required: [lat, lng]
      properties:
        lat:
          type: number
          format: double
          nullable: true
        lng:
          type: number
          format: double
          nullable: true
    VeganScoreDimension:
      type: object
      required: [score, weight, confidence]
      properties:
        score:
          type: number
          nullable: true
          minimum: 0
          maximum: 100
        weight:
          type: number
          minimum: 0
          maximum: 1
        confidence:
          $ref: '#/components/schemas/Confidence'
        evidence_ids:
          type: array
          items:
            type: string
    VeganScore:
      type: object
      required: [overall, scoring_version]
      properties:
        overall:
          type: number
          nullable: true
          minimum: 0
          maximum: 100
        scoring_version:
          type: string
          nullable: true
        dimensions:
          type: object
          properties:
            D1_vegan_coverage:
              $ref: '#/components/schemas/VeganScoreDimension'
            D2_vegan_quality:
              $ref: '#/components/schemas/VeganScoreDimension'
            D3_ingredient_clarity:
              $ref: '#/components/schemas/VeganScoreDimension'
            D4_cross_contamination:
              $ref: '#/components/schemas/VeganScoreDimension'
            D5_staff_knowledge:
              $ref: '#/components/schemas/VeganScoreDimension'
            D6_restaurant_quality:
              $ref: '#/components/schemas/VeganScoreDimension'
        reasoning:
          type: string
    DietaryProfile:
      type: object
      description: |
        Public restaurant dietary facts supported by the launch evidence model.
        Compass does not expose halal/kosher certification or allergen-safe
        free-from facts in the public launch response contract.
      required:
        - fully_vegan
        - vegan_friendly
      properties:
        fully_vegan:
          type: boolean
          nullable: true
        vegan_friendly:
          type: boolean
          nullable: true
    RestaurantBase:
      type: object
      required:
        - compass_id
        - name
        - address
        - coordinates
        - vegan_score
        - dietary_profile
        - cuisine_types
        - last_verified_at
        - last_evaluated_at
      properties:
        compass_id:
          type: string
          description: Equals the Firestore document ID. Stable across rescores.
        name:
          type: string
          nullable: true
        address:
          $ref: '#/components/schemas/Address'
        coordinates:
          $ref: '#/components/schemas/Coordinates'
        vegan_score:
          $ref: '#/components/schemas/VeganScore'
        dietary_profile:
          $ref: '#/components/schemas/DietaryProfile'
        cuisine_types:
          type: array
          items:
            type: string
        services:
          type: object
          additionalProperties:
            type: boolean
        last_verified_at:
          type: string
          format: date-time
          nullable: true
        last_evaluated_at:
          type: string
          format: date-time
          nullable: true
          description: When Compass last evaluated this restaurant for scoring and decision freshness.
        source_freshness:
          $ref: '#/components/schemas/SourceFreshness'
        evidence:
          type: array
          items:
            $ref: '#/components/schemas/Evidence'
    MatchForProfile:
      type: object
      description: |
        Evidence-aware fit guidance for the submitted user profile. `decision`
        remains one of `fit`, `not_fit`, or `unknown`; when evidence is weak,
        insufficient, stale, or conflicting, Compass downgrades apparent fits to
        conservative `unknown` with `verification_required: true`.
      required:
        - decision
        - confidence
        - reason_codes
        - risk_flags
        - verification_required
        - recommended_user_text
      properties:
        decision:
          $ref: '#/components/schemas/Decision'
        confidence:
          $ref: '#/components/schemas/Confidence'
        reason_codes:
          type: array
          items:
            $ref: '#/components/schemas/ReasonCode'
        risk_flags:
          type: array
          items:
            $ref: '#/components/schemas/RiskFlag'
        verification_required:
          type: boolean
        recommended_user_text:
          type: string
    SearchResult:
      allOf:
        - $ref: '#/components/schemas/RestaurantBase'
        - type: object
          properties:
            distance_m:
              type: number
              minimum: 0
              description: Distance from the requested location in meters. Present only when `location` is supplied and result coordinates are available.
            match_for_profile:
              $ref: '#/components/schemas/MatchForProfile'
    SearchRequest:
      type: object
      required: [query]
      properties:
        query:
          type: string
          minLength: 1
          maxLength: 500
          description: |
            Natural-language search query. Location-relative phrases such as
            `near me`, `nearby`, or `around me` require structured
            `location.lat` and `location.lng`; Compass does not infer customer
            location from IP, browser state, or query text alone.
        user_profile:
          $ref: '#/components/schemas/SearchUserProfile'
        location:
          type: object
          required: [lat, lng]
          properties:
            lat:
              type: number
              format: double
              minimum: -90
              maximum: 90
            lng:
              type: number
              format: double
              minimum: -180
              maximum: 180
            radius_m:
              type: integer
              minimum: 1
              maximum: 50000
              default: 5000
              description: |
                Search radius in meters. If omitted and the query includes an
                explicit numeric distance such as `5 miles`, `10 km`, or
                `500 meters`, Compass may infer `radius_m` from the text. An
                explicitly supplied `radius_m` always wins over text distance.
        limit:
          type: integer
          minimum: 1
          maximum: 50
          default: 10
        include_evidence:
          type: boolean
          default: true
    QueryInterpretation:
      type: object
      properties:
        diet_inferred:
          type: string
        cuisine_inferred:
          type: string
        dish_inferred:
          type: string
          nullable: true
          description: Dish target inferred from plain-text or metadata-style dish intent, when applicable.
        intent_inferred:
          type: string
          enum: [named, dish, cuisine, general]
          description: Best-effort query intent Compass used for search interpretation and ranking.
        target_inferred:
          type: string
          nullable: true
          description: Best-effort named, dish, or cuisine target inferred from the query.
        price_constraint:
          type: string
        location_inferred:
          type: string
          description: City, coordinate pair, or other location context inferred from structured input or compatibility-parsed query text.
        neighborhood_inferred:
          type: string
          description: Neighborhood name recognized from compatibility-parsed query text. This is interpretive context only and does not promise neighborhood-perfect filtering.
        radius_m:
          type: integer
          description: Radius in meters inferred from explicit query text, metadata-style text, or structured request fields.
        radius_m_inferred:
          type: boolean
          description: True when Compass inferred `radius_m` from text distance or metadata-style query text.
        radius_m_text_ignored:
          type: boolean
          description: True when text or metadata-style radius was present but structured `location.radius_m` won.
    HealthResponse:
      type: object
      required: [status, version, timestamp]
      properties:
        status:
          type: string
          enum: [ok]
        version:
          type: string
        timestamp:
          type: string
          format: date-time
    MetadataResponse:
      type: object
      required:
        - datasetVersion
        - totalRestaurants
        - totalWithVeganScore
        - lastUpdated
        - coverageByCountry
        - averageVeganScore
        - scoringVersion
        - cuisineDistribution
        - api_version
        - supported_enums
        - available_regions
        - model_versions
      properties:
        datasetVersion:
          type: string
          description: Dataset version date for the published searchable corpus.
        totalRestaurants:
          type: integer
          minimum: 0
          description: Current searchable restaurant count exposed by Compass.
        totalWithVeganScore:
          type: integer
          minimum: 0
          description: Restaurants with deterministic VeganScore coverage.
        lastUpdated:
          type: string
          format: date-time
          description: Timestamp for the current metadata snapshot. Restaurant and response freshness use last_evaluated_at on restaurant-bearing endpoints.
        coverageByCountry:
          type: object
          additionalProperties:
            type: integer
            minimum: 0
        averageVeganScore:
          type: number
          minimum: 0
          maximum: 100
        scoringVersion:
          type: string
        cuisineDistribution:
          type: object
          additionalProperties:
            type: integer
            minimum: 0
        api_version:
          type: string
          enum: [v1]
          description: Current public API version.
        supported_enums:
          type: object
          required:
            - diets
            - decisions
            - confidences
            - risk_flags
            - evidence_tiers
            - evidence_types
          description: Canonical enum values accepted and emitted by Compass.
          properties:
            diets:
              type: array
              items:
                $ref: '#/components/schemas/Diet'
            decisions:
              type: array
              items:
                $ref: '#/components/schemas/Decision'
            confidences:
              type: array
              items:
                $ref: '#/components/schemas/Confidence'
            risk_flags:
              type: array
              items:
                $ref: '#/components/schemas/RiskFlag'
            evidence_tiers:
              type: array
              items:
                $ref: '#/components/schemas/EvidenceTier'
            evidence_types:
              type: array
              items:
                $ref: '#/components/schemas/EvidenceType'
        available_regions:
          type: array
          minItems: 1
          description: Public region slugs available for the current launch.
          items:
            type: string
            enum: [us]
        model_versions:
          type: object
          required:
            - scoring
            - embedding_model
          description: Current production model/version stamps exposed for discovery.
          properties:
            scoring:
              type: string
              example: v3.0-deterministic
            evidence_builder:
              type: string
              description: Omitted until a canonical evidence-builder version exists.
            embedding_model:
              type: string
              example: voyage-4-large-512d-v1
    LegacyCoordinates:
      type: object
      required: [lat, lng]
      properties:
        lat:
          type: number
          format: double
        lng:
          type: number
          format: double
    LegacyVeganScore:
      type: object
      required: [overall, confidence, reasoning, scoringVersion]
      properties:
        overall:
          type: number
          minimum: 0
          maximum: 100
        breakdown:
          type: object
          properties:
            veganCoverage:
              type: number
            veganQuality:
              type: number
            ingredientClarity:
              type: number
            crossContamination:
              type: number
            staffKnowledge:
              type: number
            restaurantQuality:
              type: number
        confidence:
          $ref: '#/components/schemas/Confidence'
        confidenceScore:
          type: number
          minimum: 0
          maximum: 1
        reasoning:
          type: string
        scoringVersion:
          type: string
    LegacyDataFreshness:
      type: object
      required: [lastFullRefresh, overallFreshnessScore, freshnessLabel]
      properties:
        lastFullRefresh:
          type: string
          format: date-time
          nullable: true
        overallFreshnessScore:
          type: number
          minimum: 0
          maximum: 100
        freshnessLabel:
          type: string
          enum: [recent, stale, outdated]
    RestaurantLookupResponse:
      type: object
      required:
        - compass_place_id
        - name
        - address
        - city
        - state
        - zipCode
        - country
        - coordinates
        - veganScore
        - isChain
        - veganFriendly
        - isVegan
        - cuisineTypes
        - dataFreshness
      properties:
        compass_place_id:
          type: string
          format: uuid
        name:
          type: string
        address:
          type: string
        city:
          type: string
        state:
          type: string
        zipCode:
          type: string
        country:
          type: string
        coordinates:
          $ref: '#/components/schemas/LegacyCoordinates'
        veganScore:
          $ref: '#/components/schemas/LegacyVeganScore'
        isChain:
          type: boolean
        chainBrand:
          type: string
          nullable: true
        veganFriendly:
          type: boolean
        isVegan:
          type: boolean
        cuisine:
          type: string
          nullable: true
        cuisineTypes:
          type: array
          items:
            type: string
        primaryCategory:
          type: string
          nullable: true
        allCategories:
          type: array
          items:
            type: string
        dataFreshness:
          $ref: '#/components/schemas/LegacyDataFreshness'
        searxngData:
          type: object
          additionalProperties: true
        reviewAIData:
          type: object
          additionalProperties: true
        menuAIData:
          type: object
          additionalProperties: true
        nutritionProfile:
          type: object
          additionalProperties: true
        wineProfile:
          type: object
          additionalProperties: true
        wineScore:
          type: number
          nullable: true
    ChangeEntry:
      type: object
      required: [type, changedAt]
      properties:
        type:
          type: string
          enum: [created, updated, deleted]
        restaurant:
          $ref: '#/components/schemas/RestaurantLookupResponse'
        compass_place_id:
          type: string
          format: uuid
        changedAt:
          type: string
          format: date-time
        changedFields:
          type: array
          items:
            type: string
        deletedAt:
          type: string
          format: date-time
    ChangesResponse:
      type: object
      required: [changes, total, page, pageSize, since, nextSince]
      properties:
        changes:
          type: array
          items:
            $ref: '#/components/schemas/ChangeEntry'
        total:
          type: integer
          minimum: 0
        page:
          type: integer
          minimum: 1
        pageSize:
          type: integer
          minimum: 1
          maximum: 1000
        since:
          type: string
          format: date-time
        nextSince:
          type: string
          format: date-time
    SearchResponse:
      type: object
      required: [compass_request_id, results, total_results, ai_generated]
      properties:
        compass_request_id:
          type: string
        query_interpretation:
          $ref: '#/components/schemas/QueryInterpretation'
        results:
          type: array
          items:
            $ref: '#/components/schemas/SearchResult'
        total_results:
          type: integer
          minimum: 0
        ai_generated:
          type: boolean
        human_review_recommended:
          type: boolean
        metadata:
          type: object
          additionalProperties: true
          description: Search execution metadata such as mode, cache status, result source, latency, and bounded fetch diagnostics when present.
      example:
        compass_request_id: req_example_marina_search
        query_interpretation:
          diet_inferred: strict_vegan
          cuisine_inferred: sushi
        results:
          - compass_id: 620c7a36d04a4b03ecf8996e
            name: Ma-Kin Vegan Sushi
            address:
              street: 30313 Canwood St
              city: Agoura Hills
              state: CA
              postal_code: '91301'
              country: US
            coordinates:
              lat: 34.14830475866208
              lng: -118.782103653863
            vegan_score:
              overall: 60
              scoring_version: v3.0-deterministic
              dimensions:
                D1_vegan_coverage:
                  score: 90
                  weight: 0.25
                  confidence: high
                  evidence_ids:
                    - ev_620c7a36_VEGAN_OPTIONS_MENTIONED
                D2_vegan_quality:
                  score: 40
                  weight: 0.2
                  confidence: low
                D3_ingredient_clarity:
                  score: 50
                  weight: 0.15
                  confidence: medium
                D4_cross_contamination:
                  score: 40
                  weight: 0.2
                  confidence: low
                  evidence_ids:
                    - ev_620c7a36_CROSS_CONTAMINATION_UNKNOWN
                D5_staff_knowledge:
                  score: 75
                  weight: 0.1
                  confidence: high
                D6_restaurant_quality:
                  score: 40
                  weight: 0.1
                  confidence: low
              reasoning: A dedicated vegan restaurant with a solid overall offering. Menu coverage is a relative strength.
            dietary_profile:
              fully_vegan: true
              vegan_friendly: true
            cuisine_types:
              - asian
              - japanese
              - sushi
              - vegan
              - vegetarian
            services:
              takeout: true
            last_verified_at: 2026-05-04T17:00:00Z
            last_evaluated_at: 2026-05-04T17:00:00Z
            evidence:
              - evidence_id: ev_620c7a36_VEGAN_OPTIONS_MENTIONED
                type: menu_item
                source: compass://deterministic-evidence/menu_dishes
                weight: primary
                tier: A
                excerpt: 7 vegan dishes identified out of 12 parsed.
                paraphrase_method: none
              - evidence_id: ev_620c7a36_CROSS_CONTAMINATION_UNKNOWN
                type: review_signal
                source: compass://deterministic-evidence/review_signals
                weight: supporting
                tier: A
                excerpt: Cross-contamination handling not declared. no review-derived cross-contamination data.
                paraphrase_method: none
              - evidence_id: ev_620c7a36_RESTAURANT_VERIFICATION_RECOMMENDED
                type: user_report
                source: compass://deterministic-evidence/request_profile
                weight: primary
                tier: A
                excerpt: 'Manual verification recommended for: shared kitchen handling, cross-contamination practices.'
                paraphrase_method: none
              - evidence_id: ev_620c7a36_INSUFFICIENT_EVIDENCE
                type: user_report
                source: compass://deterministic-evidence/request_profile
                weight: supporting
                tier: A
                excerpt: 'Insufficient data to confirm: cross-contamination safety for strict vegan profile.'
                paraphrase_method: none
            match_for_profile:
              decision: unknown
              confidence: low
              reason_codes:
                - RESTAURANT_VERIFICATION_RECOMMENDED
                - INSUFFICIENT_EVIDENCE
              risk_flags:
                - limited_evidence
              verification_required: true
              recommended_user_text: Compass cannot confirm fit or non-fit with current evidence. Verify details with the restaurant before using this for safety-critical needs.
          - compass_id: 607b5d5409b5fb67b7c901c5
            name: Daikon Vegan Sushi
            address:
              street: 7210 W Lake Mead Blvd
              city: Las Vegas
              state: NV
              postal_code: '89128'
              country: US
            coordinates:
              lat: 36.196740662547185
              lng: -115.24930846061609
            vegan_score:
              overall: 73
              scoring_version: v3.0-deterministic
              dimensions:
                D1_vegan_coverage:
                  score: 94
                  weight: 0.25
                  confidence: high
                  evidence_ids:
                    - ev_607b5d54_VEGAN_OPTIONS_MENTIONED
                D2_vegan_quality:
                  score: 83
                  weight: 0.2
                  confidence: high
                  evidence_ids:
                    - ev_607b5d54_REVIEW_SIGNAL_POSITIVE
                D3_ingredient_clarity:
                  score: 40
                  weight: 0.15
                  confidence: low
                D4_cross_contamination:
                  score: 40
                  weight: 0.2
                  confidence: low
                  evidence_ids:
                    - ev_607b5d54_CROSS_CONTAMINATION_UNKNOWN
                D5_staff_knowledge:
                  score: 75
                  weight: 0.1
                  confidence: high
                D6_restaurant_quality:
                  score: 90
                  weight: 0.1
                  confidence: high
              reasoning: A dedicated vegan restaurant with a solid overall offering. Menu coverage is a relative strength.
            dietary_profile:
              fully_vegan: true
              vegan_friendly: true
            cuisine_types:
              - asian
              - japanese
              - sushi
            services:
              delivery: true
              reservations: true
              takeout: true
            last_verified_at: 2026-05-04T17:00:00Z
            last_evaluated_at: 2026-05-04T17:00:00Z
            evidence:
              - evidence_id: ev_607b5d54_VEGAN_OPTIONS_MENTIONED
                type: menu_item
                source: compass://deterministic-evidence/menu_dishes
                weight: primary
                tier: A
                excerpt: 5 vegan dishes identified out of 10 parsed.
                paraphrase_method: none
              - evidence_id: ev_607b5d54_CROSS_CONTAMINATION_UNKNOWN
                type: review_signal
                source: compass://deterministic-evidence/review_signals
                weight: supporting
                tier: A
                excerpt: Cross-contamination handling not declared. review signals do not mention shared equipment or dedicated prep area.
                paraphrase_method: none
              - evidence_id: ev_607b5d54_REVIEW_SIGNAL_POSITIVE
                type: review_signal
                source: compass://deterministic-evidence/review_signals
                weight: primary
                tier: A
                paraphrase_method: none
              - evidence_id: ev_607b5d54_SOURCE_CONFIDENCE_HIGH
                type: restaurant_declared
                source: compass://deterministic-evidence/source_freshness
                weight: primary
                tier: A
                excerpt: 'High source confidence: review confidence 0.8, vegan score confidence high.'
                paraphrase_method: none
              - evidence_id: ev_607b5d54_RESTAURANT_VERIFICATION_RECOMMENDED
                type: user_report
                source: compass://deterministic-evidence/request_profile
                weight: primary
                tier: A
                excerpt: 'Manual verification recommended for: shared kitchen handling, cross-contamination practices.'
                paraphrase_method: none
              - evidence_id: ev_607b5d54_INSUFFICIENT_EVIDENCE
                type: user_report
                source: compass://deterministic-evidence/request_profile
                weight: supporting
                tier: A
                excerpt: 'Insufficient data to confirm: cross-contamination safety for strict vegan profile.'
                paraphrase_method: none
            match_for_profile:
              decision: unknown
              confidence: low
              reason_codes:
                - RESTAURANT_VERIFICATION_RECOMMENDED
                - INSUFFICIENT_EVIDENCE
              risk_flags:
                - limited_evidence
              verification_required: true
              recommended_user_text: Compass cannot confirm fit or non-fit with current evidence. Verify details with the restaurant before using this for safety-critical needs.
          - compass_id: osm_11558119422
            name: Beyond Sushi - Vegan Restaurant
            address:
              street: 134 West 37th Street, New York, NY, 10018
              city: New York
              state: NY
              postal_code: null
              country: null
            coordinates:
              lat: 40.7523748
              lng: -73.9885096
            vegan_score:
              overall: 73
              scoring_version: v3.0-deterministic
              dimensions:
                D1_vegan_coverage:
                  score: 95
                  weight: 0.25
                  confidence: high
                  evidence_ids:
                    - ev_osm_1155_VEGAN_OPTIONS_MENTIONED
                D2_vegan_quality:
                  score: 90
                  weight: 0.2
                  confidence: high
                D3_ingredient_clarity:
                  score: 40
                  weight: 0.15
                  confidence: low
                D4_cross_contamination:
                  score: 40
                  weight: 0.2
                  confidence: low
                  evidence_ids:
                    - ev_osm_1155_CROSS_CONTAMINATION_UNKNOWN
                D5_staff_knowledge:
                  score: 70
                  weight: 0.1
                  confidence: medium
                D6_restaurant_quality:
                  score: 55
                  weight: 0.1
                  confidence: medium
              reasoning: A dedicated vegan restaurant with a solid overall offering. Menu coverage is a relative strength.
            dietary_profile:
              fully_vegan: true
              vegan_friendly: true
            cuisine_types:
              - asian
            services:
              delivery: true
              reservations: true
              takeout: true
            last_verified_at: 2026-05-04T17:00:00Z
            last_evaluated_at: 2026-05-04T17:00:00Z
            evidence:
              - evidence_id: ev_osm_1155_VEGAN_OPTIONS_MENTIONED
                type: menu_item
                source: compass://deterministic-evidence/menu_dishes
                weight: primary
                tier: A
                excerpt: 6 vegan dishes identified out of 51 parsed.
                paraphrase_method: none
              - evidence_id: ev_osm_1155_CROSS_CONTAMINATION_UNKNOWN
                type: review_signal
                source: compass://deterministic-evidence/review_signals
                weight: supporting
                tier: A
                excerpt: Cross-contamination handling not declared. no review-derived cross-contamination data.
                paraphrase_method: none
              - evidence_id: ev_osm_1155_SOURCE_CONFIDENCE_LOW
                type: restaurant_declared
                source: compass://deterministic-evidence/source_freshness
                weight: supporting
                tier: A
                excerpt: 'Low source confidence: menu metadata low.'
                paraphrase_method: none
              - evidence_id: ev_osm_1155_SOURCE_CONFIDENCE_HIGH
                type: restaurant_declared
                source: compass://deterministic-evidence/source_freshness
                weight: supporting
                tier: A
                excerpt: 'High source confidence: vegan score confidence high.'
                paraphrase_method: none
              - evidence_id: ev_osm_1155_RESTAURANT_VERIFICATION_RECOMMENDED
                type: user_report
                source: compass://deterministic-evidence/request_profile
                weight: primary
                tier: A
                excerpt: 'Manual verification recommended for: shared kitchen handling, cross-contamination practices.'
                paraphrase_method: none
              - evidence_id: ev_osm_1155_INSUFFICIENT_EVIDENCE
                type: user_report
                source: compass://deterministic-evidence/request_profile
                weight: supporting
                tier: A
                excerpt: 'Insufficient data to confirm: cross-contamination safety for strict vegan profile.'
                paraphrase_method: none
            match_for_profile:
              decision: unknown
              confidence: low
              reason_codes:
                - SOURCE_CONFIDENCE_LOW
                - RESTAURANT_VERIFICATION_RECOMMENDED
                - INSUFFICIENT_EVIDENCE
              risk_flags:
                - limited_evidence
              verification_required: true
              recommended_user_text: Compass cannot confirm fit or non-fit with current evidence. Verify details with the restaurant before using this for safety-critical needs.
        total_results: 3
        ai_generated: true
        human_review_recommended: false
        metadata:
          mode: rich
          cache:
            status: miss
            ttl_seconds: 3600
            profile_hash: 0cb8bd3aed1e601567853ed8ca22d0227470222a35e25c3a8ea42f22889337a3
          result_source: qdrant_restaurants_v2
          latency_ms: 1200
    EnrichRequest:
      type: object
      anyOf:
        - required: [compass_id]
        - required: [name, address]
        - required: [name, google_place_id]
      description: |
        Provide `compass_id` for direct lookup, OR `name` plus one of
        `address` or `google_place_id` for fuzzy match.
      properties:
        compass_id:
          type: string
          minLength: 1
          maxLength: 500
        name:
          type: string
          minLength: 1
          maxLength: 500
        address:
          type: string
          minLength: 1
          maxLength: 500
        google_place_id:
          type: string
          minLength: 1
          maxLength: 500
    EnrichRestaurant:
      allOf:
        - $ref: '#/components/schemas/RestaurantBase'
    MatchCandidate:
      type: object
      required: [compass_id, name, match_score]
      properties:
        compass_id:
          type: string
        name:
          type: string
        match_score:
          type: number
          minimum: 0
          maximum: 1
    EnrichResponseMatched:
      type: object
      required:
        - compass_request_id
        - matched
        - match_confidence
        - compass_id
        - restaurant
        - ai_generated
      properties:
        compass_request_id:
          type: string
        matched:
          type: boolean
          enum: [true]
        match_confidence:
          type: number
          minimum: 0
          maximum: 1
        compass_id:
          type: string
        restaurant:
          $ref: '#/components/schemas/EnrichRestaurant'
        evidence:
          type: array
          items:
            $ref: '#/components/schemas/Evidence'
        ai_generated:
          type: boolean
      x-examples:
        compass_id_lookup:
          summary: Direct compass_id lookup for Marina Sushi Bar
          value:
            compass_request_id: req_example_marina_enrich_compass_id
            matched: true
            match_confidence: 1
            compass_id: 42911d00f964a520f2231fe3
            restaurant:
              compass_id: 42911d00f964a520f2231fe3
              name: Marina Sushi Bar
              address:
                street: 2020 Lombard St
                city: San Francisco
                state: CA
                postal_code: '94123'
                country: US
              coordinates:
                lat: 37.80005063754422
                lng: -122.43486721258864
              vegan_score:
                overall: 51
                scoring_version: v3.0-deterministic
                dimensions:
                  D1_vegan_coverage:
                    score: 70
                    weight: 0.25
                    confidence: medium
                    evidence_ids:
                      - ev_42911d00_VEGAN_OPTIONS_MENTIONED
                      - ev_42911d00_VEGAN_FRIENDLY_PARTIAL
                  D2_vegan_quality:
                    score: 40
                    weight: 0.2
                    confidence: low
                  D3_ingredient_clarity:
                    score: 40
                    weight: 0.15
                    confidence: low
                  D4_cross_contamination:
                    score: 40
                    weight: 0.2
                    confidence: low
                    evidence_ids:
                      - ev_42911d00_CROSS_CONTAMINATION_UNKNOWN
                  D5_staff_knowledge:
                    score: 45
                    weight: 0.1
                    confidence: low
                  D6_restaurant_quality:
                    score: 70
                    weight: 0.1
                    confidence: medium
                reasoning: A workable vegan option, though with notable limitations. Menu coverage is a relative strength.
              dietary_profile:
                fully_vegan: false
                vegan_friendly: false
              cuisine_types:
                - asian
                - japanese
                - sushi
              last_verified_at: 2026-05-04T17:00:00Z
              last_evaluated_at: 2026-05-04T17:00:00Z
              evidence:
                - evidence_id: ev_42911d00_VEGAN_OPTIONS_MENTIONED
                  type: menu_item
                  source: compass://deterministic-evidence/menu_dishes
                  weight: primary
                  tier: A
                  excerpt: 6 vegan dishes identified out of 50 parsed.
                  paraphrase_method: none
                - evidence_id: ev_42911d00_VEGAN_FRIENDLY_PARTIAL
                  type: menu_item
                  source: compass://deterministic-evidence/menu_dishes
                  weight: primary
                  tier: A
                  excerpt: 'Vegan-friendly: 6 of 50 dishes are vegan.'
                  paraphrase_method: none
                - evidence_id: ev_42911d00_CROSS_CONTAMINATION_UNKNOWN
                  type: review_signal
                  source: compass://deterministic-evidence/review_signals
                  weight: supporting
                  tier: A
                  excerpt: Cross-contamination handling not declared. review signals do not mention shared equipment or dedicated prep area.
                  paraphrase_method: none
                - evidence_id: ev_42911d00_SOURCE_CONFIDENCE_LOW
                  type: restaurant_declared
                  source: compass://deterministic-evidence/source_freshness
                  weight: primary
                  tier: A
                  excerpt: 'Low source confidence: menu metadata low, review confidence 0.3.'
                  paraphrase_method: none
                - evidence_id: ev_42911d00_RESTAURANT_VERIFICATION_RECOMMENDED
                  type: restaurant_declared
                  source: compass://deterministic-evidence/source_freshness
                  weight: supporting
                  tier: A
                  excerpt: 'Manual verification recommended for: ingredient sourcing.'
                  paraphrase_method: none
            evidence:
              - evidence_id: ev_42911d00_VEGAN_OPTIONS_MENTIONED
                type: menu_item
                source: compass://deterministic-evidence/menu_dishes
                excerpt: 6 vegan dishes identified out of 50 parsed.
                weight: primary
                tier: A
                paraphrase_method: none
              - evidence_id: ev_42911d00_VEGAN_FRIENDLY_PARTIAL
                type: menu_item
                source: compass://deterministic-evidence/menu_dishes
                excerpt: 'Vegan-friendly: 6 of 50 dishes are vegan.'
                weight: primary
                tier: A
                paraphrase_method: none
              - evidence_id: ev_42911d00_CROSS_CONTAMINATION_UNKNOWN
                type: review_signal
                source: compass://deterministic-evidence/review_signals
                excerpt: Cross-contamination handling not declared. review signals do not mention shared equipment or dedicated prep area.
                weight: supporting
                tier: A
                paraphrase_method: none
              - evidence_id: ev_42911d00_SOURCE_CONFIDENCE_LOW
                type: restaurant_declared
                source: compass://deterministic-evidence/source_freshness
                excerpt: 'Low source confidence: menu metadata low, review confidence 0.3.'
                weight: primary
                tier: A
                paraphrase_method: none
              - evidence_id: ev_42911d00_RESTAURANT_VERIFICATION_RECOMMENDED
                type: restaurant_declared
                source: compass://deterministic-evidence/source_freshness
                excerpt: 'Manual verification recommended for: ingredient sourcing.'
                weight: supporting
                tier: A
                paraphrase_method: none
            ai_generated: true
        fuzzy_match:
          summary: Name and address fuzzy match for Marina Sushi Bar
          value:
            compass_request_id: req_example_marina_enrich_fuzzy
            matched: true
            match_confidence: 0.95
            compass_id: 42911d00f964a520f2231fe3
            restaurant:
              compass_id: 42911d00f964a520f2231fe3
              name: Marina Sushi Bar
              address:
                street: 2020 Lombard St
                city: San Francisco
                state: CA
                postal_code: '94123'
                country: US
              coordinates:
                lat: 37.80005063754422
                lng: -122.43486721258864
              vegan_score:
                overall: 51
                scoring_version: v3.0-deterministic
                dimensions:
                  D1_vegan_coverage:
                    score: 70
                    weight: 0.25
                    confidence: medium
                    evidence_ids:
                      - ev_42911d00_VEGAN_OPTIONS_MENTIONED
                      - ev_42911d00_VEGAN_FRIENDLY_PARTIAL
                  D2_vegan_quality:
                    score: 40
                    weight: 0.2
                    confidence: low
                  D3_ingredient_clarity:
                    score: 40
                    weight: 0.15
                    confidence: low
                  D4_cross_contamination:
                    score: 40
                    weight: 0.2
                    confidence: low
                    evidence_ids:
                      - ev_42911d00_CROSS_CONTAMINATION_UNKNOWN
                  D5_staff_knowledge:
                    score: 45
                    weight: 0.1
                    confidence: low
                  D6_restaurant_quality:
                    score: 70
                    weight: 0.1
                    confidence: medium
                reasoning: A workable vegan option, though with notable limitations. Menu coverage is a relative strength.
              dietary_profile:
                fully_vegan: false
                vegan_friendly: false
              cuisine_types:
                - asian
                - japanese
                - sushi
              last_verified_at: 2026-05-04T17:00:00Z
              last_evaluated_at: 2026-05-04T17:00:00Z
              evidence:
                - evidence_id: ev_42911d00_VEGAN_OPTIONS_MENTIONED
                  type: menu_item
                  source: compass://deterministic-evidence/menu_dishes
                  weight: primary
                  tier: A
                  excerpt: 6 vegan dishes identified out of 50 parsed.
                  paraphrase_method: none
                - evidence_id: ev_42911d00_VEGAN_FRIENDLY_PARTIAL
                  type: menu_item
                  source: compass://deterministic-evidence/menu_dishes
                  weight: primary
                  tier: A
                  excerpt: 'Vegan-friendly: 6 of 50 dishes are vegan.'
                  paraphrase_method: none
                - evidence_id: ev_42911d00_CROSS_CONTAMINATION_UNKNOWN
                  type: review_signal
                  source: compass://deterministic-evidence/review_signals
                  weight: supporting
                  tier: A
                  excerpt: Cross-contamination handling not declared. review signals do not mention shared equipment or dedicated prep area.
                  paraphrase_method: none
                - evidence_id: ev_42911d00_SOURCE_CONFIDENCE_LOW
                  type: restaurant_declared
                  source: compass://deterministic-evidence/source_freshness
                  weight: primary
                  tier: A
                  excerpt: 'Low source confidence: menu metadata low, review confidence 0.3.'
                  paraphrase_method: none
                - evidence_id: ev_42911d00_RESTAURANT_VERIFICATION_RECOMMENDED
                  type: restaurant_declared
                  source: compass://deterministic-evidence/source_freshness
                  weight: supporting
                  tier: A
                  excerpt: 'Manual verification recommended for: ingredient sourcing.'
                  paraphrase_method: none
            evidence:
              - evidence_id: ev_42911d00_VEGAN_OPTIONS_MENTIONED
                type: menu_item
                source: compass://deterministic-evidence/menu_dishes
                excerpt: 6 vegan dishes identified out of 50 parsed.
                weight: primary
                tier: A
                paraphrase_method: none
              - evidence_id: ev_42911d00_VEGAN_FRIENDLY_PARTIAL
                type: menu_item
                source: compass://deterministic-evidence/menu_dishes
                excerpt: 'Vegan-friendly: 6 of 50 dishes are vegan.'
                weight: primary
                tier: A
                paraphrase_method: none
              - evidence_id: ev_42911d00_CROSS_CONTAMINATION_UNKNOWN
                type: review_signal
                source: compass://deterministic-evidence/review_signals
                excerpt: Cross-contamination handling not declared. review signals do not mention shared equipment or dedicated prep area.
                weight: supporting
                tier: A
                paraphrase_method: none
              - evidence_id: ev_42911d00_SOURCE_CONFIDENCE_LOW
                type: restaurant_declared
                source: compass://deterministic-evidence/source_freshness
                excerpt: 'Low source confidence: menu metadata low, review confidence 0.3.'
                weight: primary
                tier: A
                paraphrase_method: none
              - evidence_id: ev_42911d00_RESTAURANT_VERIFICATION_RECOMMENDED
                type: restaurant_declared
                source: compass://deterministic-evidence/source_freshness
                excerpt: 'Manual verification recommended for: ingredient sourcing.'
                weight: supporting
                tier: A
                paraphrase_method: none
            ai_generated: true
    EnrichResponseUnmatched:
      type: object
      required:
        - compass_request_id
        - matched
        - match_confidence
        - compass_id
        - ai_generated
      properties:
        compass_request_id:
          type: string
        matched:
          type: boolean
          enum: [false]
        match_confidence:
          type: number
          minimum: 0
          maximum: 1
        compass_id:
          type: string
          nullable: true
        match_candidates:
          type: array
          maxItems: 5
          items:
            $ref: '#/components/schemas/MatchCandidate'
        ai_generated:
          type: boolean
    DecisionRequest:
      type: object
      required: [compass_id, user_profile]
      properties:
        compass_id:
          type: string
        user_profile:
          allOf:
            - $ref: '#/components/schemas/DecisionUserProfile'
            - type: object
              required: [diet]
    DecisionResponse:
      type: object
      description: |
        Decision-bearing response. The `unknown` verdict is correct,
        valuable, and never an error — conservative behavior is the locked
        policy when evidence is insufficient, conflicting, or stale.
      required:
        - compass_request_id
        - compass_id
        - decision
        - confidence
        - reason_codes
        - evidence
        - source_freshness
        - risk_flags
        - recommended_user_text
        - verification_required
        - last_evaluated_at
        - ai_generated
      properties:
        compass_request_id:
          type: string
        compass_id:
          type: string
        last_evaluated_at:
          type: string
          format: date-time
          nullable: true
          description: When Compass last evaluated the restaurant used for this decision.
        decision:
          $ref: '#/components/schemas/Decision'
        confidence:
          $ref: '#/components/schemas/Confidence'
        reason_codes:
          type: array
          items:
            $ref: '#/components/schemas/ReasonCode'
        risk_flags:
          type: array
          items:
            $ref: '#/components/schemas/RiskFlag'
        evidence:
          type: array
          items:
            $ref: '#/components/schemas/Evidence'
        source_freshness:
          $ref: '#/components/schemas/SourceFreshness'
        recommended_user_text:
          type: string
        verification_required:
          type: boolean
        ai_generated:
          type: boolean
        human_review_recommended:
          type: boolean
      x-examples:
        fit_outcome:
          summary: Strict-vegan fit outcome from a populated production response
          value:
            compass_request_id: req_example_decision_fit
            last_evaluated_at: 2026-05-04T17:00:00Z
            decision: fit
            confidence: high
            reason_codes:
              - VEGAN_MENU_FULL_RESTAURANT
              - SOURCE_CONFIDENCE_HIGH
              - HIGH_CONFIDENCE_DECISION
            evidence:
              - evidence_id: ev_6248e512_VEGAN_MENU_CONFIRMED
                type: menu_item
                source: compass://deterministic-evidence/menu_regex
                excerpt: Confirmed vegan menu section.
                weight: primary
                tier: A
                paraphrase_method: none
              - evidence_id: ev_6248e512_VEGAN_OPTIONS_MENTIONED
                type: menu_item
                source: compass://deterministic-evidence/menu_dishes
                excerpt: 39 vegan dishes identified out of 41 parsed.
                weight: primary
                tier: A
                paraphrase_method: none
              - evidence_id: ev_6248e512_CROSS_CONTAMINATION_UNKNOWN
                type: review_signal
                source: compass://deterministic-evidence/review_signals
                excerpt: Cross-contamination handling not declared. review signals do not mention shared equipment or dedicated prep area.
                weight: supporting
                tier: A
                paraphrase_method: none
              - evidence_id: ev_6248e512_REVIEW_SIGNAL_POSITIVE
                type: review_signal
                source: compass://deterministic-evidence/review_signals
                weight: primary
                tier: A
                paraphrase_method: none
              - evidence_id: ev_6248e512_SOURCE_CONFIDENCE_LOW
                type: restaurant_declared
                source: compass://deterministic-evidence/source_freshness
                excerpt: 'Low source confidence: limited current source evidence.'
                weight: supporting
                tier: A
                paraphrase_method: none
              - evidence_id: ev_6248e512_SOURCE_CONFIDENCE_HIGH
                type: restaurant_declared
                source: compass://deterministic-evidence/source_freshness
                excerpt: 'High source confidence: review confidence 0.9, vegan score confidence high.'
                weight: supporting
                tier: A
                paraphrase_method: none
              - evidence_id: ev_6248e512_RESTAURANT_VERIFICATION_RECOMMENDED
                type: user_report
                source: compass://deterministic-evidence/request_profile
                excerpt: 'Manual verification recommended for: shared kitchen handling, cross-contamination practices.'
                weight: primary
                tier: A
                paraphrase_method: none
              - evidence_id: ev_6248e512_INSUFFICIENT_EVIDENCE
                type: user_report
                source: compass://deterministic-evidence/request_profile
                excerpt: 'Insufficient data to confirm: cross-contamination safety for strict vegan profile.'
                weight: supporting
                tier: A
                paraphrase_method: none
              - evidence_id: ev_6248e512_VEGAN_MENU_FULL_RESTAURANT
                type: menu_item
                source: compass://deterministic-evidence/menu_dishes
                weight: primary
                tier: A
                paraphrase_method: none
            source_freshness:
              oldest_signal_age_days: 1
              newest_signal_age_days: 1
              recommended_refresh: false
            risk_flags: []
            recommended_user_text: Compass found strong evidence that this restaurant fits the submitted profile. Verify details with the restaurant when constraints are critical.
            verification_required: false
            human_review_recommended: false
            compass_id: 6248e5125fce9f7295ebe45d
            ai_generated: true
        unknown_outcome:
          summary: Strict-vegan cross-contamination unknown outcome for Marina Sushi Bar
          value:
            compass_request_id: req_example_decision_unknown
            last_evaluated_at: 2026-05-04T17:00:00Z
            decision: unknown
            confidence: low
            reason_codes:
              - SOURCE_CONFIDENCE_LOW
              - CROSS_CONTAMINATION_UNKNOWN
              - INSUFFICIENT_EVIDENCE
              - RESTAURANT_VERIFICATION_RECOMMENDED
            evidence:
              - evidence_id: ev_42911d00_VEGAN_OPTIONS_MENTIONED
                type: menu_item
                source: compass://deterministic-evidence/menu_dishes
                excerpt: 6 vegan dishes identified out of 50 parsed.
                weight: primary
                tier: A
                paraphrase_method: none
              - evidence_id: ev_42911d00_VEGAN_FRIENDLY_PARTIAL
                type: menu_item
                source: compass://deterministic-evidence/menu_dishes
                excerpt: 'Vegan-friendly: 6 of 50 dishes are vegan.'
                weight: primary
                tier: A
                paraphrase_method: none
              - evidence_id: ev_42911d00_CROSS_CONTAMINATION_UNKNOWN
                type: review_signal
                source: compass://deterministic-evidence/review_signals
                excerpt: Cross-contamination handling not declared. review signals do not mention shared equipment, dedicated prep area, or written kitchen-handling policy.
                weight: supporting
                tier: A
                paraphrase_method: none
              - evidence_id: ev_42911d00_SOURCE_CONFIDENCE_LOW
                type: restaurant_declared
                source: compass://deterministic-evidence/source_freshness
                excerpt: 'Low source confidence: menu metadata low, review confidence 0.3.'
                weight: primary
                tier: A
                paraphrase_method: none
              - evidence_id: ev_42911d00_RESTAURANT_VERIFICATION_RECOMMENDED
                type: user_report
                source: compass://deterministic-evidence/request_profile
                excerpt: 'Manual verification recommended for: shared kitchen handling, cross-contamination practices, written kitchen-handling policy.'
                weight: primary
                tier: A
                paraphrase_method: none
              - evidence_id: ev_42911d00_INSUFFICIENT_EVIDENCE
                type: user_report
                source: compass://deterministic-evidence/request_profile
                excerpt: 'Insufficient data to confirm: cross-contamination handling for strict dietary requirements.'
                weight: supporting
                tier: A
                paraphrase_method: none
            source_freshness:
              oldest_signal_age_days: 1
              newest_signal_age_days: 1
              recommended_refresh: false
            risk_flags:
              - cross_contamination_risk
            recommended_user_text: Compass has insufficient evidence for this profile. Verify details with the restaurant before visiting.
            verification_required: true
            human_review_recommended: true
            compass_id: 42911d00f964a520f2231fe3
            ai_generated: true
    Problem:
      type: object
      description: RFC 7807 problem+json error response
      required: [type, title, status]
      properties:
        type:
          type: string
          format: uri
        title:
          type: string
        status:
          type: integer
        detail:
          type: string
        compass_request_id:
          type: string
  responses:
    BadRequest:
      description: Invalid request format or missing required field
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Unauthorized:
      description: Missing or invalid API key
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    EnterpriseOnly:
      description: Valid API key, but this route requires Enterprise tier
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    RestaurantNotFound:
      description: Restaurant ID does not exist
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    MatchFailed:
      description: Restaurant match below confidence threshold
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    RateLimited:
      description: Burst rate limit hit or monthly quota exceeded
      headers:
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
        X-RateLimit-Limit:
          $ref: '#/components/headers/XRateLimitLimit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/XRateLimitRemaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/XRateLimitReset'
        X-RateLimit-IP-Remaining:
          $ref: '#/components/headers/XRateLimitIPRemaining'
        X-RateLimit-IP-Reset:
          $ref: '#/components/headers/XRateLimitIPReset'
        X-Usage-ThisMonth:
          $ref: '#/components/headers/XUsageThisMonth'
        X-Usage-Limit:
          $ref: '#/components/headers/XUsageLimit'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    InternalError:
      description: Server error
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    UpstreamUnavailable:
      description: Embedding service or vector DB temporarily unavailable
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
