> ## Documentation Index
> Fetch the complete documentation index at: https://developers.kardinal.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Manual assignment and supervision

> Lock a sequence with `state`, supervise a tour live, and pin a stop to one resource.

[Real-time re-optimization](/guides/real-time-reoptimization) covers replacing the whole plan on disruption. This page covers the finer-grained controls: locking part of a resource's tour in place while the engine re-plans the rest, and reserving a stop for exactly one resource without making it mandatory.

## Locking a sequence: `mode` × assignment `status`

`state` is set per resource and works on two levels: `state.mode` applies to the resource as a whole, while `status` applies to each individual entry in `state.assignments` (a stop, a break, or the tour's `begin` or `end`).

* `status: "assigned"` — the entry is assigned to this resource, but its position in the sequence isn't imposed: the engine sequences the resource's assigned entries according to the plan's objectives.
* `status: "fixed"` (the default) — the entry is taken as given: its position in the sequence, and its times, aren't challenged.
* `mode: "free"` (the default) — the engine can add more stops to this resource's tour.
* `mode: "fixed"` — the resource's tour is limited to its assigned entries. The engine can't add any more stops.

The two combine as follows:

| | `assignments[].status: "assigned"` | `assignments[].status: "fixed"` |
| - | - | - |
| **`mode: "fixed"`** | The engine sequences the given stops according to the plan's objectives, adding no further stops — useful to check whether assigning these stops to this resource is feasible at all (see [Testing a stop on a specific resource](/guides/handling-infeasibility#testing-a-stop-on-a-specific-resource-with-state-assignments)). | The engine only checks the given sequence as-is, adding no further stops — a debug/evaluation mode: pose an existing tour to see whether it's feasible and why a given stop isn't covered. |
| **`mode: "free"`** | Not allowed. | The engine keeps the given sequence exactly as the start of the tour, and is free to add new stops after it — the real-time supervision case below. `fixed` assignments can only form the beginning of the tour: the engine never inserts a new stop before or between them. |

## Live supervision as a tour progresses

Reflect a driver's real progress with successive `PUT /plans/{planId}` calls: a `begin` assignment with the real `departureTime`, then `stop` assignments filled in with `arrivalTime`/`beginTime`/`departureTime` as they actually happen, a `break` inserted dynamically if needed. Keep `mode: "free"` so the engine can still plan what comes after, and give every pinned assignment `status: "fixed"`. Each of these calls carries the complete plan; the following excerpt only shows the `resources` entry being updated:

```json theme={null}
{
  "resources": [
    {
      "id": "driver-1",
      "state": {
        "mode": "free",
        "assignments": [
          { "type": "begin", "status": "fixed", "departureTime": "2026-08-03T07:02:00Z" },
          { "type": "stop", "status": "fixed", "stopId": "stop-1", "arrivalTime": "2026-08-03T07:40:00Z", "departureTime": "2026-08-03T07:55:00Z" }
        ]
      }
    }
  ]
}
```

For a pinned time to be kept as given rather than re-planned by the optimization, every assignment before it in the sequence must also carry its times, and those times must be chronologically consistent: each entry's times can't be earlier than the previous entry's. In practice, fill in assignments in the order the driver actually completes them, starting from `begin`, without leaving an earlier entry's times blank.

## Pinning a stop to exactly one resource (pattern "Isolate")

`forbiddenAssignment` (see [Real-time re-optimization](/guides/real-time-reoptimization)) excludes a resource/stop pairing. There's no single dedicated field for the opposite — reserving a stop for one resource — but three mechanisms get you there, from strictest to softest:

* **`state.assignments`** — pin the stop directly onto the resource's tour, as described in the first section of this page. The only one of the three that the engine keeps exactly as given.
* **`skills`/`requiredSkills`** (pattern "Isolate") — give the resource a `skills` entry derived from its own id (for example `skills: ["resource-12"]`) and require it on the targeted order (`requiredSkills: ["resource-12"]`). No other resource can then serve the stop.
* **`preferredStopTags`** — tag the stop, list that tag in the resource's `preferredStopTags`, and include `maximizePreferredStops` in `objectives`. A soft preference: another resource can still take the stop when that serves a higher-priority objective better.

<Warning>
  Pinning a stop to a resource through `requiredSkills` doesn't guarantee that the stop is planned: it only restricts which resource can serve it. The engine can still leave the stop unplanned if the assignment degrades a higher-priority objective. To keep the stop on that resource's tour whatever the objectives, use `state.assignments` instead.
</Warning>

## See also

* [Modeling advanced constraints](/guides/advanced-constraints#driver-skills-and-qualifications) — `preferredStopTags`/`maximizePreferredStops`, the soft-preference counterpart to the preceding "Isolate" pattern.
* [Real-time re-optimization](/guides/real-time-reoptimization) — the full-plan `PUT` mechanics and `forbiddenAssignment`.
* [Data model](/reference/data-model#status-and-state) — `status`/`state` field reference.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.