{
  "feature": "routing-profile-selection",
  "version": "1.0.0",
  "description": "Associate each vehicle with a named routing profile (car, truck, hgv, bike) so travel time and distance matrices use road network rules appropriate for that vehicle class.",
  "category": "workflow",
  "tags": [
    "routing-profile",
    "hgv",
    "truck-routing",
    "road-restrictions"
  ],
  "actors": [
    {
      "id": "fleet_manager",
      "name": "Fleet Manager",
      "type": "human",
      "description": "Assigns routing profiles to vehicles"
    },
    {
      "id": "routing_engine",
      "name": "Routing Engine",
      "type": "system",
      "description": "Computes travel time/distance matrices per profile"
    }
  ],
  "fields": [
    {
      "name": "vehicle_profile",
      "type": "text",
      "label": "Routing Profile",
      "required": false
    },
    {
      "name": "speed_factor",
      "type": "number",
      "label": "Speed Factor",
      "required": false
    },
    {
      "name": "profile_duration_matrix",
      "type": "json",
      "label": "Duration Matrix",
      "required": false
    },
    {
      "name": "profile_distance_matrix",
      "type": "json",
      "label": "Distance Matrix",
      "required": false
    },
    {
      "name": "profile_cost_matrix",
      "type": "json",
      "label": "Cost Matrix",
      "required": false
    }
  ],
  "rules": {
    "one_matrix_per_profile": "Each distinct profile in the fleet triggers one separate matrix retrieval from the routing engine.",
    "custom_matrix_bypasses_engine": "When custom matrices are provided for a profile, no routing engine call is made.",
    "cost_matrix_conflict": "A custom cost matrix and a per_hour or per_km vehicle cost cannot be used together; this combination is rejected.",
    "profiles_are_opaque": "Profiles are treated as opaque strings; the optimizer does not interpret them — only the routing engine does.",
    "shared_profile_matrix": "If all vehicles share the same profile, a single matrix fetch is made.",
    "speed_factor_scales_duration": "speed_factor scales the duration matrix values after retrieval; distance values are unaffected.",
    "geometry_per_profile": "When geometry output is requested, polyline-encoded route geometry is fetched per vehicle using the vehicle's profile."
  },
  "states": {
    "field": "matrix_status",
    "values": [
      {
        "id": "pending",
        "description": "Matrix not yet retrieved for this profile",
        "initial": true
      },
      {
        "id": "fetching",
        "description": "Request sent to routing engine"
      },
      {
        "id": "ready",
        "description": "Matrix available for optimization",
        "terminal": true
      },
      {
        "id": "failed",
        "description": "Routing engine returned an error or unreachable location",
        "terminal": true
      }
    ],
    "transitions": [
      {
        "from": "pending",
        "to": "fetching",
        "actor": "routing_engine",
        "description": "Matrix request dispatched for profile"
      },
      {
        "from": "fetching",
        "to": "ready",
        "actor": "routing_engine",
        "description": "Valid matrix received"
      },
      {
        "from": "fetching",
        "to": "failed",
        "actor": "routing_engine",
        "description": "Engine error or unfound route"
      }
    ]
  },
  "outcomes": {
    "matrix_ready": {
      "priority": 10,
      "given": [
        "routing engine is reachable",
        "all vehicle locations can be snapped to the road network for this profile"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "routing.matrix.ready",
          "payload": [
            "profile",
            "matrix_size",
            "retrieval_duration_ms"
          ]
        }
      ],
      "result": "Duration (and optionally distance) matrix stored for this profile; optimizer proceeds to solving."
    },
    "matrix_from_custom_input": {
      "priority": 9,
      "given": [
        "custom duration matrix provided in problem input for this profile"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "routing.matrix.ready",
          "payload": [
            "profile",
            "matrix_size",
            "source"
          ]
        }
      ],
      "result": "Custom matrix used directly; no routing engine call made."
    },
    "routing_engine_error": {
      "priority": 2,
      "error": "ROUTING_ENGINE_ERROR",
      "given": [
        "routing engine returns error or one or more locations are unreachable"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "routing.matrix.failed",
          "payload": [
            "profile",
            "error_message",
            "problem_location"
          ]
        }
      ],
      "result": "Solve aborted with routing error; caller should verify coordinates or supply a custom matrix."
    },
    "speed_factor_applied": {
      "priority": 7,
      "given": [
        "speed_factor is set to a value other than 1.0 for a vehicle"
      ],
      "then": [
        {
          "action": "emit_event",
          "event": "routing.matrix.scaled",
          "payload": [
            "vehicle_id",
            "profile",
            "speed_factor"
          ]
        }
      ],
      "result": "All travel durations for this vehicle scaled by speed_factor."
    }
  },
  "errors": [
    {
      "code": "ROUTING_ENGINE_ERROR",
      "status": 503,
      "message": "Routing engine unreachable or returned unfound routes for one or more locations."
    },
    {
      "code": "ROUTING_PROFILE_COST_CONFLICT",
      "status": 400,
      "message": "Custom cost matrix cannot be combined with per_hour or per_km vehicle costs."
    },
    {
      "code": "ROUTING_INVALID_SPEED_FACTOR",
      "status": 400,
      "message": "speed_factor must be greater than 0 and at most 5."
    }
  ],
  "events": [
    {
      "name": "routing.matrix.ready",
      "description": "Travel matrix successfully obtained for a routing profile",
      "payload": [
        "profile",
        "matrix_size",
        "retrieval_duration_ms"
      ]
    },
    {
      "name": "routing.matrix.failed",
      "description": "Could not retrieve matrix for the routing profile",
      "payload": [
        "profile",
        "error_message",
        "problem_location"
      ]
    },
    {
      "name": "routing.matrix.scaled",
      "description": "Duration matrix scaled by speed_factor for a vehicle",
      "payload": [
        "vehicle_id",
        "profile",
        "speed_factor"
      ]
    }
  ],
  "related": [
    {
      "feature": "vrp-solving",
      "type": "required"
    },
    {
      "feature": "distance-matrix-calculation",
      "type": "required"
    },
    {
      "feature": "multi-vehicle-route-optimization",
      "type": "recommended"
    },
    {
      "feature": "cost-based-route-optimization",
      "type": "optional"
    }
  ],
  "agi": {
    "goals": [
      {
        "id": "reliable_routing_profile_selection",
        "description": "Associate each vehicle with a named routing profile (car, truck, hgv, bike) so travel time and distance matrices use road network rules appropriate for that vehicle class.",
        "success_metrics": [
          {
            "metric": "processing_time",
            "target": "< 5s",
            "measurement": "Time from request to completion"
          },
          {
            "metric": "success_rate",
            "target": ">= 99%",
            "measurement": "Successful operations divided by total attempts"
          }
        ],
        "constraints": [
          {
            "type": "performance",
            "description": "Must not block dependent workflows",
            "negotiable": true
          }
        ]
      }
    ],
    "autonomy": {
      "level": "semi_autonomous",
      "human_checkpoints": [
        "before transitioning to a terminal state"
      ],
      "escalation_triggers": [
        "error_rate > 5"
      ]
    },
    "safety": {
      "action_permissions": [
        {
          "action": "matrix_ready",
          "permission": "autonomous"
        },
        {
          "action": "matrix_from_custom_input",
          "permission": "autonomous"
        },
        {
          "action": "routing_engine_error",
          "permission": "autonomous"
        },
        {
          "action": "speed_factor_applied",
          "permission": "autonomous"
        }
      ]
    },
    "tradeoffs": [
      {
        "prefer": "reliability",
        "over": "speed",
        "reason": "workflow steps must complete correctly before proceeding"
      }
    ],
    "coordination": {
      "protocol": "orchestrated",
      "consumes": [
        {
          "capability": "vrp_solving",
          "from": "vrp-solving",
          "fallback": "degrade"
        },
        {
          "capability": "distance_matrix_calculation",
          "from": "distance-matrix-calculation",
          "fallback": "degrade"
        }
      ]
    }
  },
  "extensions": {
    "source": {
      "repo": "https://github.com/VROOM-Project/vroom",
      "project": "VROOM",
      "tech_stack": "C++20",
      "files_traced": 7,
      "entry_points": [
        "src/routing/wrapper.h",
        "src/routing/http_wrapper.h",
        "src/structures/vroom/vehicle.h",
        "src/structures/typedefs.h"
      ]
    }
  }
}