# Driver and Vehicle Allocation Agent: build spec

Free to use and adapt. From economAIcs: https://economaicsgroup.com/insights/driver-vehicle-allocation-agent/

## Goal
Propose daily vehicle blocks and driver duties that minimise empty running
and paid idle time, cover every accepted job, and never break a hard rule.
A human planner approves every plan before it reaches a driver.

## Design rule
The solver plans. Language models never produce schedules. Models are used
only to read messy inputs, translate rules into constraints, explain
failures and propose improvements.

## Steps (label each honestly)
- Ingest (code; model only for free-text fields): clean and join jobs,
  fleet, rosters, depots, maintenance holds. Output a validated snapshot
  and a data quality report.
- Constrain (LLM agent): convert rulebooks, contract terms and booking notes
  into hard and soft constraints. Every constraint links to the quoted
  source text it came from.
- Solve (solver, no model): build the model and call the solver.
- Check (rule engine; model writes the explanation): re-test every duty
  against the rules from source, independently of the solver code.
- Learn and improve (statistics plus a proposer model): recalibrate journey
  times; propose changes to weights and heuristics for replay scoring.

## Drivers' hours
Classify every job by regime before solving: assimilated rules (for example
private hire and tours in vehicles with more than eight passenger seats) or
GB domestic rules (for example a regular service on a route of 50km or less).
Handle days where one driver works under both.
Source: GOV.UK drivers' hours guidance. Verify against current guidance.

## Agent graph (conditional edges)
Ingest → Constrain → Solve → Check → Planner approval → Learn
- Ingest data quality fail: human review, stop the run
- Solve infeasible: Check names the blocking constraint, then the planner
- Check fail, rule missed or mistranslated: back to Constrain with the reason
- Check fail, rule encoded correctly: stop, alert an engineer (model bug)
- Planner reject: log the reason as a candidate soft constraint
Start simple: a script or an n8n workflow with branches. Use a stateful
graph framework only when the routing outgrows it.

## Network graph
Nodes: depot, stop, job, vehicle, driver.
Edges: travel (drive time by hour, distance, empty flag);
eligibility (driver to vehicle, vehicle to job).
Initial travel matrix from a routing engine (for example OSRM on OpenStreetMap).

## Solver (for example Google OR-Tools routing)
- Multi-depot: per-vehicle start and end depot
- Time dimension: job time windows
- Capacity dimension: seats
- Allowed vehicles per job: eligibility
- Break intervals: drivers' hours for each job's regime
- Disjunctions with a high penalty: no silent drops
- Coach default: vehicle block = driver duty; a separate driver pass
  (CP-SAT) only where drivers change over mid-block
- Re-plan: start from the current plan, freeze untouched duties, time limit
Objective: alpha x empty km + beta x paid idle hours + gamma x uncovered jobs

## Loops
- Plan: overnight, full scope
- Re-plan: on an event (breakdown, sickness, late running), affected duties only
- Learn: daily, plan against actual from telematics and tachograph data
- Improve: propose, replay on past weeks, test on held-out weeks, human sign-off.
  The proposer never edits or sees inside the evaluator.

## Non-negotiables
- Planner approval before any plan is issued
- Audit log of every plan, change and promoted improvement
- Cross-depot moves checked against operator licences and operating centres
- Role-based access to driver data (personal data under UK GDPR);
  anonymised data for any proof of concept
- Manual planning board stays usable if the system is down

## Measures
Empty km per operated km, paid idle hours per duty, rule breaches caught
by Check, planner acceptance rate.
