{
  "title": "Enjoy Thai Land decision engine",
  "description": "Explainable travel decisions computed from the signal layer and entity graph, with transparent fallback metadata instead of hidden seed scoring.",
  "generated_at": "2026-06-24T03:51:19.382Z",
  "family_count": 6,
  "decision_count": 49,
  "families": [
    {
      "id": "today",
      "name": "Where to go today",
      "decisionType": "where_to_go_today",
      "status": "active",
      "endpoint": "/api/decisions/today",
      "note": "Ranks destination entities using live AQI and comfort signals plus source confidence, regional context, and airport-scale, airport-access, airport board-surface, or airport environmental-support context where it materially changes the trip shape.",
      "output": "Best and weakest destination picks today."
    },
    {
      "id": "where-to-stay",
      "name": "Where to stay",
      "decisionType": "where_to_stay",
      "status": "active",
      "endpoint": "/api/decisions/where-to-stay",
      "note": "Ranks hotel-area entities using comfort, source confidence, parent-destination resilience, airport-ground-access support, official airport pickup-rule context, airport board-surface support, airport-scale context, airport environmental-support context, rail-support context, and official rail presence where they materially affect the stay.",
      "output": "Best current hotel bases and who they fit."
    },
    {
      "id": "route-check",
      "name": "Route check",
      "decisionType": "route_check",
      "status": "active",
      "endpoint": "/api/decisions/route-check",
      "note": "Checks high-value route templates using destination scores, transfer nodes, airport-weather context, airport-ground-access support, official airport pickup-rule context, official passenger board-surface support, airport-scale context, airport environmental-support context, rail-support context, official rail presence where the route can plausibly use it, and live pier or transfer support where coastal legs matter.",
      "output": "Route feasibility, main breaker, and pivot."
    },
    {
      "id": "ferry-check",
      "name": "Ferry check",
      "decisionType": "ferry_check",
      "status": "active",
      "endpoint": "/api/decisions/ferry-check",
      "note": "Checks pier and island-chain plans with live sea-state caution, public transfer support, ferry fragility, and honest refund logic.",
      "output": "Ferry fragility, refund logic, and backup move."
    },
    {
      "id": "food-route",
      "name": "Food route",
      "decisionType": "food_route",
      "status": "active",
      "endpoint": "/api/decisions/food-route",
      "note": "Turns destination and venue-density entity records into traveler-facing food-route picks.",
      "output": "Best food-first destination and route fit."
    },
    {
      "id": "gold-buying-check",
      "name": "Gold buying check",
      "decisionType": "gold_buying_check",
      "status": "active",
      "endpoint": "/api/decisions/gold-buying-check",
      "note": "Explains the national Thai Gold Traders Association 96.5% reference quote in THB per 1 baht-weight, then pairs it with city buying-context friction so Bangkok, Chiang Mai, Phuket, Pattaya, and Hat Yai are not mistaken for separate official local price feeds.",
      "output": "National quote, city buying context, and next gold-shopping checks."
    }
  ],
  "decisions": {
    "today": [
      {
        "decision_id": "today_chiang-mai",
        "decision_type": "where_to_go_today",
        "subject_id": "chiang-mai",
        "subject_name": "Chiang Mai",
        "subject_type": "destination",
        "score": 65,
        "component_score": 74.2,
        "penalty_points": 9,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Chiang Mai is a cautious today pick.",
        "best_for": "Culture, cafes, temples, northern food, and slower city pacing.",
        "avoid_if": "PM2.5 stays high or the trip depends on mountain views being crisp.",
        "check_first": [
          "Treat sustained PM2.5 as the main breaker.",
          "Choose Old City or Nimman based on trip shape, not a random deal.",
          "Keep Bangkok or the coast as a real pivot if smoke stays high."
        ],
        "next_action": "Check PM2.5 first, then choose Old City or Nimman before paying for side trips.",
        "pivot": "Pivot to Bangkok or the coast if smoke remains stubborn.",
        "freshness_class": "fresh",
        "score_formula_version": "same-day-signal-v3",
        "signal_coverage": {
          "total_components": 26,
          "available_components": 26,
          "live_components": 25,
          "fallback_components": 1,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "aqi_fit",
            "label": "AQI fit",
            "score": 92,
            "weight": 0.16,
            "contribution": 14.72,
            "source": "signal",
            "signal_type": "aqi_risk",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "AQI risk missing; using conservative destination fallback.",
            "note": ""
          },
          {
            "key": "outdoor_comfort",
            "label": "Outdoor comfort",
            "score": 95,
            "weight": 0.12,
            "contribution": 11.4,
            "source": "signal",
            "signal_type": "outdoor_comfort",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "Outdoor comfort missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_risk",
            "label": "Rain fit",
            "score": 56,
            "weight": 0.22,
            "contribution": 12.32,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "Rain fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "airport_weather_operability",
            "label": "Airport weather operability",
            "score": 60,
            "weight": 0.08,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "flight_delay_risk",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is airport weather and forecast disruption context, not airline on-time performance."
          },
          {
            "key": "airport_transfer_support",
            "label": "Airport transfer support",
            "score": 41,
            "weight": 0.012,
            "contribution": 0.49,
            "source": "signal",
            "signal_type": "airport_transfer_support",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is ground-access support around the main airport anchor linked to the destination, not a live airline board."
          },
          {
            "key": "airport_ground_service_support",
            "label": "Airport ground-service support",
            "score": 42,
            "weight": 0.012,
            "contribution": 0.5,
            "source": "signal",
            "signal_type": "airport_ground_service_support",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official airport taxi, Grab, rental, and pickup-rule context around the main airport anchor, not live queue, ETA, or inventory truth."
          },
          {
            "key": "airport_board_surface_support",
            "label": "Airport board-surface support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "airport_board_surface_support",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official passenger self-serve board visibility from public AOT flight-status pages. The board rows themselves use a browser turnstile token, so this is not direct live airline status truth."
          },
          {
            "key": "airport_scale_context",
            "label": "Airport scale context",
            "score": 50,
            "weight": 0.012,
            "contribution": 0.6,
            "source": "signal",
            "signal_type": "airport_scale_context",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official AOT passenger and aircraft-movement scale context behind the main airport anchor, not live delay, gate, queue, or inventory truth."
          },
          {
            "key": "airport_environmental_support",
            "label": "Airport environmental support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "airport_environmental_support",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is SET-hosted AOT annual-report disclosure context around the main airport anchor, not live measured sound-level truth."
          },
          {
            "key": "rail_feasibility",
            "label": "Rail feasibility",
            "score": 43,
            "weight": 0.012,
            "contribution": 0.52,
            "source": "signal",
            "signal_type": "rail_feasibility",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is public rail-support structure around the destination, not live seat, delay, or operator-disruption truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 86,
            "weight": 0.012,
            "contribution": 1.03,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support for overland bus planning, not live departure, seat, or booking truth."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 72,
            "weight": 0.012,
            "contribution": 0.86,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support for intercity-bus planning, not live departure, seat, or booking truth."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support for intercity-bus planning, not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 94,
            "weight": 0.012,
            "contribution": 1.13,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context, not local realtime service quality, dispatch, or incident truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 92,
            "weight": 0.012,
            "contribution": 1.1,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "water_risk",
            "label": "Water and flood fit",
            "score": 86,
            "weight": 0.08,
            "contribution": 6.88,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "Water-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 84,
            "weight": 0.012,
            "contribution": 1.01,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "park_access_context",
            "label": "Park access context",
            "score": 90,
            "weight": 0.012,
            "contribution": 1.08,
            "source": "signal",
            "signal_type": "park_access_context",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DNP protected-area planning context, not live closure, ranger, capacity, or ticket truth."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 88,
            "weight": 0.05,
            "contribution": 4.4,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "Noise-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "road_safety",
            "label": "Road safety",
            "score": 88,
            "weight": 0.05,
            "contribution": 4.4,
            "source": "signal",
            "signal_type": "road_safety_risk",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "Road-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_friction",
            "label": "Transport friction",
            "score": 63,
            "weight": 0.05,
            "contribution": 3.15,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "Transport-friction signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "source_confidence",
            "label": "Source confidence",
            "score": 97,
            "weight": 0.03,
            "contribution": 2.91,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "Source-confidence signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "disaster_context",
            "label": "Disaster context",
            "score": 46,
            "weight": 0.1,
            "contribution": 4.6,
            "source": "signal",
            "signal_type": "regional_disaster_context",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "Disaster context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "earthquake_context",
            "label": "Earthquake context",
            "score": 64,
            "weight": 0.03,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "regional_earthquake_context",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "Earthquake context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 78,
            "weight": 0.015,
            "contribution": 1.17,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "Blueprint seed score missing; using live average as the fallback baseline.",
            "note": "Blueprint baseline is now a light fallback and copy anchor, not the primary scoring driver."
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Same-day signal spread penalty",
            "points": 9,
            "applied": true,
            "spread": 49,
            "note": "Component scores spread by 49 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "30 joined sources support this decision.",
        "weakest_signal": {
          "type": "airport_transfer_support",
          "label": "Airport transfer support is weak",
          "reason": "Public transport structure around this airport shows 1 mapped stop(s), 1 mode group(s), 1 rail-linked stop(s), 0 airport-link stop(s), and 0 bus-linked stop(s). This is airport-ground-access support, not live airline board or queue truth."
        },
        "related_pages": [
          {
            "path": "/where-to-go/chiang-mai/",
            "label": "Chiang Mai destination guide"
          },
          {
            "path": "/accommodation/chiang-mai/",
            "label": "Where to stay in Chiang Mai"
          },
          {
            "path": "/food/chiang-mai-khao-soi/",
            "label": "Chiang Mai khao soi route"
          },
          {
            "path": "/today/north/",
            "label": "Northern Thailand Today"
          },
          {
            "path": "/food/chiang-mai-food-guide/",
            "label": "Chiang Mai food guide"
          },
          {
            "path": "/temples/chiang-mai/",
            "label": "Chiang Mai temple route"
          },
          {
            "path": "/research/temples/chiang-mai/",
            "label": "Chiang Mai temple research"
          }
        ],
        "path": "/entities/chiang-mai/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T09:51:33.917Z"
      },
      {
        "decision_id": "today_ayutthaya",
        "decision_type": "where_to_go_today",
        "subject_id": "ayutthaya",
        "subject_name": "Ayutthaya",
        "subject_type": "destination",
        "score": 64,
        "component_score": 75.3,
        "penalty_points": 11,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Ayutthaya is a cautious today pick.",
        "best_for": "Easy history from Bangkok with low commitment.",
        "avoid_if": "You hate heat exposure or want a slow overnight small-town mood instead.",
        "check_first": [
          "Start early in hot months.",
          "Use train or simple road logic rather than over-designing the transfer.",
          "Treat Bangkok as the hotel base unless the trip specifically wants slower nights."
        ],
        "next_action": "Go early, travel light, and keep the day tight enough to avoid a punishing noon slog.",
        "pivot": "Return to Bangkok early if heat becomes the real story.",
        "freshness_class": "fresh",
        "score_formula_version": "same-day-signal-v3",
        "signal_coverage": {
          "total_components": 22,
          "available_components": 21,
          "live_components": 20,
          "fallback_components": 1,
          "defaulted_components": 1,
          "coverage_ratio": 0.955
        },
        "score_components": [
          {
            "key": "aqi_fit",
            "label": "AQI fit",
            "score": 92,
            "weight": 0.16,
            "contribution": 14.72,
            "source": "signal",
            "signal_type": "aqi_risk",
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "AQI risk missing; using conservative destination fallback.",
            "note": ""
          },
          {
            "key": "outdoor_comfort",
            "label": "Outdoor comfort",
            "score": 95,
            "weight": 0.12,
            "contribution": 11.4,
            "source": "signal",
            "signal_type": "outdoor_comfort",
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "Outdoor comfort missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_risk",
            "label": "Rain fit",
            "score": 56,
            "weight": 0.22,
            "contribution": 12.32,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "Rain fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "airport_transfer_support",
            "label": "Airport transfer support",
            "score": 82,
            "weight": 0.012,
            "contribution": 0.98,
            "source": "signal",
            "signal_type": "airport_transfer_support",
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "",
            "note": "This is ground-access support around the main airport anchor linked to the destination, not a live airline board."
          },
          {
            "key": "airport_ground_service_support",
            "label": "Airport ground-service support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "airport_ground_service_support",
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "",
            "note": "This is official airport taxi, Grab, rental, and pickup-rule context around the main airport anchor, not live queue, ETA, or inventory truth."
          },
          {
            "key": "airport_board_surface_support",
            "label": "Airport board-surface support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "airport_board_surface_support",
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "",
            "note": "This is official passenger self-serve board visibility from public AOT flight-status pages. The board rows themselves use a browser turnstile token, so this is not direct live airline status truth."
          },
          {
            "key": "airport_scale_context",
            "label": "Airport scale context",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "airport_scale_context",
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "",
            "note": "This is official AOT passenger and aircraft-movement scale context behind the main airport anchor, not live delay, gate, queue, or inventory truth."
          },
          {
            "key": "airport_environmental_support",
            "label": "Airport environmental support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "airport_environmental_support",
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "",
            "note": "This is SET-hosted AOT annual-report disclosure context around the main airport anchor, not live measured sound-level truth."
          },
          {
            "key": "rail_feasibility",
            "label": "Rail feasibility",
            "score": 52,
            "weight": 0.012,
            "contribution": 0.62,
            "source": "signal",
            "signal_type": "rail_feasibility",
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "",
            "note": "This is public rail-support structure around the destination, not live seat, delay, or operator-disruption truth."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 92,
            "weight": 0.012,
            "contribution": 1.1,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support for intercity-bus planning, not live departure, seat, or booking truth."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support for intercity-bus planning, not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 94,
            "weight": 0.012,
            "contribution": 1.13,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context, not local realtime service quality, dispatch, or incident truth."
          },
          {
            "key": "water_risk",
            "label": "Water and flood fit",
            "score": 76,
            "weight": 0.08,
            "contribution": 6.08,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "Water-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "highway_transfer_friction",
            "label": "Highway transfer friction",
            "score": 88,
            "weight": 0.04,
            "contribution": 3.52,
            "source": "signal",
            "signal_type": "highway_transfer_friction",
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DOH and EXAT road-support context, not live speed, queue, lane, or incident truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 82,
            "weight": 0.012,
            "contribution": 0.98,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 68,
            "weight": 0.05,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "ayutthaya",
            "used_default": true,
            "default_reason": "Noise-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "road_safety",
            "label": "Road safety",
            "score": 77,
            "weight": 0.05,
            "contribution": 3.85,
            "source": "signal",
            "signal_type": "road_safety_risk",
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "Road-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_friction",
            "label": "Transport friction",
            "score": 75,
            "weight": 0.05,
            "contribution": 3.75,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "Transport-friction signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "source_confidence",
            "label": "Source confidence",
            "score": 97,
            "weight": 0.03,
            "contribution": 2.91,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "Source-confidence signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "disaster_context",
            "label": "Disaster context",
            "score": 46,
            "weight": 0.1,
            "contribution": 4.6,
            "source": "signal",
            "signal_type": "regional_disaster_context",
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "Disaster context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "earthquake_context",
            "label": "Earthquake context",
            "score": 64,
            "weight": 0.03,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "regional_earthquake_context",
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "Earthquake context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 79,
            "weight": 0.015,
            "contribution": 1.19,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "ayutthaya",
            "used_default": false,
            "default_reason": "Blueprint seed score missing; using live average as the fallback baseline.",
            "note": "Blueprint baseline is now a light fallback and copy anchor, not the primary scoring driver."
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 1,
            "points": 2,
            "applied": true,
            "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Same-day signal spread penalty",
            "points": 9,
            "applied": true,
            "spread": 49,
            "note": "Component scores spread by 49 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "noise_comfort"
        ],
        "source_summary": "23 joined sources support this decision.",
        "weakest_signal": {
          "type": "regional_disaster_context",
          "label": "Regional disaster context is busy",
          "reason": "GDACS currently shows 4 active hazard groups across 32 tracked events. This is a route-confidence layer, not a local place safety verdict."
        },
        "related_pages": [
          {
            "path": "/where-to-go/ayutthaya/",
            "label": "Ayutthaya destination guide"
          },
          {
            "path": "/rail/bangkok-ayutthaya-train/",
            "label": "Bangkok to Ayutthaya train"
          },
          {
            "path": "/accommodation/ayutthaya/",
            "label": "Ayutthaya stay guide"
          },
          {
            "path": "/food/ayutthaya-food-route/",
            "label": "Ayutthaya food guide"
          },
          {
            "path": "/temples/ayutthaya/",
            "label": "Ayutthaya temple route"
          },
          {
            "path": "/research/temples/ayutthaya/",
            "label": "Ayutthaya temple research"
          }
        ],
        "path": "/entities/ayutthaya/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T09:00:00.000Z"
      },
      {
        "decision_id": "today_bangkok",
        "decision_type": "where_to_go_today",
        "subject_id": "bangkok",
        "subject_name": "Bangkok",
        "subject_type": "destination",
        "score": 63,
        "component_score": 74.2,
        "penalty_points": 11,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Bangkok is a cautious today pick.",
        "best_for": "First trips, rainy-day resilience, food density, hospitals, and rail-linked city movement.",
        "avoid_if": "You want a quiet, taxi-heavy, or outdoor-only city break.",
        "check_first": [
          "Check Air4Thai before heavy outdoor days.",
          "Choose a BTS/MRT-linked base before paying for a hotel.",
          "Treat cross-city taxi-heavy days as a risk, not a default."
        ],
        "next_action": "Pick a BTS/MRT-linked base first, then shape temple, food, and river days around nearby zones.",
        "pivot": "Use Ayutthaya or Kanchanaburi as the easier side-trip move, or shift to a coast if city noise is the real problem.",
        "freshness_class": "fresh",
        "score_formula_version": "same-day-signal-v3",
        "signal_coverage": {
          "total_components": 31,
          "available_components": 30,
          "live_components": 29,
          "fallback_components": 1,
          "defaulted_components": 1,
          "coverage_ratio": 0.968
        },
        "score_components": [
          {
            "key": "aqi_fit",
            "label": "AQI fit",
            "score": 92,
            "weight": 0.16,
            "contribution": 14.72,
            "source": "signal",
            "signal_type": "aqi_risk",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "AQI risk missing; using conservative destination fallback.",
            "note": ""
          },
          {
            "key": "outdoor_comfort",
            "label": "Outdoor comfort",
            "score": 95,
            "weight": 0.12,
            "contribution": 11.4,
            "source": "signal",
            "signal_type": "outdoor_comfort",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "Outdoor comfort missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_risk",
            "label": "Rain fit",
            "score": 56,
            "weight": 0.22,
            "contribution": 12.32,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "Rain fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "airport_weather_operability",
            "label": "Airport weather operability",
            "score": 60,
            "weight": 0.08,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "flight_delay_risk",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is airport weather and forecast disruption context, not airline on-time performance."
          },
          {
            "key": "airport_transfer_support",
            "label": "Airport transfer support",
            "score": 82,
            "weight": 0.012,
            "contribution": 0.98,
            "source": "signal",
            "signal_type": "airport_transfer_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is ground-access support around the main airport anchor linked to the destination, not a live airline board."
          },
          {
            "key": "airport_ground_service_support",
            "label": "Airport ground-service support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "airport_ground_service_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official airport taxi, Grab, rental, and pickup-rule context around the main airport anchor, not live queue, ETA, or inventory truth."
          },
          {
            "key": "airport_board_surface_support",
            "label": "Airport board-surface support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "airport_board_surface_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official passenger self-serve board visibility from public AOT flight-status pages. The board rows themselves use a browser turnstile token, so this is not direct live airline status truth."
          },
          {
            "key": "airport_scale_context",
            "label": "Airport scale context",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "airport_scale_context",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official AOT passenger and aircraft-movement scale context behind the main airport anchor, not live delay, gate, queue, or inventory truth."
          },
          {
            "key": "airport_environmental_support",
            "label": "Airport environmental support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "airport_environmental_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is SET-hosted AOT annual-report disclosure context around the main airport anchor, not live measured sound-level truth."
          },
          {
            "key": "rail_feasibility",
            "label": "Rail feasibility",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "rail_feasibility",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is public rail-support structure around the destination, not live seat, delay, or operator-disruption truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 86,
            "weight": 0.012,
            "contribution": 1.03,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support for overland bus planning, not live departure, seat, or booking truth."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 92,
            "weight": 0.012,
            "contribution": 1.1,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support for intercity-bus planning, not live departure, seat, or booking truth."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support for intercity-bus planning, not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 94,
            "weight": 0.012,
            "contribution": 1.13,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context, not local realtime service quality, dispatch, or incident truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "official_motorcycle_taxi_support",
            "label": "Official motorcycle-taxi support",
            "score": 88,
            "weight": 0.012,
            "contribution": 1.06,
            "source": "signal",
            "signal_type": "official_motorcycle_taxi_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Bangkok motorcycle-taxi stand and driver coverage from the public DLT/data.go.th dataset, useful as last-mile support context rather than live availability, dispatch, or queue truth."
          },
          {
            "key": "taxi_pickup_dropoff_support",
            "label": "Taxi pickup and dropoff support",
            "score": 92,
            "weight": 0.012,
            "contribution": 1.1,
            "source": "signal",
            "signal_type": "taxi_pickup_dropoff_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is public OTP monthly taxi GPS analytics and hotspot coverage around Bangkok traveler entities, useful as aggregate demand and pickup/dropoff context rather than live dispatch, ETA, queue, or raw trip truth."
          },
          {
            "key": "urban_rapid_transit_support",
            "label": "Urban rapid-transit support",
            "score": 98,
            "weight": 0.012,
            "contribution": 1.18,
            "source": "signal",
            "signal_type": "urban_rapid_transit_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BTS and MRTA route-map and service-page support, not live headway, crowding, or outage truth."
          },
          {
            "key": "urban_bus_operator_support",
            "label": "Urban bus-operator support",
            "score": 88,
            "weight": 0.012,
            "contribution": 1.06,
            "source": "signal",
            "signal_type": "urban_bus_operator_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is public Thai Smile Group branch and depot footprint around Bangkok traveler entities, not realtime vehicle, ETA, crowding, or outage truth."
          },
          {
            "key": "water_risk",
            "label": "Water and flood fit",
            "score": 44,
            "weight": 0.08,
            "contribution": 3.52,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "Water-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "highway_transfer_friction",
            "label": "Highway transfer friction",
            "score": 88,
            "weight": 0.04,
            "contribution": 3.52,
            "source": "signal",
            "signal_type": "highway_transfer_friction",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DOH and EXAT road-support context, not live speed, queue, lane, or incident truth."
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 50,
            "weight": 0.05,
            "contribution": 2.5,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "Noise-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "civic_friction",
            "label": "Civic friction",
            "score": 68,
            "weight": 0.012,
            "contribution": 0.82,
            "source": "signal",
            "signal_type": "civic_friction",
            "entity_id": "bangkok",
            "used_default": true,
            "default_reason": "Civic-friction signal missing for this Bangkok layer; using conservative fallback.",
            "note": "Civic friction is only weighted where Bangkok civic complaint statistics are available."
          },
          {
            "key": "road_safety",
            "label": "Road safety",
            "score": 90,
            "weight": 0.05,
            "contribution": 4.5,
            "source": "signal",
            "signal_type": "road_safety_risk",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "Road-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_friction",
            "label": "Transport friction",
            "score": 86,
            "weight": 0.05,
            "contribution": 4.3,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "Transport-friction signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "source_confidence",
            "label": "Source confidence",
            "score": 97,
            "weight": 0.03,
            "contribution": 2.91,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "Source-confidence signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "disaster_context",
            "label": "Disaster context",
            "score": 46,
            "weight": 0.1,
            "contribution": 4.6,
            "source": "signal",
            "signal_type": "regional_disaster_context",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "Disaster context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "earthquake_context",
            "label": "Earthquake context",
            "score": 64,
            "weight": 0.03,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "regional_earthquake_context",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "Earthquake context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 88,
            "weight": 0.015,
            "contribution": 1.32,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "Blueprint seed score missing; using live average as the fallback baseline.",
            "note": "Blueprint baseline is now a light fallback and copy anchor, not the primary scoring driver."
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 1,
            "points": 2,
            "applied": true,
            "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Same-day signal spread penalty",
            "points": 9,
            "applied": true,
            "spread": 51,
            "note": "Component scores spread by 51 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "civic_friction"
        ],
        "source_summary": "46 joined sources support this decision.",
        "weakest_signal": {
          "type": "flood_water_risk",
          "label": "Water and flood-adjacent risk is elevated",
          "reason": "Thaiwater status proxy scores 33 with dissolved oxygen 0 mg/L. This is a river and canal caution layer, not a full flood-stage model."
        },
        "related_pages": [
          {
            "path": "/today/bangkok/",
            "label": "Bangkok Today"
          },
          {
            "path": "/where-to-go/bangkok/",
            "label": "Bangkok destination guide"
          },
          {
            "path": "/accommodation/bangkok/",
            "label": "Where to stay in Bangkok"
          },
          {
            "path": "/venues/restaurants/bangkok/",
            "label": "Bangkok restaurants"
          },
          {
            "path": "/food/bangkok-food-guide/",
            "label": "Bangkok food guide"
          },
          {
            "path": "/temples/bangkok/",
            "label": "Bangkok temple route"
          },
          {
            "path": "/research/temples/bangkok/",
            "label": "Bangkok temple research"
          }
        ],
        "path": "/entities/bangkok/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T09:51:33.917Z"
      },
      {
        "decision_id": "today_isaan",
        "decision_type": "where_to_go_today",
        "subject_id": "isaan",
        "subject_name": "Isaan",
        "subject_type": "destination",
        "score": 63,
        "component_score": 71.1,
        "penalty_points": 8,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Isaan is a cautious today pick.",
        "best_for": "Repeat visitors, regional food, and deeper province-level travel.",
        "avoid_if": "You want one obvious first-trip infrastructure answer.",
        "check_first": [
          "Treat province choice as the real decision, not just the region label.",
          "Use Khon Kaen, Ubon, Nong Khai, or Korat as actual anchors.",
          "Do not expect first-trip infrastructure everywhere."
        ],
        "next_action": "Choose one actual province cluster instead of treating the whole region as a single stop.",
        "pivot": "Use Bangkok as the setup base, then move east only when the trip length justifies it.",
        "freshness_class": "fresh",
        "score_formula_version": "same-day-signal-v3",
        "signal_coverage": {
          "total_components": 17,
          "available_components": 16,
          "live_components": 15,
          "fallback_components": 1,
          "defaulted_components": 1,
          "coverage_ratio": 0.941
        },
        "score_components": [
          {
            "key": "aqi_fit",
            "label": "AQI fit",
            "score": 82,
            "weight": 0.16,
            "contribution": 13.12,
            "source": "signal",
            "signal_type": "aqi_risk",
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "AQI risk missing; using conservative destination fallback.",
            "note": ""
          },
          {
            "key": "outdoor_comfort",
            "label": "Outdoor comfort",
            "score": 78,
            "weight": 0.12,
            "contribution": 9.36,
            "source": "signal",
            "signal_type": "outdoor_comfort",
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "Outdoor comfort missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_risk",
            "label": "Rain fit",
            "score": 64,
            "weight": 0.22,
            "contribution": 14.08,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "Rain fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 92,
            "weight": 0.012,
            "contribution": 1.1,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support for overland bus planning, not live departure, seat, or booking truth."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 92,
            "weight": 0.012,
            "contribution": 1.1,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support for intercity-bus planning, not live departure, seat, or booking truth."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support for intercity-bus planning, not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 94,
            "weight": 0.012,
            "contribution": 1.13,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context, not local realtime service quality, dispatch, or incident truth."
          },
          {
            "key": "water_risk",
            "label": "Water and flood fit",
            "score": 76,
            "weight": 0.08,
            "contribution": 6.08,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "Water-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 78,
            "weight": 0.012,
            "contribution": 0.94,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "park_access_context",
            "label": "Park access context",
            "score": 84,
            "weight": 0.012,
            "contribution": 1.01,
            "source": "signal",
            "signal_type": "park_access_context",
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DNP protected-area planning context, not live closure, ranger, capacity, or ticket truth."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 68,
            "weight": 0.05,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "isaan",
            "used_default": true,
            "default_reason": "Noise-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "road_safety",
            "label": "Road safety",
            "score": 76,
            "weight": 0.05,
            "contribution": 3.8,
            "source": "signal",
            "signal_type": "road_safety_risk",
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "Road-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_friction",
            "label": "Transport friction",
            "score": 58,
            "weight": 0.05,
            "contribution": 2.9,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "Transport-friction signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "source_confidence",
            "label": "Source confidence",
            "score": 91,
            "weight": 0.03,
            "contribution": 2.73,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "Source-confidence signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "disaster_context",
            "label": "Disaster context",
            "score": 46,
            "weight": 0.1,
            "contribution": 4.6,
            "source": "signal",
            "signal_type": "regional_disaster_context",
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "Disaster context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "earthquake_context",
            "label": "Earthquake context",
            "score": 64,
            "weight": 0.03,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "regional_earthquake_context",
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "Earthquake context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 71,
            "weight": 0.015,
            "contribution": 1.06,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "Blueprint seed score missing; using live average as the fallback baseline.",
            "note": "Blueprint baseline is now a light fallback and copy anchor, not the primary scoring driver."
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 1,
            "points": 2,
            "applied": true,
            "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Same-day signal spread penalty",
            "points": 6,
            "applied": true,
            "spread": 36,
            "note": "Component scores spread by 36 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "noise_comfort"
        ],
        "source_summary": "23 joined sources support this decision.",
        "weakest_signal": {
          "type": "regional_disaster_context",
          "label": "Regional disaster context is busy",
          "reason": "GDACS currently shows 4 active hazard groups across 32 tracked events. This is a route-confidence layer, not a local place safety verdict."
        },
        "related_pages": [
          {
            "path": "/where-to-go/isaan/",
            "label": "Isaan destination guide"
          },
          {
            "path": "/food/isaan-food-for-first-timers/",
            "label": "Isaan food guide"
          },
          {
            "path": "/food/isaan-food-guide/",
            "label": "Isaan food guide"
          }
        ],
        "path": "/entities/isaan/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T09:51:33.917Z"
      },
      {
        "decision_id": "today_koh-samui",
        "decision_type": "where_to_go_today",
        "subject_id": "koh-samui",
        "subject_name": "Koh Samui",
        "subject_type": "destination",
        "score": 59,
        "component_score": 70,
        "penalty_points": 11,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Koh Samui is a cautious today pick.",
        "best_for": "Comfort-first island stays with airport access and a softer Gulf pivot.",
        "avoid_if": "You need a no-transfer beach answer or want to chain too many boats tightly.",
        "check_first": [
          "Compare Gulf weather directly with the Andaman coast.",
          "Use Samui itself as the stable base before adding Phangan or Tao.",
          "Check airport-plus-ferry stacks before paying for tight itineraries."
        ],
        "next_action": "Compare Gulf weather directly with Phuket and Krabi before locking the coast.",
        "pivot": "Use Bangkok or Phuket if flights and ferries stack badly.",
        "freshness_class": "fresh",
        "score_formula_version": "same-day-signal-v3",
        "signal_coverage": {
          "total_components": 21,
          "available_components": 20,
          "live_components": 19,
          "fallback_components": 1,
          "defaulted_components": 1,
          "coverage_ratio": 0.952
        },
        "score_components": [
          {
            "key": "aqi_fit",
            "label": "AQI fit",
            "score": 92,
            "weight": 0.16,
            "contribution": 14.72,
            "source": "signal",
            "signal_type": "aqi_risk",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "AQI risk missing; using conservative destination fallback.",
            "note": ""
          },
          {
            "key": "outdoor_comfort",
            "label": "Outdoor comfort",
            "score": 95,
            "weight": 0.12,
            "contribution": 11.4,
            "source": "signal",
            "signal_type": "outdoor_comfort",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "Outdoor comfort missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_risk",
            "label": "Rain fit",
            "score": 56,
            "weight": 0.22,
            "contribution": 12.32,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "Rain fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "marine_warning_risk",
            "label": "Marine warning risk",
            "score": 34,
            "weight": 0.1,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "marine_warning_risk",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "",
            "note": "This is coastal sea-state caution for ferry and beach-dependent destinations."
          },
          {
            "key": "pier_transfer_support",
            "label": "Pier transfer support",
            "score": 25,
            "weight": 0.05,
            "contribution": 1.25,
            "source": "signal",
            "signal_type": "pier_transfer_support",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "",
            "note": "This is public pier and transfer structure support around coastal anchors, not operator seat or queue truth."
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 94,
            "weight": 0.02,
            "contribution": 1.88,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Marine Department passenger-berth support around coastal anchors, not live ferry schedule, closure, queue, or seat truth."
          },
          {
            "key": "airport_weather_operability",
            "label": "Airport weather operability",
            "score": 93,
            "weight": 0.08,
            "contribution": 7.44,
            "source": "signal",
            "signal_type": "flight_delay_risk",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "",
            "note": "This is airport weather and forecast disruption context, not airline on-time performance."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 68,
            "weight": 0.012,
            "contribution": 0.82,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support for overland bus planning, not live departure, seat, or booking truth."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 58,
            "weight": 0.012,
            "contribution": 0.7,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support for intercity-bus planning, not live departure, seat, or booking truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 81,
            "weight": 0.012,
            "contribution": 0.97,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context, not local realtime service quality, dispatch, or incident truth."
          },
          {
            "key": "water_risk",
            "label": "Water and flood fit",
            "score": 86,
            "weight": 0.08,
            "contribution": 6.88,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "Water-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 86,
            "weight": 0.012,
            "contribution": 1.03,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 84,
            "weight": 0.012,
            "contribution": 1.01,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "park_access_context",
            "label": "Park access context",
            "score": 86,
            "weight": 0.012,
            "contribution": 1.03,
            "source": "signal",
            "signal_type": "park_access_context",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DNP protected-area planning context, not live closure, ranger, capacity, or ticket truth."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 68,
            "weight": 0.05,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "koh-samui",
            "used_default": true,
            "default_reason": "Noise-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "road_safety",
            "label": "Road safety",
            "score": 81,
            "weight": 0.05,
            "contribution": 4.05,
            "source": "signal",
            "signal_type": "road_safety_risk",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "Road-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_friction",
            "label": "Transport friction",
            "score": 60,
            "weight": 0.05,
            "contribution": 3,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "Transport-friction signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "source_confidence",
            "label": "Source confidence",
            "score": 97,
            "weight": 0.03,
            "contribution": 2.91,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "Source-confidence signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "disaster_context",
            "label": "Disaster context",
            "score": 46,
            "weight": 0.1,
            "contribution": 4.6,
            "source": "signal",
            "signal_type": "regional_disaster_context",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "Disaster context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "earthquake_context",
            "label": "Earthquake context",
            "score": 64,
            "weight": 0.03,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "regional_earthquake_context",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "Earthquake context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 77,
            "weight": 0.015,
            "contribution": 1.16,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "Blueprint seed score missing; using live average as the fallback baseline.",
            "note": "Blueprint baseline is now a light fallback and copy anchor, not the primary scoring driver."
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 1,
            "points": 2,
            "applied": true,
            "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Same-day signal spread penalty",
            "points": 9,
            "applied": true,
            "spread": 70,
            "note": "Component scores spread by 70 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "noise_comfort"
        ],
        "source_summary": "20 joined sources support this decision.",
        "weakest_signal": {
          "type": "pier_transfer_support",
          "label": "Pier transfer support is weak",
          "reason": "Public transport structure around this coastal anchor shows 2 mapped stop(s), 1 mode group(s), 0 boat-linked stop(s), and 2 bus-linked stop(s). This is public transfer support, not operator schedule or queue-length truth."
        },
        "related_pages": [
          {
            "path": "/where-to-go/koh-samui/",
            "label": "Koh Samui destination guide"
          },
          {
            "path": "/accommodation/koh-samui/",
            "label": "Where to stay in Koh Samui"
          },
          {
            "path": "/ferries/koh-samui-koh-phangan-koh-tao/",
            "label": "Samui / Phangan / Tao ferries"
          }
        ],
        "path": "/entities/koh-samui/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T12:00:00.000Z"
      },
      {
        "decision_id": "today_kanchanaburi",
        "decision_type": "where_to_go_today",
        "subject_id": "kanchanaburi",
        "subject_name": "Kanchanaburi",
        "subject_type": "destination",
        "score": 59,
        "component_score": 70.4,
        "penalty_points": 11,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Kanchanaburi is a cautious today pick.",
        "best_for": "River, rail-history, and light nature detours from Bangkok.",
        "avoid_if": "The trip window is too short to absorb transfers and outdoor time.",
        "check_first": [
          "Check waterfall and outdoor-weather logic before paying for remote stays.",
          "Treat the road burden honestly.",
          "Use Bangkok or Hua Hin as lower-friction pivots."
        ],
        "next_action": "Pick one river/history thread and keep waterfalls optional if rain weakens the day.",
        "pivot": "Stay in Bangkok if road or weather comfort slips.",
        "freshness_class": "fresh",
        "score_formula_version": "same-day-signal-v3",
        "signal_coverage": {
          "total_components": 18,
          "available_components": 17,
          "live_components": 16,
          "fallback_components": 1,
          "defaulted_components": 1,
          "coverage_ratio": 0.944
        },
        "score_components": [
          {
            "key": "aqi_fit",
            "label": "AQI fit",
            "score": 82,
            "weight": 0.16,
            "contribution": 13.12,
            "source": "signal",
            "signal_type": "aqi_risk",
            "entity_id": "kanchanaburi",
            "used_default": false,
            "default_reason": "AQI risk missing; using conservative destination fallback.",
            "note": ""
          },
          {
            "key": "outdoor_comfort",
            "label": "Outdoor comfort",
            "score": 78,
            "weight": 0.12,
            "contribution": 9.36,
            "source": "signal",
            "signal_type": "outdoor_comfort",
            "entity_id": "kanchanaburi",
            "used_default": false,
            "default_reason": "Outdoor comfort missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_risk",
            "label": "Rain fit",
            "score": 56,
            "weight": 0.22,
            "contribution": 12.32,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "kanchanaburi",
            "used_default": false,
            "default_reason": "Rain fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 68,
            "weight": 0.012,
            "contribution": 0.82,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "kanchanaburi",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support for overland bus planning, not live departure, seat, or booking truth."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 58,
            "weight": 0.012,
            "contribution": 0.7,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "kanchanaburi",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support for intercity-bus planning, not live departure, seat, or booking truth."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "kanchanaburi",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support for intercity-bus planning, not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 94,
            "weight": 0.012,
            "contribution": 1.13,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "kanchanaburi",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context, not local realtime service quality, dispatch, or incident truth."
          },
          {
            "key": "water_risk",
            "label": "Water and flood fit",
            "score": 86,
            "weight": 0.08,
            "contribution": 6.88,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "kanchanaburi",
            "used_default": false,
            "default_reason": "Water-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "highway_transfer_friction",
            "label": "Highway transfer friction",
            "score": 88,
            "weight": 0.04,
            "contribution": 3.52,
            "source": "signal",
            "signal_type": "highway_transfer_friction",
            "entity_id": "kanchanaburi",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DOH and EXAT road-support context, not live speed, queue, lane, or incident truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 76,
            "weight": 0.012,
            "contribution": 0.91,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "kanchanaburi",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "park_access_context",
            "label": "Park access context",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "park_access_context",
            "entity_id": "kanchanaburi",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DNP protected-area planning context, not live closure, ranger, capacity, or ticket truth."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 68,
            "weight": 0.05,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "kanchanaburi",
            "used_default": true,
            "default_reason": "Noise-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "road_safety",
            "label": "Road safety",
            "score": 64,
            "weight": 0.05,
            "contribution": 3.2,
            "source": "signal",
            "signal_type": "road_safety_risk",
            "entity_id": "kanchanaburi",
            "used_default": false,
            "default_reason": "Road-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_friction",
            "label": "Transport friction",
            "score": 68,
            "weight": 0.05,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "kanchanaburi",
            "used_default": false,
            "default_reason": "Transport-friction signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "source_confidence",
            "label": "Source confidence",
            "score": 97,
            "weight": 0.03,
            "contribution": 2.91,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "kanchanaburi",
            "used_default": false,
            "default_reason": "Source-confidence signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "disaster_context",
            "label": "Disaster context",
            "score": 46,
            "weight": 0.1,
            "contribution": 4.6,
            "source": "signal",
            "signal_type": "regional_disaster_context",
            "entity_id": "kanchanaburi",
            "used_default": false,
            "default_reason": "Disaster context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "earthquake_context",
            "label": "Earthquake context",
            "score": 64,
            "weight": 0.03,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "regional_earthquake_context",
            "entity_id": "kanchanaburi",
            "used_default": false,
            "default_reason": "Earthquake context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 75,
            "weight": 0.015,
            "contribution": 1.13,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "kanchanaburi",
            "used_default": false,
            "default_reason": "Blueprint seed score missing; using live average as the fallback baseline.",
            "note": "Blueprint baseline is now a light fallback and copy anchor, not the primary scoring driver."
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 1,
            "points": 2,
            "applied": true,
            "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Same-day signal spread penalty",
            "points": 9,
            "applied": true,
            "spread": 42,
            "note": "Component scores spread by 42 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "noise_comfort"
        ],
        "source_summary": "18 joined sources support this decision.",
        "weakest_signal": {
          "type": "regional_disaster_context",
          "label": "Regional disaster context is busy",
          "reason": "GDACS currently shows 4 active hazard groups across 32 tracked events. This is a route-confidence layer, not a local place safety verdict."
        },
        "related_pages": [
          {
            "path": "/where-to-go/kanchanaburi/",
            "label": "Kanchanaburi destination guide"
          },
          {
            "path": "/rail/bangkok-kanchanaburi-train/",
            "label": "Bangkok to Kanchanaburi train"
          },
          {
            "path": "/accommodation/kanchanaburi/",
            "label": "Kanchanaburi stay guide"
          },
          {
            "path": "/temples/kanchanaburi/",
            "label": "Kanchanaburi temple route"
          },
          {
            "path": "/research/temples/kanchanaburi/",
            "label": "Kanchanaburi temple research"
          }
        ],
        "path": "/entities/kanchanaburi/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T09:51:33.917Z"
      },
      {
        "decision_id": "today_koh-phangan",
        "decision_type": "where_to_go_today",
        "subject_id": "koh-phangan",
        "subject_name": "Koh Phangan",
        "subject_type": "destination",
        "score": 58,
        "component_score": 69.4,
        "penalty_points": 11,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Koh Phangan is a cautious today pick.",
        "best_for": "Longer Gulf stays, wellness pockets, and travelers who can tolerate ferry dependence.",
        "avoid_if": "You have low weather tolerance or Full Moon timing is the wrong fit.",
        "check_first": [
          "Treat Full Moon timing as a routing signal, not a footnote.",
          "Do not force Phangan behind a weak ferry day.",
          "Use Samui as the softer pivot if the chain looks brittle."
        ],
        "next_action": "Keep Samui as the stable fallback and avoid tight same-day transfers.",
        "pivot": "Sleep on Samui and use Phangan as the optional second move.",
        "freshness_class": "fresh",
        "score_formula_version": "same-day-signal-v3",
        "signal_coverage": {
          "total_components": 18,
          "available_components": 17,
          "live_components": 16,
          "fallback_components": 1,
          "defaulted_components": 1,
          "coverage_ratio": 0.944
        },
        "score_components": [
          {
            "key": "aqi_fit",
            "label": "AQI fit",
            "score": 92,
            "weight": 0.16,
            "contribution": 14.72,
            "source": "signal",
            "signal_type": "aqi_risk",
            "entity_id": "koh-phangan",
            "used_default": false,
            "default_reason": "AQI risk missing; using conservative destination fallback.",
            "note": ""
          },
          {
            "key": "outdoor_comfort",
            "label": "Outdoor comfort",
            "score": 95,
            "weight": 0.12,
            "contribution": 11.4,
            "source": "signal",
            "signal_type": "outdoor_comfort",
            "entity_id": "koh-phangan",
            "used_default": false,
            "default_reason": "Outdoor comfort missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_risk",
            "label": "Rain fit",
            "score": 56,
            "weight": 0.22,
            "contribution": 12.32,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "koh-phangan",
            "used_default": false,
            "default_reason": "Rain fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "marine_warning_risk",
            "label": "Marine warning risk",
            "score": 34,
            "weight": 0.1,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "marine_warning_risk",
            "entity_id": "koh-phangan",
            "used_default": false,
            "default_reason": "",
            "note": "This is coastal sea-state caution for ferry and beach-dependent destinations."
          },
          {
            "key": "pier_transfer_support",
            "label": "Pier transfer support",
            "score": 25,
            "weight": 0.05,
            "contribution": 1.25,
            "source": "signal",
            "signal_type": "pier_transfer_support",
            "entity_id": "koh-phangan",
            "used_default": false,
            "default_reason": "",
            "note": "This is public pier and transfer structure support around coastal anchors, not operator seat or queue truth."
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 94,
            "weight": 0.02,
            "contribution": 1.88,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": "koh-phangan",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Marine Department passenger-berth support around coastal anchors, not live ferry schedule, closure, queue, or seat truth."
          },
          {
            "key": "airport_weather_operability",
            "label": "Airport weather operability",
            "score": 93,
            "weight": 0.08,
            "contribution": 7.44,
            "source": "signal",
            "signal_type": "flight_delay_risk",
            "entity_id": "koh-phangan",
            "used_default": false,
            "default_reason": "",
            "note": "This is airport weather and forecast disruption context, not airline on-time performance."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 81,
            "weight": 0.012,
            "contribution": 0.97,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "koh-phangan",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context, not local realtime service quality, dispatch, or incident truth."
          },
          {
            "key": "water_risk",
            "label": "Water and flood fit",
            "score": 86,
            "weight": 0.08,
            "contribution": 6.88,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "koh-phangan",
            "used_default": false,
            "default_reason": "Water-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 70,
            "weight": 0.012,
            "contribution": 0.84,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "koh-phangan",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "park_access_context",
            "label": "Park access context",
            "score": 82,
            "weight": 0.012,
            "contribution": 0.98,
            "source": "signal",
            "signal_type": "park_access_context",
            "entity_id": "koh-phangan",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DNP protected-area planning context, not live closure, ranger, capacity, or ticket truth."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 68,
            "weight": 0.05,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "koh-phangan",
            "used_default": true,
            "default_reason": "Noise-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "road_safety",
            "label": "Road safety",
            "score": 81,
            "weight": 0.05,
            "contribution": 4.05,
            "source": "signal",
            "signal_type": "road_safety_risk",
            "entity_id": "koh-phangan",
            "used_default": false,
            "default_reason": "Road-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_friction",
            "label": "Transport friction",
            "score": 57,
            "weight": 0.05,
            "contribution": 2.85,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "koh-phangan",
            "used_default": false,
            "default_reason": "Transport-friction signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "source_confidence",
            "label": "Source confidence",
            "score": 90,
            "weight": 0.03,
            "contribution": 2.7,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "koh-phangan",
            "used_default": false,
            "default_reason": "Source-confidence signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "disaster_context",
            "label": "Disaster context",
            "score": 46,
            "weight": 0.1,
            "contribution": 4.6,
            "source": "signal",
            "signal_type": "regional_disaster_context",
            "entity_id": "koh-phangan",
            "used_default": false,
            "default_reason": "Disaster context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "earthquake_context",
            "label": "Earthquake context",
            "score": 64,
            "weight": 0.03,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "regional_earthquake_context",
            "entity_id": "koh-phangan",
            "used_default": false,
            "default_reason": "Earthquake context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 69,
            "weight": 0.015,
            "contribution": 1.03,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "koh-phangan",
            "used_default": false,
            "default_reason": "Blueprint seed score missing; using live average as the fallback baseline.",
            "note": "Blueprint baseline is now a light fallback and copy anchor, not the primary scoring driver."
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 1,
            "points": 2,
            "applied": true,
            "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Same-day signal spread penalty",
            "points": 9,
            "applied": true,
            "spread": 70,
            "note": "Component scores spread by 70 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "noise_comfort"
        ],
        "source_summary": "14 joined sources support this decision.",
        "weakest_signal": {
          "type": "pier_transfer_support",
          "label": "Pier transfer support is weak",
          "reason": "Public transport structure around this coastal anchor shows 2 mapped stop(s), 1 mode group(s), 0 boat-linked stop(s), and 2 bus-linked stop(s). This is public transfer support, not operator schedule or queue-length truth."
        },
        "related_pages": [
          {
            "path": "/where-to-go/koh-phangan/",
            "label": "Koh Phangan destination guide"
          },
          {
            "path": "/ferries/koh-samui-koh-phangan-koh-tao/",
            "label": "Samui / Phangan / Tao ferries"
          }
        ],
        "path": "/entities/koh-phangan/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T12:00:00.000Z"
      },
      {
        "decision_id": "today_phuket",
        "decision_type": "where_to_go_today",
        "subject_id": "phuket",
        "subject_name": "Phuket",
        "subject_type": "destination",
        "score": 56,
        "component_score": 67.4,
        "penalty_points": 11,
        "confidence": "High",
        "label": "fragile",
        "recommendation": "Phuket is a cautious today pick.",
        "best_for": "Infrastructure-first beach trips, flights, and weather backup.",
        "avoid_if": "You want a fragile island mood more than an easy base.",
        "check_first": [
          "Choose the beach area before the hotel.",
          "Check marine and weather layers before committing to boat-heavy days.",
          "Use Old Town as the indoor and food pivot when beach weather weakens."
        ],
        "next_action": "Choose the beach area before the hotel, then decide which boat days can stay optional.",
        "pivot": "Use Old Town as the indoor-food fallback or Samui if Gulf weather wins.",
        "freshness_class": "fresh",
        "score_formula_version": "same-day-signal-v3",
        "signal_coverage": {
          "total_components": 28,
          "available_components": 27,
          "live_components": 26,
          "fallback_components": 1,
          "defaulted_components": 1,
          "coverage_ratio": 0.964
        },
        "score_components": [
          {
            "key": "aqi_fit",
            "label": "AQI fit",
            "score": 92,
            "weight": 0.16,
            "contribution": 14.72,
            "source": "signal",
            "signal_type": "aqi_risk",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "AQI risk missing; using conservative destination fallback.",
            "note": ""
          },
          {
            "key": "outdoor_comfort",
            "label": "Outdoor comfort",
            "score": 95,
            "weight": 0.12,
            "contribution": 11.4,
            "source": "signal",
            "signal_type": "outdoor_comfort",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "Outdoor comfort missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_risk",
            "label": "Rain fit",
            "score": 44,
            "weight": 0.22,
            "contribution": 9.68,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "Rain fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "marine_warning_risk",
            "label": "Marine warning risk",
            "score": 34,
            "weight": 0.1,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "marine_warning_risk",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is coastal sea-state caution for ferry and beach-dependent destinations."
          },
          {
            "key": "pier_transfer_support",
            "label": "Pier transfer support",
            "score": 47,
            "weight": 0.05,
            "contribution": 2.35,
            "source": "signal",
            "signal_type": "pier_transfer_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is public pier and transfer structure support around coastal anchors, not operator seat or queue truth."
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 96,
            "weight": 0.02,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Marine Department passenger-berth support around coastal anchors, not live ferry schedule, closure, queue, or seat truth."
          },
          {
            "key": "airport_weather_operability",
            "label": "Airport weather operability",
            "score": 69,
            "weight": 0.08,
            "contribution": 5.52,
            "source": "signal",
            "signal_type": "flight_delay_risk",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is airport weather and forecast disruption context, not airline on-time performance."
          },
          {
            "key": "airport_transfer_support",
            "label": "Airport transfer support",
            "score": 32,
            "weight": 0.012,
            "contribution": 0.38,
            "source": "signal",
            "signal_type": "airport_transfer_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is ground-access support around the main airport anchor linked to the destination, not a live airline board."
          },
          {
            "key": "airport_ground_service_support",
            "label": "Airport ground-service support",
            "score": 42,
            "weight": 0.012,
            "contribution": 0.5,
            "source": "signal",
            "signal_type": "airport_ground_service_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is official airport taxi, Grab, rental, and pickup-rule context around the main airport anchor, not live queue, ETA, or inventory truth."
          },
          {
            "key": "airport_board_surface_support",
            "label": "Airport board-surface support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "airport_board_surface_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is official passenger self-serve board visibility from public AOT flight-status pages. The board rows themselves use a browser turnstile token, so this is not direct live airline status truth."
          },
          {
            "key": "airport_scale_context",
            "label": "Airport scale context",
            "score": 63,
            "weight": 0.012,
            "contribution": 0.76,
            "source": "signal",
            "signal_type": "airport_scale_context",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is official AOT passenger and aircraft-movement scale context behind the main airport anchor, not live delay, gate, queue, or inventory truth."
          },
          {
            "key": "airport_environmental_support",
            "label": "Airport environmental support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "airport_environmental_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is SET-hosted AOT annual-report disclosure context around the main airport anchor, not live measured sound-level truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 78,
            "weight": 0.012,
            "contribution": 0.94,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support for overland bus planning, not live departure, seat, or booking truth."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 77,
            "weight": 0.012,
            "contribution": 0.92,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support for intercity-bus planning, not live departure, seat, or booking truth."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support for intercity-bus planning, not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 89,
            "weight": 0.012,
            "contribution": 1.07,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context, not local realtime service quality, dispatch, or incident truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 84,
            "weight": 0.012,
            "contribution": 1.01,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "water_risk",
            "label": "Water and flood fit",
            "score": 68,
            "weight": 0.08,
            "contribution": 5.44,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "phuket",
            "used_default": true,
            "default_reason": "Water-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 82,
            "weight": 0.012,
            "contribution": 0.98,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "park_access_context",
            "label": "Park access context",
            "score": 88,
            "weight": 0.012,
            "contribution": 1.06,
            "source": "signal",
            "signal_type": "park_access_context",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DNP protected-area planning context, not live closure, ranger, capacity, or ticket truth."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 74,
            "weight": 0.05,
            "contribution": 3.7,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "Noise-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "road_safety",
            "label": "Road safety",
            "score": 86,
            "weight": 0.05,
            "contribution": 4.3,
            "source": "signal",
            "signal_type": "road_safety_risk",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "Road-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_friction",
            "label": "Transport friction",
            "score": 61,
            "weight": 0.05,
            "contribution": 3.05,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "Transport-friction signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "source_confidence",
            "label": "Source confidence",
            "score": 97,
            "weight": 0.03,
            "contribution": 2.91,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "Source-confidence signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "disaster_context",
            "label": "Disaster context",
            "score": 46,
            "weight": 0.1,
            "contribution": 4.6,
            "source": "signal",
            "signal_type": "regional_disaster_context",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "Disaster context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "earthquake_context",
            "label": "Earthquake context",
            "score": 64,
            "weight": 0.03,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "regional_earthquake_context",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "Earthquake context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 82,
            "weight": 0.015,
            "contribution": 1.23,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "Blueprint seed score missing; using live average as the fallback baseline.",
            "note": "Blueprint baseline is now a light fallback and copy anchor, not the primary scoring driver."
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 1,
            "points": 2,
            "applied": true,
            "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Same-day signal spread penalty",
            "points": 9,
            "applied": true,
            "spread": 61,
            "note": "Component scores spread by 61 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "water_risk"
        ],
        "source_summary": "27 joined sources support this decision.",
        "weakest_signal": {
          "type": "airport_transfer_support",
          "label": "Airport transfer support is weak",
          "reason": "Public transport structure around this airport shows 1 mapped stop(s), 1 mode group(s), 0 rail-linked stop(s), 0 airport-link stop(s), and 1 bus-linked stop(s). This is airport-ground-access support, not live airline board or queue truth."
        },
        "related_pages": [
          {
            "path": "/where-to-go/phuket/",
            "label": "Phuket destination guide"
          },
          {
            "path": "/accommodation/phuket/",
            "label": "Where to stay in Phuket"
          },
          {
            "path": "/venues/restaurants/phuket/",
            "label": "Phuket restaurants"
          },
          {
            "path": "/ferries/phuket-krabi/",
            "label": "Phuket to Krabi ferries"
          },
          {
            "path": "/food/phuket-food-route/",
            "label": "Phuket food guide"
          },
          {
            "path": "/temples/phuket/",
            "label": "Phuket temple route"
          },
          {
            "path": "/research/temples/phuket/",
            "label": "Phuket temple research"
          }
        ],
        "path": "/entities/phuket/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T12:00:00.000Z"
      },
      {
        "decision_id": "today_pai",
        "decision_type": "where_to_go_today",
        "subject_id": "pai",
        "subject_name": "Pai",
        "subject_type": "destination",
        "score": 56,
        "component_score": 68.6,
        "penalty_points": 13,
        "confidence": "High",
        "label": "fragile",
        "recommendation": "Pai is a cautious today pick.",
        "best_for": "Mountain slow travel when the north is clean and the group accepts road burden.",
        "avoid_if": "PM2.5 is high, rain is heavy, or carsickness tolerance is low.",
        "check_first": [
          "Treat Pai as optional, not mandatory.",
          "Use Chiang Mai AQI as the minimum smoke reality check.",
          "Avoid forcing Pai into a rushed route."
        ],
        "next_action": "Treat Pai as optional and do not buy it emotionally before checking the air.",
        "pivot": "Keep Chiang Mai itself as the stable plan.",
        "freshness_class": "fresh",
        "score_formula_version": "same-day-signal-v3",
        "signal_coverage": {
          "total_components": 13,
          "available_components": 11,
          "live_components": 10,
          "fallback_components": 1,
          "defaulted_components": 2,
          "coverage_ratio": 0.846
        },
        "score_components": [
          {
            "key": "aqi_fit",
            "label": "AQI fit",
            "score": 92,
            "weight": 0.16,
            "contribution": 14.72,
            "source": "signal",
            "signal_type": "aqi_risk",
            "entity_id": "pai",
            "used_default": false,
            "default_reason": "AQI risk missing; using conservative destination fallback.",
            "note": ""
          },
          {
            "key": "outdoor_comfort",
            "label": "Outdoor comfort",
            "score": 95,
            "weight": 0.12,
            "contribution": 11.4,
            "source": "signal",
            "signal_type": "outdoor_comfort",
            "entity_id": "pai",
            "used_default": false,
            "default_reason": "Outdoor comfort missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_risk",
            "label": "Rain fit",
            "score": 56,
            "weight": 0.22,
            "contribution": 12.32,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "pai",
            "used_default": false,
            "default_reason": "Rain fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "water_risk",
            "label": "Water and flood fit",
            "score": 68,
            "weight": 0.08,
            "contribution": 5.44,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "pai",
            "used_default": true,
            "default_reason": "Water-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 64,
            "weight": 0.012,
            "contribution": 0.77,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "pai",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "park_access_context",
            "label": "Park access context",
            "score": 92,
            "weight": 0.012,
            "contribution": 1.1,
            "source": "signal",
            "signal_type": "park_access_context",
            "entity_id": "pai",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DNP protected-area planning context, not live closure, ranger, capacity, or ticket truth."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 68,
            "weight": 0.05,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "pai",
            "used_default": true,
            "default_reason": "Noise-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "road_safety",
            "label": "Road safety",
            "score": 37,
            "weight": 0.05,
            "contribution": 1.85,
            "source": "signal",
            "signal_type": "road_safety_risk",
            "entity_id": "pai",
            "used_default": false,
            "default_reason": "Road-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_friction",
            "label": "Transport friction",
            "score": 51,
            "weight": 0.05,
            "contribution": 2.55,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "pai",
            "used_default": false,
            "default_reason": "Transport-friction signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "source_confidence",
            "label": "Source confidence",
            "score": 90,
            "weight": 0.03,
            "contribution": 2.7,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "pai",
            "used_default": false,
            "default_reason": "Source-confidence signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "disaster_context",
            "label": "Disaster context",
            "score": 46,
            "weight": 0.1,
            "contribution": 4.6,
            "source": "signal",
            "signal_type": "regional_disaster_context",
            "entity_id": "pai",
            "used_default": false,
            "default_reason": "Disaster context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "earthquake_context",
            "label": "Earthquake context",
            "score": 64,
            "weight": 0.03,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "regional_earthquake_context",
            "entity_id": "pai",
            "used_default": false,
            "default_reason": "Earthquake context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 63,
            "weight": 0.015,
            "contribution": 0.94,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "pai",
            "used_default": false,
            "default_reason": "Blueprint seed score missing; using live average as the fallback baseline.",
            "note": "Blueprint baseline is now a light fallback and copy anchor, not the primary scoring driver."
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 2,
            "points": 4,
            "applied": true,
            "note": "2 component(s) used fallback defaults, so the engine applies a 4-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Same-day signal spread penalty",
            "points": 9,
            "applied": true,
            "spread": 58,
            "note": "Component scores spread by 58 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "water_risk",
          "noise_comfort"
        ],
        "source_summary": "10 joined sources support this decision.",
        "weakest_signal": {
          "type": "road_safety_risk",
          "label": "Road safety burden is high",
          "reason": "28 deaths and 990 injuries are attached to this province proxy year to date. Province burden percentile 92"
        },
        "related_pages": [
          {
            "path": "/where-to-go/pai/",
            "label": "Pai destination guide"
          },
          {
            "path": "/routes/chiang-mai-pai-chiang-rai/",
            "label": "Chiang Mai / Pai / Chiang Rai route"
          },
          {
            "path": "/accommodation/pai/",
            "label": "Pai stay guide"
          },
          {
            "path": "/food/chiang-mai-food-guide/",
            "label": "Pai food guide"
          },
          {
            "path": "/temples/pai/",
            "label": "Pai temple route"
          },
          {
            "path": "/research/temples/pai/",
            "label": "Pai temple research"
          }
        ],
        "path": "/entities/pai/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T09:00:00.000Z"
      },
      {
        "decision_id": "today_krabi",
        "decision_type": "where_to_go_today",
        "subject_id": "krabi",
        "subject_name": "Krabi",
        "subject_type": "destination",
        "score": 53,
        "component_score": 66,
        "penalty_points": 13,
        "confidence": "High",
        "label": "fragile",
        "recommendation": "Krabi is a cautious today pick.",
        "best_for": "Scenery-heavy beach trips when boats are a bonus instead of a requirement.",
        "avoid_if": "You are forcing every day through a pier.",
        "check_first": [
          "Do not treat every day as a boat day.",
          "Pick Ao Nang for logistics unless scenery alone justifies a more fragile base.",
          "Keep Phuket as the infrastructure pivot if weather worsens."
        ],
        "next_action": "Choose Ao Nang for logistics and keep one non-boat day in reserve.",
        "pivot": "Use Phuket if the coast weakens but you still want the Andaman.",
        "freshness_class": "fresh",
        "score_formula_version": "same-day-signal-v3",
        "signal_coverage": {
          "total_components": 24,
          "available_components": 22,
          "live_components": 21,
          "fallback_components": 1,
          "defaulted_components": 2,
          "coverage_ratio": 0.917
        },
        "score_components": [
          {
            "key": "aqi_fit",
            "label": "AQI fit",
            "score": 92,
            "weight": 0.16,
            "contribution": 14.72,
            "source": "signal",
            "signal_type": "aqi_risk",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "AQI risk missing; using conservative destination fallback.",
            "note": ""
          },
          {
            "key": "outdoor_comfort",
            "label": "Outdoor comfort",
            "score": 95,
            "weight": 0.12,
            "contribution": 11.4,
            "source": "signal",
            "signal_type": "outdoor_comfort",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "Outdoor comfort missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_risk",
            "label": "Rain fit",
            "score": 44,
            "weight": 0.22,
            "contribution": 9.68,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "Rain fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "marine_warning_risk",
            "label": "Marine warning risk",
            "score": 34,
            "weight": 0.1,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "marine_warning_risk",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "",
            "note": "This is coastal sea-state caution for ferry and beach-dependent destinations."
          },
          {
            "key": "pier_transfer_support",
            "label": "Pier transfer support",
            "score": 78,
            "weight": 0.05,
            "contribution": 3.9,
            "source": "signal",
            "signal_type": "pier_transfer_support",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "",
            "note": "This is public pier and transfer structure support around coastal anchors, not operator seat or queue truth."
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 78,
            "weight": 0.02,
            "contribution": 1.56,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Marine Department passenger-berth support around coastal anchors, not live ferry schedule, closure, queue, or seat truth."
          },
          {
            "key": "airport_weather_operability",
            "label": "Airport weather operability",
            "score": 69,
            "weight": 0.08,
            "contribution": 5.52,
            "source": "signal",
            "signal_type": "flight_delay_risk",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "",
            "note": "This is airport weather and forecast disruption context, not airline on-time performance."
          },
          {
            "key": "airport_transfer_support",
            "label": "Airport transfer support",
            "score": 47,
            "weight": 0.012,
            "contribution": 0.56,
            "source": "signal",
            "signal_type": "airport_transfer_support",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "",
            "note": "This is ground-access support around the main airport anchor linked to the destination, not a live airline board."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 68,
            "weight": 0.012,
            "contribution": 0.82,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support for overland bus planning, not live departure, seat, or booking truth."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 58,
            "weight": 0.012,
            "contribution": 0.7,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support for intercity-bus planning, not live departure, seat, or booking truth."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support for intercity-bus planning, not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 89,
            "weight": 0.012,
            "contribution": 1.07,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context, not local realtime service quality, dispatch, or incident truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 84,
            "weight": 0.012,
            "contribution": 1.01,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "water_risk",
            "label": "Water and flood fit",
            "score": 68,
            "weight": 0.08,
            "contribution": 5.44,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "krabi",
            "used_default": true,
            "default_reason": "Water-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 76,
            "weight": 0.012,
            "contribution": 0.91,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 86,
            "weight": 0.012,
            "contribution": 1.03,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "park_access_context",
            "label": "Park access context",
            "score": 94,
            "weight": 0.012,
            "contribution": 1.13,
            "source": "signal",
            "signal_type": "park_access_context",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DNP protected-area planning context, not live closure, ranger, capacity, or ticket truth."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 68,
            "weight": 0.05,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "krabi",
            "used_default": true,
            "default_reason": "Noise-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "road_safety",
            "label": "Road safety",
            "score": 48,
            "weight": 0.05,
            "contribution": 2.4,
            "source": "signal",
            "signal_type": "road_safety_risk",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "Road-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_friction",
            "label": "Transport friction",
            "score": 60,
            "weight": 0.05,
            "contribution": 3,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "Transport-friction signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "source_confidence",
            "label": "Source confidence",
            "score": 97,
            "weight": 0.03,
            "contribution": 2.91,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "Source-confidence signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "disaster_context",
            "label": "Disaster context",
            "score": 46,
            "weight": 0.1,
            "contribution": 4.6,
            "source": "signal",
            "signal_type": "regional_disaster_context",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "Disaster context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "earthquake_context",
            "label": "Earthquake context",
            "score": 64,
            "weight": 0.03,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "regional_earthquake_context",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "Earthquake context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 76,
            "weight": 0.015,
            "contribution": 1.14,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "Blueprint seed score missing; using live average as the fallback baseline.",
            "note": "Blueprint baseline is now a light fallback and copy anchor, not the primary scoring driver."
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 2,
            "points": 4,
            "applied": true,
            "note": "2 component(s) used fallback defaults, so the engine applies a 4-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Same-day signal spread penalty",
            "points": 9,
            "applied": true,
            "spread": 61,
            "note": "Component scores spread by 61 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "water_risk",
          "noise_comfort"
        ],
        "source_summary": "21 joined sources support this decision.",
        "weakest_signal": {
          "type": "marine_warning_risk",
          "label": "Marine warning risk is high",
          "reason": "Regional marine context shows wave height 1.5 m, thunderstorm wave height 2.0 m, and wind around 27.5 km/h, with thunderstorm wording present. This is sea-state caution, not live operator closure truth."
        },
        "related_pages": [
          {
            "path": "/where-to-go/krabi/",
            "label": "Krabi destination guide"
          },
          {
            "path": "/accommodation/krabi/",
            "label": "Where to stay in Krabi"
          },
          {
            "path": "/ferries/krabi-koh-lanta/",
            "label": "Krabi to Koh Lanta ferries"
          },
          {
            "path": "/food/southern-thai-food-for-beach-trips/",
            "label": "Krabi food guide"
          },
          {
            "path": "/temples/krabi/",
            "label": "Krabi temple route"
          },
          {
            "path": "/research/temples/krabi/",
            "label": "Krabi temple research"
          }
        ],
        "path": "/entities/krabi/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T12:00:00.000Z"
      },
      {
        "decision_id": "today_pattaya-chonburi",
        "decision_type": "where_to_go_today",
        "subject_id": "pattaya-chonburi",
        "subject_name": "Pattaya / Chonburi",
        "subject_type": "destination",
        "score": 51,
        "component_score": 70.4,
        "penalty_points": 19,
        "confidence": "High",
        "label": "fragile",
        "recommendation": "Pattaya / Chonburi is a cautious today pick.",
        "best_for": "Quick coast pivots from Bangkok, nightlife, seafood, and short beach breaks with strong fallback infrastructure.",
        "avoid_if": "You want remote island mood, low traffic, or a quiet hotel-first coast stay.",
        "check_first": [
          "Treat weekend traffic as a real input, not a footnote.",
          "Pick the beach or hotel zone before the hotel brand.",
          "Use Pattaya / Chonburi when you want coast access without island-transfer fragility."
        ],
        "next_action": "Choose the hotel zone before the brand, and let weekend traffic shape the real coast call.",
        "pivot": "Use Hua Hin / Cha-am for a calmer coast, or stay in Bangkok if the sea-air mood is not worth the road burden.",
        "freshness_class": "fresh",
        "score_formula_version": "same-day-signal-v3",
        "signal_coverage": {
          "total_components": 22,
          "available_components": 16,
          "live_components": 15,
          "fallback_components": 1,
          "defaulted_components": 6,
          "coverage_ratio": 0.727
        },
        "score_components": [
          {
            "key": "aqi_fit",
            "label": "AQI fit",
            "score": 66,
            "weight": 0.16,
            "contribution": 10.56,
            "source": "signal",
            "signal_type": "aqi_risk",
            "entity_id": "pattaya-chonburi",
            "used_default": true,
            "default_reason": "AQI risk missing; using conservative destination fallback.",
            "note": ""
          },
          {
            "key": "outdoor_comfort",
            "label": "Outdoor comfort",
            "score": 70,
            "weight": 0.12,
            "contribution": 8.4,
            "source": "signal",
            "signal_type": "outdoor_comfort",
            "entity_id": "pattaya-chonburi",
            "used_default": true,
            "default_reason": "Outdoor comfort missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_risk",
            "label": "Rain fit",
            "score": 68,
            "weight": 0.22,
            "contribution": 14.96,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "pattaya-chonburi",
            "used_default": true,
            "default_reason": "Rain fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 82,
            "weight": 0.02,
            "contribution": 1.64,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Marine Department passenger-berth support around coastal anchors, not live ferry schedule, closure, queue, or seat truth."
          },
          {
            "key": "airport_weather_operability",
            "label": "Airport weather operability",
            "score": 93,
            "weight": 0.08,
            "contribution": 7.44,
            "source": "signal",
            "signal_type": "flight_delay_risk",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "",
            "note": "This is airport weather and forecast disruption context, not airline on-time performance."
          },
          {
            "key": "airport_transfer_support",
            "label": "Airport transfer support",
            "score": 32,
            "weight": 0.012,
            "contribution": 0.38,
            "source": "signal",
            "signal_type": "airport_transfer_support",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "",
            "note": "This is ground-access support around the main airport anchor linked to the destination, not a live airline board."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 78,
            "weight": 0.012,
            "contribution": 0.94,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support for overland bus planning, not live departure, seat, or booking truth."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 90,
            "weight": 0.012,
            "contribution": 1.08,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support for intercity-bus planning, not live departure, seat, or booking truth."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.012,
            "contribution": 1.15,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support for intercity-bus planning, not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 94,
            "weight": 0.012,
            "contribution": 1.13,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context, not local realtime service quality, dispatch, or incident truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 84,
            "weight": 0.012,
            "contribution": 1.01,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "water_risk",
            "label": "Water and flood fit",
            "score": 68,
            "weight": 0.08,
            "contribution": 5.44,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "pattaya-chonburi",
            "used_default": true,
            "default_reason": "Water-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "highway_transfer_friction",
            "label": "Highway transfer friction",
            "score": 88,
            "weight": 0.04,
            "contribution": 3.52,
            "source": "signal",
            "signal_type": "highway_transfer_friction",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DOH and EXAT road-support context, not live speed, queue, lane, or incident truth."
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 80,
            "weight": 0.012,
            "contribution": 0.96,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 94,
            "weight": 0.012,
            "contribution": 1.13,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 68,
            "weight": 0.05,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "pattaya-chonburi",
            "used_default": true,
            "default_reason": "Noise-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "road_safety",
            "label": "Road safety",
            "score": 66,
            "weight": 0.05,
            "contribution": 3.3,
            "source": "signal",
            "signal_type": "road_safety_risk",
            "entity_id": "pattaya-chonburi",
            "used_default": true,
            "default_reason": "Road-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_friction",
            "label": "Transport friction",
            "score": 68,
            "weight": 0.05,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "Transport-friction signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "source_confidence",
            "label": "Source confidence",
            "score": 97,
            "weight": 0.03,
            "contribution": 2.91,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "Source-confidence signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "disaster_context",
            "label": "Disaster context",
            "score": 46,
            "weight": 0.1,
            "contribution": 4.6,
            "source": "signal",
            "signal_type": "regional_disaster_context",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "Disaster context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "earthquake_context",
            "label": "Earthquake context",
            "score": 64,
            "weight": 0.03,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "regional_earthquake_context",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "Earthquake context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 74,
            "weight": 0.015,
            "contribution": 1.11,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "Blueprint seed score missing; using live average as the fallback baseline.",
            "note": "Blueprint baseline is now a light fallback and copy anchor, not the primary scoring driver."
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 6,
            "points": 10,
            "applied": true,
            "note": "6 component(s) used fallback defaults, so the engine applies a 10-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Same-day signal spread penalty",
            "points": 9,
            "applied": true,
            "spread": 47,
            "note": "Component scores spread by 47 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "aqi_fit",
          "outdoor_comfort",
          "rain_risk",
          "water_risk",
          "noise_comfort",
          "road_safety"
        ],
        "source_summary": "21 joined sources support this decision.",
        "weakest_signal": {
          "type": "airport_transfer_support",
          "label": "Airport transfer support is weak",
          "reason": "Public transport structure around this airport shows 1 mapped stop(s), 1 mode group(s), 0 rail-linked stop(s), 0 airport-link stop(s), and 1 bus-linked stop(s). This is airport-ground-access support, not live airline board or queue truth."
        },
        "related_pages": [
          {
            "path": "/where-to-go/pattaya-chonburi/",
            "label": "Pattaya / Chonburi destination guide"
          },
          {
            "path": "/venues/nightlife/",
            "label": "Thailand nightlife venue layer"
          },
          {
            "path": "/venues/restaurants/",
            "label": "Thailand restaurant venue layer"
          },
          {
            "path": "/accommodation/pattaya/",
            "label": "Pattaya / Chonburi stay guide"
          },
          {
            "path": "/food/pattaya-food-route/",
            "label": "Pattaya / Chonburi food guide"
          },
          {
            "path": "/temples/pattaya/",
            "label": "Pattaya / Chonburi temple route"
          },
          {
            "path": "/research/temples/pattaya/",
            "label": "Pattaya / Chonburi temple research"
          }
        ],
        "path": "/entities/pattaya-chonburi/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T09:51:33.917Z"
      },
      {
        "decision_id": "today_hua-hin",
        "decision_type": "where_to_go_today",
        "subject_id": "hua-hin",
        "subject_name": "Hua Hin / Cha-am",
        "subject_type": "destination",
        "score": 49,
        "component_score": 68.1,
        "penalty_points": 19,
        "confidence": "High",
        "label": "fragile",
        "recommendation": "Hua Hin / Cha-am is a cautious today pick.",
        "best_for": "Families, gentle beach days, seafood, markets, golf, and lower-friction coast access from Bangkok.",
        "avoid_if": "You want dramatic island scenery or nightlife-heavy beach energy.",
        "check_first": [
          "Choose the exact beach-town base before paying.",
          "Treat rail and road convenience as part of the value, not just background logistics.",
          "Use Hua Hin / Cha-am when you want a calmer coast than Pattaya without island transfer risk."
        ],
        "next_action": "Pick the exact beach-town base first and let rail or road convenience help decide the stay.",
        "pivot": "Use Pattaya / Chonburi for a shorter faster coast move, or Bangkok if the weather weakens and you need city backup.",
        "freshness_class": "fresh",
        "score_formula_version": "same-day-signal-v3",
        "signal_coverage": {
          "total_components": 22,
          "available_components": 16,
          "live_components": 15,
          "fallback_components": 1,
          "defaulted_components": 6,
          "coverage_ratio": 0.727
        },
        "score_components": [
          {
            "key": "aqi_fit",
            "label": "AQI fit",
            "score": 66,
            "weight": 0.16,
            "contribution": 10.56,
            "source": "signal",
            "signal_type": "aqi_risk",
            "entity_id": "hua-hin",
            "used_default": true,
            "default_reason": "AQI risk missing; using conservative destination fallback.",
            "note": ""
          },
          {
            "key": "outdoor_comfort",
            "label": "Outdoor comfort",
            "score": 70,
            "weight": 0.12,
            "contribution": 8.4,
            "source": "signal",
            "signal_type": "outdoor_comfort",
            "entity_id": "hua-hin",
            "used_default": true,
            "default_reason": "Outdoor comfort missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_risk",
            "label": "Rain fit",
            "score": 68,
            "weight": 0.22,
            "contribution": 14.96,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "hua-hin",
            "used_default": true,
            "default_reason": "Rain fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 60,
            "weight": 0.02,
            "contribution": 1.2,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Marine Department passenger-berth support around coastal anchors, not live ferry schedule, closure, queue, or seat truth."
          },
          {
            "key": "rail_feasibility",
            "label": "Rail feasibility",
            "score": 46,
            "weight": 0.012,
            "contribution": 0.55,
            "source": "signal",
            "signal_type": "rail_feasibility",
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "",
            "note": "This is public rail-support structure around the destination, not live seat, delay, or operator-disruption truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 68,
            "weight": 0.012,
            "contribution": 0.82,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support for overland bus planning, not live departure, seat, or booking truth."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 58,
            "weight": 0.012,
            "contribution": 0.7,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support for intercity-bus planning, not live departure, seat, or booking truth."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 95,
            "weight": 0.012,
            "contribution": 1.14,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support for intercity-bus planning, not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 94,
            "weight": 0.012,
            "contribution": 1.13,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context, not local realtime service quality, dispatch, or incident truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 84,
            "weight": 0.012,
            "contribution": 1.01,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "water_risk",
            "label": "Water and flood fit",
            "score": 68,
            "weight": 0.08,
            "contribution": 5.44,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "hua-hin",
            "used_default": true,
            "default_reason": "Water-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "highway_transfer_friction",
            "label": "Highway transfer friction",
            "score": 88,
            "weight": 0.04,
            "contribution": 3.52,
            "source": "signal",
            "signal_type": "highway_transfer_friction",
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DOH and EXAT road-support context, not live speed, queue, lane, or incident truth."
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 78,
            "weight": 0.012,
            "contribution": 0.94,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 82,
            "weight": 0.012,
            "contribution": 0.98,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "park_access_context",
            "label": "Park access context",
            "score": 80,
            "weight": 0.012,
            "contribution": 0.96,
            "source": "signal",
            "signal_type": "park_access_context",
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DNP protected-area planning context, not live closure, ranger, capacity, or ticket truth."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 68,
            "weight": 0.05,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "hua-hin",
            "used_default": true,
            "default_reason": "Noise-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "road_safety",
            "label": "Road safety",
            "score": 66,
            "weight": 0.05,
            "contribution": 3.3,
            "source": "signal",
            "signal_type": "road_safety_risk",
            "entity_id": "hua-hin",
            "used_default": true,
            "default_reason": "Road-risk signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_friction",
            "label": "Transport friction",
            "score": 70,
            "weight": 0.05,
            "contribution": 3.5,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "Transport-friction signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "source_confidence",
            "label": "Source confidence",
            "score": 97,
            "weight": 0.03,
            "contribution": 2.91,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "Source-confidence signal missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "disaster_context",
            "label": "Disaster context",
            "score": 46,
            "weight": 0.1,
            "contribution": 4.6,
            "source": "signal",
            "signal_type": "regional_disaster_context",
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "Disaster context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "earthquake_context",
            "label": "Earthquake context",
            "score": 64,
            "weight": 0.03,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "regional_earthquake_context",
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "Earthquake context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 75,
            "weight": 0.015,
            "contribution": 1.13,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "Blueprint seed score missing; using live average as the fallback baseline.",
            "note": "Blueprint baseline is now a light fallback and copy anchor, not the primary scoring driver."
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 6,
            "points": 10,
            "applied": true,
            "note": "6 component(s) used fallback defaults, so the engine applies a 10-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Same-day signal spread penalty",
            "points": 9,
            "applied": true,
            "spread": 42,
            "note": "Component scores spread by 42 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "aqi_fit",
          "outdoor_comfort",
          "rain_risk",
          "water_risk",
          "noise_comfort",
          "road_safety"
        ],
        "source_summary": "22 joined sources support this decision.",
        "weakest_signal": {
          "type": "rail_feasibility",
          "label": "Rail feasibility is thin",
          "reason": "Public transport structure around this destination shows 3 mapped stop(s), 1 rail-linked stop(s), 0 airport-link stop(s), and 2 bus-linked stop(s). This is rail-support context, not live seat, delay, or operator-disruption truth."
        },
        "related_pages": [
          {
            "path": "/where-to-go/hua-hin/",
            "label": "Hua Hin / Cha-am destination guide"
          },
          {
            "path": "/venues/restaurants/",
            "label": "Thailand restaurant venue layer"
          },
          {
            "path": "/rail/",
            "label": "Thailand rail layer"
          },
          {
            "path": "/accommodation/hua-hin/",
            "label": "Hua Hin / Cha-am stay guide"
          },
          {
            "path": "/temples/hua-hin-cha-am/",
            "label": "Hua Hin / Cha-am temple route"
          },
          {
            "path": "/research/temples/hua-hin-cha-am/",
            "label": "Hua Hin / Cha-am temple research"
          }
        ],
        "path": "/entities/hua-hin/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T09:51:33.917Z"
      }
    ],
    "where_to_stay": [
      {
        "decision_id": "stay_ari",
        "decision_type": "where_to_stay",
        "subject_id": "ari",
        "subject_name": "Ari",
        "subject_type": "hotel_area",
        "parent_destination_id": "bangkok",
        "parent_destination_name": "Bangkok",
        "score": 71,
        "component_score": 81.5,
        "penalty_points": 11,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Ari is a good current hotel base.",
        "best_for": "Repeat visitors, calmer mornings, cafes, and BTS-linked Bangkok without peak nightlife pressure.",
        "avoid_if": "You want the fastest first-timer checklist base or temple-heavy days every morning.",
        "check_first": [
          "Use Ari when the trip wants calmer mornings and fewer nightlife penalties.",
          "Keep temple-heavy or river-heavy days separate instead of forcing cross-city hops.",
          "Choose a truly BTS-linked hotel rather than a loose district label."
        ],
        "next_action": "Choose a truly BTS-linked hotel and keep the trip in a smaller Bangkok orbit.",
        "pivot": "Use Sukhumvit or Silom / Sathorn if the trip becomes more transit-heavy or nightlife-heavy.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 27,
          "available_components": 26,
          "live_components": 23,
          "fallback_components": 4,
          "defaulted_components": 1,
          "coverage_ratio": 0.963
        },
        "score_components": [
          {
            "key": "local_source_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.18,
            "contribution": 17.46,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "ari",
            "used_default": false,
            "default_reason": "No local source-confidence signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 93.5,
            "weight": 0.18,
            "contribution": 16.83,
            "source": "derived",
            "signal_type": null,
            "entity_id": "ari",
            "used_default": false,
            "default_reason": "",
            "note": "Blends local AQI and outdoor comfort, with parent-destination fallback when hotel-area signals are sparse."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 50,
            "weight": 0.12,
            "contribution": 6,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "ari",
            "used_default": false,
            "default_reason": "No local or parent noise signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "civic_friction",
            "label": "Civic friction",
            "score": 68,
            "weight": 0.08,
            "contribution": 5.44,
            "source": "derived",
            "signal_type": "civic_friction",
            "entity_id": "ari",
            "used_default": true,
            "default_reason": "No local or parent civic-friction signal; using conservative fallback.",
            "note": "Civic friction is only weighted where Bangkok district complaint statistics can inform hotel-area fit."
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 56,
            "weight": 0.1,
            "contribution": 5.6,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "ari",
            "used_default": false,
            "default_reason": "No local or parent rain signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 86,
            "weight": 0.14,
            "contribution": 12.04,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "ari",
            "used_default": false,
            "default_reason": "No local or parent transport signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "highway_transfer_friction",
            "label": "Highway transfer friction",
            "score": 88,
            "weight": 0.05,
            "contribution": 4.4,
            "source": "signal",
            "signal_type": "highway_transfer_friction",
            "entity_id": "ari",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DOH and EXAT road-support context behind the local base, not live speed, queue, lane, or incident truth."
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 96,
            "weight": 0.04,
            "contribution": 3.84,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "ari",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support around the local base or parent destination, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 96,
            "weight": 0.05,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "ari",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context around the local base or parent destination, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "rail_feasibility",
            "label": "Rail feasibility",
            "score": 96,
            "weight": 0.06,
            "contribution": 5.76,
            "source": "signal",
            "signal_type": "rail_feasibility",
            "entity_id": "ari",
            "used_default": false,
            "default_reason": "",
            "note": "This is public rail-support structure around the local base or parent destination, not live train seat or delay truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 86,
            "weight": 0.05,
            "contribution": 4.3,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "ari",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 92,
            "weight": 0.04,
            "contribution": 3.68,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "ari",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "ari",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support around the stay zone or its parent destination, useful for overland flexibility but not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 94,
            "weight": 0.04,
            "contribution": 3.76,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "ari",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context around the stay zone or its parent destination, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 96,
            "weight": 0.05,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "ari",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context around the stay zone or its parent destination, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "official_motorcycle_taxi_support",
            "label": "Official motorcycle-taxi support",
            "score": 55,
            "weight": 0.05,
            "contribution": 2.75,
            "source": "signal",
            "signal_type": "official_motorcycle_taxi_support",
            "entity_id": "ari",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Bangkok motorcycle-taxi stand and driver coverage from the public DLT/data.go.th dataset around the stay zone or its parent destination, useful as last-mile support context rather than live availability, dispatch, or queue truth."
          },
          {
            "key": "taxi_pickup_dropoff_support",
            "label": "Taxi pickup and dropoff support",
            "score": 87,
            "weight": 0.05,
            "contribution": 4.35,
            "source": "signal",
            "signal_type": "taxi_pickup_dropoff_support",
            "entity_id": "ari",
            "used_default": false,
            "default_reason": "",
            "note": "This is public OTP monthly taxi GPS analytics and hotspot context around the stay zone or its parent destination, useful as aggregate pickup/dropoff support rather than live dispatch, ETA, queue, or raw trip truth."
          },
          {
            "key": "urban_rapid_transit_support",
            "label": "Urban rapid-transit support",
            "score": 97,
            "weight": 0.1,
            "contribution": 9.7,
            "source": "signal",
            "signal_type": "urban_rapid_transit_support",
            "entity_id": "ari",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BTS and MRTA route-map and service-page support around the local base, not live train headway, crowding, or outage truth."
          },
          {
            "key": "urban_bus_operator_support",
            "label": "Urban bus-operator support",
            "score": 88,
            "weight": 0.06,
            "contribution": 5.28,
            "source": "signal",
            "signal_type": "urban_bus_operator_support",
            "entity_id": "ari",
            "used_default": false,
            "default_reason": "",
            "note": "This is public Thai Smile Group branch and depot footprint around Bangkok hotel-base entities, useful as a fallback and last-mile layer rather than live bus operations truth."
          },
          {
            "key": "airport_transfer_support",
            "label": "Airport transfer support",
            "score": 82,
            "weight": 0.06,
            "contribution": 4.92,
            "source": "signal",
            "signal_type": "airport_transfer_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is ground-access support around the main airport anchor behind this stay decision."
          },
          {
            "key": "airport_ground_service_support",
            "label": "Airport ground-service support",
            "score": 96,
            "weight": 0.05,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "airport_ground_service_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official airport taxi, Grab, rental, and pickup-rule context behind the stay decision, not live queue, ETA, or inventory truth."
          },
          {
            "key": "airport_board_surface_support",
            "label": "Airport board-surface support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_board_surface_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official passenger self-serve board visibility from public AOT flight-status pages, not direct live airline row truth."
          },
          {
            "key": "airport_scale_context",
            "label": "Airport scale context",
            "score": 96,
            "weight": 0.04,
            "contribution": 3.84,
            "source": "signal",
            "signal_type": "airport_scale_context",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official AOT passenger and aircraft-movement scale context behind the main airport anchor, not live delay, queue, or inventory truth."
          },
          {
            "key": "airport_environmental_support",
            "label": "Airport environmental support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_environmental_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is SET-hosted AOT annual-report disclosure context behind the stay decision, not live measured sound-level truth."
          },
          {
            "key": "water_fit",
            "label": "Water and flood fit",
            "score": 44,
            "weight": 0.08,
            "contribution": 3.52,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "ari",
            "used_default": false,
            "default_reason": "No local or parent water-risk signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "parent_destination_fit",
            "label": "Parent destination fit",
            "score": 63,
            "weight": 0.16,
            "contribution": 10.08,
            "source": "decision",
            "signal_type": null,
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "Parent destination decision missing; using blueprint fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 79,
            "weight": 0.04,
            "contribution": 3.16,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "ari",
            "used_default": false,
            "default_reason": "Blueprint seed missing; using parent score as fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 1,
            "points": 2,
            "applied": true,
            "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Stay contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 53,
            "note": "Component scores spread by 53 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "civic_friction"
        ],
        "source_summary": "40 joined sources support this decision.",
        "path": "/entities/ari/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:40:00.000Z"
      },
      {
        "decision_id": "stay_sukhumvit",
        "decision_type": "where_to_stay",
        "subject_id": "sukhumvit",
        "subject_name": "Sukhumvit",
        "subject_type": "hotel_area",
        "parent_destination_id": "bangkok",
        "parent_destination_name": "Bangkok",
        "score": 70,
        "component_score": 80.9,
        "penalty_points": 11,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Sukhumvit is a good current hotel base.",
        "best_for": "First-timers, late dinners, malls, rail access, and flexible city days.",
        "avoid_if": "You are sleep-sensitive or want temple-first city texture.",
        "check_first": [
          "Choose a station-linked hotel, not just a Sukhumvit address.",
          "Accept the noise tradeoff if nightlife is the point.",
          "Do not use Sukhumvit if the trip is really a temple-first Old Town visit."
        ],
        "next_action": "Choose a station-adjacent hotel, not just a Sukhumvit address.",
        "pivot": "Move to Silom / Sathorn for a calmer balanced base.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 27,
          "available_components": 26,
          "live_components": 23,
          "fallback_components": 4,
          "defaulted_components": 1,
          "coverage_ratio": 0.963
        },
        "score_components": [
          {
            "key": "local_source_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.18,
            "contribution": 17.46,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "sukhumvit",
            "used_default": false,
            "default_reason": "No local source-confidence signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 93.5,
            "weight": 0.18,
            "contribution": 16.83,
            "source": "derived",
            "signal_type": null,
            "entity_id": "sukhumvit",
            "used_default": false,
            "default_reason": "",
            "note": "Blends local AQI and outdoor comfort, with parent-destination fallback when hotel-area signals are sparse."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 50,
            "weight": 0.12,
            "contribution": 6,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "sukhumvit",
            "used_default": false,
            "default_reason": "No local or parent noise signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "civic_friction",
            "label": "Civic friction",
            "score": 68,
            "weight": 0.08,
            "contribution": 5.44,
            "source": "derived",
            "signal_type": "civic_friction",
            "entity_id": "sukhumvit",
            "used_default": true,
            "default_reason": "No local or parent civic-friction signal; using conservative fallback.",
            "note": "Civic friction is only weighted where Bangkok district complaint statistics can inform hotel-area fit."
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 56,
            "weight": 0.1,
            "contribution": 5.6,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "sukhumvit",
            "used_default": false,
            "default_reason": "No local or parent rain signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 86,
            "weight": 0.14,
            "contribution": 12.04,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "sukhumvit",
            "used_default": false,
            "default_reason": "No local or parent transport signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "highway_transfer_friction",
            "label": "Highway transfer friction",
            "score": 88,
            "weight": 0.05,
            "contribution": 4.4,
            "source": "signal",
            "signal_type": "highway_transfer_friction",
            "entity_id": "sukhumvit",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DOH and EXAT road-support context behind the local base, not live speed, queue, lane, or incident truth."
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 92,
            "weight": 0.04,
            "contribution": 3.68,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "sukhumvit",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support around the local base or parent destination, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 96,
            "weight": 0.05,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "sukhumvit",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context around the local base or parent destination, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "rail_feasibility",
            "label": "Rail feasibility",
            "score": 96,
            "weight": 0.06,
            "contribution": 5.76,
            "source": "signal",
            "signal_type": "rail_feasibility",
            "entity_id": "sukhumvit",
            "used_default": false,
            "default_reason": "",
            "note": "This is public rail-support structure around the local base or parent destination, not live train seat or delay truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 86,
            "weight": 0.05,
            "contribution": 4.3,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "sukhumvit",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 88,
            "weight": 0.04,
            "contribution": 3.52,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "sukhumvit",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "sukhumvit",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support around the stay zone or its parent destination, useful for overland flexibility but not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 94,
            "weight": 0.04,
            "contribution": 3.76,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "sukhumvit",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context around the stay zone or its parent destination, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 96,
            "weight": 0.05,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "sukhumvit",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context around the stay zone or its parent destination, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "official_motorcycle_taxi_support",
            "label": "Official motorcycle-taxi support",
            "score": 75,
            "weight": 0.05,
            "contribution": 3.75,
            "source": "signal",
            "signal_type": "official_motorcycle_taxi_support",
            "entity_id": "sukhumvit",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Bangkok motorcycle-taxi stand and driver coverage from the public DLT/data.go.th dataset around the stay zone or its parent destination, useful as last-mile support context rather than live availability, dispatch, or queue truth."
          },
          {
            "key": "taxi_pickup_dropoff_support",
            "label": "Taxi pickup and dropoff support",
            "score": 74,
            "weight": 0.05,
            "contribution": 3.7,
            "source": "signal",
            "signal_type": "taxi_pickup_dropoff_support",
            "entity_id": "sukhumvit",
            "used_default": false,
            "default_reason": "",
            "note": "This is public OTP monthly taxi GPS analytics and hotspot context around the stay zone or its parent destination, useful as aggregate pickup/dropoff support rather than live dispatch, ETA, queue, or raw trip truth."
          },
          {
            "key": "urban_rapid_transit_support",
            "label": "Urban rapid-transit support",
            "score": 98,
            "weight": 0.1,
            "contribution": 9.8,
            "source": "signal",
            "signal_type": "urban_rapid_transit_support",
            "entity_id": "sukhumvit",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BTS and MRTA route-map and service-page support around the local base, not live train headway, crowding, or outage truth."
          },
          {
            "key": "urban_bus_operator_support",
            "label": "Urban bus-operator support",
            "score": 62,
            "weight": 0.06,
            "contribution": 3.72,
            "source": "signal",
            "signal_type": "urban_bus_operator_support",
            "entity_id": "sukhumvit",
            "used_default": false,
            "default_reason": "",
            "note": "This is public Thai Smile Group branch and depot footprint around Bangkok hotel-base entities, useful as a fallback and last-mile layer rather than live bus operations truth."
          },
          {
            "key": "airport_transfer_support",
            "label": "Airport transfer support",
            "score": 82,
            "weight": 0.06,
            "contribution": 4.92,
            "source": "signal",
            "signal_type": "airport_transfer_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is ground-access support around the main airport anchor behind this stay decision."
          },
          {
            "key": "airport_ground_service_support",
            "label": "Airport ground-service support",
            "score": 96,
            "weight": 0.05,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "airport_ground_service_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official airport taxi, Grab, rental, and pickup-rule context behind the stay decision, not live queue, ETA, or inventory truth."
          },
          {
            "key": "airport_board_surface_support",
            "label": "Airport board-surface support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_board_surface_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official passenger self-serve board visibility from public AOT flight-status pages, not direct live airline row truth."
          },
          {
            "key": "airport_scale_context",
            "label": "Airport scale context",
            "score": 96,
            "weight": 0.04,
            "contribution": 3.84,
            "source": "signal",
            "signal_type": "airport_scale_context",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official AOT passenger and aircraft-movement scale context behind the main airport anchor, not live delay, queue, or inventory truth."
          },
          {
            "key": "airport_environmental_support",
            "label": "Airport environmental support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_environmental_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is SET-hosted AOT annual-report disclosure context behind the stay decision, not live measured sound-level truth."
          },
          {
            "key": "water_fit",
            "label": "Water and flood fit",
            "score": 44,
            "weight": 0.08,
            "contribution": 3.52,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "sukhumvit",
            "used_default": false,
            "default_reason": "No local or parent water-risk signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "parent_destination_fit",
            "label": "Parent destination fit",
            "score": 63,
            "weight": 0.16,
            "contribution": 10.08,
            "source": "decision",
            "signal_type": null,
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "Parent destination decision missing; using blueprint fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 85,
            "weight": 0.04,
            "contribution": 3.4,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "sukhumvit",
            "used_default": false,
            "default_reason": "Blueprint seed missing; using parent score as fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 1,
            "points": 2,
            "applied": true,
            "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Stay contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 54,
            "note": "Component scores spread by 54 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "civic_friction"
        ],
        "source_summary": "40 joined sources support this decision.",
        "path": "/entities/sukhumvit/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:51:33.917Z"
      },
      {
        "decision_id": "stay_silom-sathorn",
        "decision_type": "where_to_stay",
        "subject_id": "silom-sathorn",
        "subject_name": "Silom / Sathorn",
        "subject_type": "hotel_area",
        "parent_destination_id": "bangkok",
        "parent_destination_name": "Bangkok",
        "score": 70,
        "component_score": 80.9,
        "penalty_points": 11,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Silom / Sathorn is a good current hotel base.",
        "best_for": "Balanced city stays, dinners, queer nightlife, and rail access without full Sukhumvit intensity.",
        "avoid_if": "You want river mood or a low-rise slower city feel.",
        "check_first": [
          "Make sure the hotel is actually station-adjacent.",
          "Use this zone when you want balanced evenings rather than constant nightlife.",
          "Treat Silom and Sathorn as different micro-feels, not one flat blob."
        ],
        "next_action": "Verify the exact BTS or MRT walking distance before paying.",
        "pivot": "Use Riverside / Old Town for culture-first days.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 27,
          "available_components": 26,
          "live_components": 23,
          "fallback_components": 4,
          "defaulted_components": 1,
          "coverage_ratio": 0.963
        },
        "score_components": [
          {
            "key": "local_source_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.18,
            "contribution": 17.46,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "silom-sathorn",
            "used_default": false,
            "default_reason": "No local source-confidence signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 93.5,
            "weight": 0.18,
            "contribution": 16.83,
            "source": "derived",
            "signal_type": null,
            "entity_id": "silom-sathorn",
            "used_default": false,
            "default_reason": "",
            "note": "Blends local AQI and outdoor comfort, with parent-destination fallback when hotel-area signals are sparse."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 50,
            "weight": 0.12,
            "contribution": 6,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "silom-sathorn",
            "used_default": false,
            "default_reason": "No local or parent noise signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "civic_friction",
            "label": "Civic friction",
            "score": 68,
            "weight": 0.08,
            "contribution": 5.44,
            "source": "derived",
            "signal_type": "civic_friction",
            "entity_id": "silom-sathorn",
            "used_default": true,
            "default_reason": "No local or parent civic-friction signal; using conservative fallback.",
            "note": "Civic friction is only weighted where Bangkok district complaint statistics can inform hotel-area fit."
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 56,
            "weight": 0.1,
            "contribution": 5.6,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "silom-sathorn",
            "used_default": false,
            "default_reason": "No local or parent rain signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 85,
            "weight": 0.14,
            "contribution": 11.9,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "silom-sathorn",
            "used_default": false,
            "default_reason": "No local or parent transport signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "highway_transfer_friction",
            "label": "Highway transfer friction",
            "score": 88,
            "weight": 0.05,
            "contribution": 4.4,
            "source": "signal",
            "signal_type": "highway_transfer_friction",
            "entity_id": "silom-sathorn",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DOH and EXAT road-support context behind the local base, not live speed, queue, lane, or incident truth."
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 90,
            "weight": 0.04,
            "contribution": 3.6,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "silom-sathorn",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support around the local base or parent destination, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 96,
            "weight": 0.05,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "silom-sathorn",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context around the local base or parent destination, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "rail_feasibility",
            "label": "Rail feasibility",
            "score": 96,
            "weight": 0.06,
            "contribution": 5.76,
            "source": "signal",
            "signal_type": "rail_feasibility",
            "entity_id": "silom-sathorn",
            "used_default": false,
            "default_reason": "",
            "note": "This is public rail-support structure around the local base or parent destination, not live train seat or delay truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 86,
            "weight": 0.05,
            "contribution": 4.3,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "silom-sathorn",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 92,
            "weight": 0.04,
            "contribution": 3.68,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "silom-sathorn",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "silom-sathorn",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support around the stay zone or its parent destination, useful for overland flexibility but not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 94,
            "weight": 0.04,
            "contribution": 3.76,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "silom-sathorn",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context around the stay zone or its parent destination, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 96,
            "weight": 0.05,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "silom-sathorn",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context around the stay zone or its parent destination, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "official_motorcycle_taxi_support",
            "label": "Official motorcycle-taxi support",
            "score": 64,
            "weight": 0.05,
            "contribution": 3.2,
            "source": "signal",
            "signal_type": "official_motorcycle_taxi_support",
            "entity_id": "silom-sathorn",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Bangkok motorcycle-taxi stand and driver coverage from the public DLT/data.go.th dataset around the stay zone or its parent destination, useful as last-mile support context rather than live availability, dispatch, or queue truth."
          },
          {
            "key": "taxi_pickup_dropoff_support",
            "label": "Taxi pickup and dropoff support",
            "score": 86,
            "weight": 0.05,
            "contribution": 4.3,
            "source": "signal",
            "signal_type": "taxi_pickup_dropoff_support",
            "entity_id": "silom-sathorn",
            "used_default": false,
            "default_reason": "",
            "note": "This is public OTP monthly taxi GPS analytics and hotspot context around the stay zone or its parent destination, useful as aggregate pickup/dropoff support rather than live dispatch, ETA, queue, or raw trip truth."
          },
          {
            "key": "urban_rapid_transit_support",
            "label": "Urban rapid-transit support",
            "score": 98,
            "weight": 0.1,
            "contribution": 9.8,
            "source": "signal",
            "signal_type": "urban_rapid_transit_support",
            "entity_id": "silom-sathorn",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BTS and MRTA route-map and service-page support around the local base, not live train headway, crowding, or outage truth."
          },
          {
            "key": "urban_bus_operator_support",
            "label": "Urban bus-operator support",
            "score": 62,
            "weight": 0.06,
            "contribution": 3.72,
            "source": "signal",
            "signal_type": "urban_bus_operator_support",
            "entity_id": "silom-sathorn",
            "used_default": false,
            "default_reason": "",
            "note": "This is public Thai Smile Group branch and depot footprint around Bangkok hotel-base entities, useful as a fallback and last-mile layer rather than live bus operations truth."
          },
          {
            "key": "airport_transfer_support",
            "label": "Airport transfer support",
            "score": 82,
            "weight": 0.06,
            "contribution": 4.92,
            "source": "signal",
            "signal_type": "airport_transfer_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is ground-access support around the main airport anchor behind this stay decision."
          },
          {
            "key": "airport_ground_service_support",
            "label": "Airport ground-service support",
            "score": 96,
            "weight": 0.05,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "airport_ground_service_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official airport taxi, Grab, rental, and pickup-rule context behind the stay decision, not live queue, ETA, or inventory truth."
          },
          {
            "key": "airport_board_surface_support",
            "label": "Airport board-surface support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_board_surface_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official passenger self-serve board visibility from public AOT flight-status pages, not direct live airline row truth."
          },
          {
            "key": "airport_scale_context",
            "label": "Airport scale context",
            "score": 96,
            "weight": 0.04,
            "contribution": 3.84,
            "source": "signal",
            "signal_type": "airport_scale_context",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official AOT passenger and aircraft-movement scale context behind the main airport anchor, not live delay, queue, or inventory truth."
          },
          {
            "key": "airport_environmental_support",
            "label": "Airport environmental support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_environmental_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is SET-hosted AOT annual-report disclosure context behind the stay decision, not live measured sound-level truth."
          },
          {
            "key": "water_fit",
            "label": "Water and flood fit",
            "score": 44,
            "weight": 0.08,
            "contribution": 3.52,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "silom-sathorn",
            "used_default": false,
            "default_reason": "No local or parent water-risk signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "parent_destination_fit",
            "label": "Parent destination fit",
            "score": 63,
            "weight": 0.16,
            "contribution": 10.08,
            "source": "decision",
            "signal_type": null,
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "Parent destination decision missing; using blueprint fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 84,
            "weight": 0.04,
            "contribution": 3.36,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "silom-sathorn",
            "used_default": false,
            "default_reason": "Blueprint seed missing; using parent score as fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 1,
            "points": 2,
            "applied": true,
            "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Stay contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 54,
            "note": "Component scores spread by 54 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "civic_friction"
        ],
        "source_summary": "40 joined sources support this decision.",
        "path": "/entities/silom-sathorn/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:51:33.917Z"
      },
      {
        "decision_id": "stay_riverside-old-town",
        "decision_type": "where_to_stay",
        "subject_id": "riverside-old-town",
        "subject_name": "Riverside / Old Town",
        "subject_type": "hotel_area",
        "parent_destination_id": "bangkok",
        "parent_destination_name": "Bangkok",
        "score": 69,
        "component_score": 80.2,
        "penalty_points": 11,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Riverside / Old Town needs a more intentional fit before you book it.",
        "best_for": "Temple, ferry, and old-city texture with slower evenings.",
        "avoid_if": "You expect the easiest rail movement in the city.",
        "check_first": [
          "Use riverside when the trip is truly temple and river-first.",
          "Accept slightly weaker rail logic.",
          "Do not combine this base with nonstop cross-city nightlife plans."
        ],
        "next_action": "Use this base only if temples and the river are truly the point.",
        "pivot": "Switch to Sukhumvit or Silom if the plan turns transit-heavy.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 27,
          "available_components": 26,
          "live_components": 23,
          "fallback_components": 4,
          "defaulted_components": 1,
          "coverage_ratio": 0.963
        },
        "score_components": [
          {
            "key": "local_source_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.18,
            "contribution": 17.46,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "riverside-old-town",
            "used_default": false,
            "default_reason": "No local source-confidence signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 93.5,
            "weight": 0.18,
            "contribution": 16.83,
            "source": "derived",
            "signal_type": null,
            "entity_id": "riverside-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "Blends local AQI and outdoor comfort, with parent-destination fallback when hotel-area signals are sparse."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 50,
            "weight": 0.12,
            "contribution": 6,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "riverside-old-town",
            "used_default": false,
            "default_reason": "No local or parent noise signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "civic_friction",
            "label": "Civic friction",
            "score": 68,
            "weight": 0.08,
            "contribution": 5.44,
            "source": "derived",
            "signal_type": "civic_friction",
            "entity_id": "riverside-old-town",
            "used_default": true,
            "default_reason": "No local or parent civic-friction signal; using conservative fallback.",
            "note": "Civic friction is only weighted where Bangkok district complaint statistics can inform hotel-area fit."
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 56,
            "weight": 0.1,
            "contribution": 5.6,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "riverside-old-town",
            "used_default": false,
            "default_reason": "No local or parent rain signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 82,
            "weight": 0.14,
            "contribution": 11.48,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "riverside-old-town",
            "used_default": false,
            "default_reason": "No local or parent transport signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "highway_transfer_friction",
            "label": "Highway transfer friction",
            "score": 88,
            "weight": 0.05,
            "contribution": 4.4,
            "source": "signal",
            "signal_type": "highway_transfer_friction",
            "entity_id": "riverside-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DOH and EXAT road-support context behind the local base, not live speed, queue, lane, or incident truth."
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 96,
            "weight": 0.04,
            "contribution": 3.84,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "riverside-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support around the local base or parent destination, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 96,
            "weight": 0.05,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "riverside-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context around the local base or parent destination, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "rail_feasibility",
            "label": "Rail feasibility",
            "score": 96,
            "weight": 0.06,
            "contribution": 5.76,
            "source": "signal",
            "signal_type": "rail_feasibility",
            "entity_id": "riverside-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is public rail-support structure around the local base or parent destination, not live train seat or delay truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 86,
            "weight": 0.05,
            "contribution": 4.3,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "riverside-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 92,
            "weight": 0.04,
            "contribution": 3.68,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "riverside-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "riverside-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support around the stay zone or its parent destination, useful for overland flexibility but not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 94,
            "weight": 0.04,
            "contribution": 3.76,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "riverside-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context around the stay zone or its parent destination, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 96,
            "weight": 0.05,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "riverside-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context around the stay zone or its parent destination, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "official_motorcycle_taxi_support",
            "label": "Official motorcycle-taxi support",
            "score": 61,
            "weight": 0.05,
            "contribution": 3.05,
            "source": "signal",
            "signal_type": "official_motorcycle_taxi_support",
            "entity_id": "riverside-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Bangkok motorcycle-taxi stand and driver coverage from the public DLT/data.go.th dataset around the stay zone or its parent destination, useful as last-mile support context rather than live availability, dispatch, or queue truth."
          },
          {
            "key": "taxi_pickup_dropoff_support",
            "label": "Taxi pickup and dropoff support",
            "score": 89,
            "weight": 0.05,
            "contribution": 4.45,
            "source": "signal",
            "signal_type": "taxi_pickup_dropoff_support",
            "entity_id": "riverside-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is public OTP monthly taxi GPS analytics and hotspot context around the stay zone or its parent destination, useful as aggregate pickup/dropoff support rather than live dispatch, ETA, queue, or raw trip truth."
          },
          {
            "key": "urban_rapid_transit_support",
            "label": "Urban rapid-transit support",
            "score": 85,
            "weight": 0.1,
            "contribution": 8.5,
            "source": "signal",
            "signal_type": "urban_rapid_transit_support",
            "entity_id": "riverside-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BTS and MRTA route-map and service-page support around the local base, not live train headway, crowding, or outage truth."
          },
          {
            "key": "urban_bus_operator_support",
            "label": "Urban bus-operator support",
            "score": 70,
            "weight": 0.06,
            "contribution": 4.2,
            "source": "signal",
            "signal_type": "urban_bus_operator_support",
            "entity_id": "riverside-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is public Thai Smile Group branch and depot footprint around Bangkok hotel-base entities, useful as a fallback and last-mile layer rather than live bus operations truth."
          },
          {
            "key": "airport_transfer_support",
            "label": "Airport transfer support",
            "score": 82,
            "weight": 0.06,
            "contribution": 4.92,
            "source": "signal",
            "signal_type": "airport_transfer_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is ground-access support around the main airport anchor behind this stay decision."
          },
          {
            "key": "airport_ground_service_support",
            "label": "Airport ground-service support",
            "score": 96,
            "weight": 0.05,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "airport_ground_service_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official airport taxi, Grab, rental, and pickup-rule context behind the stay decision, not live queue, ETA, or inventory truth."
          },
          {
            "key": "airport_board_surface_support",
            "label": "Airport board-surface support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_board_surface_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official passenger self-serve board visibility from public AOT flight-status pages, not direct live airline row truth."
          },
          {
            "key": "airport_scale_context",
            "label": "Airport scale context",
            "score": 96,
            "weight": 0.04,
            "contribution": 3.84,
            "source": "signal",
            "signal_type": "airport_scale_context",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is official AOT passenger and aircraft-movement scale context behind the main airport anchor, not live delay, queue, or inventory truth."
          },
          {
            "key": "airport_environmental_support",
            "label": "Airport environmental support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_environmental_support",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": "This is SET-hosted AOT annual-report disclosure context behind the stay decision, not live measured sound-level truth."
          },
          {
            "key": "water_fit",
            "label": "Water and flood fit",
            "score": 44,
            "weight": 0.08,
            "contribution": 3.52,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "riverside-old-town",
            "used_default": false,
            "default_reason": "No local or parent water-risk signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "parent_destination_fit",
            "label": "Parent destination fit",
            "score": 63,
            "weight": 0.16,
            "contribution": 10.08,
            "source": "decision",
            "signal_type": null,
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "Parent destination decision missing; using blueprint fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 77,
            "weight": 0.04,
            "contribution": 3.08,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "riverside-old-town",
            "used_default": false,
            "default_reason": "Blueprint seed missing; using parent score as fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 1,
            "points": 2,
            "applied": true,
            "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Stay contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 53,
            "note": "Component scores spread by 53 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "civic_friction"
        ],
        "source_summary": "41 joined sources support this decision.",
        "path": "/entities/riverside-old-town/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:51:33.917Z"
      },
      {
        "decision_id": "stay_nimman",
        "decision_type": "where_to_stay",
        "subject_id": "nimman",
        "subject_name": "Nimman",
        "subject_type": "hotel_area",
        "parent_destination_id": "chiang-mai",
        "parent_destination_name": "Chiang Mai",
        "score": 68,
        "component_score": 76.9,
        "penalty_points": 9,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Nimman needs a more intentional fit before you book it.",
        "best_for": "Longer Chiang Mai stays, cafes, comfort, and coworking rhythm.",
        "avoid_if": "You want temple density right outside the hotel or AQI is bad enough to sink the city.",
        "check_first": [
          "Choose Nimman when comfort and cafes matter more than temple density.",
          "Keep Old City as the culture pivot.",
          "Let AQI outrank the hotel pool."
        ],
        "next_action": "Let PM2.5 outrank the hotel pool before you commit.",
        "pivot": "Use Old City for a shorter temple-first stay.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 21,
          "available_components": 21,
          "live_components": 18,
          "fallback_components": 3,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "local_source_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.18,
            "contribution": 17.46,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "nimman",
            "used_default": false,
            "default_reason": "No local source-confidence signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 93.5,
            "weight": 0.18,
            "contribution": 16.83,
            "source": "derived",
            "signal_type": null,
            "entity_id": "nimman",
            "used_default": false,
            "default_reason": "",
            "note": "Blends local AQI and outdoor comfort, with parent-destination fallback when hotel-area signals are sparse."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 88,
            "weight": 0.12,
            "contribution": 10.56,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "nimman",
            "used_default": false,
            "default_reason": "No local or parent noise signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 56,
            "weight": 0.1,
            "contribution": 5.6,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "nimman",
            "used_default": false,
            "default_reason": "No local or parent rain signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 63,
            "weight": 0.14,
            "contribution": 8.82,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "nimman",
            "used_default": false,
            "default_reason": "No local or parent transport signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 82,
            "weight": 0.04,
            "contribution": 3.28,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "nimman",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support around the local base or parent destination, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 96,
            "weight": 0.05,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "nimman",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context around the local base or parent destination, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "rail_feasibility",
            "label": "Rail feasibility",
            "score": 37,
            "weight": 0.06,
            "contribution": 2.22,
            "source": "signal",
            "signal_type": "rail_feasibility",
            "entity_id": "nimman",
            "used_default": false,
            "default_reason": "",
            "note": "This is public rail-support structure around the local base or parent destination, not live train seat or delay truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 86,
            "weight": 0.05,
            "contribution": 4.3,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "nimman",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 72,
            "weight": 0.04,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "nimman",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "nimman",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support around the stay zone or its parent destination, useful for overland flexibility but not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 94,
            "weight": 0.04,
            "contribution": 3.76,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "nimman",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context around the stay zone or its parent destination, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 92,
            "weight": 0.05,
            "contribution": 4.6,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "nimman",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context around the stay zone or its parent destination, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "airport_transfer_support",
            "label": "Airport transfer support",
            "score": 41,
            "weight": 0.06,
            "contribution": 2.46,
            "source": "signal",
            "signal_type": "airport_transfer_support",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is ground-access support around the main airport anchor behind this stay decision."
          },
          {
            "key": "airport_ground_service_support",
            "label": "Airport ground-service support",
            "score": 42,
            "weight": 0.05,
            "contribution": 2.1,
            "source": "signal",
            "signal_type": "airport_ground_service_support",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official airport taxi, Grab, rental, and pickup-rule context behind the stay decision, not live queue, ETA, or inventory truth."
          },
          {
            "key": "airport_board_surface_support",
            "label": "Airport board-surface support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_board_surface_support",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official passenger self-serve board visibility from public AOT flight-status pages, not direct live airline row truth."
          },
          {
            "key": "airport_scale_context",
            "label": "Airport scale context",
            "score": 50,
            "weight": 0.04,
            "contribution": 2,
            "source": "signal",
            "signal_type": "airport_scale_context",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official AOT passenger and aircraft-movement scale context behind the main airport anchor, not live delay, queue, or inventory truth."
          },
          {
            "key": "airport_environmental_support",
            "label": "Airport environmental support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_environmental_support",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is SET-hosted AOT annual-report disclosure context behind the stay decision, not live measured sound-level truth."
          },
          {
            "key": "water_fit",
            "label": "Water and flood fit",
            "score": 86,
            "weight": 0.08,
            "contribution": 6.88,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "nimman",
            "used_default": false,
            "default_reason": "No local or parent water-risk signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "parent_destination_fit",
            "label": "Parent destination fit",
            "score": 65,
            "weight": 0.16,
            "contribution": 10.4,
            "source": "decision",
            "signal_type": null,
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "Parent destination decision missing; using blueprint fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 80,
            "weight": 0.04,
            "contribution": 3.2,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "nimman",
            "used_default": false,
            "default_reason": "Blueprint seed missing; using parent score as fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Stay contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 60,
            "note": "Component scores spread by 60 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "25 joined sources support this decision.",
        "path": "/entities/nimman/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:00:00.000Z"
      },
      {
        "decision_id": "stay_old-city-chiang-mai",
        "decision_type": "where_to_stay",
        "subject_id": "old-city-chiang-mai",
        "subject_name": "Old City Chiang Mai",
        "subject_type": "hotel_area",
        "parent_destination_id": "chiang-mai",
        "parent_destination_name": "Chiang Mai",
        "score": 68,
        "component_score": 77,
        "penalty_points": 9,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Old City Chiang Mai needs a more intentional fit before you book it.",
        "best_for": "First Chiang Mai stays, temples, markets, and compact food walks when AQI is acceptable.",
        "avoid_if": "PM2.5 is high or you want coworking and comfort more than heritage mood.",
        "check_first": [
          "Use Old City when temple density and walkable food matter more than coworking comfort.",
          "Let PM2.5 outrank the charm of a heritage hotel.",
          "Switch to Nimman when comfort and indoor backup become the real need."
        ],
        "next_action": "Let AQI outrank the hotel charm, then choose a walkable lane inside or just outside the old walls.",
        "pivot": "Use Nimman if comfort and indoor backup become more important than temple density.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 21,
          "available_components": 21,
          "live_components": 18,
          "fallback_components": 3,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "local_source_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.18,
            "contribution": 17.46,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "old-city-chiang-mai",
            "used_default": false,
            "default_reason": "No local source-confidence signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 93.5,
            "weight": 0.18,
            "contribution": 16.83,
            "source": "derived",
            "signal_type": null,
            "entity_id": "old-city-chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "Blends local AQI and outdoor comfort, with parent-destination fallback when hotel-area signals are sparse."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 88,
            "weight": 0.12,
            "contribution": 10.56,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "old-city-chiang-mai",
            "used_default": false,
            "default_reason": "No local or parent noise signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 56,
            "weight": 0.1,
            "contribution": 5.6,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "old-city-chiang-mai",
            "used_default": false,
            "default_reason": "No local or parent rain signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 64,
            "weight": 0.14,
            "contribution": 8.96,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "old-city-chiang-mai",
            "used_default": false,
            "default_reason": "No local or parent transport signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 84,
            "weight": 0.04,
            "contribution": 3.36,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "old-city-chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support around the local base or parent destination, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 96,
            "weight": 0.05,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "old-city-chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context around the local base or parent destination, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "rail_feasibility",
            "label": "Rail feasibility",
            "score": 43,
            "weight": 0.06,
            "contribution": 2.58,
            "source": "signal",
            "signal_type": "rail_feasibility",
            "entity_id": "old-city-chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is public rail-support structure around the local base or parent destination, not live train seat or delay truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 80,
            "weight": 0.05,
            "contribution": 4,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "old-city-chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 68,
            "weight": 0.04,
            "contribution": 2.72,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "old-city-chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "old-city-chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support around the stay zone or its parent destination, useful for overland flexibility but not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 94,
            "weight": 0.04,
            "contribution": 3.76,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "old-city-chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context around the stay zone or its parent destination, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 91,
            "weight": 0.05,
            "contribution": 4.55,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "old-city-chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context around the stay zone or its parent destination, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "airport_transfer_support",
            "label": "Airport transfer support",
            "score": 41,
            "weight": 0.06,
            "contribution": 2.46,
            "source": "signal",
            "signal_type": "airport_transfer_support",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is ground-access support around the main airport anchor behind this stay decision."
          },
          {
            "key": "airport_ground_service_support",
            "label": "Airport ground-service support",
            "score": 42,
            "weight": 0.05,
            "contribution": 2.1,
            "source": "signal",
            "signal_type": "airport_ground_service_support",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official airport taxi, Grab, rental, and pickup-rule context behind the stay decision, not live queue, ETA, or inventory truth."
          },
          {
            "key": "airport_board_surface_support",
            "label": "Airport board-surface support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_board_surface_support",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official passenger self-serve board visibility from public AOT flight-status pages, not direct live airline row truth."
          },
          {
            "key": "airport_scale_context",
            "label": "Airport scale context",
            "score": 50,
            "weight": 0.04,
            "contribution": 2,
            "source": "signal",
            "signal_type": "airport_scale_context",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official AOT passenger and aircraft-movement scale context behind the main airport anchor, not live delay, queue, or inventory truth."
          },
          {
            "key": "airport_environmental_support",
            "label": "Airport environmental support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_environmental_support",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": "This is SET-hosted AOT annual-report disclosure context behind the stay decision, not live measured sound-level truth."
          },
          {
            "key": "water_fit",
            "label": "Water and flood fit",
            "score": 86,
            "weight": 0.08,
            "contribution": 6.88,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "old-city-chiang-mai",
            "used_default": false,
            "default_reason": "No local or parent water-risk signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "parent_destination_fit",
            "label": "Parent destination fit",
            "score": 65,
            "weight": 0.16,
            "contribution": 10.4,
            "source": "decision",
            "signal_type": null,
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "Parent destination decision missing; using blueprint fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 82,
            "weight": 0.04,
            "contribution": 3.28,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "old-city-chiang-mai",
            "used_default": false,
            "default_reason": "Blueprint seed missing; using parent score as fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Stay contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 56,
            "note": "Component scores spread by 56 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "25 joined sources support this decision.",
        "path": "/entities/old-city-chiang-mai/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:51:33.917Z"
      },
      {
        "decision_id": "stay_bophut-fishermans-village",
        "decision_type": "where_to_stay",
        "subject_id": "bophut-fishermans-village",
        "subject_name": "Bophut / Fisherman's Village",
        "subject_type": "hotel_area",
        "parent_destination_id": "koh-samui",
        "parent_destination_name": "Koh Samui",
        "score": 64,
        "component_score": 74.8,
        "penalty_points": 11,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Bophut / Fisherman's Village needs a more intentional fit before you book it.",
        "best_for": "Balanced Samui comfort, families, and evening walks without maximum party energy.",
        "avoid_if": "You need Samui only as a launchpad for a fragile island chain.",
        "check_first": [
          "Use Bophut when you want Samui to be the stable base.",
          "Keep Chaweng only for bigger nightlife needs.",
          "Do not chain extra boats without checking the weather stack."
        ],
        "next_action": "Keep Samui itself as the stable base before adding extra ferries.",
        "pivot": "Use Bangkok if the transfer stack becomes the whole problem.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 16,
          "available_components": 15,
          "live_components": 12,
          "fallback_components": 4,
          "defaulted_components": 1,
          "coverage_ratio": 0.938
        },
        "score_components": [
          {
            "key": "local_source_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.18,
            "contribution": 17.46,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "bophut-fishermans-village",
            "used_default": false,
            "default_reason": "No local source-confidence signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 93.5,
            "weight": 0.18,
            "contribution": 16.83,
            "source": "derived",
            "signal_type": null,
            "entity_id": "bophut-fishermans-village",
            "used_default": false,
            "default_reason": "",
            "note": "Blends local AQI and outdoor comfort, with parent-destination fallback when hotel-area signals are sparse."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 66,
            "weight": 0.12,
            "contribution": 7.92,
            "source": "derived",
            "signal_type": "noise_risk",
            "entity_id": "bophut-fishermans-village",
            "used_default": true,
            "default_reason": "No local or parent noise signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 56,
            "weight": 0.1,
            "contribution": 5.6,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "bophut-fishermans-village",
            "used_default": false,
            "default_reason": "No local or parent rain signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 61,
            "weight": 0.14,
            "contribution": 8.54,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "bophut-fishermans-village",
            "used_default": false,
            "default_reason": "No local or parent transport signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 84,
            "weight": 0.04,
            "contribution": 3.36,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "bophut-fishermans-village",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support around the local base or parent destination, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 84,
            "weight": 0.05,
            "contribution": 4.2,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "bophut-fishermans-village",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context around the local base or parent destination, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 68,
            "weight": 0.05,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "bophut-fishermans-village",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 58,
            "weight": 0.04,
            "contribution": 2.32,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "bophut-fishermans-village",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 77,
            "weight": 0.04,
            "contribution": 3.08,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "bophut-fishermans-village",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context around the stay zone or its parent destination, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 83,
            "weight": 0.05,
            "contribution": 4.15,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "bophut-fishermans-village",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context around the stay zone or its parent destination, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "pier_transfer_support",
            "label": "Pier transfer support",
            "score": 22,
            "weight": 0.04,
            "contribution": 0.88,
            "source": "signal",
            "signal_type": "pier_transfer_support",
            "entity_id": "bophut-fishermans-village",
            "used_default": false,
            "default_reason": "",
            "note": "This is public pier and transfer structure around the stay zone, linked pier anchor, or parent destination, not operator schedule or queue-length truth."
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 90,
            "weight": 0.05,
            "contribution": 4.5,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": "bophut-fishermans-village",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Marine Department passenger-berth support around the stay zone or its parent destination, not live ferry schedule, closure, queue, or seat truth."
          },
          {
            "key": "water_fit",
            "label": "Water and flood fit",
            "score": 86,
            "weight": 0.08,
            "contribution": 6.88,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "bophut-fishermans-village",
            "used_default": false,
            "default_reason": "No local or parent water-risk signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "parent_destination_fit",
            "label": "Parent destination fit",
            "score": 59,
            "weight": 0.16,
            "contribution": 9.44,
            "source": "decision",
            "signal_type": null,
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "Parent destination decision missing; using blueprint fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 80,
            "weight": 0.04,
            "contribution": 3.2,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "bophut-fishermans-village",
            "used_default": false,
            "default_reason": "Blueprint seed missing; using parent score as fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 1,
            "points": 2,
            "applied": true,
            "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Stay contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 75,
            "note": "Component scores spread by 75 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "noise_comfort"
        ],
        "source_summary": "17 joined sources support this decision.",
        "path": "/entities/bophut-fishermans-village/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T18:00:00.000Z"
      },
      {
        "decision_id": "stay_chaweng",
        "decision_type": "where_to_stay",
        "subject_id": "chaweng",
        "subject_name": "Chaweng",
        "subject_type": "hotel_area",
        "parent_destination_id": "koh-samui",
        "parent_destination_name": "Koh Samui",
        "score": 64,
        "component_score": 74.6,
        "penalty_points": 11,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Chaweng needs a more intentional fit before you book it.",
        "best_for": "Short Samui stays, nightlife, hotel choice, and airport convenience.",
        "avoid_if": "Quiet sleep matters more than service density.",
        "check_first": [
          "Choose Chaweng when service density and evening energy matter more than quiet sleep.",
          "Do not overpay for Chaweng if the trip is really a calm beach reset.",
          "Keep Bophut or Lamai visible as the softer pivot."
        ],
        "next_action": "Choose Chaweng only when the trip really wants energy and easy services close by.",
        "pivot": "Use Bophut or Lamai when Samui needs a softer base.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 16,
          "available_components": 15,
          "live_components": 12,
          "fallback_components": 4,
          "defaulted_components": 1,
          "coverage_ratio": 0.938
        },
        "score_components": [
          {
            "key": "local_source_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.18,
            "contribution": 17.46,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "chaweng",
            "used_default": false,
            "default_reason": "No local source-confidence signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 93.5,
            "weight": 0.18,
            "contribution": 16.83,
            "source": "derived",
            "signal_type": null,
            "entity_id": "chaweng",
            "used_default": false,
            "default_reason": "",
            "note": "Blends local AQI and outdoor comfort, with parent-destination fallback when hotel-area signals are sparse."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 66,
            "weight": 0.12,
            "contribution": 7.92,
            "source": "derived",
            "signal_type": "noise_risk",
            "entity_id": "chaweng",
            "used_default": true,
            "default_reason": "No local or parent noise signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 56,
            "weight": 0.1,
            "contribution": 5.6,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "chaweng",
            "used_default": false,
            "default_reason": "No local or parent rain signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 62,
            "weight": 0.14,
            "contribution": 8.68,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "chaweng",
            "used_default": false,
            "default_reason": "No local or parent transport signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 82,
            "weight": 0.04,
            "contribution": 3.28,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "chaweng",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support around the local base or parent destination, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 84,
            "weight": 0.05,
            "contribution": 4.2,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "chaweng",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context around the local base or parent destination, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 62,
            "weight": 0.05,
            "contribution": 3.1,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "chaweng",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 54,
            "weight": 0.04,
            "contribution": 2.16,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "chaweng",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 77,
            "weight": 0.04,
            "contribution": 3.08,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "chaweng",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context around the stay zone or its parent destination, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 83,
            "weight": 0.05,
            "contribution": 4.15,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "chaweng",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context around the stay zone or its parent destination, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "pier_transfer_support",
            "label": "Pier transfer support",
            "score": 25,
            "weight": 0.04,
            "contribution": 1,
            "source": "signal",
            "signal_type": "pier_transfer_support",
            "entity_id": "chaweng",
            "used_default": false,
            "default_reason": "",
            "note": "This is public pier and transfer structure around the stay zone, linked pier anchor, or parent destination, not operator schedule or queue-length truth."
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 90,
            "weight": 0.05,
            "contribution": 4.5,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": "chaweng",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Marine Department passenger-berth support around the stay zone or its parent destination, not live ferry schedule, closure, queue, or seat truth."
          },
          {
            "key": "water_fit",
            "label": "Water and flood fit",
            "score": 86,
            "weight": 0.08,
            "contribution": 6.88,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "chaweng",
            "used_default": false,
            "default_reason": "No local or parent water-risk signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "parent_destination_fit",
            "label": "Parent destination fit",
            "score": 59,
            "weight": 0.16,
            "contribution": 9.44,
            "source": "decision",
            "signal_type": null,
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "Parent destination decision missing; using blueprint fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 78,
            "weight": 0.04,
            "contribution": 3.12,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "chaweng",
            "used_default": false,
            "default_reason": "Blueprint seed missing; using parent score as fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 1,
            "points": 2,
            "applied": true,
            "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Stay contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 72,
            "note": "Component scores spread by 72 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "noise_comfort"
        ],
        "source_summary": "17 joined sources support this decision.",
        "path": "/entities/chaweng/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T18:00:00.000Z"
      },
      {
        "decision_id": "stay_lamai",
        "decision_type": "where_to_stay",
        "subject_id": "lamai",
        "subject_name": "Lamai",
        "subject_type": "hotel_area",
        "parent_destination_id": "koh-samui",
        "parent_destination_name": "Koh Samui",
        "score": 64,
        "component_score": 74.5,
        "penalty_points": 11,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Lamai needs a more intentional fit before you book it.",
        "best_for": "Middle-ground Samui beach stays with softer pacing than Chaweng.",
        "avoid_if": "You want the widest service density or the quietest north-coast retreat.",
        "check_first": [
          "Use Lamai when the trip wants a calmer beach base without losing all convenience.",
          "Do not assume Lamai solves island-wide transfer friction by itself.",
          "Keep Bophut visible when evening walks and food matter more than beach time."
        ],
        "next_action": "Use Lamai when beach comfort and readable evenings matter more than maximum nightlife.",
        "pivot": "Use Bophut for a more balanced food-and-family base.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 16,
          "available_components": 15,
          "live_components": 12,
          "fallback_components": 4,
          "defaulted_components": 1,
          "coverage_ratio": 0.938
        },
        "score_components": [
          {
            "key": "local_source_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.18,
            "contribution": 17.46,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "lamai",
            "used_default": false,
            "default_reason": "No local source-confidence signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 93.5,
            "weight": 0.18,
            "contribution": 16.83,
            "source": "derived",
            "signal_type": null,
            "entity_id": "lamai",
            "used_default": false,
            "default_reason": "",
            "note": "Blends local AQI and outdoor comfort, with parent-destination fallback when hotel-area signals are sparse."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 66,
            "weight": 0.12,
            "contribution": 7.92,
            "source": "derived",
            "signal_type": "noise_risk",
            "entity_id": "lamai",
            "used_default": true,
            "default_reason": "No local or parent noise signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 56,
            "weight": 0.1,
            "contribution": 5.6,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "lamai",
            "used_default": false,
            "default_reason": "No local or parent rain signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 62,
            "weight": 0.14,
            "contribution": 8.68,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "lamai",
            "used_default": false,
            "default_reason": "No local or parent transport signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 80,
            "weight": 0.04,
            "contribution": 3.2,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "lamai",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support around the local base or parent destination, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 84,
            "weight": 0.05,
            "contribution": 4.2,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "lamai",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context around the local base or parent destination, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 62,
            "weight": 0.05,
            "contribution": 3.1,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "lamai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 54,
            "weight": 0.04,
            "contribution": 2.16,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "lamai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 77,
            "weight": 0.04,
            "contribution": 3.08,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "lamai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context around the stay zone or its parent destination, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 83,
            "weight": 0.05,
            "contribution": 4.15,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "lamai",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context around the stay zone or its parent destination, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "pier_transfer_support",
            "label": "Pier transfer support",
            "score": 25,
            "weight": 0.04,
            "contribution": 1,
            "source": "signal",
            "signal_type": "pier_transfer_support",
            "entity_id": "lamai",
            "used_default": false,
            "default_reason": "",
            "note": "This is public pier and transfer structure around the stay zone, linked pier anchor, or parent destination, not operator schedule or queue-length truth."
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 90,
            "weight": 0.05,
            "contribution": 4.5,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": "lamai",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Marine Department passenger-berth support around the stay zone or its parent destination, not live ferry schedule, closure, queue, or seat truth."
          },
          {
            "key": "water_fit",
            "label": "Water and flood fit",
            "score": 86,
            "weight": 0.08,
            "contribution": 6.88,
            "source": "signal",
            "signal_type": "flood_water_risk",
            "entity_id": "lamai",
            "used_default": false,
            "default_reason": "No local or parent water-risk signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "parent_destination_fit",
            "label": "Parent destination fit",
            "score": 59,
            "weight": 0.16,
            "contribution": 9.44,
            "source": "decision",
            "signal_type": null,
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "Parent destination decision missing; using blueprint fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 79,
            "weight": 0.04,
            "contribution": 3.16,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "lamai",
            "used_default": false,
            "default_reason": "Blueprint seed missing; using parent score as fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 1,
            "points": 2,
            "applied": true,
            "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Stay contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 72,
            "note": "Component scores spread by 72 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "noise_comfort"
        ],
        "source_summary": "17 joined sources support this decision.",
        "path": "/entities/lamai/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T18:00:00.000Z"
      },
      {
        "decision_id": "stay_kata-karon",
        "decision_type": "where_to_stay",
        "subject_id": "kata-karon",
        "subject_name": "Kata / Karon",
        "subject_type": "hotel_area",
        "parent_destination_id": "phuket",
        "parent_destination_name": "Phuket",
        "score": 63,
        "component_score": 73.6,
        "penalty_points": 11,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Kata / Karon needs a more intentional fit before you book it.",
        "best_for": "Balanced Phuket beach stays, families, and manageable services.",
        "avoid_if": "You want nightlife density or the freedom to ignore coast conditions.",
        "check_first": [
          "Use Kata / Karon when first-beach simplicity matters.",
          "Do not assume all Phuket beaches behave the same.",
          "Use Old Town as the rain and food fallback."
        ],
        "next_action": "Use Old Town as the rain and food fallback before locking the beach.",
        "pivot": "Switch to Phuket Old Town or a different coast if beach conditions weaken.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 22,
          "available_components": 21,
          "live_components": 18,
          "fallback_components": 4,
          "defaulted_components": 1,
          "coverage_ratio": 0.955
        },
        "score_components": [
          {
            "key": "local_source_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.18,
            "contribution": 17.46,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "kata-karon",
            "used_default": false,
            "default_reason": "No local source-confidence signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 93.5,
            "weight": 0.18,
            "contribution": 16.83,
            "source": "derived",
            "signal_type": null,
            "entity_id": "kata-karon",
            "used_default": false,
            "default_reason": "",
            "note": "Blends local AQI and outdoor comfort, with parent-destination fallback when hotel-area signals are sparse."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 74,
            "weight": 0.12,
            "contribution": 8.88,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "kata-karon",
            "used_default": false,
            "default_reason": "No local or parent noise signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 44,
            "weight": 0.1,
            "contribution": 4.4,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "kata-karon",
            "used_default": false,
            "default_reason": "No local or parent rain signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 60,
            "weight": 0.14,
            "contribution": 8.4,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "kata-karon",
            "used_default": false,
            "default_reason": "No local or parent transport signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 80,
            "weight": 0.04,
            "contribution": 3.2,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "kata-karon",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support around the local base or parent destination, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 96,
            "weight": 0.05,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "kata-karon",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context around the local base or parent destination, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 78,
            "weight": 0.05,
            "contribution": 3.9,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "kata-karon",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 77,
            "weight": 0.04,
            "contribution": 3.08,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "kata-karon",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "kata-karon",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support around the stay zone or its parent destination, useful for overland flexibility but not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 85,
            "weight": 0.04,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "kata-karon",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context around the stay zone or its parent destination, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 83,
            "weight": 0.05,
            "contribution": 4.15,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "kata-karon",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context around the stay zone or its parent destination, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "pier_transfer_support",
            "label": "Pier transfer support",
            "score": 48,
            "weight": 0.04,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "pier_transfer_support",
            "entity_id": "kata-karon",
            "used_default": false,
            "default_reason": "",
            "note": "This is public pier and transfer structure around the stay zone, linked pier anchor, or parent destination, not operator schedule or queue-length truth."
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 92,
            "weight": 0.05,
            "contribution": 4.6,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": "kata-karon",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Marine Department passenger-berth support around the stay zone or its parent destination, not live ferry schedule, closure, queue, or seat truth."
          },
          {
            "key": "airport_transfer_support",
            "label": "Airport transfer support",
            "score": 32,
            "weight": 0.06,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "airport_transfer_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is ground-access support around the main airport anchor behind this stay decision."
          },
          {
            "key": "airport_ground_service_support",
            "label": "Airport ground-service support",
            "score": 42,
            "weight": 0.05,
            "contribution": 2.1,
            "source": "signal",
            "signal_type": "airport_ground_service_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is official airport taxi, Grab, rental, and pickup-rule context behind the stay decision, not live queue, ETA, or inventory truth."
          },
          {
            "key": "airport_board_surface_support",
            "label": "Airport board-surface support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_board_surface_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is official passenger self-serve board visibility from public AOT flight-status pages, not direct live airline row truth."
          },
          {
            "key": "airport_scale_context",
            "label": "Airport scale context",
            "score": 63,
            "weight": 0.04,
            "contribution": 2.52,
            "source": "signal",
            "signal_type": "airport_scale_context",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is official AOT passenger and aircraft-movement scale context behind the main airport anchor, not live delay, queue, or inventory truth."
          },
          {
            "key": "airport_environmental_support",
            "label": "Airport environmental support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_environmental_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is SET-hosted AOT annual-report disclosure context behind the stay decision, not live measured sound-level truth."
          },
          {
            "key": "water_fit",
            "label": "Water and flood fit",
            "score": 68,
            "weight": 0.08,
            "contribution": 5.44,
            "source": "derived",
            "signal_type": "flood_water_risk",
            "entity_id": "kata-karon",
            "used_default": true,
            "default_reason": "No local or parent water-risk signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "parent_destination_fit",
            "label": "Parent destination fit",
            "score": 56,
            "weight": 0.16,
            "contribution": 8.96,
            "source": "decision",
            "signal_type": null,
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "Parent destination decision missing; using blueprint fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 81,
            "weight": 0.04,
            "contribution": 3.24,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "kata-karon",
            "used_default": false,
            "default_reason": "Blueprint seed missing; using parent score as fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 1,
            "points": 2,
            "applied": true,
            "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Stay contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 65,
            "note": "Component scores spread by 65 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "water_fit"
        ],
        "source_summary": "23 joined sources support this decision.",
        "path": "/entities/kata-karon/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T18:00:00.000Z"
      },
      {
        "decision_id": "stay_phuket-old-town",
        "decision_type": "where_to_stay",
        "subject_id": "phuket-old-town",
        "subject_name": "Phuket Old Town",
        "subject_type": "hotel_area",
        "parent_destination_id": "phuket",
        "parent_destination_name": "Phuket",
        "score": 63,
        "component_score": 73.7,
        "penalty_points": 11,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Phuket Old Town needs a more intentional fit before you book it.",
        "best_for": "Food-first Phuket, rain backup, cafes, architecture, and town-based slower stays.",
        "avoid_if": "You expect a beach outside the room every morning.",
        "check_first": [
          "Use Old Town when weather, food, or architecture outranks waking up by the beach.",
          "Do not confuse a stylish town hotel with a beach holiday base.",
          "Keep Patong or Kata / Karon visible when the trip is still beach-first."
        ],
        "next_action": "Treat Old Town as a weather and food base, not a hidden beach hack.",
        "pivot": "Use Kata / Karon or Patong if the trip stays beach-first.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 22,
          "available_components": 21,
          "live_components": 18,
          "fallback_components": 4,
          "defaulted_components": 1,
          "coverage_ratio": 0.955
        },
        "score_components": [
          {
            "key": "local_source_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.18,
            "contribution": 17.46,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "phuket-old-town",
            "used_default": false,
            "default_reason": "No local source-confidence signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 93.5,
            "weight": 0.18,
            "contribution": 16.83,
            "source": "derived",
            "signal_type": null,
            "entity_id": "phuket-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "Blends local AQI and outdoor comfort, with parent-destination fallback when hotel-area signals are sparse."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 74,
            "weight": 0.12,
            "contribution": 8.88,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "phuket-old-town",
            "used_default": false,
            "default_reason": "No local or parent noise signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 44,
            "weight": 0.1,
            "contribution": 4.4,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "phuket-old-town",
            "used_default": false,
            "default_reason": "No local or parent rain signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 62,
            "weight": 0.14,
            "contribution": 8.68,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "phuket-old-town",
            "used_default": false,
            "default_reason": "No local or parent transport signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 82,
            "weight": 0.04,
            "contribution": 3.28,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "phuket-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support around the local base or parent destination, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 96,
            "weight": 0.05,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "phuket-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context around the local base or parent destination, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 72,
            "weight": 0.05,
            "contribution": 3.6,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "phuket-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 73,
            "weight": 0.04,
            "contribution": 2.92,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "phuket-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "phuket-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support around the stay zone or its parent destination, useful for overland flexibility but not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 85,
            "weight": 0.04,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "phuket-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context around the stay zone or its parent destination, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 83,
            "weight": 0.05,
            "contribution": 4.15,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "phuket-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context around the stay zone or its parent destination, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "pier_transfer_support",
            "label": "Pier transfer support",
            "score": 48,
            "weight": 0.04,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "pier_transfer_support",
            "entity_id": "phuket-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is public pier and transfer structure around the stay zone, linked pier anchor, or parent destination, not operator schedule or queue-length truth."
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 96,
            "weight": 0.05,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": "phuket-old-town",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Marine Department passenger-berth support around the stay zone or its parent destination, not live ferry schedule, closure, queue, or seat truth."
          },
          {
            "key": "airport_transfer_support",
            "label": "Airport transfer support",
            "score": 32,
            "weight": 0.06,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "airport_transfer_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is ground-access support around the main airport anchor behind this stay decision."
          },
          {
            "key": "airport_ground_service_support",
            "label": "Airport ground-service support",
            "score": 42,
            "weight": 0.05,
            "contribution": 2.1,
            "source": "signal",
            "signal_type": "airport_ground_service_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is official airport taxi, Grab, rental, and pickup-rule context behind the stay decision, not live queue, ETA, or inventory truth."
          },
          {
            "key": "airport_board_surface_support",
            "label": "Airport board-surface support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_board_surface_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is official passenger self-serve board visibility from public AOT flight-status pages, not direct live airline row truth."
          },
          {
            "key": "airport_scale_context",
            "label": "Airport scale context",
            "score": 63,
            "weight": 0.04,
            "contribution": 2.52,
            "source": "signal",
            "signal_type": "airport_scale_context",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is official AOT passenger and aircraft-movement scale context behind the main airport anchor, not live delay, queue, or inventory truth."
          },
          {
            "key": "airport_environmental_support",
            "label": "Airport environmental support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_environmental_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is SET-hosted AOT annual-report disclosure context behind the stay decision, not live measured sound-level truth."
          },
          {
            "key": "water_fit",
            "label": "Water and flood fit",
            "score": 68,
            "weight": 0.08,
            "contribution": 5.44,
            "source": "derived",
            "signal_type": "flood_water_risk",
            "entity_id": "phuket-old-town",
            "used_default": true,
            "default_reason": "No local or parent water-risk signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "parent_destination_fit",
            "label": "Parent destination fit",
            "score": 56,
            "weight": 0.16,
            "contribution": 8.96,
            "source": "decision",
            "signal_type": null,
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "Parent destination decision missing; using blueprint fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 79,
            "weight": 0.04,
            "contribution": 3.16,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "phuket-old-town",
            "used_default": false,
            "default_reason": "Blueprint seed missing; using parent score as fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 1,
            "points": 2,
            "applied": true,
            "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Stay contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 65,
            "note": "Component scores spread by 65 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "water_fit"
        ],
        "source_summary": "23 joined sources support this decision.",
        "path": "/entities/phuket-old-town/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:51:33.917Z"
      },
      {
        "decision_id": "stay_patong",
        "decision_type": "where_to_stay",
        "subject_id": "patong",
        "subject_name": "Patong",
        "subject_type": "hotel_area",
        "parent_destination_id": "phuket",
        "parent_destination_name": "Phuket",
        "score": 62,
        "component_score": 73.4,
        "penalty_points": 11,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Patong needs a more intentional fit before you book it.",
        "best_for": "Nightlife, service density, short stays, and beach trips where convenience matters more than quiet.",
        "avoid_if": "You are noise-sensitive or want a calmer family beach base.",
        "check_first": [
          "Choose Patong only when nightlife, services, or short-stay convenience are really the point.",
          "Do not pay Patong prices for a quiet family beach trip.",
          "Keep Old Town or Kata / Karon visible as the calmer pivot."
        ],
        "next_action": "Use Patong only when the energy and late return convenience are worth the tradeoff.",
        "pivot": "Use Kata / Karon or Phuket Old Town if sleep, food, or rain-backup logic becomes more important.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 22,
          "available_components": 21,
          "live_components": 18,
          "fallback_components": 4,
          "defaulted_components": 1,
          "coverage_ratio": 0.955
        },
        "score_components": [
          {
            "key": "local_source_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.18,
            "contribution": 17.46,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "patong",
            "used_default": false,
            "default_reason": "No local source-confidence signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 93.5,
            "weight": 0.18,
            "contribution": 16.83,
            "source": "derived",
            "signal_type": null,
            "entity_id": "patong",
            "used_default": false,
            "default_reason": "",
            "note": "Blends local AQI and outdoor comfort, with parent-destination fallback when hotel-area signals are sparse."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 74,
            "weight": 0.12,
            "contribution": 8.88,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "patong",
            "used_default": false,
            "default_reason": "No local or parent noise signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 44,
            "weight": 0.1,
            "contribution": 4.4,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "patong",
            "used_default": false,
            "default_reason": "No local or parent rain signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 62,
            "weight": 0.14,
            "contribution": 8.68,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "patong",
            "used_default": false,
            "default_reason": "No local or parent transport signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 78,
            "weight": 0.04,
            "contribution": 3.12,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "patong",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support around the local base or parent destination, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 96,
            "weight": 0.05,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "patong",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context around the local base or parent destination, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 72,
            "weight": 0.05,
            "contribution": 3.6,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "patong",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 73,
            "weight": 0.04,
            "contribution": 2.92,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "patong",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "patong",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support around the stay zone or its parent destination, useful for overland flexibility but not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 85,
            "weight": 0.04,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "patong",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context around the stay zone or its parent destination, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 83,
            "weight": 0.05,
            "contribution": 4.15,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "patong",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context around the stay zone or its parent destination, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "pier_transfer_support",
            "label": "Pier transfer support",
            "score": 48,
            "weight": 0.04,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "pier_transfer_support",
            "entity_id": "patong",
            "used_default": false,
            "default_reason": "",
            "note": "This is public pier and transfer structure around the stay zone, linked pier anchor, or parent destination, not operator schedule or queue-length truth."
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 92,
            "weight": 0.05,
            "contribution": 4.6,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": "patong",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Marine Department passenger-berth support around the stay zone or its parent destination, not live ferry schedule, closure, queue, or seat truth."
          },
          {
            "key": "airport_transfer_support",
            "label": "Airport transfer support",
            "score": 32,
            "weight": 0.06,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "airport_transfer_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is ground-access support around the main airport anchor behind this stay decision."
          },
          {
            "key": "airport_ground_service_support",
            "label": "Airport ground-service support",
            "score": 42,
            "weight": 0.05,
            "contribution": 2.1,
            "source": "signal",
            "signal_type": "airport_ground_service_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is official airport taxi, Grab, rental, and pickup-rule context behind the stay decision, not live queue, ETA, or inventory truth."
          },
          {
            "key": "airport_board_surface_support",
            "label": "Airport board-surface support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_board_surface_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is official passenger self-serve board visibility from public AOT flight-status pages, not direct live airline row truth."
          },
          {
            "key": "airport_scale_context",
            "label": "Airport scale context",
            "score": 63,
            "weight": 0.04,
            "contribution": 2.52,
            "source": "signal",
            "signal_type": "airport_scale_context",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is official AOT passenger and aircraft-movement scale context behind the main airport anchor, not live delay, queue, or inventory truth."
          },
          {
            "key": "airport_environmental_support",
            "label": "Airport environmental support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_environmental_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is SET-hosted AOT annual-report disclosure context behind the stay decision, not live measured sound-level truth."
          },
          {
            "key": "water_fit",
            "label": "Water and flood fit",
            "score": 68,
            "weight": 0.08,
            "contribution": 5.44,
            "source": "derived",
            "signal_type": "flood_water_risk",
            "entity_id": "patong",
            "used_default": true,
            "default_reason": "No local or parent water-risk signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "parent_destination_fit",
            "label": "Parent destination fit",
            "score": 56,
            "weight": 0.16,
            "contribution": 8.96,
            "source": "decision",
            "signal_type": null,
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "Parent destination decision missing; using blueprint fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 78,
            "weight": 0.04,
            "contribution": 3.12,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "patong",
            "used_default": false,
            "default_reason": "Blueprint seed missing; using parent score as fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 1,
            "points": 2,
            "applied": true,
            "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Stay contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 65,
            "note": "Component scores spread by 65 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "water_fit"
        ],
        "source_summary": "23 joined sources support this decision.",
        "path": "/entities/patong/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T18:00:00.000Z"
      },
      {
        "decision_id": "stay_rawai-nai-harn",
        "decision_type": "where_to_stay",
        "subject_id": "rawai-nai-harn",
        "subject_name": "Rawai / Nai Harn",
        "subject_type": "hotel_area",
        "parent_destination_id": "phuket",
        "parent_destination_name": "Phuket",
        "score": 62,
        "component_score": 73.4,
        "penalty_points": 11,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Rawai / Nai Harn needs a more intentional fit before you book it.",
        "best_for": "Longer Phuket stays, villas, south-coast pacing, and quieter beach routines.",
        "avoid_if": "You need low-friction movement around the whole island.",
        "check_first": [
          "Use Rawai / Nai Harn when longer, slower south-coast days are the real goal.",
          "Do not assume a cheaper villa beats a better-located first-timer base.",
          "Keep Phuket Old Town or Kata / Karon as the lower-friction fallback."
        ],
        "next_action": "Accept the transfer burden before paying for a bigger room or villa.",
        "pivot": "Use Kata / Karon for a cleaner first-timer base or Old Town when weather weakens.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 22,
          "available_components": 21,
          "live_components": 18,
          "fallback_components": 4,
          "defaulted_components": 1,
          "coverage_ratio": 0.955
        },
        "score_components": [
          {
            "key": "local_source_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.18,
            "contribution": 17.46,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "rawai-nai-harn",
            "used_default": false,
            "default_reason": "No local source-confidence signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 93.5,
            "weight": 0.18,
            "contribution": 16.83,
            "source": "derived",
            "signal_type": null,
            "entity_id": "rawai-nai-harn",
            "used_default": false,
            "default_reason": "",
            "note": "Blends local AQI and outdoor comfort, with parent-destination fallback when hotel-area signals are sparse."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 74,
            "weight": 0.12,
            "contribution": 8.88,
            "source": "signal",
            "signal_type": "noise_risk",
            "entity_id": "rawai-nai-harn",
            "used_default": false,
            "default_reason": "No local or parent noise signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 44,
            "weight": 0.1,
            "contribution": 4.4,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "rawai-nai-harn",
            "used_default": false,
            "default_reason": "No local or parent rain signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 62,
            "weight": 0.14,
            "contribution": 8.68,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "rawai-nai-harn",
            "used_default": false,
            "default_reason": "No local or parent transport signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 78,
            "weight": 0.04,
            "contribution": 3.12,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "rawai-nai-harn",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support around the local base or parent destination, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 96,
            "weight": 0.05,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "rawai-nai-harn",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context around the local base or parent destination, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 72,
            "weight": 0.05,
            "contribution": 3.6,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "rawai-nai-harn",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 73,
            "weight": 0.04,
            "contribution": 2.92,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "rawai-nai-harn",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "rawai-nai-harn",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support around the stay zone or its parent destination, useful for overland flexibility but not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 85,
            "weight": 0.04,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "rawai-nai-harn",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context around the stay zone or its parent destination, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 83,
            "weight": 0.05,
            "contribution": 4.15,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "rawai-nai-harn",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context around the stay zone or its parent destination, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "pier_transfer_support",
            "label": "Pier transfer support",
            "score": 48,
            "weight": 0.04,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "pier_transfer_support",
            "entity_id": "rawai-nai-harn",
            "used_default": false,
            "default_reason": "",
            "note": "This is public pier and transfer structure around the stay zone, linked pier anchor, or parent destination, not operator schedule or queue-length truth."
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 92,
            "weight": 0.05,
            "contribution": 4.6,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": "rawai-nai-harn",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Marine Department passenger-berth support around the stay zone or its parent destination, not live ferry schedule, closure, queue, or seat truth."
          },
          {
            "key": "airport_transfer_support",
            "label": "Airport transfer support",
            "score": 32,
            "weight": 0.06,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "airport_transfer_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is ground-access support around the main airport anchor behind this stay decision."
          },
          {
            "key": "airport_ground_service_support",
            "label": "Airport ground-service support",
            "score": 42,
            "weight": 0.05,
            "contribution": 2.1,
            "source": "signal",
            "signal_type": "airport_ground_service_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is official airport taxi, Grab, rental, and pickup-rule context behind the stay decision, not live queue, ETA, or inventory truth."
          },
          {
            "key": "airport_board_surface_support",
            "label": "Airport board-surface support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_board_surface_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is official passenger self-serve board visibility from public AOT flight-status pages, not direct live airline row truth."
          },
          {
            "key": "airport_scale_context",
            "label": "Airport scale context",
            "score": 63,
            "weight": 0.04,
            "contribution": 2.52,
            "source": "signal",
            "signal_type": "airport_scale_context",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is official AOT passenger and aircraft-movement scale context behind the main airport anchor, not live delay, queue, or inventory truth."
          },
          {
            "key": "airport_environmental_support",
            "label": "Airport environmental support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_environmental_support",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": "This is SET-hosted AOT annual-report disclosure context behind the stay decision, not live measured sound-level truth."
          },
          {
            "key": "water_fit",
            "label": "Water and flood fit",
            "score": 68,
            "weight": 0.08,
            "contribution": 5.44,
            "source": "derived",
            "signal_type": "flood_water_risk",
            "entity_id": "rawai-nai-harn",
            "used_default": true,
            "default_reason": "No local or parent water-risk signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "parent_destination_fit",
            "label": "Parent destination fit",
            "score": 56,
            "weight": 0.16,
            "contribution": 8.96,
            "source": "decision",
            "signal_type": null,
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "Parent destination decision missing; using blueprint fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 76,
            "weight": 0.04,
            "contribution": 3.04,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "rawai-nai-harn",
            "used_default": false,
            "default_reason": "Blueprint seed missing; using parent score as fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 1,
            "points": 2,
            "applied": true,
            "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Stay contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 65,
            "note": "Component scores spread by 65 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "water_fit"
        ],
        "source_summary": "23 joined sources support this decision.",
        "path": "/entities/rawai-nai-harn/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T18:00:00.000Z"
      },
      {
        "decision_id": "stay_ao-nang",
        "decision_type": "where_to_stay",
        "subject_id": "ao-nang",
        "subject_name": "Ao Nang",
        "subject_type": "hotel_area",
        "parent_destination_id": "krabi",
        "parent_destination_name": "Krabi",
        "score": 59,
        "component_score": 72.2,
        "penalty_points": 13,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Ao Nang needs a more intentional fit before you book it.",
        "best_for": "First-time Krabi stays, tour logistics, and coast trips that need a practical backup plan.",
        "avoid_if": "You only want scenery payoff and hate any resort-strip convenience.",
        "check_first": [
          "Choose Ao Nang when practical coast access matters more than perfect scenery mood.",
          "Keep one non-boat day available.",
          "Do not confuse a scenic promo photo with a resilient base."
        ],
        "next_action": "Use Ao Nang when the coast needs to stay usable even if one boat day weakens.",
        "pivot": "Use Railay only when the scenery premium is worth the fragility.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 18,
          "available_components": 16,
          "live_components": 13,
          "fallback_components": 5,
          "defaulted_components": 2,
          "coverage_ratio": 0.889
        },
        "score_components": [
          {
            "key": "local_source_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.18,
            "contribution": 17.46,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "ao-nang",
            "used_default": false,
            "default_reason": "No local source-confidence signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 93.5,
            "weight": 0.18,
            "contribution": 16.83,
            "source": "derived",
            "signal_type": null,
            "entity_id": "ao-nang",
            "used_default": false,
            "default_reason": "",
            "note": "Blends local AQI and outdoor comfort, with parent-destination fallback when hotel-area signals are sparse."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 66,
            "weight": 0.12,
            "contribution": 7.92,
            "source": "derived",
            "signal_type": "noise_risk",
            "entity_id": "ao-nang",
            "used_default": true,
            "default_reason": "No local or parent noise signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 44,
            "weight": 0.1,
            "contribution": 4.4,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "ao-nang",
            "used_default": false,
            "default_reason": "No local or parent rain signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 59,
            "weight": 0.14,
            "contribution": 8.26,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "ao-nang",
            "used_default": false,
            "default_reason": "No local or parent transport signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 78,
            "weight": 0.04,
            "contribution": 3.12,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "ao-nang",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support around the local base or parent destination, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 86,
            "weight": 0.05,
            "contribution": 4.3,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "ao-nang",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context around the local base or parent destination, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 62,
            "weight": 0.05,
            "contribution": 3.1,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "ao-nang",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 54,
            "weight": 0.04,
            "contribution": 2.16,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "ao-nang",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "ao-nang",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support around the stay zone or its parent destination, useful for overland flexibility but not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 85,
            "weight": 0.04,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "ao-nang",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context around the stay zone or its parent destination, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 83,
            "weight": 0.05,
            "contribution": 4.15,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "ao-nang",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context around the stay zone or its parent destination, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "pier_transfer_support",
            "label": "Pier transfer support",
            "score": 75,
            "weight": 0.04,
            "contribution": 3,
            "source": "signal",
            "signal_type": "pier_transfer_support",
            "entity_id": "ao-nang",
            "used_default": false,
            "default_reason": "",
            "note": "This is public pier and transfer structure around the stay zone, linked pier anchor, or parent destination, not operator schedule or queue-length truth."
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 76,
            "weight": 0.05,
            "contribution": 3.8,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": "ao-nang",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Marine Department passenger-berth support around the stay zone or its parent destination, not live ferry schedule, closure, queue, or seat truth."
          },
          {
            "key": "airport_transfer_support",
            "label": "Airport transfer support",
            "score": 47,
            "weight": 0.06,
            "contribution": 2.82,
            "source": "signal",
            "signal_type": "airport_transfer_support",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "",
            "note": "This is ground-access support around the main airport anchor behind this stay decision."
          },
          {
            "key": "water_fit",
            "label": "Water and flood fit",
            "score": 68,
            "weight": 0.08,
            "contribution": 5.44,
            "source": "derived",
            "signal_type": "flood_water_risk",
            "entity_id": "ao-nang",
            "used_default": true,
            "default_reason": "No local or parent water-risk signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "parent_destination_fit",
            "label": "Parent destination fit",
            "score": 53,
            "weight": 0.16,
            "contribution": 8.48,
            "source": "decision",
            "signal_type": null,
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "Parent destination decision missing; using blueprint fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 80,
            "weight": 0.04,
            "contribution": 3.2,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "ao-nang",
            "used_default": false,
            "default_reason": "Blueprint seed missing; using parent score as fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 2,
            "points": 4,
            "applied": true,
            "note": "2 component(s) used fallback defaults, so the engine applies a 4-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Stay contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 53,
            "note": "Component scores spread by 53 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "noise_comfort",
          "water_fit"
        ],
        "source_summary": "16 joined sources support this decision.",
        "path": "/entities/ao-nang/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T18:00:00.000Z"
      },
      {
        "decision_id": "stay_railay",
        "decision_type": "where_to_stay",
        "subject_id": "railay",
        "subject_name": "Railay",
        "subject_type": "hotel_area",
        "parent_destination_id": "krabi",
        "parent_destination_name": "Krabi",
        "score": 59,
        "component_score": 71.6,
        "penalty_points": 13,
        "confidence": "High",
        "label": "mixed",
        "recommendation": "Railay needs a more intentional fit before you book it.",
        "best_for": "High-payoff Krabi scenery when transfer fragility is acceptable.",
        "avoid_if": "Arrival timing is tight or weather tolerance is low.",
        "check_first": [
          "Use Railay only when the scenery payoff is worth a more fragile arrival and exit stack.",
          "Do not force Railay on a tight arrival day.",
          "Keep Ao Nang visible as the practical fallback."
        ],
        "next_action": "Treat Railay as the reward move, not the safest default.",
        "pivot": "Use Ao Nang if the practical transfer story starts to dominate.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 18,
          "available_components": 16,
          "live_components": 13,
          "fallback_components": 5,
          "defaulted_components": 2,
          "coverage_ratio": 0.889
        },
        "score_components": [
          {
            "key": "local_source_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.18,
            "contribution": 17.46,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "railay",
            "used_default": false,
            "default_reason": "No local source-confidence signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 93.5,
            "weight": 0.18,
            "contribution": 16.83,
            "source": "derived",
            "signal_type": null,
            "entity_id": "railay",
            "used_default": false,
            "default_reason": "",
            "note": "Blends local AQI and outdoor comfort, with parent-destination fallback when hotel-area signals are sparse."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 66,
            "weight": 0.12,
            "contribution": 7.92,
            "source": "derived",
            "signal_type": "noise_risk",
            "entity_id": "railay",
            "used_default": true,
            "default_reason": "No local or parent noise signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 44,
            "weight": 0.1,
            "contribution": 4.4,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "railay",
            "used_default": false,
            "default_reason": "No local or parent rain signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 58,
            "weight": 0.14,
            "contribution": 8.12,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "railay",
            "used_default": false,
            "default_reason": "No local or parent transport signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 76,
            "weight": 0.04,
            "contribution": 3.04,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "railay",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support around the local base or parent destination, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 86,
            "weight": 0.05,
            "contribution": 4.3,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "railay",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context around the local base or parent destination, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 62,
            "weight": 0.05,
            "contribution": 3.1,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "railay",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 54,
            "weight": 0.04,
            "contribution": 2.16,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "railay",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "railay",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support around the stay zone or its parent destination, useful for overland flexibility but not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 85,
            "weight": 0.04,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "railay",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context around the stay zone or its parent destination, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 83,
            "weight": 0.05,
            "contribution": 4.15,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "railay",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context around the stay zone or its parent destination, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "pier_transfer_support",
            "label": "Pier transfer support",
            "score": 65,
            "weight": 0.04,
            "contribution": 2.6,
            "source": "signal",
            "signal_type": "pier_transfer_support",
            "entity_id": "railay",
            "used_default": false,
            "default_reason": "",
            "note": "This is public pier and transfer structure around the stay zone, linked pier anchor, or parent destination, not operator schedule or queue-length truth."
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 76,
            "weight": 0.05,
            "contribution": 3.8,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": "railay",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Marine Department passenger-berth support around the stay zone or its parent destination, not live ferry schedule, closure, queue, or seat truth."
          },
          {
            "key": "airport_transfer_support",
            "label": "Airport transfer support",
            "score": 47,
            "weight": 0.06,
            "contribution": 2.82,
            "source": "signal",
            "signal_type": "airport_transfer_support",
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "",
            "note": "This is ground-access support around the main airport anchor behind this stay decision."
          },
          {
            "key": "water_fit",
            "label": "Water and flood fit",
            "score": 68,
            "weight": 0.08,
            "contribution": 5.44,
            "source": "derived",
            "signal_type": "flood_water_risk",
            "entity_id": "railay",
            "used_default": true,
            "default_reason": "No local or parent water-risk signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "parent_destination_fit",
            "label": "Parent destination fit",
            "score": 53,
            "weight": 0.16,
            "contribution": 8.48,
            "source": "decision",
            "signal_type": null,
            "entity_id": "krabi",
            "used_default": false,
            "default_reason": "Parent destination decision missing; using blueprint fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 73,
            "weight": 0.04,
            "contribution": 2.92,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "railay",
            "used_default": false,
            "default_reason": "Blueprint seed missing; using parent score as fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 2,
            "points": 4,
            "applied": true,
            "note": "2 component(s) used fallback defaults, so the engine applies a 4-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Stay contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 53,
            "note": "Component scores spread by 53 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "noise_comfort",
          "water_fit"
        ],
        "source_summary": "16 joined sources support this decision.",
        "path": "/entities/railay/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T18:00:00.000Z"
      },
      {
        "decision_id": "stay_central-pattaya-jomtien",
        "decision_type": "where_to_stay",
        "subject_id": "central-pattaya-jomtien",
        "subject_name": "Central Pattaya / Jomtien",
        "subject_type": "hotel_area",
        "parent_destination_id": "pattaya-chonburi",
        "parent_destination_name": "Pattaya / Chonburi",
        "score": 57,
        "component_score": 71.9,
        "penalty_points": 15,
        "confidence": "High",
        "label": "fragile",
        "recommendation": "Central Pattaya / Jomtien needs a more intentional fit before you book it.",
        "best_for": "Short coast breaks, hotel convenience, beach access, and nightlife flexibility with a practical Bangkok escape shape.",
        "avoid_if": "You are sleep-sensitive, crowd-averse, or want all beach time without traffic tradeoffs.",
        "check_first": [
          "Choose the exact zone before the hotel.",
          "Use Jomtien when sleep and softer pacing matter more than nightlife.",
          "Do not assume all Pattaya-area hotels have the same return-route convenience."
        ],
        "next_action": "Decide whether nightlife or sleep matters more before choosing Central Pattaya versus Jomtien.",
        "pivot": "Use Hua Hin / Cha-am for a calmer hotel rhythm.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 18,
          "available_components": 15,
          "live_components": 12,
          "fallback_components": 6,
          "defaulted_components": 3,
          "coverage_ratio": 0.833
        },
        "score_components": [
          {
            "key": "local_source_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.18,
            "contribution": 17.46,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "central-pattaya-jomtien",
            "used_default": false,
            "default_reason": "No local source-confidence signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 68,
            "weight": 0.18,
            "contribution": 12.24,
            "source": "derived",
            "signal_type": null,
            "entity_id": "central-pattaya-jomtien",
            "used_default": false,
            "default_reason": "",
            "note": "Blends local AQI and outdoor comfort, with parent-destination fallback when hotel-area signals are sparse."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 66,
            "weight": 0.12,
            "contribution": 7.92,
            "source": "derived",
            "signal_type": "noise_risk",
            "entity_id": "central-pattaya-jomtien",
            "used_default": true,
            "default_reason": "No local or parent noise signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 68,
            "weight": 0.1,
            "contribution": 6.8,
            "source": "derived",
            "signal_type": "rain_risk",
            "entity_id": "central-pattaya-jomtien",
            "used_default": true,
            "default_reason": "No local or parent rain signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 56,
            "weight": 0.14,
            "contribution": 7.84,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "central-pattaya-jomtien",
            "used_default": false,
            "default_reason": "No local or parent transport signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "highway_transfer_friction",
            "label": "Highway transfer friction",
            "score": 88,
            "weight": 0.05,
            "contribution": 4.4,
            "source": "signal",
            "signal_type": "highway_transfer_friction",
            "entity_id": "central-pattaya-jomtien",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DOH and EXAT road-support context behind the local base, not live speed, queue, lane, or incident truth."
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 80,
            "weight": 0.04,
            "contribution": 3.2,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "central-pattaya-jomtien",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support around the local base or parent destination, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 94,
            "weight": 0.05,
            "contribution": 4.7,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "central-pattaya-jomtien",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context around the local base or parent destination, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 72,
            "weight": 0.05,
            "contribution": 3.6,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "central-pattaya-jomtien",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 86,
            "weight": 0.04,
            "contribution": 3.44,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "central-pattaya-jomtien",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "central-pattaya-jomtien",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support around the stay zone or its parent destination, useful for overland flexibility but not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 94,
            "weight": 0.04,
            "contribution": 3.76,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "central-pattaya-jomtien",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context around the stay zone or its parent destination, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 83,
            "weight": 0.05,
            "contribution": 4.15,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "central-pattaya-jomtien",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context around the stay zone or its parent destination, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 80,
            "weight": 0.05,
            "contribution": 4,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": "central-pattaya-jomtien",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Marine Department passenger-berth support around the stay zone or its parent destination, not live ferry schedule, closure, queue, or seat truth."
          },
          {
            "key": "airport_transfer_support",
            "label": "Airport transfer support",
            "score": 32,
            "weight": 0.06,
            "contribution": 1.92,
            "source": "signal",
            "signal_type": "airport_transfer_support",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "",
            "note": "This is ground-access support around the main airport anchor behind this stay decision."
          },
          {
            "key": "water_fit",
            "label": "Water and flood fit",
            "score": 68,
            "weight": 0.08,
            "contribution": 5.44,
            "source": "derived",
            "signal_type": "flood_water_risk",
            "entity_id": "central-pattaya-jomtien",
            "used_default": true,
            "default_reason": "No local or parent water-risk signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "parent_destination_fit",
            "label": "Parent destination fit",
            "score": 51,
            "weight": 0.16,
            "contribution": 8.16,
            "source": "decision",
            "signal_type": null,
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "Parent destination decision missing; using blueprint fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 77,
            "weight": 0.04,
            "contribution": 3.08,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "central-pattaya-jomtien",
            "used_default": false,
            "default_reason": "Blueprint seed missing; using parent score as fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 3,
            "points": 6,
            "applied": true,
            "note": "3 component(s) used fallback defaults, so the engine applies a 6-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Stay contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 65,
            "note": "Component scores spread by 65 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "noise_comfort",
          "rain_fit",
          "water_fit"
        ],
        "source_summary": "17 joined sources support this decision.",
        "path": "/entities/central-pattaya-jomtien/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:51:33.917Z"
      },
      {
        "decision_id": "stay_central-hua-hin-khao-takiab",
        "decision_type": "where_to_stay",
        "subject_id": "central-hua-hin-khao-takiab",
        "subject_name": "Central Hua Hin / Khao Takiab",
        "subject_type": "hotel_area",
        "parent_destination_id": "hua-hin",
        "parent_destination_name": "Hua Hin / Cha-am",
        "score": 55,
        "component_score": 69.8,
        "penalty_points": 15,
        "confidence": "High",
        "label": "fragile",
        "recommendation": "Central Hua Hin / Khao Takiab needs a more intentional fit before you book it.",
        "best_for": "Families, calmer beach-town pacing, seafood, and hotel stays that value rail or road simplicity over nightlife.",
        "avoid_if": "You need nightlife density or a highly compact walk-everywhere beach strip.",
        "check_first": [
          "Use this base when calm beach-town logic matters more than nightlife.",
          "Check station or road transfer time before paying if arrival day is tight.",
          "Treat Cha-am as a separate feel, not the same strip."
        ],
        "next_action": "Choose the exact part of Hua Hin or Khao Takiab before paying, especially on holiday weekends.",
        "pivot": "Use Pattaya / Chonburi if the trip needs a shorter coast hop and more late-night energy.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 18,
          "available_components": 15,
          "live_components": 12,
          "fallback_components": 6,
          "defaulted_components": 3,
          "coverage_ratio": 0.833
        },
        "score_components": [
          {
            "key": "local_source_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.18,
            "contribution": 17.46,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "central-hua-hin-khao-takiab",
            "used_default": false,
            "default_reason": "No local source-confidence signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 68,
            "weight": 0.18,
            "contribution": 12.24,
            "source": "derived",
            "signal_type": null,
            "entity_id": "central-hua-hin-khao-takiab",
            "used_default": false,
            "default_reason": "",
            "note": "Blends local AQI and outdoor comfort, with parent-destination fallback when hotel-area signals are sparse."
          },
          {
            "key": "noise_comfort",
            "label": "Noise comfort",
            "score": 66,
            "weight": 0.12,
            "contribution": 7.92,
            "source": "derived",
            "signal_type": "noise_risk",
            "entity_id": "central-hua-hin-khao-takiab",
            "used_default": true,
            "default_reason": "No local or parent noise signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 68,
            "weight": 0.1,
            "contribution": 6.8,
            "source": "derived",
            "signal_type": "rain_risk",
            "entity_id": "central-hua-hin-khao-takiab",
            "used_default": true,
            "default_reason": "No local or parent rain signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 58,
            "weight": 0.14,
            "contribution": 8.12,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "central-hua-hin-khao-takiab",
            "used_default": false,
            "default_reason": "No local or parent transport signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "highway_transfer_friction",
            "label": "Highway transfer friction",
            "score": 88,
            "weight": 0.05,
            "contribution": 4.4,
            "source": "signal",
            "signal_type": "highway_transfer_friction",
            "entity_id": "central-hua-hin-khao-takiab",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DOH and EXAT road-support context behind the local base, not live speed, queue, lane, or incident truth."
          },
          {
            "key": "spa_license_support",
            "label": "Spa license support",
            "score": 78,
            "weight": 0.04,
            "contribution": 3.12,
            "source": "signal",
            "signal_type": "spa_license_support",
            "entity_id": "central-hua-hin-khao-takiab",
            "used_default": false,
            "default_reason": "",
            "note": "This is public HSS wellness-license lookup support around the local base or parent destination, not live booking, treatment quality, or venue popularity truth."
          },
          {
            "key": "medical_fallback_support",
            "label": "Medical fallback support",
            "score": 82,
            "weight": 0.05,
            "contribution": 4.1,
            "source": "signal",
            "signal_type": "medical_fallback_support",
            "entity_id": "central-hua-hin-khao-takiab",
            "used_default": false,
            "default_reason": "",
            "note": "This is public MOPH facility-support context around the local base or parent destination, not live bed, wait-time, dispatch, or specialist-availability truth."
          },
          {
            "key": "rail_feasibility",
            "label": "Rail feasibility",
            "score": 39,
            "weight": 0.06,
            "contribution": 2.34,
            "source": "signal",
            "signal_type": "rail_feasibility",
            "entity_id": "central-hua-hin-khao-takiab",
            "used_default": false,
            "default_reason": "",
            "note": "This is public rail-support structure around the local base or parent destination, not live train seat or delay truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 62,
            "weight": 0.05,
            "contribution": 3.1,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": "central-hua-hin-khao-takiab",
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 54,
            "weight": 0.04,
            "contribution": 2.16,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": "central-hua-hin-khao-takiab",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 95,
            "weight": 0.03,
            "contribution": 2.85,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": "central-hua-hin-khao-takiab",
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support around the stay zone or its parent destination, useful for overland flexibility but not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 94,
            "weight": 0.04,
            "contribution": 3.76,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": "central-hua-hin-khao-takiab",
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context around the stay zone or its parent destination, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 83,
            "weight": 0.05,
            "contribution": 4.15,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": "central-hua-hin-khao-takiab",
            "used_default": false,
            "default_reason": "",
            "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context around the stay zone or its parent destination, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 58,
            "weight": 0.05,
            "contribution": 2.9,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": "central-hua-hin-khao-takiab",
            "used_default": false,
            "default_reason": "",
            "note": "This is official Marine Department passenger-berth support around the stay zone or its parent destination, not live ferry schedule, closure, queue, or seat truth."
          },
          {
            "key": "water_fit",
            "label": "Water and flood fit",
            "score": 68,
            "weight": 0.08,
            "contribution": 5.44,
            "source": "derived",
            "signal_type": "flood_water_risk",
            "entity_id": "central-hua-hin-khao-takiab",
            "used_default": true,
            "default_reason": "No local or parent water-risk signal; using conservative fallback.",
            "note": ""
          },
          {
            "key": "parent_destination_fit",
            "label": "Parent destination fit",
            "score": 49,
            "weight": 0.16,
            "contribution": 7.84,
            "source": "decision",
            "signal_type": null,
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "Parent destination decision missing; using blueprint fallback.",
            "note": ""
          },
          {
            "key": "blueprint_baseline",
            "label": "Blueprint baseline",
            "score": 79,
            "weight": 0.04,
            "contribution": 3.16,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "central-hua-hin-khao-takiab",
            "used_default": false,
            "default_reason": "Blueprint seed missing; using parent score as fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 3,
            "points": 6,
            "applied": true,
            "note": "3 component(s) used fallback defaults, so the engine applies a 6-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Stay contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 58,
            "note": "Component scores spread by 58 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "noise_comfort",
          "rain_fit",
          "water_fit"
        ],
        "source_summary": "17 joined sources support this decision.",
        "path": "/entities/central-hua-hin-khao-takiab/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:51:33.917Z"
      }
    ],
    "route_check": [
      {
        "decision_id": "route_bangkok-ayutthaya-kanchanaburi",
        "decision_type": "route_check",
        "subject_id": "bangkok-ayutthaya-kanchanaburi",
        "subject_name": "Bangkok -> Ayutthaya -> Kanchanaburi",
        "subject_type": "route",
        "score": 67,
        "component_score": 73.3,
        "penalty_points": 6,
        "confidence": "Medium",
        "label": "mixed",
        "recommendation": "Bangkok -> Ayutthaya -> Kanchanaburi is a cautious route shape right now.",
        "best_for": "Easy central-Thai culture loop with lower airport dependence.",
        "avoid_if": "You only have a rushed long weekend and hate transfers.",
        "check_first": [
          "heat exposure",
          "road and rail comfort",
          "whether Kanchanaburi is actually worth the detour for this trip shape"
        ],
        "next_action": "Use Bangkok as the base and decide whether both side trips really belong in the same short window.",
        "pivot": "Drop Kanchanaburi first if the loop starts to feel too transfer-heavy.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 19,
          "available_components": 19,
          "live_components": 16,
          "fallback_components": 3,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "destination_average",
            "label": "Destination fit average",
            "score": 62,
            "weight": 0.34,
            "contribution": 21.08,
            "source": "decision",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "Average destination strength across the route chain."
          },
          {
            "key": "weakest_destination",
            "label": "Weakest destination leg",
            "score": 59,
            "weight": 0.18,
            "contribution": 10.62,
            "source": "decision",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "No weakest destination leg was available, so the route uses the average destination score.",
            "note": ""
          },
          {
            "key": "transport_average",
            "label": "Transport friction average",
            "score": 77.75,
            "weight": 0.16,
            "contribution": 12.44,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "highway_transfer_friction",
            "label": "Highway transfer friction",
            "score": 88,
            "weight": 0.08,
            "contribution": 7.04,
            "source": "signal",
            "signal_type": "highway_transfer_friction",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official DOH and EXAT road-support context across overland route legs, not live speed, queue, lane, or incident truth."
          },
          {
            "key": "rain_average",
            "label": "Rain fit average",
            "score": 56,
            "weight": 0.1,
            "contribution": 5.6,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "airport_weather_operability",
            "label": "Airport weather operability",
            "score": 60,
            "weight": 0.1,
            "contribution": 6,
            "source": "signal",
            "signal_type": "flight_delay_risk",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is airport weather and forecast disruption context on flight-dependent legs, not airline on-time performance."
          },
          {
            "key": "rail_feasibility",
            "label": "Rail feasibility",
            "score": 74.33333333333333,
            "weight": 0.08,
            "contribution": 5.95,
            "source": "signal",
            "signal_type": "rail_feasibility",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is public rail-support structure across the route chain, not live train seat, timetable, or disruption truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 83.33333333333333,
            "weight": 0.06,
            "contribution": 5,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support across the route chain for overland backup and bus-linked resilience, not live departure or booking truth."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 84.5,
            "weight": 0.04,
            "contribution": 3.38,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support across the route chain for overland backup and bus-linked resilience, not live departure or booking truth."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.04,
            "contribution": 3.84,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support across the route chain for overland route-search confidence, not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 94,
            "weight": 0.04,
            "contribution": 3.76,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context across the route chain, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 96,
            "weight": 0.04,
            "contribution": 3.84,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT GPS and Taxi OK regulated-taxi oversight, complaint, and station-search support across the route chain, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "official_motorcycle_taxi_support",
            "label": "Official motorcycle-taxi support",
            "score": 73,
            "weight": 0.03,
            "contribution": 2.19,
            "source": "signal",
            "signal_type": "official_motorcycle_taxi_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official Bangkok motorcycle-taxi stand and driver coverage from the public DLT/data.go.th dataset, useful as route-level last-mile support context rather than live availability, dispatch, or queue truth."
          },
          {
            "key": "taxi_pickup_dropoff_support",
            "label": "Taxi pickup and dropoff support",
            "score": 88.5,
            "weight": 0.03,
            "contribution": 2.65,
            "source": "signal",
            "signal_type": "taxi_pickup_dropoff_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is public OTP monthly taxi GPS analytics and hotspot context across Bangkok-linked route nodes, useful as aggregate pickup/dropoff support rather than live dispatch, ETA, queue, or raw trip truth."
          },
          {
            "key": "urban_rapid_transit_support",
            "label": "Urban rapid-transit support",
            "score": 94.5,
            "weight": 0.05,
            "contribution": 4.73,
            "source": "signal",
            "signal_type": "urban_rapid_transit_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official BTS and MRTA route-map and service-page support on Bangkok-linked route nodes, not live headway, crowding, or outage truth."
          },
          {
            "key": "urban_bus_operator_support",
            "label": "Urban bus-operator support",
            "score": 74,
            "weight": 0.04,
            "contribution": 2.96,
            "source": "signal",
            "signal_type": "urban_bus_operator_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is public Thai Smile Group branch and depot footprint on Bangkok-linked route nodes, useful as fallback urban bus support rather than live bus operations truth."
          },
          {
            "key": "park_access_context",
            "label": "Park access context",
            "score": 96,
            "weight": 0.04,
            "contribution": 3.84,
            "source": "signal",
            "signal_type": "park_access_context",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is public DNP protected-area planning context across nature-heavy route legs, not live closure, ranger, capacity, or ticket truth."
          },
          {
            "key": "node_confidence",
            "label": "Transfer-node confidence",
            "score": 97,
            "weight": 0.08,
            "contribution": 7.76,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "route_baseline",
            "label": "Route template baseline",
            "score": 65.25,
            "weight": 0.06,
            "contribution": 3.92,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "Route templates now act as low-weight route-shape hints instead of dominating the score."
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Route contradiction penalty",
            "points": 6,
            "applied": true,
            "spread": 41,
            "note": "Component scores spread by 41 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "3 destination anchors and 1 transfer nodes support this route check.",
        "main_risk": "Regional disaster context is busy",
        "weakest_leg": "Kanchanaburi",
        "path": "/routes/bangkok-ayutthaya-kanchanaburi/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:52:38.613Z"
      },
      {
        "decision_id": "route_chiang-mai-pai-chiang-rai",
        "decision_type": "route_check",
        "subject_id": "chiang-mai-pai-chiang-rai",
        "subject_name": "Chiang Mai -> Pai / Chiang Rai north loop",
        "subject_type": "route",
        "score": 64,
        "component_score": 69.8,
        "penalty_points": 6,
        "confidence": "Medium",
        "label": "mixed",
        "recommendation": "Chiang Mai -> Pai / Chiang Rai north loop is a cautious route shape right now.",
        "best_for": "Repeat visitors who want the north to stay the main character.",
        "avoid_if": "AQI is elevated or the group has low road tolerance.",
        "check_first": [
          "PM2.5",
          "mountain weather",
          "road tolerance",
          "whether Pai is optional or emotionally fixed"
        ],
        "next_action": "Let Chiang Mai stay strong on its own before you add the road burden.",
        "pivot": "Keep Chiang Mai only, or shift south if air quality fails.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 19,
          "available_components": 19,
          "live_components": 16,
          "fallback_components": 3,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "destination_average",
            "label": "Destination fit average",
            "score": 60.5,
            "weight": 0.34,
            "contribution": 20.57,
            "source": "decision",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "Average destination strength across the route chain."
          },
          {
            "key": "weakest_destination",
            "label": "Weakest destination leg",
            "score": 56,
            "weight": 0.18,
            "contribution": 10.08,
            "source": "decision",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "No weakest destination leg was available, so the route uses the average destination score.",
            "note": ""
          },
          {
            "key": "transport_average",
            "label": "Transport friction average",
            "score": 65.33333333333333,
            "weight": 0.16,
            "contribution": 10.45,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "highway_transfer_friction",
            "label": "Highway transfer friction",
            "score": 88,
            "weight": 0.08,
            "contribution": 7.04,
            "source": "signal",
            "signal_type": "highway_transfer_friction",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official DOH and EXAT road-support context across overland route legs, not live speed, queue, lane, or incident truth."
          },
          {
            "key": "rain_average",
            "label": "Rain fit average",
            "score": 56,
            "weight": 0.1,
            "contribution": 5.6,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "airport_weather_operability",
            "label": "Airport weather operability",
            "score": 60,
            "weight": 0.1,
            "contribution": 6,
            "source": "signal",
            "signal_type": "flight_delay_risk",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is airport weather and forecast disruption context on flight-dependent legs, not airline on-time performance."
          },
          {
            "key": "rail_feasibility",
            "label": "Rail feasibility",
            "score": 59,
            "weight": 0.08,
            "contribution": 4.72,
            "source": "signal",
            "signal_type": "rail_feasibility",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is public rail-support structure across the route chain, not live train seat, timetable, or disruption truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 91,
            "weight": 0.06,
            "contribution": 5.46,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support across the route chain for overland backup and bus-linked resilience, not live departure or booking truth."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 84,
            "weight": 0.04,
            "contribution": 3.36,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support across the route chain for overland backup and bus-linked resilience, not live departure or booking truth."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.04,
            "contribution": 3.84,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support across the route chain for overland route-search confidence, not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 94,
            "weight": 0.04,
            "contribution": 3.76,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context across the route chain, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 94,
            "weight": 0.04,
            "contribution": 3.76,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT GPS and Taxi OK regulated-taxi oversight, complaint, and station-search support across the route chain, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "official_motorcycle_taxi_support",
            "label": "Official motorcycle-taxi support",
            "score": 58,
            "weight": 0.03,
            "contribution": 1.74,
            "source": "signal",
            "signal_type": "official_motorcycle_taxi_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official Bangkok motorcycle-taxi stand and driver coverage from the public DLT/data.go.th dataset, useful as route-level last-mile support context rather than live availability, dispatch, or queue truth."
          },
          {
            "key": "taxi_pickup_dropoff_support",
            "label": "Taxi pickup and dropoff support",
            "score": 85,
            "weight": 0.03,
            "contribution": 2.55,
            "source": "signal",
            "signal_type": "taxi_pickup_dropoff_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is public OTP monthly taxi GPS analytics and hotspot context across Bangkok-linked route nodes, useful as aggregate pickup/dropoff support rather than live dispatch, ETA, queue, or raw trip truth."
          },
          {
            "key": "urban_rapid_transit_support",
            "label": "Urban rapid-transit support",
            "score": 91,
            "weight": 0.05,
            "contribution": 4.55,
            "source": "signal",
            "signal_type": "urban_rapid_transit_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official BTS and MRTA route-map and service-page support on Bangkok-linked route nodes, not live headway, crowding, or outage truth."
          },
          {
            "key": "urban_bus_operator_support",
            "label": "Urban bus-operator support",
            "score": 60,
            "weight": 0.04,
            "contribution": 2.4,
            "source": "signal",
            "signal_type": "urban_bus_operator_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is public Thai Smile Group branch and depot footprint on Bangkok-linked route nodes, useful as fallback urban bus support rather than live bus operations truth."
          },
          {
            "key": "park_access_context",
            "label": "Park access context",
            "score": 91,
            "weight": 0.04,
            "contribution": 3.64,
            "source": "signal",
            "signal_type": "park_access_context",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is public DNP protected-area planning context across nature-heavy route legs, not live closure, ranger, capacity, or ticket truth."
          },
          {
            "key": "node_confidence",
            "label": "Transfer-node confidence",
            "score": 97,
            "weight": 0.08,
            "contribution": 7.76,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "route_baseline",
            "label": "Route template baseline",
            "score": 60.61111111111111,
            "weight": 0.06,
            "contribution": 3.64,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "Route templates now act as low-weight route-shape hints instead of dominating the score."
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Route contradiction penalty",
            "points": 6,
            "applied": true,
            "spread": 41,
            "note": "Component scores spread by 41 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "2 destination anchors and 1 transfer nodes support this route check.",
        "main_risk": "Road safety burden is high",
        "weakest_leg": "Pai",
        "path": "/routes/chiang-mai-pai-chiang-rai/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:52:38.613Z"
      },
      {
        "decision_id": "route_bangkok-chiang-mai-phuket",
        "decision_type": "route_check",
        "subject_id": "bangkok-chiang-mai-phuket",
        "subject_name": "Bangkok -> Chiang Mai -> Phuket",
        "subject_type": "route",
        "score": 61,
        "component_score": 69.6,
        "penalty_points": 9,
        "confidence": "Medium",
        "label": "mixed",
        "recommendation": "Bangkok -> Chiang Mai -> Phuket is a cautious route shape right now.",
        "best_for": "Classic first trip with city depth, northern culture, and a beach finish.",
        "avoid_if": "Northern AQI is weak or you need a fully overland route.",
        "check_first": [
          "Chiang Mai PM2.5",
          "airport timing between long legs",
          "beach area choice in Phuket"
        ],
        "next_action": "Lock Bangkok and Phuket first, then leave the Chiang Mai segment soft until AQI feels solid.",
        "pivot": "Go Bangkok -> Phuket directly if the north weakens.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 27,
          "available_components": 27,
          "live_components": 24,
          "fallback_components": 3,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "destination_average",
            "label": "Destination fit average",
            "score": 61.333333333333336,
            "weight": 0.34,
            "contribution": 20.85,
            "source": "decision",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "Average destination strength across the route chain."
          },
          {
            "key": "weakest_destination",
            "label": "Weakest destination leg",
            "score": 56,
            "weight": 0.18,
            "contribution": 10.08,
            "source": "decision",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "No weakest destination leg was available, so the route uses the average destination score.",
            "note": ""
          },
          {
            "key": "transport_average",
            "label": "Transport friction average",
            "score": 70.71428571428571,
            "weight": 0.16,
            "contribution": 11.31,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "highway_transfer_friction",
            "label": "Highway transfer friction",
            "score": 88,
            "weight": 0.08,
            "contribution": 7.04,
            "source": "signal",
            "signal_type": "highway_transfer_friction",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official DOH and EXAT road-support context across overland route legs, not live speed, queue, lane, or incident truth."
          },
          {
            "key": "rain_average",
            "label": "Rain fit average",
            "score": 52,
            "weight": 0.1,
            "contribution": 5.2,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "marine_warning_risk",
            "label": "Marine warning risk",
            "score": 34,
            "weight": 0.1,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "marine_warning_risk",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is coastal sea-state caution for ferry- or island-shaped route legs."
          },
          {
            "key": "pier_transfer_support",
            "label": "Pier transfer support",
            "score": 47,
            "weight": 0.08,
            "contribution": 3.76,
            "source": "signal",
            "signal_type": "pier_transfer_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is public transfer support around pier and coastal route anchors, not operator schedule truth."
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 96,
            "weight": 0.06,
            "contribution": 5.76,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official Marine Department passenger-berth support across coastal route anchors, not live ferry schedule, closure, queue, or seat truth."
          },
          {
            "key": "airport_weather_operability",
            "label": "Airport weather operability",
            "score": 62.57142857142857,
            "weight": 0.1,
            "contribution": 6.26,
            "source": "signal",
            "signal_type": "flight_delay_risk",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is airport weather and forecast disruption context on flight-dependent legs, not airline on-time performance."
          },
          {
            "key": "airport_transfer_support",
            "label": "Airport transfer support",
            "score": 62.75,
            "weight": 0.08,
            "contribution": 5.02,
            "source": "signal",
            "signal_type": "airport_transfer_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is public ground-access support around route airport nodes, not live check-in or queue truth."
          },
          {
            "key": "airport_ground_service_support",
            "label": "Airport ground-service support",
            "score": 60,
            "weight": 0.06,
            "contribution": 3.6,
            "source": "signal",
            "signal_type": "airport_ground_service_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official airport taxi, Grab, rental, and pickup-rule context around route airport nodes, not live queue, ETA, or rental inventory truth."
          },
          {
            "key": "airport_board_surface_support",
            "label": "Airport board-surface support",
            "score": 96,
            "weight": 0.05,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "airport_board_surface_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official passenger self-serve board visibility from public AOT flight-status pages, not direct live airline row truth."
          },
          {
            "key": "airport_scale_context",
            "label": "Airport scale context",
            "score": 72,
            "weight": 0.05,
            "contribution": 3.6,
            "source": "signal",
            "signal_type": "airport_scale_context",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official AOT passenger and aircraft-movement scale context around route airport nodes, not live airline on-time, queue, gate, or inventory truth."
          },
          {
            "key": "airport_environmental_support",
            "label": "Airport environmental support",
            "score": 96,
            "weight": 0.03,
            "contribution": 2.88,
            "source": "signal",
            "signal_type": "airport_environmental_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is SET-hosted AOT annual-report disclosure context around route airport nodes, not live measured sound-level truth."
          },
          {
            "key": "rail_feasibility",
            "label": "Rail feasibility",
            "score": 69.5,
            "weight": 0.08,
            "contribution": 5.56,
            "source": "signal",
            "signal_type": "rail_feasibility",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is public rail-support structure across the route chain, not live train seat, timetable, or disruption truth."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 83.33333333333333,
            "weight": 0.06,
            "contribution": 5,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support across the route chain for overland backup and bus-linked resilience, not live departure or booking truth."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 80.33333333333333,
            "weight": 0.04,
            "contribution": 3.21,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support across the route chain for overland backup and bus-linked resilience, not live departure or booking truth."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.04,
            "contribution": 3.84,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support across the route chain for overland route-search confidence, not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 92.33333333333333,
            "weight": 0.04,
            "contribution": 3.69,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context across the route chain, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 93.71428571428571,
            "weight": 0.04,
            "contribution": 3.75,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT GPS and Taxi OK regulated-taxi oversight, complaint, and station-search support across the route chain, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "official_motorcycle_taxi_support",
            "label": "Official motorcycle-taxi support",
            "score": 56.333333333333336,
            "weight": 0.03,
            "contribution": 1.69,
            "source": "signal",
            "signal_type": "official_motorcycle_taxi_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official Bangkok motorcycle-taxi stand and driver coverage from the public DLT/data.go.th dataset, useful as route-level last-mile support context rather than live availability, dispatch, or queue truth."
          },
          {
            "key": "taxi_pickup_dropoff_support",
            "label": "Taxi pickup and dropoff support",
            "score": 81,
            "weight": 0.03,
            "contribution": 2.43,
            "source": "signal",
            "signal_type": "taxi_pickup_dropoff_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is public OTP monthly taxi GPS analytics and hotspot context across Bangkok-linked route nodes, useful as aggregate pickup/dropoff support rather than live dispatch, ETA, queue, or raw trip truth."
          },
          {
            "key": "urban_rapid_transit_support",
            "label": "Urban rapid-transit support",
            "score": 98,
            "weight": 0.05,
            "contribution": 4.9,
            "source": "signal",
            "signal_type": "urban_rapid_transit_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official BTS and MRTA route-map and service-page support on Bangkok-linked route nodes, not live headway, crowding, or outage truth."
          },
          {
            "key": "urban_bus_operator_support",
            "label": "Urban bus-operator support",
            "score": 88,
            "weight": 0.04,
            "contribution": 3.52,
            "source": "signal",
            "signal_type": "urban_bus_operator_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is public Thai Smile Group branch and depot footprint on Bangkok-linked route nodes, useful as fallback urban bus support rather than live bus operations truth."
          },
          {
            "key": "park_access_context",
            "label": "Park access context",
            "score": 89,
            "weight": 0.04,
            "contribution": 3.56,
            "source": "signal",
            "signal_type": "park_access_context",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is public DNP protected-area planning context across nature-heavy route legs, not live closure, ranger, capacity, or ticket truth."
          },
          {
            "key": "node_confidence",
            "label": "Transfer-node confidence",
            "score": 97,
            "weight": 0.08,
            "contribution": 7.76,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "route_baseline",
            "label": "Route template baseline",
            "score": 61.34920634920635,
            "weight": 0.06,
            "contribution": 3.68,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "Route templates now act as low-weight route-shape hints instead of dominating the score."
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Route contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 64,
            "note": "Component scores spread by 64 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "3 destination anchors and 4 transfer nodes support this route check.",
        "main_risk": "Airport transfer support is weak",
        "weakest_leg": "Phuket",
        "path": "/routes/bangkok-chiang-mai-phuket/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:52:38.613Z"
      },
      {
        "decision_id": "route_phuket-krabi-koh-lanta",
        "decision_type": "route_check",
        "subject_id": "phuket-krabi-koh-lanta",
        "subject_name": "Phuket -> Krabi / Koh Lanta coast chain",
        "subject_type": "route",
        "score": 54,
        "component_score": 62.6,
        "penalty_points": 9,
        "confidence": "Medium",
        "label": "fragile",
        "recommendation": "Phuket -> Krabi / Koh Lanta coast chain is a cautious route shape right now.",
        "best_for": "Andaman scenery and flexible beach pacing.",
        "avoid_if": "The trip depends on tight ferries or you need maximum weather resilience.",
        "check_first": [
          "Andaman weather",
          "pier timing",
          "whether Phuket should stay the stable base"
        ],
        "next_action": "Keep at least one hotel refundable and do not make every scenic stop mandatory.",
        "pivot": "Use Phuket as the infrastructure answer if boats weaken.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 16,
          "available_components": 16,
          "live_components": 13,
          "fallback_components": 3,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "destination_average",
            "label": "Destination fit average",
            "score": 54.5,
            "weight": 0.34,
            "contribution": 18.53,
            "source": "decision",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "Average destination strength across the route chain."
          },
          {
            "key": "weakest_destination",
            "label": "Weakest destination leg",
            "score": 53,
            "weight": 0.18,
            "contribution": 9.54,
            "source": "decision",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "No weakest destination leg was available, so the route uses the average destination score.",
            "note": ""
          },
          {
            "key": "transport_average",
            "label": "Transport friction average",
            "score": 60.666666666666664,
            "weight": 0.16,
            "contribution": 9.71,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "rain_average",
            "label": "Rain fit average",
            "score": 44,
            "weight": 0.1,
            "contribution": 4.4,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "marine_warning_risk",
            "label": "Marine warning risk",
            "score": 34,
            "weight": 0.1,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "marine_warning_risk",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is coastal sea-state caution for ferry- or island-shaped route legs."
          },
          {
            "key": "pier_transfer_support",
            "label": "Pier transfer support",
            "score": 60,
            "weight": 0.08,
            "contribution": 4.8,
            "source": "signal",
            "signal_type": "pier_transfer_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is public transfer support around pier and coastal route anchors, not operator schedule truth."
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 90.66666666666667,
            "weight": 0.06,
            "contribution": 5.44,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official Marine Department passenger-berth support across coastal route anchors, not live ferry schedule, closure, queue, or seat truth."
          },
          {
            "key": "airport_weather_operability",
            "label": "Airport weather operability",
            "score": 69,
            "weight": 0.1,
            "contribution": 6.9,
            "source": "signal",
            "signal_type": "flight_delay_risk",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is airport weather and forecast disruption context on flight-dependent legs, not airline on-time performance."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 73,
            "weight": 0.06,
            "contribution": 4.38,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support across the route chain for overland backup and bus-linked resilience, not live departure or booking truth."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 67.5,
            "weight": 0.04,
            "contribution": 2.7,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support across the route chain for overland backup and bus-linked resilience, not live departure or booking truth."
          },
          {
            "key": "official_intercity_bus_search_support",
            "label": "Official intercity-bus search support",
            "score": 96,
            "weight": 0.04,
            "contribution": 3.84,
            "source": "signal",
            "signal_type": "official_intercity_bus_search_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS booking/search-surface support across the route chain for overland route-search confidence, not live departures, seats, or booking inventory truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 89,
            "weight": 0.04,
            "contribution": 3.56,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context across the route chain, not local realtime service quality or dispatch truth."
          },
          {
            "key": "official_taxi_oversight_support",
            "label": "Official taxi-oversight support",
            "score": 84,
            "weight": 0.04,
            "contribution": 3.36,
            "source": "signal",
            "signal_type": "official_taxi_oversight_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT GPS and Taxi OK regulated-taxi oversight, complaint, and station-search support across the route chain, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
          },
          {
            "key": "park_access_context",
            "label": "Park access context",
            "score": 91,
            "weight": 0.04,
            "contribution": 3.64,
            "source": "signal",
            "signal_type": "park_access_context",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is public DNP protected-area planning context across nature-heavy route legs, not live closure, ranger, capacity, or ticket truth."
          },
          {
            "key": "node_confidence",
            "label": "Transfer-node confidence",
            "score": 97,
            "weight": 0.08,
            "contribution": 7.76,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "route_baseline",
            "label": "Route template baseline",
            "score": 53.05555555555555,
            "weight": 0.06,
            "contribution": 3.18,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "Route templates now act as low-weight route-shape hints instead of dominating the score."
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Route contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 63,
            "note": "Component scores spread by 63 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "2 destination anchors and 1 transfer nodes support this route check.",
        "main_risk": "Marine warning risk is high",
        "weakest_leg": "Krabi",
        "path": "/routes/phuket-krabi-koh-lanta/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:52:38.613Z"
      },
      {
        "decision_id": "route_samui-phangan-tao",
        "decision_type": "route_check",
        "subject_id": "samui-phangan-tao",
        "subject_name": "Samui -> Phangan / Tao island chain",
        "subject_type": "route",
        "score": 53,
        "component_score": 62.3,
        "penalty_points": 9,
        "confidence": "Medium",
        "label": "fragile",
        "recommendation": "Samui -> Phangan / Tao island chain is a cautious route shape right now.",
        "best_for": "Gulf island pacing when weather and ferry timing cooperate.",
        "avoid_if": "You need a no-risk transfer chain or are forcing too many islands into a short trip.",
        "check_first": [
          "Gulf weather",
          "last boat timing",
          "mainland-to-pier burden",
          "event timing on Phangan"
        ],
        "next_action": "Keep Samui as the stable base and make extra islands earn their place.",
        "pivot": "Stay on Samui only if the chain looks brittle.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 14,
          "available_components": 14,
          "live_components": 11,
          "fallback_components": 3,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "destination_average",
            "label": "Destination fit average",
            "score": 58.5,
            "weight": 0.34,
            "contribution": 19.89,
            "source": "decision",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "Average destination strength across the route chain."
          },
          {
            "key": "weakest_destination",
            "label": "Weakest destination leg",
            "score": 58,
            "weight": 0.18,
            "contribution": 10.44,
            "source": "decision",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "No weakest destination leg was available, so the route uses the average destination score.",
            "note": ""
          },
          {
            "key": "transport_average",
            "label": "Transport friction average",
            "score": 58,
            "weight": 0.16,
            "contribution": 9.28,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "rain_average",
            "label": "Rain fit average",
            "score": 56,
            "weight": 0.1,
            "contribution": 5.6,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "marine_warning_risk",
            "label": "Marine warning risk",
            "score": 34,
            "weight": 0.1,
            "contribution": 3.4,
            "source": "signal",
            "signal_type": "marine_warning_risk",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is coastal sea-state caution for ferry- or island-shaped route legs."
          },
          {
            "key": "pier_transfer_support",
            "label": "Pier transfer support",
            "score": 23.5,
            "weight": 0.08,
            "contribution": 1.88,
            "source": "signal",
            "signal_type": "pier_transfer_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is public transfer support around pier and coastal route anchors, not operator schedule truth."
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 96,
            "weight": 0.06,
            "contribution": 5.76,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official Marine Department passenger-berth support across coastal route anchors, not live ferry schedule, closure, queue, or seat truth."
          },
          {
            "key": "airport_weather_operability",
            "label": "Airport weather operability",
            "score": 93,
            "weight": 0.1,
            "contribution": 9.3,
            "source": "signal",
            "signal_type": "flight_delay_risk",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is airport weather and forecast disruption context on flight-dependent legs, not airline on-time performance."
          },
          {
            "key": "official_bus_terminal_support",
            "label": "Official bus-terminal support",
            "score": 68,
            "weight": 0.06,
            "contribution": 4.08,
            "source": "signal",
            "signal_type": "official_bus_terminal_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official MOT terminal-master support across the route chain for overland backup and bus-linked resilience, not live departure or booking truth."
          },
          {
            "key": "official_intercity_bus_support",
            "label": "Official intercity-bus support",
            "score": 58,
            "weight": 0.04,
            "contribution": 2.32,
            "source": "signal",
            "signal_type": "official_intercity_bus_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official BKS station and ticket-point support across the route chain for overland backup and bus-linked resilience, not live departure or booking truth."
          },
          {
            "key": "official_transport_complaint_support",
            "label": "Official transport complaint support",
            "score": 81,
            "weight": 0.04,
            "contribution": 3.24,
            "source": "signal",
            "signal_type": "official_transport_complaint_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is official DLT 1584 complaint recourse and transport-burden context across the route chain, not local realtime service quality or dispatch truth."
          },
          {
            "key": "park_access_context",
            "label": "Park access context",
            "score": 84,
            "weight": 0.04,
            "contribution": 3.36,
            "source": "signal",
            "signal_type": "park_access_context",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "This is public DNP protected-area planning context across nature-heavy route legs, not live closure, ranger, capacity, or ticket truth."
          },
          {
            "key": "node_confidence",
            "label": "Transfer-node confidence",
            "score": 97,
            "weight": 0.08,
            "contribution": 7.76,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "route_baseline",
            "label": "Route template baseline",
            "score": 57.5,
            "weight": 0.06,
            "contribution": 3.45,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": "Route templates now act as low-weight route-shape hints instead of dominating the score."
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Route contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 73.5,
            "note": "Component scores spread by 74 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "2 destination anchors and 2 transfer nodes support this route check.",
        "main_risk": "Pier transfer support is weak",
        "weakest_leg": "Koh Phangan",
        "path": "/routes/koh-samui-koh-phangan-koh-tao/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:52:38.613Z"
      }
    ],
    "ferry_check": [
      {
        "decision_id": "ferry_phuket-krabi-ferry",
        "decision_type": "ferry_check",
        "subject_id": "phuket-krabi-ferry",
        "subject_name": "Phuket <-> Krabi ferry check",
        "subject_type": "ferry_route",
        "score": 52,
        "component_score": 63.4,
        "penalty_points": 11,
        "confidence": "Medium",
        "label": "fragile",
        "recommendation": "Phuket <-> Krabi ferry check needs refund-friendly planning and a backup move.",
        "best_for": "Andaman travelers who want coast changes without overcommitting every day to boats.",
        "avoid_if": "Your hotel stack stops being useful when one boat slips.",
        "check_first": [
          "live weather fit and ferry fragility",
          "last boat timing",
          "pier check-in and transfer burden"
        ],
        "next_action": "Keep the first island or coast hotel refundable until weather and pier timing feel solid.",
        "pivot": "Stay on Phuket and use road/day-trip logic if boats weaken.",
        "freshness_class": "acceptable",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 10,
          "available_components": 10,
          "live_components": 9,
          "fallback_components": 1,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "destination_fit",
            "label": "Destination chain fit",
            "score": 54.5,
            "weight": 0.22,
            "contribution": 11.99,
            "source": "decision",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "pier_confidence",
            "label": "Pier confidence",
            "score": 97,
            "weight": 0.14,
            "contribution": 13.58,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "pier_transfer_support",
            "label": "Pier transfer support",
            "score": 60,
            "weight": 0.14,
            "contribution": 8.4,
            "source": "signal",
            "signal_type": "pier_transfer_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 90.66666666666667,
            "weight": 0.12,
            "contribution": 10.88,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "berth_operability_context",
            "label": "Berth operability context",
            "score": 93.83333333333334,
            "weight": 0.1,
            "contribution": 9.38,
            "source": "signal",
            "signal_type": "berth_operability_context",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "ferry_fragility",
            "label": "Ferry fragility",
            "score": 55.666666666666664,
            "weight": 0.24,
            "contribution": 13.36,
            "source": "signal",
            "signal_type": "ferry_fragility",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "marine_warning_risk",
            "label": "Marine warning risk",
            "score": 34,
            "weight": 0.14,
            "contribution": 4.76,
            "source": "signal",
            "signal_type": "marine_warning_risk",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Weather fit",
            "score": 44,
            "weight": 0.08,
            "contribution": 3.52,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "transport_stack",
            "label": "Transfer burden",
            "score": 60.666666666666664,
            "weight": 0.1,
            "contribution": 6.07,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "weakest_ferry_leg",
            "label": "Weakest ferry leg",
            "score": 54,
            "weight": 0.08,
            "contribution": 4.32,
            "source": "signal",
            "signal_type": "ferry_fragility",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "acceptable",
            "points": 2,
            "applied": true,
            "note": "Freshness class is acceptable, so the engine applies a 2-point penalty."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Ferry contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 63,
            "note": "Component scores spread by 63 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "1 pier anchors and 2 island or coast anchors currently support this ferry check.",
        "main_risk": "Ferry fragility is elevated, so refund flexibility matters before you lock the island chain.",
        "path": "/ferries/phuket-krabi/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:52:38.613Z"
      },
      {
        "decision_id": "ferry_samui-phangan-chain",
        "decision_type": "ferry_check",
        "subject_id": "samui-phangan-chain",
        "subject_name": "Samui <-> Phangan ferry check",
        "subject_type": "ferry_route",
        "score": 50,
        "component_score": 60.6,
        "penalty_points": 11,
        "confidence": "Medium",
        "label": "fragile",
        "recommendation": "Samui <-> Phangan ferry check needs refund-friendly planning and a backup move.",
        "best_for": "Gulf island chains with at least one stable Samui base night.",
        "avoid_if": "You are stacking the last boat behind a long road or flight day.",
        "check_first": [
          "live weather fit and ferry fragility",
          "last boat timing",
          "pier check-in and transfer burden"
        ],
        "next_action": "Keep mainland and island hotel policies forgiving until the transfer day is clear.",
        "pivot": "Use Samui only if the chain becomes brittle.",
        "freshness_class": "acceptable",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 10,
          "available_components": 10,
          "live_components": 9,
          "fallback_components": 1,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "destination_fit",
            "label": "Destination chain fit",
            "score": 58.5,
            "weight": 0.22,
            "contribution": 12.87,
            "source": "decision",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "pier_confidence",
            "label": "Pier confidence",
            "score": 97,
            "weight": 0.14,
            "contribution": 13.58,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "pier_transfer_support",
            "label": "Pier transfer support",
            "score": 23.5,
            "weight": 0.14,
            "contribution": 3.29,
            "source": "signal",
            "signal_type": "pier_transfer_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 96,
            "weight": 0.12,
            "contribution": 11.52,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "berth_operability_context",
            "label": "Berth operability context",
            "score": 96.5,
            "weight": 0.1,
            "contribution": 9.65,
            "source": "signal",
            "signal_type": "berth_operability_context",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "ferry_fragility",
            "label": "Ferry fragility",
            "score": 51.75,
            "weight": 0.24,
            "contribution": 12.42,
            "source": "signal",
            "signal_type": "ferry_fragility",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "marine_warning_risk",
            "label": "Marine warning risk",
            "score": 34,
            "weight": 0.14,
            "contribution": 4.76,
            "source": "signal",
            "signal_type": "marine_warning_risk",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Weather fit",
            "score": 56,
            "weight": 0.08,
            "contribution": 4.48,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "transport_stack",
            "label": "Transfer burden",
            "score": 58,
            "weight": 0.1,
            "contribution": 5.8,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "weakest_ferry_leg",
            "label": "Weakest ferry leg",
            "score": 51,
            "weight": 0.08,
            "contribution": 4.08,
            "source": "signal",
            "signal_type": "ferry_fragility",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "acceptable",
            "points": 2,
            "applied": true,
            "note": "Freshness class is acceptable, so the engine applies a 2-point penalty."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Ferry contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 73.5,
            "note": "Component scores spread by 74 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "2 pier anchors and 2 island or coast anchors currently support this ferry check.",
        "main_risk": "Ferry fragility is elevated, so refund flexibility matters before you lock the island chain.",
        "path": "/ferries/koh-samui-koh-phangan-koh-tao/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:52:38.613Z"
      },
      {
        "decision_id": "ferry_mainland-to-samui",
        "decision_type": "ferry_check",
        "subject_id": "mainland-to-samui",
        "subject_name": "Mainland -> Samui ferry stack",
        "subject_type": "ferry_route",
        "score": 50,
        "component_score": 60.9,
        "penalty_points": 11,
        "confidence": "Medium",
        "label": "fragile",
        "recommendation": "Mainland -> Samui ferry stack needs refund-friendly planning and a backup move.",
        "best_for": "Travelers who intentionally build a mainland-to-island arrival day.",
        "avoid_if": "You are pretending the road leg is a small detail.",
        "check_first": [
          "live weather fit and ferry fragility",
          "last boat timing",
          "pier check-in and transfer burden"
        ],
        "next_action": "Treat the road-to-pier leg as part of the ferry decision, not a separate problem.",
        "pivot": "Fly if the schedule is already fragile before you even reach the pier.",
        "freshness_class": "acceptable",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 10,
          "available_components": 10,
          "live_components": 9,
          "fallback_components": 1,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "destination_fit",
            "label": "Destination chain fit",
            "score": 59,
            "weight": 0.22,
            "contribution": 12.98,
            "source": "decision",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "pier_confidence",
            "label": "Pier confidence",
            "score": 97,
            "weight": 0.14,
            "contribution": 13.58,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "pier_transfer_support",
            "label": "Pier transfer support",
            "score": 23,
            "weight": 0.14,
            "contribution": 3.22,
            "source": "signal",
            "signal_type": "pier_transfer_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "official_pier_support",
            "label": "Official pier support",
            "score": 96.66666666666667,
            "weight": 0.12,
            "contribution": 11.6,
            "source": "signal",
            "signal_type": "official_pier_support",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "berth_operability_context",
            "label": "Berth operability context",
            "score": 96.83333333333334,
            "weight": 0.1,
            "contribution": 9.68,
            "source": "signal",
            "signal_type": "berth_operability_context",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "ferry_fragility",
            "label": "Ferry fragility",
            "score": 52,
            "weight": 0.24,
            "contribution": 12.48,
            "source": "signal",
            "signal_type": "ferry_fragility",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "marine_warning_risk",
            "label": "Marine warning risk",
            "score": 34,
            "weight": 0.14,
            "contribution": 4.76,
            "source": "signal",
            "signal_type": "marine_warning_risk",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Weather fit",
            "score": 56,
            "weight": 0.08,
            "contribution": 4.48,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "transport_stack",
            "label": "Transfer burden",
            "score": 58.333333333333336,
            "weight": 0.1,
            "contribution": 5.83,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "weakest_ferry_leg",
            "label": "Weakest ferry leg",
            "score": 52,
            "weight": 0.08,
            "contribution": 4.16,
            "source": "signal",
            "signal_type": "ferry_fragility",
            "entity_id": null,
            "used_default": false,
            "default_reason": "",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "acceptable",
            "points": 2,
            "applied": true,
            "note": "Freshness class is acceptable, so the engine applies a 2-point penalty."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Ferry contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 74,
            "note": "Component scores spread by 74 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "2 pier anchors and 1 island or coast anchors currently support this ferry check.",
        "main_risk": "Ferry fragility is elevated, so refund flexibility matters before you lock the island chain.",
        "path": "/ferries/thailand-island-transfers/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:52:38.613Z"
      }
    ],
    "food_route": [
      {
        "decision_id": "food_bangkok",
        "decision_type": "food_route",
        "subject_id": "bangkok",
        "subject_name": "Bangkok",
        "subject_type": "destination",
        "score": 73,
        "component_score": 79,
        "penalty_points": 6,
        "confidence": "Medium",
        "label": "good",
        "recommendation": "Bangkok is a good food-route pick right now.",
        "best_for": "First-trip range, Chinatown, rail-linked eating, and rainy-day fallback.",
        "avoid_if": "You want one quiet neighborhood to explain the whole city.",
        "check_first": [
          "Check Air4Thai before heavy outdoor days.",
          "Choose a BTS/MRT-linked base before paying for a hotel."
        ],
        "next_action": "Choose the neighborhood first, then the named place.",
        "pivot": "Use malls, Chinatown, or BTS-linked zones when rain and heat stack.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 6,
          "available_components": 6,
          "live_components": 3,
          "fallback_components": 3,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "destination_fit",
            "label": "Destination fit",
            "score": 63,
            "weight": 0.26,
            "contribution": 16.38,
            "source": "decision",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "Destination decision missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.16,
            "contribution": 15.52,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "Food-route source confidence missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 93.5,
            "weight": 0.12,
            "contribution": 11.22,
            "source": "derived",
            "signal_type": null,
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 56,
            "weight": 0.1,
            "contribution": 5.6,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "Food-route rain fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 86,
            "weight": 0.1,
            "contribution": 8.6,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "Food-route transport fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "food_blueprint_baseline",
            "label": "Food blueprint baseline",
            "score": 90,
            "weight": 0.1,
            "contribution": 9,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "Food blueprint seed missing; using destination score fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Food-route contradiction penalty",
            "points": 6,
            "applied": true,
            "spread": 41,
            "note": "Component scores spread by 41 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "19 joined sources support this decision.",
        "path": "/today/bangkok/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:51:33.917Z"
      },
      {
        "decision_id": "food_chiang-mai",
        "decision_type": "food_route",
        "subject_id": "chiang-mai",
        "subject_name": "Chiang Mai",
        "subject_type": "destination",
        "score": 70,
        "component_score": 76.1,
        "penalty_points": 6,
        "confidence": "Medium",
        "label": "mixed",
        "recommendation": "Chiang Mai works better as a supporting food move than the main food trip answer.",
        "best_for": "Khao soi, northern flavors, markets, and cafe routing.",
        "avoid_if": "AQI is high enough to make outdoor city walking feel punishing.",
        "check_first": [
          "Treat sustained PM2.5 as the main breaker.",
          "Choose Old City or Nimman based on trip shape, not a random deal."
        ],
        "next_action": "Use khao soi as the anchor, not the entire route.",
        "pivot": "Use Nimman comfort or indoor-heavy stops if the air is only borderline.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 6,
          "available_components": 6,
          "live_components": 3,
          "fallback_components": 3,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "destination_fit",
            "label": "Destination fit",
            "score": 65,
            "weight": 0.26,
            "contribution": 16.9,
            "source": "decision",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "Destination decision missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.16,
            "contribution": 15.52,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "Food-route source confidence missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 93.5,
            "weight": 0.12,
            "contribution": 11.22,
            "source": "derived",
            "signal_type": null,
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 56,
            "weight": 0.1,
            "contribution": 5.6,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "Food-route rain fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 63,
            "weight": 0.1,
            "contribution": 6.3,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "Food-route transport fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "food_blueprint_baseline",
            "label": "Food blueprint baseline",
            "score": 84,
            "weight": 0.1,
            "contribution": 8.4,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "Food blueprint seed missing; using destination score fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Food-route contradiction penalty",
            "points": 6,
            "applied": true,
            "spread": 41,
            "note": "Component scores spread by 41 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "10 joined sources support this decision.",
        "path": "/where-to-go/chiang-mai/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:51:33.917Z"
      },
      {
        "decision_id": "food_koh-samui",
        "decision_type": "food_route",
        "subject_id": "koh-samui",
        "subject_name": "Koh Samui",
        "subject_type": "destination",
        "score": 67,
        "component_score": 72.6,
        "penalty_points": 6,
        "confidence": "Medium",
        "label": "mixed",
        "recommendation": "Koh Samui works better as a supporting food move than the main food trip answer.",
        "best_for": "Island comfort stays that want enough dining without turning nightlife into the whole trip.",
        "avoid_if": "You are chasing a city-level food graph on a resort island.",
        "check_first": [
          "Compare Gulf weather directly with the Andaman coast.",
          "Use Samui itself as the stable base before adding Phangan or Tao."
        ],
        "next_action": "Let the hotel base and transfer burden decide how wide the food route should spread.",
        "pivot": "Use Bangkok or Chiang Mai for the food-heavy segment of a split trip.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 6,
          "available_components": 6,
          "live_components": 3,
          "fallback_components": 3,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "destination_fit",
            "label": "Destination fit",
            "score": 59,
            "weight": 0.26,
            "contribution": 15.34,
            "source": "decision",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "Destination decision missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.16,
            "contribution": 15.52,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "Food-route source confidence missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 93.5,
            "weight": 0.12,
            "contribution": 11.22,
            "source": "derived",
            "signal_type": null,
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 56,
            "weight": 0.1,
            "contribution": 5.6,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "Food-route rain fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 60,
            "weight": 0.1,
            "contribution": 6,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "Food-route transport fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "food_blueprint_baseline",
            "label": "Food blueprint baseline",
            "score": 73,
            "weight": 0.1,
            "contribution": 7.3,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "koh-samui",
            "used_default": false,
            "default_reason": "Food blueprint seed missing; using destination score fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Food-route contradiction penalty",
            "points": 6,
            "applied": true,
            "spread": 41,
            "note": "Component scores spread by 41 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "9 joined sources support this decision.",
        "path": "/where-to-go/koh-samui/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T18:00:00.000Z"
      },
      {
        "decision_id": "food_isaan",
        "decision_type": "food_route",
        "subject_id": "isaan",
        "subject_name": "Isaan",
        "subject_type": "destination",
        "score": 67,
        "component_score": 72.5,
        "penalty_points": 6,
        "confidence": "Medium",
        "label": "mixed",
        "recommendation": "Isaan works better as a supporting food move than the main food trip answer.",
        "best_for": "Repeat visitors who want regional food identity over a polished tourist script.",
        "avoid_if": "You need one easy first-trip dining district to do all the work.",
        "check_first": [
          "Treat province choice as the real decision, not just the region label.",
          "Use Khon Kaen, Ubon, Nong Khai, or Korat as actual anchors."
        ],
        "next_action": "Pick one province cluster and let the food justify the route.",
        "pivot": "Use Bangkok or Khon Kaen as the easier bridge into the region.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 6,
          "available_components": 6,
          "live_components": 3,
          "fallback_components": 3,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "destination_fit",
            "label": "Destination fit",
            "score": 63,
            "weight": 0.26,
            "contribution": 16.38,
            "source": "decision",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "Destination decision missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_confidence",
            "label": "Local source confidence",
            "score": 91,
            "weight": 0.16,
            "contribution": 14.56,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "Food-route source confidence missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 80,
            "weight": 0.12,
            "contribution": 9.6,
            "source": "derived",
            "signal_type": null,
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 64,
            "weight": 0.1,
            "contribution": 6.4,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "Food-route rain fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 58,
            "weight": 0.1,
            "contribution": 5.8,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "Food-route transport fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "food_blueprint_baseline",
            "label": "Food blueprint baseline",
            "score": 82,
            "weight": 0.1,
            "contribution": 8.2,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "isaan",
            "used_default": false,
            "default_reason": "Food blueprint seed missing; using destination score fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Food-route contradiction penalty",
            "points": 6,
            "applied": true,
            "spread": 33,
            "note": "Component scores spread by 33 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "14 joined sources support this decision.",
        "path": "/where-to-go/isaan/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:51:33.917Z"
      },
      {
        "decision_id": "food_phuket",
        "decision_type": "food_route",
        "subject_id": "phuket",
        "subject_name": "Phuket",
        "subject_type": "destination",
        "score": 62,
        "component_score": 70.7,
        "penalty_points": 9,
        "confidence": "Medium",
        "label": "mixed",
        "recommendation": "Phuket works better as a supporting food move than the main food trip answer.",
        "best_for": "Beach-trip food routes that need Old Town and rain backup in the mix.",
        "avoid_if": "You expect one beach strip to solve every meal mood.",
        "check_first": [
          "Choose the beach area before the hotel.",
          "Check marine and weather layers before committing to boat-heavy days."
        ],
        "next_action": "Keep Old Town as the fallback even if the hotel is beach-first.",
        "pivot": "Move the eating day away from the beach when weather weakens.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 6,
          "available_components": 6,
          "live_components": 3,
          "fallback_components": 3,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "destination_fit",
            "label": "Destination fit",
            "score": 56,
            "weight": 0.26,
            "contribution": 14.56,
            "source": "decision",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "Destination decision missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.16,
            "contribution": 15.52,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "Food-route source confidence missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 93.5,
            "weight": 0.12,
            "contribution": 11.22,
            "source": "derived",
            "signal_type": null,
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 44,
            "weight": 0.1,
            "contribution": 4.4,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "Food-route rain fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 61,
            "weight": 0.1,
            "contribution": 6.1,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "Food-route transport fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "food_blueprint_baseline",
            "label": "Food blueprint baseline",
            "score": 76,
            "weight": 0.1,
            "contribution": 7.6,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "Food blueprint seed missing; using destination score fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Food-route contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 53,
            "note": "Component scores spread by 53 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "9 joined sources support this decision.",
        "path": "/where-to-go/phuket/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T18:00:00.000Z"
      },
      {
        "decision_id": "food_pattaya-chonburi",
        "decision_type": "food_route",
        "subject_id": "pattaya-chonburi",
        "subject_name": "Pattaya / Chonburi",
        "subject_type": "destination",
        "score": 58,
        "component_score": 68.9,
        "penalty_points": 11,
        "confidence": "Medium",
        "label": "mixed",
        "recommendation": "Pattaya / Chonburi works better as a supporting food move than the main food trip answer.",
        "best_for": "Seafood, Thai-Chinese coastal eating, short-notice Bangkok coast pivots, and nightlife-adjacent food runs.",
        "avoid_if": "You want one calm district to explain the whole destination or you dislike traffic-heavy meal routing.",
        "check_first": [
          "Treat weekend traffic as a real input, not a footnote.",
          "Pick the beach or hotel zone before the hotel brand."
        ],
        "next_action": "Pick the zone first, then the named place, and let weekend traffic change the meal plan if needed.",
        "pivot": "Use Bangkok for the deeper food segment if the coast is only a short break.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 6,
          "available_components": 5,
          "live_components": 2,
          "fallback_components": 3,
          "defaulted_components": 1,
          "coverage_ratio": 0.833
        },
        "score_components": [
          {
            "key": "destination_fit",
            "label": "Destination fit",
            "score": 51,
            "weight": 0.26,
            "contribution": 13.26,
            "source": "decision",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "Destination decision missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.16,
            "contribution": 15.52,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "Food-route source confidence missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 70,
            "weight": 0.12,
            "contribution": 8.4,
            "source": "derived",
            "signal_type": null,
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 68,
            "weight": 0.1,
            "contribution": 6.8,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "pattaya-chonburi",
            "used_default": true,
            "default_reason": "Food-route rain fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 68,
            "weight": 0.1,
            "contribution": 6.8,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "Food-route transport fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "food_blueprint_baseline",
            "label": "Food blueprint baseline",
            "score": 71,
            "weight": 0.1,
            "contribution": 7.1,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "Food blueprint seed missing; using destination score fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 1,
            "points": 2,
            "applied": true,
            "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Food-route contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 46,
            "note": "Component scores spread by 46 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "rain_fit"
        ],
        "source_summary": "8 joined sources support this decision.",
        "path": "/where-to-go/pattaya-chonburi/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:51:33.917Z"
      },
      {
        "decision_id": "food_hua-hin",
        "decision_type": "food_route",
        "subject_id": "hua-hin",
        "subject_name": "Hua Hin / Cha-am",
        "subject_type": "destination",
        "score": 58,
        "component_score": 68.9,
        "penalty_points": 11,
        "confidence": "Medium",
        "label": "mixed",
        "recommendation": "Hua Hin / Cha-am works better as a supporting food move than the main food trip answer.",
        "best_for": "Seafood, night markets, resort-town comfort food, and gentler family-paced coast eating.",
        "avoid_if": "You expect city-level restaurant density or nightlife to solve the whole evening plan.",
        "check_first": [
          "Choose the exact beach-town base before paying.",
          "Treat rail and road convenience as part of the value, not just background logistics."
        ],
        "next_action": "Choose the market or beach-town zone first, then keep one easy indoor or hotel fallback in reserve.",
        "pivot": "Use Bangkok if the trip turns food-first rather than coast-first.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 6,
          "available_components": 5,
          "live_components": 2,
          "fallback_components": 3,
          "defaulted_components": 1,
          "coverage_ratio": 0.833
        },
        "score_components": [
          {
            "key": "destination_fit",
            "label": "Destination fit",
            "score": 49,
            "weight": 0.26,
            "contribution": 12.74,
            "source": "decision",
            "signal_type": null,
            "entity_id": null,
            "used_default": false,
            "default_reason": "Destination decision missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_confidence",
            "label": "Local source confidence",
            "score": 97,
            "weight": 0.16,
            "contribution": 15.52,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "Food-route source confidence missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "local_comfort",
            "label": "Local comfort",
            "score": 70,
            "weight": 0.12,
            "contribution": 8.4,
            "source": "derived",
            "signal_type": null,
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "rain_fit",
            "label": "Rain fit",
            "score": 68,
            "weight": 0.1,
            "contribution": 6.8,
            "source": "signal",
            "signal_type": "rain_risk",
            "entity_id": "hua-hin",
            "used_default": true,
            "default_reason": "Food-route rain fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "transport_fit",
            "label": "Transport fit",
            "score": 70,
            "weight": 0.1,
            "contribution": 7,
            "source": "signal",
            "signal_type": "transport_friction",
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "Food-route transport fit missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "food_blueprint_baseline",
            "label": "Food blueprint baseline",
            "score": 74,
            "weight": 0.1,
            "contribution": 7.4,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "hua-hin",
            "used_default": false,
            "default_reason": "Food blueprint seed missing; using destination score fallback.",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 1,
            "points": 2,
            "applied": true,
            "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
          },
          {
            "key": "contradiction_penalty",
            "label": "Food-route contradiction penalty",
            "points": 9,
            "applied": true,
            "spread": 48,
            "note": "Component scores spread by 48 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": true,
        "fallback_components": [
          "rain_fit"
        ],
        "source_summary": "9 joined sources support this decision.",
        "path": "/where-to-go/hua-hin/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T15:51:33.917Z"
      }
    ],
    "gold_buying_check": [
      {
        "decision_id": "gold_bangkok",
        "decision_type": "gold_buying_check",
        "subject_id": "bangkok",
        "subject_name": "Bangkok / Yaowarat",
        "subject_type": "destination",
        "score": 88,
        "component_score": 87.6,
        "penalty_points": 0,
        "confidence": "Medium",
        "label": "strong",
        "recommendation": "Bangkok / Yaowarat is the strongest gold-buying context right now if you still compare multiple shops against the national quote.",
        "best_for": "Comparison shopping, dense shop clusters, clearer receipt and buyback expectations, and travelers who want the strongest public gold-buying context in Thailand.",
        "avoid_if": "You are treating the national reference quote like a guaranteed final shop price without checking workmanship, receipt detail, and buyback terms.",
        "check_first": [
          "latest GTA bar and ornament quote",
          "receipt detail and buyback terms",
          "whether you want bar or ornament gold"
        ],
        "next_action": "Use the national GTA quote first, then compare multiple Yaowarat shops before paying.",
        "pivot": "Use Chiang Mai for regional convenience if the trip is not passing through Bangkok anyway.",
        "city_context": "Bangkok / Yaowarat",
        "entity_anchor_id": "yaowarat-gold-district",
        "entity_anchor_path": "/entities/yaowarat-gold-district/",
        "entity_anchor_name": "Yaowarat gold district",
        "reference_price": 64300,
        "reference_buy_price": 64100,
        "reference_unit": "THB per 1 baht-weight of 96.5% Thai gold",
        "updated_at": "2026-06-24T03:43:00.000Z",
        "fx_context": "Published GTA USD/THB context shows USD/THB around 33.38, intraday quote change +50 THB, and previous-day change -500 THB. GTA spot reference is 4,065. This is pricing context, not investment advice.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 5,
          "available_components": 5,
          "live_components": 4,
          "fallback_components": 1,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "national_reference",
            "label": "National GTA reference",
            "score": 86,
            "weight": 0.32,
            "contribution": 27.52,
            "source": "signal",
            "signal_type": "thai_gold_reference_price",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "fx_pressure",
            "label": "FX and quote pressure",
            "score": 82,
            "weight": 0.18,
            "contribution": 14.76,
            "source": "signal",
            "signal_type": "thai_gold_fx_pressure",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "Gold FX-pressure context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "city_friction",
            "label": "City buying friction",
            "score": 88,
            "weight": 0.28,
            "contribution": 24.64,
            "source": "signal",
            "signal_type": "thai_gold_buying_friction",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "source_confidence",
            "label": "Source confidence",
            "score": 97,
            "weight": 0.12,
            "contribution": 11.64,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "Source confidence missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "city_baseline",
            "label": "City baseline",
            "score": 90,
            "weight": 0.1,
            "contribution": 9,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "bangkok",
            "used_default": false,
            "default_reason": "",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Gold-buying contradiction penalty",
            "points": 0,
            "applied": false,
            "spread": 15,
            "note": "Component scores are not meaningfully contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "8 joined sources support this decision.",
        "path": "/gold/yaowarat-gold-shops/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T11:51:33.917Z"
      },
      {
        "decision_id": "gold_chiang-mai",
        "decision_type": "gold_buying_check",
        "subject_id": "chiang-mai",
        "subject_name": "Chiang Mai",
        "subject_type": "destination",
        "score": 83,
        "component_score": 83.4,
        "penalty_points": 0,
        "confidence": "Medium",
        "label": "good",
        "recommendation": "Chiang Mai is workable for gold buying if you keep the national quote visible and check spread and receipts carefully.",
        "best_for": "Regional convenience buying when the trip already centers on Chiang Mai and you do not need the deepest comparison-shopping field.",
        "avoid_if": "You want maximum shop density or are using a single tourist-area quote as if it were a special local benchmark.",
        "check_first": [
          "latest GTA reference quote",
          "ornament workmanship or premium",
          "buyback convenience versus Bangkok"
        ],
        "next_action": "Treat Chiang Mai as a convenience market and compare against the national GTA quote before agreeing to local ornament premiums.",
        "pivot": "Use Bangkok / Yaowarat if the purchase is large enough that deeper comparison shopping matters.",
        "city_context": "Chiang Mai",
        "entity_anchor_id": "chiang-mai-gold-shopping",
        "entity_anchor_path": "/entities/chiang-mai-gold-shopping/",
        "entity_anchor_name": "Chiang Mai gold shopping",
        "reference_price": 64300,
        "reference_buy_price": 64100,
        "reference_unit": "THB per 1 baht-weight of 96.5% Thai gold",
        "updated_at": "2026-06-24T03:43:00.000Z",
        "fx_context": "Published GTA USD/THB context shows USD/THB around 33.38, intraday quote change +50 THB, and previous-day change -500 THB. GTA spot reference is 4,065. This is pricing context, not investment advice.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 5,
          "available_components": 5,
          "live_components": 4,
          "fallback_components": 1,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "national_reference",
            "label": "National GTA reference",
            "score": 86,
            "weight": 0.32,
            "contribution": 27.52,
            "source": "signal",
            "signal_type": "thai_gold_reference_price",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "fx_pressure",
            "label": "FX and quote pressure",
            "score": 82,
            "weight": 0.18,
            "contribution": 14.76,
            "source": "signal",
            "signal_type": "thai_gold_fx_pressure",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "Gold FX-pressure context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "city_friction",
            "label": "City buying friction",
            "score": 78,
            "weight": 0.28,
            "contribution": 21.84,
            "source": "signal",
            "signal_type": "thai_gold_buying_friction",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "source_confidence",
            "label": "Source confidence",
            "score": 97,
            "weight": 0.12,
            "contribution": 11.64,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "Source confidence missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "city_baseline",
            "label": "City baseline",
            "score": 76,
            "weight": 0.1,
            "contribution": 7.6,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "chiang-mai",
            "used_default": false,
            "default_reason": "",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Gold-buying contradiction penalty",
            "points": 0,
            "applied": false,
            "spread": 21,
            "note": "Component scores are not meaningfully contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "7 joined sources support this decision.",
        "path": "/gold/thailand-gold-price/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T11:51:33.917Z"
      },
      {
        "decision_id": "gold_hat-yai-gold-shopping",
        "decision_type": "gold_buying_check",
        "subject_id": "hat-yai-gold-shopping",
        "subject_name": "Hat Yai",
        "subject_type": "market_district",
        "score": 81,
        "component_score": 81.2,
        "penalty_points": 0,
        "confidence": "Medium",
        "label": "good",
        "recommendation": "Hat Yai is workable for gold buying if you keep the national quote visible and check spread and receipts carefully.",
        "best_for": "Southern regional convenience buying when the trip already centers on Songkhla or the lower south and Bangkok-level comparison density is not the goal.",
        "avoid_if": "You are assuming Hat Yai has a separate official southern price or you still need the deepest comparison-shopping field in Thailand.",
        "check_first": [
          "latest GTA reference quote",
          "spread and buyback terms",
          "receipt detail and workmanship"
        ],
        "next_action": "Treat Hat Yai as a southern convenience market and keep the national quote visible while you compare local spread, receipt, and buyback terms.",
        "pivot": "Use Bangkok / Yaowarat if the purchase is large enough that maximum comparison density matters more than southern convenience.",
        "city_context": "Hat Yai",
        "entity_anchor_id": "hat-yai-gold-shopping",
        "entity_anchor_path": "/entities/hat-yai-gold-shopping/",
        "entity_anchor_name": "Hat Yai gold shopping",
        "reference_price": 64300,
        "reference_buy_price": 64100,
        "reference_unit": "THB per 1 baht-weight of 96.5% Thai gold",
        "updated_at": "2026-06-24T03:43:00.000Z",
        "fx_context": "Published GTA USD/THB context shows USD/THB around 33.38, intraday quote change +50 THB, and previous-day change -500 THB. GTA spot reference is 4,065. This is pricing context, not investment advice.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 5,
          "available_components": 5,
          "live_components": 4,
          "fallback_components": 1,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "national_reference",
            "label": "National GTA reference",
            "score": 86,
            "weight": 0.32,
            "contribution": 27.52,
            "source": "signal",
            "signal_type": "thai_gold_reference_price",
            "entity_id": "hat-yai-gold-shopping",
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "fx_pressure",
            "label": "FX and quote pressure",
            "score": 82,
            "weight": 0.18,
            "contribution": 14.76,
            "source": "signal",
            "signal_type": "thai_gold_fx_pressure",
            "entity_id": "hat-yai-gold-shopping",
            "used_default": false,
            "default_reason": "Gold FX-pressure context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "city_friction",
            "label": "City buying friction",
            "score": 75,
            "weight": 0.28,
            "contribution": 21,
            "source": "signal",
            "signal_type": "thai_gold_buying_friction",
            "entity_id": "hat-yai-gold-shopping",
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "source_confidence",
            "label": "Source confidence",
            "score": 89,
            "weight": 0.12,
            "contribution": 10.68,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "hat-yai-gold-shopping",
            "used_default": false,
            "default_reason": "Source confidence missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "city_baseline",
            "label": "City baseline",
            "score": 72,
            "weight": 0.1,
            "contribution": 7.2,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "hat-yai-gold-shopping",
            "used_default": false,
            "default_reason": "",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Gold-buying contradiction penalty",
            "points": 0,
            "applied": false,
            "spread": 17,
            "note": "Component scores are not meaningfully contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "3 joined sources support this decision.",
        "path": "/gold/thailand-gold-price/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T11:43:00.000Z"
      },
      {
        "decision_id": "gold_phuket",
        "decision_type": "gold_buying_check",
        "subject_id": "phuket",
        "subject_name": "Phuket",
        "subject_type": "destination",
        "score": 72,
        "component_score": 78.4,
        "penalty_points": 6,
        "confidence": "Medium",
        "label": "good",
        "recommendation": "Phuket is workable for gold buying if you keep the national quote visible and check spread and receipts carefully.",
        "best_for": "Trip-convenience buying where the national quote is the anchor but tourist-market friction is accepted.",
        "avoid_if": "You are assuming Phuket has a different official price or ignoring spread, language, and receipt-quality risk.",
        "check_first": [
          "latest GTA reference quote",
          "spread and workmanship",
          "receipt and buyback clarity"
        ],
        "next_action": "Use Phuket only when convenience matters more than the widest shop comparison field, and keep the national quote visible while you compare.",
        "pivot": "Move the purchase to Bangkok if the trip will pass through Yaowarat anyway.",
        "city_context": "Phuket",
        "entity_anchor_id": "phuket-gold-shopping",
        "entity_anchor_path": "/entities/phuket-gold-shopping/",
        "entity_anchor_name": "Phuket gold shopping",
        "reference_price": 64300,
        "reference_buy_price": 64100,
        "reference_unit": "THB per 1 baht-weight of 96.5% Thai gold",
        "updated_at": "2026-06-24T03:43:00.000Z",
        "fx_context": "Published GTA USD/THB context shows USD/THB around 33.38, intraday quote change +50 THB, and previous-day change -500 THB. GTA spot reference is 4,065. This is pricing context, not investment advice.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 5,
          "available_components": 5,
          "live_components": 4,
          "fallback_components": 1,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "national_reference",
            "label": "National GTA reference",
            "score": 86,
            "weight": 0.32,
            "contribution": 27.52,
            "source": "signal",
            "signal_type": "thai_gold_reference_price",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "fx_pressure",
            "label": "FX and quote pressure",
            "score": 82,
            "weight": 0.18,
            "contribution": 14.76,
            "source": "signal",
            "signal_type": "thai_gold_fx_pressure",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "Gold FX-pressure context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "city_friction",
            "label": "City buying friction",
            "score": 66,
            "weight": 0.28,
            "contribution": 18.48,
            "source": "signal",
            "signal_type": "thai_gold_buying_friction",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "source_confidence",
            "label": "Source confidence",
            "score": 97,
            "weight": 0.12,
            "contribution": 11.64,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "Source confidence missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "city_baseline",
            "label": "City baseline",
            "score": 60,
            "weight": 0.1,
            "contribution": 6,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "phuket",
            "used_default": false,
            "default_reason": "",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Gold-buying contradiction penalty",
            "points": 6,
            "applied": true,
            "spread": 37,
            "note": "Component scores spread by 37 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "7 joined sources support this decision.",
        "path": "/gold/thailand-gold-price/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T14:00:00.000Z"
      },
      {
        "decision_id": "gold_pattaya-chonburi",
        "decision_type": "gold_buying_check",
        "subject_id": "pattaya-chonburi",
        "subject_name": "Pattaya / Chonburi",
        "subject_type": "destination",
        "score": 72,
        "component_score": 77.9,
        "penalty_points": 6,
        "confidence": "Medium",
        "label": "good",
        "recommendation": "Pattaya / Chonburi is workable for gold buying if you keep the national quote visible and check spread and receipts carefully.",
        "best_for": "Short-trip convenience when the national quote is the anchor and the buyer is comfortable asking careful shop-level questions.",
        "avoid_if": "You want Bangkok-style comparison density or are relying on one tourist-area quote as if it were a separate official market.",
        "check_first": [
          "latest GTA reference quote",
          "spread and buyback terms",
          "receipt detail"
        ],
        "next_action": "Treat Pattaya / Chonburi as a convenience context and ask directly about spread, workmanship, and buyback terms before paying.",
        "pivot": "Use Bangkok for the purchase if comparison-shopping confidence matters more than convenience.",
        "city_context": "Pattaya / Chonburi",
        "entity_anchor_id": "pattaya-gold-shopping",
        "entity_anchor_path": "/entities/pattaya-gold-shopping/",
        "entity_anchor_name": "Pattaya / Chonburi gold shopping",
        "reference_price": 64300,
        "reference_buy_price": 64100,
        "reference_unit": "THB per 1 baht-weight of 96.5% Thai gold",
        "updated_at": "2026-06-24T03:43:00.000Z",
        "fx_context": "Published GTA USD/THB context shows USD/THB around 33.38, intraday quote change +50 THB, and previous-day change -500 THB. GTA spot reference is 4,065. This is pricing context, not investment advice.",
        "freshness_class": "fresh",
        "score_formula_version": "signal-first-v2",
        "signal_coverage": {
          "total_components": 5,
          "available_components": 5,
          "live_components": 4,
          "fallback_components": 1,
          "defaulted_components": 0,
          "coverage_ratio": 1
        },
        "score_components": [
          {
            "key": "national_reference",
            "label": "National GTA reference",
            "score": 86,
            "weight": 0.32,
            "contribution": 27.52,
            "source": "signal",
            "signal_type": "thai_gold_reference_price",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "fx_pressure",
            "label": "FX and quote pressure",
            "score": 82,
            "weight": 0.18,
            "contribution": 14.76,
            "source": "signal",
            "signal_type": "thai_gold_fx_pressure",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "Gold FX-pressure context missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "city_friction",
            "label": "City buying friction",
            "score": 65,
            "weight": 0.28,
            "contribution": 18.2,
            "source": "signal",
            "signal_type": "thai_gold_buying_friction",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "",
            "note": ""
          },
          {
            "key": "source_confidence",
            "label": "Source confidence",
            "score": 97,
            "weight": 0.12,
            "contribution": 11.64,
            "source": "signal",
            "signal_type": "source_confidence",
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "Source confidence missing; using conservative fallback.",
            "note": ""
          },
          {
            "key": "city_baseline",
            "label": "City baseline",
            "score": 58,
            "weight": 0.1,
            "contribution": 5.8,
            "source": "blueprint",
            "signal_type": null,
            "entity_id": "pattaya-chonburi",
            "used_default": false,
            "default_reason": "",
            "note": ""
          }
        ],
        "penalty_components": [
          {
            "key": "freshness_penalty",
            "label": "Freshness penalty",
            "freshness_class": "fresh",
            "points": 0,
            "applied": false,
            "note": "Signals are fresh enough that no freshness penalty applies."
          },
          {
            "key": "coverage_penalty",
            "label": "Coverage penalty",
            "defaulted_components": 0,
            "points": 0,
            "applied": false,
            "note": "All decision components are covered by live or persisted graph values."
          },
          {
            "key": "contradiction_penalty",
            "label": "Gold-buying contradiction penalty",
            "points": 6,
            "applied": true,
            "spread": 39,
            "note": "Component scores spread by 39 points, so the engine treats the answer as more contradictory."
          }
        ],
        "fallback_used": false,
        "fallback_components": [],
        "source_summary": "6 joined sources support this decision.",
        "path": "/gold/thailand-gold-price/",
        "computed_at": "2026-06-24T03:51:19.382Z",
        "expires_at": "2026-06-24T11:51:33.917Z"
      }
    ]
  },
  "storage": {
    "mode": "persisted",
    "snapshot_kind": "decisions",
    "generated_at": "2026-06-24T03:51:19.382Z",
    "stored_at": "2026-06-24T03:52:52.037Z",
    "fresh": false
  },
  "filters": {
    "destination": "all",
    "city": "all",
    "route": "all",
    "limit": "all"
  },
  "overview": {
    "today": {
      "decision_id": "today_chiang-mai",
      "decision_type": "where_to_go_today",
      "subject_id": "chiang-mai",
      "subject_name": "Chiang Mai",
      "subject_type": "destination",
      "score": 65,
      "component_score": 74.2,
      "penalty_points": 9,
      "confidence": "High",
      "label": "mixed",
      "recommendation": "Chiang Mai is a cautious today pick.",
      "best_for": "Culture, cafes, temples, northern food, and slower city pacing.",
      "avoid_if": "PM2.5 stays high or the trip depends on mountain views being crisp.",
      "check_first": [
        "Treat sustained PM2.5 as the main breaker.",
        "Choose Old City or Nimman based on trip shape, not a random deal.",
        "Keep Bangkok or the coast as a real pivot if smoke stays high."
      ],
      "next_action": "Check PM2.5 first, then choose Old City or Nimman before paying for side trips.",
      "pivot": "Pivot to Bangkok or the coast if smoke remains stubborn.",
      "freshness_class": "fresh",
      "score_formula_version": "same-day-signal-v3",
      "signal_coverage": {
        "total_components": 26,
        "available_components": 26,
        "live_components": 25,
        "fallback_components": 1,
        "defaulted_components": 0,
        "coverage_ratio": 1
      },
      "score_components": [
        {
          "key": "aqi_fit",
          "label": "AQI fit",
          "score": 92,
          "weight": 0.16,
          "contribution": 14.72,
          "source": "signal",
          "signal_type": "aqi_risk",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "AQI risk missing; using conservative destination fallback.",
          "note": ""
        },
        {
          "key": "outdoor_comfort",
          "label": "Outdoor comfort",
          "score": 95,
          "weight": 0.12,
          "contribution": 11.4,
          "source": "signal",
          "signal_type": "outdoor_comfort",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "Outdoor comfort missing; using conservative fallback.",
          "note": ""
        },
        {
          "key": "rain_risk",
          "label": "Rain fit",
          "score": 56,
          "weight": 0.22,
          "contribution": 12.32,
          "source": "signal",
          "signal_type": "rain_risk",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "Rain fit missing; using conservative fallback.",
          "note": ""
        },
        {
          "key": "airport_weather_operability",
          "label": "Airport weather operability",
          "score": 60,
          "weight": 0.08,
          "contribution": 4.8,
          "source": "signal",
          "signal_type": "flight_delay_risk",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "",
          "note": "This is airport weather and forecast disruption context, not airline on-time performance."
        },
        {
          "key": "airport_transfer_support",
          "label": "Airport transfer support",
          "score": 41,
          "weight": 0.012,
          "contribution": 0.49,
          "source": "signal",
          "signal_type": "airport_transfer_support",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "",
          "note": "This is ground-access support around the main airport anchor linked to the destination, not a live airline board."
        },
        {
          "key": "airport_ground_service_support",
          "label": "Airport ground-service support",
          "score": 42,
          "weight": 0.012,
          "contribution": 0.5,
          "source": "signal",
          "signal_type": "airport_ground_service_support",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "",
          "note": "This is official airport taxi, Grab, rental, and pickup-rule context around the main airport anchor, not live queue, ETA, or inventory truth."
        },
        {
          "key": "airport_board_surface_support",
          "label": "Airport board-surface support",
          "score": 96,
          "weight": 0.012,
          "contribution": 1.15,
          "source": "signal",
          "signal_type": "airport_board_surface_support",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "",
          "note": "This is official passenger self-serve board visibility from public AOT flight-status pages. The board rows themselves use a browser turnstile token, so this is not direct live airline status truth."
        },
        {
          "key": "airport_scale_context",
          "label": "Airport scale context",
          "score": 50,
          "weight": 0.012,
          "contribution": 0.6,
          "source": "signal",
          "signal_type": "airport_scale_context",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "",
          "note": "This is official AOT passenger and aircraft-movement scale context behind the main airport anchor, not live delay, gate, queue, or inventory truth."
        },
        {
          "key": "airport_environmental_support",
          "label": "Airport environmental support",
          "score": 96,
          "weight": 0.012,
          "contribution": 1.15,
          "source": "signal",
          "signal_type": "airport_environmental_support",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "",
          "note": "This is SET-hosted AOT annual-report disclosure context around the main airport anchor, not live measured sound-level truth."
        },
        {
          "key": "rail_feasibility",
          "label": "Rail feasibility",
          "score": 43,
          "weight": 0.012,
          "contribution": 0.52,
          "source": "signal",
          "signal_type": "rail_feasibility",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "",
          "note": "This is public rail-support structure around the destination, not live seat, delay, or operator-disruption truth."
        },
        {
          "key": "official_bus_terminal_support",
          "label": "Official bus-terminal support",
          "score": 86,
          "weight": 0.012,
          "contribution": 1.03,
          "source": "signal",
          "signal_type": "official_bus_terminal_support",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "",
          "note": "This is official MOT terminal-master support for overland bus planning, not live departure, seat, or booking truth."
        },
        {
          "key": "official_intercity_bus_support",
          "label": "Official intercity-bus support",
          "score": 72,
          "weight": 0.012,
          "contribution": 0.86,
          "source": "signal",
          "signal_type": "official_intercity_bus_support",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "",
          "note": "This is official BKS station and ticket-point support for intercity-bus planning, not live departure, seat, or booking truth."
        },
        {
          "key": "official_intercity_bus_search_support",
          "label": "Official intercity-bus search support",
          "score": 96,
          "weight": 0.012,
          "contribution": 1.15,
          "source": "signal",
          "signal_type": "official_intercity_bus_search_support",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "",
          "note": "This is official BKS booking/search-surface support for intercity-bus planning, not live departures, seats, or booking inventory truth."
        },
        {
          "key": "official_transport_complaint_support",
          "label": "Official transport complaint support",
          "score": 94,
          "weight": 0.012,
          "contribution": 1.13,
          "source": "signal",
          "signal_type": "official_transport_complaint_support",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "",
          "note": "This is official DLT 1584 complaint recourse and transport-burden context, not local realtime service quality, dispatch, or incident truth."
        },
        {
          "key": "official_taxi_oversight_support",
          "label": "Official taxi-oversight support",
          "score": 92,
          "weight": 0.012,
          "contribution": 1.1,
          "source": "signal",
          "signal_type": "official_taxi_oversight_support",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "",
          "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
        },
        {
          "key": "water_risk",
          "label": "Water and flood fit",
          "score": 86,
          "weight": 0.08,
          "contribution": 6.88,
          "source": "signal",
          "signal_type": "flood_water_risk",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "Water-risk signal missing; using conservative fallback.",
          "note": ""
        },
        {
          "key": "spa_license_support",
          "label": "Spa license support",
          "score": 84,
          "weight": 0.012,
          "contribution": 1.01,
          "source": "signal",
          "signal_type": "spa_license_support",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "",
          "note": "This is public HSS wellness-license lookup support, not live booking, treatment quality, or venue popularity truth."
        },
        {
          "key": "medical_fallback_support",
          "label": "Medical fallback support",
          "score": 96,
          "weight": 0.012,
          "contribution": 1.15,
          "source": "signal",
          "signal_type": "medical_fallback_support",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "",
          "note": "This is public MOPH facility-support context, not live bed, wait-time, dispatch, or specialist-availability truth."
        },
        {
          "key": "park_access_context",
          "label": "Park access context",
          "score": 90,
          "weight": 0.012,
          "contribution": 1.08,
          "source": "signal",
          "signal_type": "park_access_context",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "",
          "note": "This is public DNP protected-area planning context, not live closure, ranger, capacity, or ticket truth."
        },
        {
          "key": "noise_comfort",
          "label": "Noise comfort",
          "score": 88,
          "weight": 0.05,
          "contribution": 4.4,
          "source": "signal",
          "signal_type": "noise_risk",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "Noise-risk signal missing; using conservative fallback.",
          "note": ""
        },
        {
          "key": "road_safety",
          "label": "Road safety",
          "score": 88,
          "weight": 0.05,
          "contribution": 4.4,
          "source": "signal",
          "signal_type": "road_safety_risk",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "Road-risk signal missing; using conservative fallback.",
          "note": ""
        },
        {
          "key": "transport_friction",
          "label": "Transport friction",
          "score": 63,
          "weight": 0.05,
          "contribution": 3.15,
          "source": "signal",
          "signal_type": "transport_friction",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "Transport-friction signal missing; using conservative fallback.",
          "note": ""
        },
        {
          "key": "source_confidence",
          "label": "Source confidence",
          "score": 97,
          "weight": 0.03,
          "contribution": 2.91,
          "source": "signal",
          "signal_type": "source_confidence",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "Source-confidence signal missing; using conservative fallback.",
          "note": ""
        },
        {
          "key": "disaster_context",
          "label": "Disaster context",
          "score": 46,
          "weight": 0.1,
          "contribution": 4.6,
          "source": "signal",
          "signal_type": "regional_disaster_context",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "Disaster context missing; using conservative fallback.",
          "note": ""
        },
        {
          "key": "earthquake_context",
          "label": "Earthquake context",
          "score": 64,
          "weight": 0.03,
          "contribution": 1.92,
          "source": "signal",
          "signal_type": "regional_earthquake_context",
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "Earthquake context missing; using conservative fallback.",
          "note": ""
        },
        {
          "key": "blueprint_baseline",
          "label": "Blueprint baseline",
          "score": 78,
          "weight": 0.015,
          "contribution": 1.17,
          "source": "blueprint",
          "signal_type": null,
          "entity_id": "chiang-mai",
          "used_default": false,
          "default_reason": "Blueprint seed score missing; using live average as the fallback baseline.",
          "note": "Blueprint baseline is now a light fallback and copy anchor, not the primary scoring driver."
        }
      ],
      "penalty_components": [
        {
          "key": "freshness_penalty",
          "label": "Freshness penalty",
          "freshness_class": "fresh",
          "points": 0,
          "applied": false,
          "note": "Signals are fresh enough that no freshness penalty applies."
        },
        {
          "key": "coverage_penalty",
          "label": "Coverage penalty",
          "defaulted_components": 0,
          "points": 0,
          "applied": false,
          "note": "All decision components are covered by live or persisted graph values."
        },
        {
          "key": "contradiction_penalty",
          "label": "Same-day signal spread penalty",
          "points": 9,
          "applied": true,
          "spread": 49,
          "note": "Component scores spread by 49 points, so the engine treats the answer as more contradictory."
        }
      ],
      "fallback_used": false,
      "fallback_components": [],
      "source_summary": "30 joined sources support this decision.",
      "weakest_signal": {
        "type": "airport_transfer_support",
        "label": "Airport transfer support is weak",
        "reason": "Public transport structure around this airport shows 1 mapped stop(s), 1 mode group(s), 1 rail-linked stop(s), 0 airport-link stop(s), and 0 bus-linked stop(s). This is airport-ground-access support, not live airline board or queue truth."
      },
      "related_pages": [
        {
          "path": "/where-to-go/chiang-mai/",
          "label": "Chiang Mai destination guide"
        },
        {
          "path": "/accommodation/chiang-mai/",
          "label": "Where to stay in Chiang Mai"
        },
        {
          "path": "/food/chiang-mai-khao-soi/",
          "label": "Chiang Mai khao soi route"
        },
        {
          "path": "/today/north/",
          "label": "Northern Thailand Today"
        },
        {
          "path": "/food/chiang-mai-food-guide/",
          "label": "Chiang Mai food guide"
        },
        {
          "path": "/temples/chiang-mai/",
          "label": "Chiang Mai temple route"
        },
        {
          "path": "/research/temples/chiang-mai/",
          "label": "Chiang Mai temple research"
        }
      ],
      "path": "/entities/chiang-mai/",
      "computed_at": "2026-06-24T03:51:19.382Z",
      "expires_at": "2026-06-24T09:51:33.917Z"
    },
    "where_to_stay": {
      "decision_id": "stay_ari",
      "decision_type": "where_to_stay",
      "subject_id": "ari",
      "subject_name": "Ari",
      "subject_type": "hotel_area",
      "parent_destination_id": "bangkok",
      "parent_destination_name": "Bangkok",
      "score": 71,
      "component_score": 81.5,
      "penalty_points": 11,
      "confidence": "High",
      "label": "mixed",
      "recommendation": "Ari is a good current hotel base.",
      "best_for": "Repeat visitors, calmer mornings, cafes, and BTS-linked Bangkok without peak nightlife pressure.",
      "avoid_if": "You want the fastest first-timer checklist base or temple-heavy days every morning.",
      "check_first": [
        "Use Ari when the trip wants calmer mornings and fewer nightlife penalties.",
        "Keep temple-heavy or river-heavy days separate instead of forcing cross-city hops.",
        "Choose a truly BTS-linked hotel rather than a loose district label."
      ],
      "next_action": "Choose a truly BTS-linked hotel and keep the trip in a smaller Bangkok orbit.",
      "pivot": "Use Sukhumvit or Silom / Sathorn if the trip becomes more transit-heavy or nightlife-heavy.",
      "freshness_class": "fresh",
      "score_formula_version": "signal-first-v2",
      "signal_coverage": {
        "total_components": 27,
        "available_components": 26,
        "live_components": 23,
        "fallback_components": 4,
        "defaulted_components": 1,
        "coverage_ratio": 0.963
      },
      "score_components": [
        {
          "key": "local_source_confidence",
          "label": "Local source confidence",
          "score": 97,
          "weight": 0.18,
          "contribution": 17.46,
          "source": "signal",
          "signal_type": "source_confidence",
          "entity_id": "ari",
          "used_default": false,
          "default_reason": "No local source-confidence signal; using conservative fallback.",
          "note": ""
        },
        {
          "key": "local_comfort",
          "label": "Local comfort",
          "score": 93.5,
          "weight": 0.18,
          "contribution": 16.83,
          "source": "derived",
          "signal_type": null,
          "entity_id": "ari",
          "used_default": false,
          "default_reason": "",
          "note": "Blends local AQI and outdoor comfort, with parent-destination fallback when hotel-area signals are sparse."
        },
        {
          "key": "noise_comfort",
          "label": "Noise comfort",
          "score": 50,
          "weight": 0.12,
          "contribution": 6,
          "source": "signal",
          "signal_type": "noise_risk",
          "entity_id": "ari",
          "used_default": false,
          "default_reason": "No local or parent noise signal; using conservative fallback.",
          "note": ""
        },
        {
          "key": "civic_friction",
          "label": "Civic friction",
          "score": 68,
          "weight": 0.08,
          "contribution": 5.44,
          "source": "derived",
          "signal_type": "civic_friction",
          "entity_id": "ari",
          "used_default": true,
          "default_reason": "No local or parent civic-friction signal; using conservative fallback.",
          "note": "Civic friction is only weighted where Bangkok district complaint statistics can inform hotel-area fit."
        },
        {
          "key": "rain_fit",
          "label": "Rain fit",
          "score": 56,
          "weight": 0.1,
          "contribution": 5.6,
          "source": "signal",
          "signal_type": "rain_risk",
          "entity_id": "ari",
          "used_default": false,
          "default_reason": "No local or parent rain signal; using conservative fallback.",
          "note": ""
        },
        {
          "key": "transport_fit",
          "label": "Transport fit",
          "score": 86,
          "weight": 0.14,
          "contribution": 12.04,
          "source": "signal",
          "signal_type": "transport_friction",
          "entity_id": "ari",
          "used_default": false,
          "default_reason": "No local or parent transport signal; using conservative fallback.",
          "note": ""
        },
        {
          "key": "highway_transfer_friction",
          "label": "Highway transfer friction",
          "score": 88,
          "weight": 0.05,
          "contribution": 4.4,
          "source": "signal",
          "signal_type": "highway_transfer_friction",
          "entity_id": "ari",
          "used_default": false,
          "default_reason": "",
          "note": "This is official DOH and EXAT road-support context behind the local base, not live speed, queue, lane, or incident truth."
        },
        {
          "key": "spa_license_support",
          "label": "Spa license support",
          "score": 96,
          "weight": 0.04,
          "contribution": 3.84,
          "source": "signal",
          "signal_type": "spa_license_support",
          "entity_id": "ari",
          "used_default": false,
          "default_reason": "",
          "note": "This is public HSS wellness-license lookup support around the local base or parent destination, not live booking, treatment quality, or venue popularity truth."
        },
        {
          "key": "medical_fallback_support",
          "label": "Medical fallback support",
          "score": 96,
          "weight": 0.05,
          "contribution": 4.8,
          "source": "signal",
          "signal_type": "medical_fallback_support",
          "entity_id": "ari",
          "used_default": false,
          "default_reason": "",
          "note": "This is public MOPH facility-support context around the local base or parent destination, not live bed, wait-time, dispatch, or specialist-availability truth."
        },
        {
          "key": "rail_feasibility",
          "label": "Rail feasibility",
          "score": 96,
          "weight": 0.06,
          "contribution": 5.76,
          "source": "signal",
          "signal_type": "rail_feasibility",
          "entity_id": "ari",
          "used_default": false,
          "default_reason": "",
          "note": "This is public rail-support structure around the local base or parent destination, not live train seat or delay truth."
        },
        {
          "key": "official_bus_terminal_support",
          "label": "Official bus-terminal support",
          "score": 86,
          "weight": 0.05,
          "contribution": 4.3,
          "source": "signal",
          "signal_type": "official_bus_terminal_support",
          "entity_id": "ari",
          "used_default": false,
          "default_reason": "",
          "note": "This is official MOT terminal-master support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
        },
        {
          "key": "official_intercity_bus_support",
          "label": "Official intercity-bus support",
          "score": 92,
          "weight": 0.04,
          "contribution": 3.68,
          "source": "signal",
          "signal_type": "official_intercity_bus_support",
          "entity_id": "ari",
          "used_default": false,
          "default_reason": "",
          "note": "This is official BKS station and ticket-point support around the stay zone or its parent destination, useful for overland flexibility but not a live departure or booking feed."
        },
        {
          "key": "official_intercity_bus_search_support",
          "label": "Official intercity-bus search support",
          "score": 96,
          "weight": 0.03,
          "contribution": 2.88,
          "source": "signal",
          "signal_type": "official_intercity_bus_search_support",
          "entity_id": "ari",
          "used_default": false,
          "default_reason": "",
          "note": "This is official BKS booking/search-surface support around the stay zone or its parent destination, useful for overland flexibility but not live departures, seats, or booking inventory truth."
        },
        {
          "key": "official_transport_complaint_support",
          "label": "Official transport complaint support",
          "score": 94,
          "weight": 0.04,
          "contribution": 3.76,
          "source": "signal",
          "signal_type": "official_transport_complaint_support",
          "entity_id": "ari",
          "used_default": false,
          "default_reason": "",
          "note": "This is official DLT 1584 complaint recourse and transport-burden context around the stay zone or its parent destination, not local realtime service quality or dispatch truth."
        },
        {
          "key": "official_taxi_oversight_support",
          "label": "Official taxi-oversight support",
          "score": 96,
          "weight": 0.05,
          "contribution": 4.8,
          "source": "signal",
          "signal_type": "official_taxi_oversight_support",
          "entity_id": "ari",
          "used_default": false,
          "default_reason": "",
          "note": "This is public DLT GPS and Taxi OK / VIP oversight, complaint, and station-search context around the stay zone or its parent destination, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
        },
        {
          "key": "official_motorcycle_taxi_support",
          "label": "Official motorcycle-taxi support",
          "score": 55,
          "weight": 0.05,
          "contribution": 2.75,
          "source": "signal",
          "signal_type": "official_motorcycle_taxi_support",
          "entity_id": "ari",
          "used_default": false,
          "default_reason": "",
          "note": "This is official Bangkok motorcycle-taxi stand and driver coverage from the public DLT/data.go.th dataset around the stay zone or its parent destination, useful as last-mile support context rather than live availability, dispatch, or queue truth."
        },
        {
          "key": "taxi_pickup_dropoff_support",
          "label": "Taxi pickup and dropoff support",
          "score": 87,
          "weight": 0.05,
          "contribution": 4.35,
          "source": "signal",
          "signal_type": "taxi_pickup_dropoff_support",
          "entity_id": "ari",
          "used_default": false,
          "default_reason": "",
          "note": "This is public OTP monthly taxi GPS analytics and hotspot context around the stay zone or its parent destination, useful as aggregate pickup/dropoff support rather than live dispatch, ETA, queue, or raw trip truth."
        },
        {
          "key": "urban_rapid_transit_support",
          "label": "Urban rapid-transit support",
          "score": 97,
          "weight": 0.1,
          "contribution": 9.7,
          "source": "signal",
          "signal_type": "urban_rapid_transit_support",
          "entity_id": "ari",
          "used_default": false,
          "default_reason": "",
          "note": "This is official BTS and MRTA route-map and service-page support around the local base, not live train headway, crowding, or outage truth."
        },
        {
          "key": "urban_bus_operator_support",
          "label": "Urban bus-operator support",
          "score": 88,
          "weight": 0.06,
          "contribution": 5.28,
          "source": "signal",
          "signal_type": "urban_bus_operator_support",
          "entity_id": "ari",
          "used_default": false,
          "default_reason": "",
          "note": "This is public Thai Smile Group branch and depot footprint around Bangkok hotel-base entities, useful as a fallback and last-mile layer rather than live bus operations truth."
        },
        {
          "key": "airport_transfer_support",
          "label": "Airport transfer support",
          "score": 82,
          "weight": 0.06,
          "contribution": 4.92,
          "source": "signal",
          "signal_type": "airport_transfer_support",
          "entity_id": "bangkok",
          "used_default": false,
          "default_reason": "",
          "note": "This is ground-access support around the main airport anchor behind this stay decision."
        },
        {
          "key": "airport_ground_service_support",
          "label": "Airport ground-service support",
          "score": 96,
          "weight": 0.05,
          "contribution": 4.8,
          "source": "signal",
          "signal_type": "airport_ground_service_support",
          "entity_id": "bangkok",
          "used_default": false,
          "default_reason": "",
          "note": "This is official airport taxi, Grab, rental, and pickup-rule context behind the stay decision, not live queue, ETA, or inventory truth."
        },
        {
          "key": "airport_board_surface_support",
          "label": "Airport board-surface support",
          "score": 96,
          "weight": 0.03,
          "contribution": 2.88,
          "source": "signal",
          "signal_type": "airport_board_surface_support",
          "entity_id": "bangkok",
          "used_default": false,
          "default_reason": "",
          "note": "This is official passenger self-serve board visibility from public AOT flight-status pages, not direct live airline row truth."
        },
        {
          "key": "airport_scale_context",
          "label": "Airport scale context",
          "score": 96,
          "weight": 0.04,
          "contribution": 3.84,
          "source": "signal",
          "signal_type": "airport_scale_context",
          "entity_id": "bangkok",
          "used_default": false,
          "default_reason": "",
          "note": "This is official AOT passenger and aircraft-movement scale context behind the main airport anchor, not live delay, queue, or inventory truth."
        },
        {
          "key": "airport_environmental_support",
          "label": "Airport environmental support",
          "score": 96,
          "weight": 0.03,
          "contribution": 2.88,
          "source": "signal",
          "signal_type": "airport_environmental_support",
          "entity_id": "bangkok",
          "used_default": false,
          "default_reason": "",
          "note": "This is SET-hosted AOT annual-report disclosure context behind the stay decision, not live measured sound-level truth."
        },
        {
          "key": "water_fit",
          "label": "Water and flood fit",
          "score": 44,
          "weight": 0.08,
          "contribution": 3.52,
          "source": "signal",
          "signal_type": "flood_water_risk",
          "entity_id": "ari",
          "used_default": false,
          "default_reason": "No local or parent water-risk signal; using conservative fallback.",
          "note": ""
        },
        {
          "key": "parent_destination_fit",
          "label": "Parent destination fit",
          "score": 63,
          "weight": 0.16,
          "contribution": 10.08,
          "source": "decision",
          "signal_type": null,
          "entity_id": "bangkok",
          "used_default": false,
          "default_reason": "Parent destination decision missing; using blueprint fallback.",
          "note": ""
        },
        {
          "key": "blueprint_baseline",
          "label": "Blueprint baseline",
          "score": 79,
          "weight": 0.04,
          "contribution": 3.16,
          "source": "blueprint",
          "signal_type": null,
          "entity_id": "ari",
          "used_default": false,
          "default_reason": "Blueprint seed missing; using parent score as fallback.",
          "note": ""
        }
      ],
      "penalty_components": [
        {
          "key": "freshness_penalty",
          "label": "Freshness penalty",
          "freshness_class": "fresh",
          "points": 0,
          "applied": false,
          "note": "Signals are fresh enough that no freshness penalty applies."
        },
        {
          "key": "coverage_penalty",
          "label": "Coverage penalty",
          "defaulted_components": 1,
          "points": 2,
          "applied": true,
          "note": "1 component(s) used fallback defaults, so the engine applies a 2-point coverage penalty."
        },
        {
          "key": "contradiction_penalty",
          "label": "Stay contradiction penalty",
          "points": 9,
          "applied": true,
          "spread": 53,
          "note": "Component scores spread by 53 points, so the engine treats the answer as more contradictory."
        }
      ],
      "fallback_used": true,
      "fallback_components": [
        "civic_friction"
      ],
      "source_summary": "40 joined sources support this decision.",
      "path": "/entities/ari/",
      "computed_at": "2026-06-24T03:51:19.382Z",
      "expires_at": "2026-06-24T15:40:00.000Z"
    },
    "route_check": {
      "decision_id": "route_bangkok-ayutthaya-kanchanaburi",
      "decision_type": "route_check",
      "subject_id": "bangkok-ayutthaya-kanchanaburi",
      "subject_name": "Bangkok -> Ayutthaya -> Kanchanaburi",
      "subject_type": "route",
      "score": 67,
      "component_score": 73.3,
      "penalty_points": 6,
      "confidence": "Medium",
      "label": "mixed",
      "recommendation": "Bangkok -> Ayutthaya -> Kanchanaburi is a cautious route shape right now.",
      "best_for": "Easy central-Thai culture loop with lower airport dependence.",
      "avoid_if": "You only have a rushed long weekend and hate transfers.",
      "check_first": [
        "heat exposure",
        "road and rail comfort",
        "whether Kanchanaburi is actually worth the detour for this trip shape"
      ],
      "next_action": "Use Bangkok as the base and decide whether both side trips really belong in the same short window.",
      "pivot": "Drop Kanchanaburi first if the loop starts to feel too transfer-heavy.",
      "freshness_class": "fresh",
      "score_formula_version": "signal-first-v2",
      "signal_coverage": {
        "total_components": 19,
        "available_components": 19,
        "live_components": 16,
        "fallback_components": 3,
        "defaulted_components": 0,
        "coverage_ratio": 1
      },
      "score_components": [
        {
          "key": "destination_average",
          "label": "Destination fit average",
          "score": 62,
          "weight": 0.34,
          "contribution": 21.08,
          "source": "decision",
          "signal_type": null,
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": "Average destination strength across the route chain."
        },
        {
          "key": "weakest_destination",
          "label": "Weakest destination leg",
          "score": 59,
          "weight": 0.18,
          "contribution": 10.62,
          "source": "decision",
          "signal_type": null,
          "entity_id": null,
          "used_default": false,
          "default_reason": "No weakest destination leg was available, so the route uses the average destination score.",
          "note": ""
        },
        {
          "key": "transport_average",
          "label": "Transport friction average",
          "score": 77.75,
          "weight": 0.16,
          "contribution": 12.44,
          "source": "signal",
          "signal_type": "transport_friction",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": ""
        },
        {
          "key": "highway_transfer_friction",
          "label": "Highway transfer friction",
          "score": 88,
          "weight": 0.08,
          "contribution": 7.04,
          "source": "signal",
          "signal_type": "highway_transfer_friction",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": "This is official DOH and EXAT road-support context across overland route legs, not live speed, queue, lane, or incident truth."
        },
        {
          "key": "rain_average",
          "label": "Rain fit average",
          "score": 56,
          "weight": 0.1,
          "contribution": 5.6,
          "source": "signal",
          "signal_type": "rain_risk",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": ""
        },
        {
          "key": "airport_weather_operability",
          "label": "Airport weather operability",
          "score": 60,
          "weight": 0.1,
          "contribution": 6,
          "source": "signal",
          "signal_type": "flight_delay_risk",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": "This is airport weather and forecast disruption context on flight-dependent legs, not airline on-time performance."
        },
        {
          "key": "rail_feasibility",
          "label": "Rail feasibility",
          "score": 74.33333333333333,
          "weight": 0.08,
          "contribution": 5.95,
          "source": "signal",
          "signal_type": "rail_feasibility",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": "This is public rail-support structure across the route chain, not live train seat, timetable, or disruption truth."
        },
        {
          "key": "official_bus_terminal_support",
          "label": "Official bus-terminal support",
          "score": 83.33333333333333,
          "weight": 0.06,
          "contribution": 5,
          "source": "signal",
          "signal_type": "official_bus_terminal_support",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": "This is official MOT terminal-master support across the route chain for overland backup and bus-linked resilience, not live departure or booking truth."
        },
        {
          "key": "official_intercity_bus_support",
          "label": "Official intercity-bus support",
          "score": 84.5,
          "weight": 0.04,
          "contribution": 3.38,
          "source": "signal",
          "signal_type": "official_intercity_bus_support",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": "This is official BKS station and ticket-point support across the route chain for overland backup and bus-linked resilience, not live departure or booking truth."
        },
        {
          "key": "official_intercity_bus_search_support",
          "label": "Official intercity-bus search support",
          "score": 96,
          "weight": 0.04,
          "contribution": 3.84,
          "source": "signal",
          "signal_type": "official_intercity_bus_search_support",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": "This is official BKS booking/search-surface support across the route chain for overland route-search confidence, not live departures, seats, or booking inventory truth."
        },
        {
          "key": "official_transport_complaint_support",
          "label": "Official transport complaint support",
          "score": 94,
          "weight": 0.04,
          "contribution": 3.76,
          "source": "signal",
          "signal_type": "official_transport_complaint_support",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": "This is official DLT 1584 complaint recourse and transport-burden context across the route chain, not local realtime service quality or dispatch truth."
        },
        {
          "key": "official_taxi_oversight_support",
          "label": "Official taxi-oversight support",
          "score": 96,
          "weight": 0.04,
          "contribution": 3.84,
          "source": "signal",
          "signal_type": "official_taxi_oversight_support",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": "This is official DLT GPS and Taxi OK regulated-taxi oversight, complaint, and station-search support across the route chain, not live vehicle location, dispatch, ETA, or raw taxi GPS truth."
        },
        {
          "key": "official_motorcycle_taxi_support",
          "label": "Official motorcycle-taxi support",
          "score": 73,
          "weight": 0.03,
          "contribution": 2.19,
          "source": "signal",
          "signal_type": "official_motorcycle_taxi_support",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": "This is official Bangkok motorcycle-taxi stand and driver coverage from the public DLT/data.go.th dataset, useful as route-level last-mile support context rather than live availability, dispatch, or queue truth."
        },
        {
          "key": "taxi_pickup_dropoff_support",
          "label": "Taxi pickup and dropoff support",
          "score": 88.5,
          "weight": 0.03,
          "contribution": 2.65,
          "source": "signal",
          "signal_type": "taxi_pickup_dropoff_support",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": "This is public OTP monthly taxi GPS analytics and hotspot context across Bangkok-linked route nodes, useful as aggregate pickup/dropoff support rather than live dispatch, ETA, queue, or raw trip truth."
        },
        {
          "key": "urban_rapid_transit_support",
          "label": "Urban rapid-transit support",
          "score": 94.5,
          "weight": 0.05,
          "contribution": 4.73,
          "source": "signal",
          "signal_type": "urban_rapid_transit_support",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": "This is official BTS and MRTA route-map and service-page support on Bangkok-linked route nodes, not live headway, crowding, or outage truth."
        },
        {
          "key": "urban_bus_operator_support",
          "label": "Urban bus-operator support",
          "score": 74,
          "weight": 0.04,
          "contribution": 2.96,
          "source": "signal",
          "signal_type": "urban_bus_operator_support",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": "This is public Thai Smile Group branch and depot footprint on Bangkok-linked route nodes, useful as fallback urban bus support rather than live bus operations truth."
        },
        {
          "key": "park_access_context",
          "label": "Park access context",
          "score": 96,
          "weight": 0.04,
          "contribution": 3.84,
          "source": "signal",
          "signal_type": "park_access_context",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": "This is public DNP protected-area planning context across nature-heavy route legs, not live closure, ranger, capacity, or ticket truth."
        },
        {
          "key": "node_confidence",
          "label": "Transfer-node confidence",
          "score": 97,
          "weight": 0.08,
          "contribution": 7.76,
          "source": "signal",
          "signal_type": "source_confidence",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": ""
        },
        {
          "key": "route_baseline",
          "label": "Route template baseline",
          "score": 65.25,
          "weight": 0.06,
          "contribution": 3.92,
          "source": "blueprint",
          "signal_type": null,
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": "Route templates now act as low-weight route-shape hints instead of dominating the score."
        }
      ],
      "penalty_components": [
        {
          "key": "freshness_penalty",
          "label": "Freshness penalty",
          "freshness_class": "fresh",
          "points": 0,
          "applied": false,
          "note": "Signals are fresh enough that no freshness penalty applies."
        },
        {
          "key": "coverage_penalty",
          "label": "Coverage penalty",
          "defaulted_components": 0,
          "points": 0,
          "applied": false,
          "note": "All decision components are covered by live or persisted graph values."
        },
        {
          "key": "contradiction_penalty",
          "label": "Route contradiction penalty",
          "points": 6,
          "applied": true,
          "spread": 41,
          "note": "Component scores spread by 41 points, so the engine treats the answer as more contradictory."
        }
      ],
      "fallback_used": false,
      "fallback_components": [],
      "source_summary": "3 destination anchors and 1 transfer nodes support this route check.",
      "main_risk": "Regional disaster context is busy",
      "weakest_leg": "Kanchanaburi",
      "path": "/routes/bangkok-ayutthaya-kanchanaburi/",
      "computed_at": "2026-06-24T03:51:19.382Z",
      "expires_at": "2026-06-24T15:52:38.613Z"
    },
    "ferry_check": {
      "decision_id": "ferry_phuket-krabi-ferry",
      "decision_type": "ferry_check",
      "subject_id": "phuket-krabi-ferry",
      "subject_name": "Phuket <-> Krabi ferry check",
      "subject_type": "ferry_route",
      "score": 52,
      "component_score": 63.4,
      "penalty_points": 11,
      "confidence": "Medium",
      "label": "fragile",
      "recommendation": "Phuket <-> Krabi ferry check needs refund-friendly planning and a backup move.",
      "best_for": "Andaman travelers who want coast changes without overcommitting every day to boats.",
      "avoid_if": "Your hotel stack stops being useful when one boat slips.",
      "check_first": [
        "live weather fit and ferry fragility",
        "last boat timing",
        "pier check-in and transfer burden"
      ],
      "next_action": "Keep the first island or coast hotel refundable until weather and pier timing feel solid.",
      "pivot": "Stay on Phuket and use road/day-trip logic if boats weaken.",
      "freshness_class": "acceptable",
      "score_formula_version": "signal-first-v2",
      "signal_coverage": {
        "total_components": 10,
        "available_components": 10,
        "live_components": 9,
        "fallback_components": 1,
        "defaulted_components": 0,
        "coverage_ratio": 1
      },
      "score_components": [
        {
          "key": "destination_fit",
          "label": "Destination chain fit",
          "score": 54.5,
          "weight": 0.22,
          "contribution": 11.99,
          "source": "decision",
          "signal_type": null,
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": ""
        },
        {
          "key": "pier_confidence",
          "label": "Pier confidence",
          "score": 97,
          "weight": 0.14,
          "contribution": 13.58,
          "source": "signal",
          "signal_type": "source_confidence",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": ""
        },
        {
          "key": "pier_transfer_support",
          "label": "Pier transfer support",
          "score": 60,
          "weight": 0.14,
          "contribution": 8.4,
          "source": "signal",
          "signal_type": "pier_transfer_support",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": ""
        },
        {
          "key": "official_pier_support",
          "label": "Official pier support",
          "score": 90.66666666666667,
          "weight": 0.12,
          "contribution": 10.88,
          "source": "signal",
          "signal_type": "official_pier_support",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": ""
        },
        {
          "key": "berth_operability_context",
          "label": "Berth operability context",
          "score": 93.83333333333334,
          "weight": 0.1,
          "contribution": 9.38,
          "source": "signal",
          "signal_type": "berth_operability_context",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": ""
        },
        {
          "key": "ferry_fragility",
          "label": "Ferry fragility",
          "score": 55.666666666666664,
          "weight": 0.24,
          "contribution": 13.36,
          "source": "signal",
          "signal_type": "ferry_fragility",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": ""
        },
        {
          "key": "marine_warning_risk",
          "label": "Marine warning risk",
          "score": 34,
          "weight": 0.14,
          "contribution": 4.76,
          "source": "signal",
          "signal_type": "marine_warning_risk",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": ""
        },
        {
          "key": "rain_fit",
          "label": "Weather fit",
          "score": 44,
          "weight": 0.08,
          "contribution": 3.52,
          "source": "signal",
          "signal_type": "rain_risk",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": ""
        },
        {
          "key": "transport_stack",
          "label": "Transfer burden",
          "score": 60.666666666666664,
          "weight": 0.1,
          "contribution": 6.07,
          "source": "signal",
          "signal_type": "transport_friction",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": ""
        },
        {
          "key": "weakest_ferry_leg",
          "label": "Weakest ferry leg",
          "score": 54,
          "weight": 0.08,
          "contribution": 4.32,
          "source": "signal",
          "signal_type": "ferry_fragility",
          "entity_id": null,
          "used_default": false,
          "default_reason": "",
          "note": ""
        }
      ],
      "penalty_components": [
        {
          "key": "freshness_penalty",
          "label": "Freshness penalty",
          "freshness_class": "acceptable",
          "points": 2,
          "applied": true,
          "note": "Freshness class is acceptable, so the engine applies a 2-point penalty."
        },
        {
          "key": "coverage_penalty",
          "label": "Coverage penalty",
          "defaulted_components": 0,
          "points": 0,
          "applied": false,
          "note": "All decision components are covered by live or persisted graph values."
        },
        {
          "key": "contradiction_penalty",
          "label": "Ferry contradiction penalty",
          "points": 9,
          "applied": true,
          "spread": 63,
          "note": "Component scores spread by 63 points, so the engine treats the answer as more contradictory."
        }
      ],
      "fallback_used": false,
      "fallback_components": [],
      "source_summary": "1 pier anchors and 2 island or coast anchors currently support this ferry check.",
      "main_risk": "Ferry fragility is elevated, so refund flexibility matters before you lock the island chain.",
      "path": "/ferries/phuket-krabi/",
      "computed_at": "2026-06-24T03:51:19.382Z",
      "expires_at": "2026-06-24T15:52:38.613Z"
    },
    "food_route": {
      "decision_id": "food_bangkok",
      "decision_type": "food_route",
      "subject_id": "bangkok",
      "subject_name": "Bangkok",
      "subject_type": "destination",
      "score": 73,
      "component_score": 79,
      "penalty_points": 6,
      "confidence": "Medium",
      "label": "good",
      "recommendation": "Bangkok is a good food-route pick right now.",
      "best_for": "First-trip range, Chinatown, rail-linked eating, and rainy-day fallback.",
      "avoid_if": "You want one quiet neighborhood to explain the whole city.",
      "check_first": [
        "Check Air4Thai before heavy outdoor days.",
        "Choose a BTS/MRT-linked base before paying for a hotel."
      ],
      "next_action": "Choose the neighborhood first, then the named place.",
      "pivot": "Use malls, Chinatown, or BTS-linked zones when rain and heat stack.",
      "freshness_class": "fresh",
      "score_formula_version": "signal-first-v2",
      "signal_coverage": {
        "total_components": 6,
        "available_components": 6,
        "live_components": 3,
        "fallback_components": 3,
        "defaulted_components": 0,
        "coverage_ratio": 1
      },
      "score_components": [
        {
          "key": "destination_fit",
          "label": "Destination fit",
          "score": 63,
          "weight": 0.26,
          "contribution": 16.38,
          "source": "decision",
          "signal_type": null,
          "entity_id": null,
          "used_default": false,
          "default_reason": "Destination decision missing; using conservative fallback.",
          "note": ""
        },
        {
          "key": "local_confidence",
          "label": "Local source confidence",
          "score": 97,
          "weight": 0.16,
          "contribution": 15.52,
          "source": "signal",
          "signal_type": "source_confidence",
          "entity_id": "bangkok",
          "used_default": false,
          "default_reason": "Food-route source confidence missing; using conservative fallback.",
          "note": ""
        },
        {
          "key": "local_comfort",
          "label": "Local comfort",
          "score": 93.5,
          "weight": 0.12,
          "contribution": 11.22,
          "source": "derived",
          "signal_type": null,
          "entity_id": "bangkok",
          "used_default": false,
          "default_reason": "",
          "note": ""
        },
        {
          "key": "rain_fit",
          "label": "Rain fit",
          "score": 56,
          "weight": 0.1,
          "contribution": 5.6,
          "source": "signal",
          "signal_type": "rain_risk",
          "entity_id": "bangkok",
          "used_default": false,
          "default_reason": "Food-route rain fit missing; using conservative fallback.",
          "note": ""
        },
        {
          "key": "transport_fit",
          "label": "Transport fit",
          "score": 86,
          "weight": 0.1,
          "contribution": 8.6,
          "source": "signal",
          "signal_type": "transport_friction",
          "entity_id": "bangkok",
          "used_default": false,
          "default_reason": "Food-route transport fit missing; using conservative fallback.",
          "note": ""
        },
        {
          "key": "food_blueprint_baseline",
          "label": "Food blueprint baseline",
          "score": 90,
          "weight": 0.1,
          "contribution": 9,
          "source": "blueprint",
          "signal_type": null,
          "entity_id": "bangkok",
          "used_default": false,
          "default_reason": "Food blueprint seed missing; using destination score fallback.",
          "note": ""
        }
      ],
      "penalty_components": [
        {
          "key": "freshness_penalty",
          "label": "Freshness penalty",
          "freshness_class": "fresh",
          "points": 0,
          "applied": false,
          "note": "Signals are fresh enough that no freshness penalty applies."
        },
        {
          "key": "coverage_penalty",
          "label": "Coverage penalty",
          "defaulted_components": 0,
          "points": 0,
          "applied": false,
          "note": "All decision components are covered by live or persisted graph values."
        },
        {
          "key": "contradiction_penalty",
          "label": "Food-route contradiction penalty",
          "points": 6,
          "applied": true,
          "spread": 41,
          "note": "Component scores spread by 41 points, so the engine treats the answer as more contradictory."
        }
      ],
      "fallback_used": false,
      "fallback_components": [],
      "source_summary": "19 joined sources support this decision.",
      "path": "/today/bangkok/",
      "computed_at": "2026-06-24T03:51:19.382Z",
      "expires_at": "2026-06-24T15:51:33.917Z"
    },
    "gold_buying_check": {
      "decision_id": "gold_bangkok",
      "decision_type": "gold_buying_check",
      "subject_id": "bangkok",
      "subject_name": "Bangkok / Yaowarat",
      "subject_type": "destination",
      "score": 88,
      "component_score": 87.6,
      "penalty_points": 0,
      "confidence": "Medium",
      "label": "strong",
      "recommendation": "Bangkok / Yaowarat is the strongest gold-buying context right now if you still compare multiple shops against the national quote.",
      "best_for": "Comparison shopping, dense shop clusters, clearer receipt and buyback expectations, and travelers who want the strongest public gold-buying context in Thailand.",
      "avoid_if": "You are treating the national reference quote like a guaranteed final shop price without checking workmanship, receipt detail, and buyback terms.",
      "check_first": [
        "latest GTA bar and ornament quote",
        "receipt detail and buyback terms",
        "whether you want bar or ornament gold"
      ],
      "next_action": "Use the national GTA quote first, then compare multiple Yaowarat shops before paying.",
      "pivot": "Use Chiang Mai for regional convenience if the trip is not passing through Bangkok anyway.",
      "city_context": "Bangkok / Yaowarat",
      "entity_anchor_id": "yaowarat-gold-district",
      "entity_anchor_path": "/entities/yaowarat-gold-district/",
      "entity_anchor_name": "Yaowarat gold district",
      "reference_price": 64300,
      "reference_buy_price": 64100,
      "reference_unit": "THB per 1 baht-weight of 96.5% Thai gold",
      "updated_at": "2026-06-24T03:43:00.000Z",
      "fx_context": "Published GTA USD/THB context shows USD/THB around 33.38, intraday quote change +50 THB, and previous-day change -500 THB. GTA spot reference is 4,065. This is pricing context, not investment advice.",
      "freshness_class": "fresh",
      "score_formula_version": "signal-first-v2",
      "signal_coverage": {
        "total_components": 5,
        "available_components": 5,
        "live_components": 4,
        "fallback_components": 1,
        "defaulted_components": 0,
        "coverage_ratio": 1
      },
      "score_components": [
        {
          "key": "national_reference",
          "label": "National GTA reference",
          "score": 86,
          "weight": 0.32,
          "contribution": 27.52,
          "source": "signal",
          "signal_type": "thai_gold_reference_price",
          "entity_id": "bangkok",
          "used_default": false,
          "default_reason": "",
          "note": ""
        },
        {
          "key": "fx_pressure",
          "label": "FX and quote pressure",
          "score": 82,
          "weight": 0.18,
          "contribution": 14.76,
          "source": "signal",
          "signal_type": "thai_gold_fx_pressure",
          "entity_id": "bangkok",
          "used_default": false,
          "default_reason": "Gold FX-pressure context missing; using conservative fallback.",
          "note": ""
        },
        {
          "key": "city_friction",
          "label": "City buying friction",
          "score": 88,
          "weight": 0.28,
          "contribution": 24.64,
          "source": "signal",
          "signal_type": "thai_gold_buying_friction",
          "entity_id": "bangkok",
          "used_default": false,
          "default_reason": "",
          "note": ""
        },
        {
          "key": "source_confidence",
          "label": "Source confidence",
          "score": 97,
          "weight": 0.12,
          "contribution": 11.64,
          "source": "signal",
          "signal_type": "source_confidence",
          "entity_id": "bangkok",
          "used_default": false,
          "default_reason": "Source confidence missing; using conservative fallback.",
          "note": ""
        },
        {
          "key": "city_baseline",
          "label": "City baseline",
          "score": 90,
          "weight": 0.1,
          "contribution": 9,
          "source": "blueprint",
          "signal_type": null,
          "entity_id": "bangkok",
          "used_default": false,
          "default_reason": "",
          "note": ""
        }
      ],
      "penalty_components": [
        {
          "key": "freshness_penalty",
          "label": "Freshness penalty",
          "freshness_class": "fresh",
          "points": 0,
          "applied": false,
          "note": "Signals are fresh enough that no freshness penalty applies."
        },
        {
          "key": "coverage_penalty",
          "label": "Coverage penalty",
          "defaulted_components": 0,
          "points": 0,
          "applied": false,
          "note": "All decision components are covered by live or persisted graph values."
        },
        {
          "key": "contradiction_penalty",
          "label": "Gold-buying contradiction penalty",
          "points": 0,
          "applied": false,
          "spread": 15,
          "note": "Component scores are not meaningfully contradictory."
        }
      ],
      "fallback_used": false,
      "fallback_components": [],
      "source_summary": "8 joined sources support this decision.",
      "path": "/gold/yaowarat-gold-shops/",
      "computed_at": "2026-06-24T03:51:19.382Z",
      "expires_at": "2026-06-24T11:51:33.917Z"
    }
  }
}