> For the complete documentation index, see [llms.txt](https://help.resouris.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.resouris.com/how-it-works/roster-lifecycle.md).

# Roster lifecycle

The published roster is the operational output of ReSouris's [resource management model](/how-it-works/resource-management-model.md). This page walks the roster's own lifecycle — the states + transitions between a solve request and the live published schedule.

Read [Resource management model](/how-it-works/resource-management-model.md) first for the mental scaffold: the roster is a *view* onto the live resource pool (people, rooms, equipment, competencies, demand). Everything on this page is about producing that view.

## The states

```
draft → queued → solving → solved → published → superseded
```

* **draft** — configuration exists (service lines, staff, patterns, policy) but no solve has been attempted.
* **queued** — an admin has requested a solve; the job is waiting for the solver worker.
* **solving** — the CP-SAT solver is running.
* **solved** — the solver produced a candidate roster. Admin can review, adjust, and publish or discard.
* **published** — the roster is live. Notifications have dispatched. Workers see it in `/ui/my-roster`.
* **superseded** — a newer roster covering the same window has been published, replacing this one.

`failed` is a terminal state alternative to `solved` when the solver couldn't produce a feasible assignment or crashed. The job produces an error report.

## The solve step

The solver is Google's CP-SAT. It reads the tenant's live resource pool + demand shape (the five asset classes named in [Resource management model](/how-it-works/resource-management-model.md)) and produces an assignment set. Universe input includes:

* **People** — currently-employed staff with contracted hours, working-pattern assignments, competencies + direct skills, absence overlay (extended leave, sickness, approved leave requests), availability preferences, line-management context (v1.7.3 shared-manager aware).
* **Service lines** (demand) — with activities, priority, target roster tier, `has_on_call`, `allow_split_shifts` + per-activity `splittable` flags.
* **Rooms + equipment** — room catalogue with room-service-line patterns pinning rooms to service lines per sub-slot (P24), room-equipment fixed catalogue, service-line-equipment eligibility.
* **Room-SL patterns** + **overrides** — HARD constraint; only staff who can work in a room-permitted sub-slot are eligible for that cell.
* **Job plans + entitlements** — SOFT constraint influencing equity scoring.
* **Training plans + development goals** — SOFT constraint that biases toward training slots.
* **Allocation policy** — the weights + windows + exclusions used to score candidate assignments.

Output is a set of `assignments` rows (or, since P27, `slot_assignment` rows for split-shift sub-window granularity). Each has a companion `assignment_score_breakdown` recording the five score components (priority + mandatory-bonus + competency-value + equity-deficit + entitlement-debt) that led the solver to pick this staff for this slot.

## Split shifts (P27)

Prior to v1.6.2, one slot mapped to one staff-assignment across its full window. From v1.6.2, service lines can opt into `allow_split_shifts` per activity's `splittable` flag. This produces `slot_assignment` rows — one per sub-window (a slot may split into 2+ non-overlapping sub-windows, each with its own staff and its own handover minutes).

Composability with the equity model: the `job_plan_ledger` credit for a split slot is **hours-proportional** — a staff who works 5h of a 10h slot gets 0.5 credit, applied uniformly to ledger, equity deficit, and entitlement debt. See [Equity and fairness model](/how-it-works/equity-model.md).

## Publish and notify

Publishing atomically flips the roster to `published` and:

* dispatches per-staff notifications (email + Web Push where configured) with a link to `/ui/my-roster` for the affected week,
* emits `roster.published` audit events per assignment change (create / update / delete relative to any prior published roster covering the same window),
* signals the sickness/leave/cover subsystems to start recognising the new schedule as the source of truth.

## Post-publish disruption

Reality intrudes: someone calls in sick, someone submits a leave request, a room becomes unavailable, a manager retires and their subordinates need a new home. Each disruption is a **change to the resource pool**, and ReSouris models each as a first-class flow (see [Resource management model → Change-of-plan flows](/how-it-works/resource-management-model.md#change-of-plan-flows)). None of them require a full roster regeneration:

* **Sickness** — reported via `/ui/my-resouris` → **Report sick** or admin-authored via the sickness-batch wizard. See [Sickness and leave](/how-it-works/sickness-and-leave.md).
* **Leave** — worker submits via `/ui/my-roster/leave/new`; admin decides via `/ui/admin/leave-dashboard`; approved leave marks the affected sub-slots for the reschedule worker to backfill.
* **Extended leave** — admin starts an extended-leave spell (maternity / paternity / long sickness / sabbatical / etc.); solver's F6 gate then filters the worker out of candidate lists for the leave duration.
* **Room / equipment unavailability** — admin marks the room via `/ui/admin/spaces/{id}/edit`; affected sub-slots enter the reschedule queue.
* **Reporting reshuffle** — roster-area admin uses the [Reporting-structure tool](/manage-people/reporting-structure-tool.md) to bulk-reassign subordinates or add/remove shared managers. Doesn't affect published assignments directly but keeps the resource model current for the next re-solve.

Each disruption produces one or more **reschedule proposals** — candidate reassignments that respect current constraints. Admin reviews and accepts. Sibling proposals (multiple candidates for the same sub-slot) supersede automatically on accept-one.

## The rolling roster

A department can run its roster as a **rolling** window rather than solving a fixed horizon by hand each time. Turn it on per department at `/ui/admin/departments`.

A rolling roster is always **this Monday, plus eight weeks**. A background worker checks each department and, whenever its roster has fallen behind that window, advances the horizon, supersedes any draft nobody authorised, and queues a fresh solve.

> ⛔ **IT PROPOSES; IT NEVER PUBLISHES.** The solve produces a `ready` revision and stops. A person still authorises it. Nothing reaches a worker's published roster without somebody deciding it should.

Two consequences worth understanding:

* **Weeks 1–7 do not churn.** The solve anchors on the last *published* revision, so it reproduces what is already out there and only week 8 is genuinely new. Rolling the window does not reshuffle next week's rota.
* **A fresh draft compounds disruption rather than hiding it.** Because the anchor is the published revision and the solve reads current sickness and leave, each new draft reflects *everything* that has accumulated since publication — not just what changed since the last draft. You see the real position, not a position relative to a draft nobody approved.

⚠️ A missed tick is harmless: the worker acts only when a roster is behind, so it catches up on the next one. The poll interval is just how long a behind roster waits.

## Regeneration vs reschedule

Two distinct actions on top of the live resource pool:

* **Regenerate** — re-runs the full solve for a horizon against the current resource pool. Used when the pool or demand shape changed enough that piecemeal reschedule proposals wouldn't be efficient (e.g. new service line, new allocation policy, competency-wide reissue, new cohort of hires). Requires `roster.regenerate`.
* **Reschedule** — surgical: one or a handful of assignments changed via reschedule proposals. The rest of the published roster stays unchanged; the resource pool is unchanged aside from the specific disruption.

Rule of thumb: reschedule for daily disruption; regenerate when weekly / monthly resource-pool or policy changes.

## Failure modes

* **`PRE_FILL_CONFLICT`** — the room-SL pattern rules out every candidate for a required cell. Admin needs to fix the pattern / override before the solve can proceed.
* **`INFEASIBLE`** — the solver proved no feasible assignment exists given constraints. Usually indicates over-allocated staff or missing competencies. The error report names the constraint that failed.
* **`TIMEOUT`** — solver exceeded the time budget. Retry with a smaller horizon or a warmer starting seed.

## Audit trail

Every state transition emits an audit event: `roster.generation.started`, `roster.generation.completed`, `roster.published`, `roster.reschedule.proposed`, `roster.reschedule.accepted`. The audit page (nav → **Audit**) filters by these action strings.

The `assignment_score_breakdown` table is queryable directly; the audit trail links each assignment change to its score justification for defensibility during compliance reviews.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://help.resouris.com/how-it-works/roster-lifecycle.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
