> 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/run-the-roster/report-a-sickness-batch.md).

# Report a sickness batch

**Who:** roster-area admin (multi-staff batch), or worker (single self-report). **Perm:** `sickness.batch.create` (admin), `my_roster.read` (worker self-report). **Time:** \~3 minutes for the wizard; reschedule proposals then appear over the following minutes.

The sickness-batch subsystem is what makes multi-staff sickness triage safe: five staff calling in sick on the same morning during flu season, or a whole team hit by a food-poisoning event. The wizard groups their absences so the reschedule proposals see the full picture — not five sequential single-staff re-plans that each ignore the others.

## When to use the wizard

Use the admin wizard when:

* More than one staff is absent for overlapping dates.
* You know about a bulk event before workers self-report (e.g. a team-day sickness, industrial action).
* You need to pre-triage cover before the day starts.

Use worker self-report (from `/ui/my-roster`) for standard single-staff sick calls. The system auto-joins to any matching open batch or creates a new one with a K=3 stub if none exists.

## 1. Navigate

Start one at `/ui/admin/sickness-batches/new`; open batches are listed at `/ui/admin/sickness-batches-dashboard`.

## 2. Pick affected staff

The wizard shows the staff list scoped to your roster areas. Multi-select the staff who are absent.

If you know only the names but not the IDs, use the search-by-name box. Staff currently on approved leave for the same dates are visually flagged — they don't need to be re-triaged.

## 3. Set date range

* **From** — the first day of absence.
* **To** — the last day of expected absence (guess if unknown; you can amend later).
* **Absence kind** — `sickness | industrial | force_majeure | other`.

The system computes the overlap between each affected staff's published assignments and this window — that's what the reschedule worker will produce proposals for.

## 4. Pick affected roster area

Even if the affected staff span multiple areas, the batch is filed against one primary area (typically the one where the majority of their published assignments sit). This drives the sickness-batches dashboard grouping.

## 5. Notes (optional)

Free-text notes for the audit trail. Typical use: "food-poisoning incident at team lunch 2026-07-08; expected 48h absence." Notes are not visible to affected workers.

## 6. Submit

Click **Submit**. The batch is created in state `open`. The reschedule worker starts producing proposals within seconds.

Audit events emitted:

* `sickness.batch.created` (SUCCESS)
* One `sickness.member_added` per affected staff
* `roster.reschedule.proposed` per proposal generated

## 7. Review proposals

Sidebar → **Fairness & cover** → **Reschedule proposals** (`/ui/admin/reschedule-proposals`). Filter by `parent_batch_id = <your batch>`.

For each affected sub-window, one or more candidate covers appear as **sibling proposals**. Each candidate shows:

* proposed cover staff,
* their competency match against the required activity,
* their current equity-deficit position (higher deficit = a legitimate reason to prefer them),
* their job-plan entitlement debt if the activity is in their plan.

## 8. Accept covers

For each sub-window, click **Accept** on the preferred proposal. The action:

* Transitions the accepted proposal to `accepted`.
* Transitions sibling proposals for the same sub-window to `superseded_by_sibling` (per MIG-140 F5 lock).
* Emits `roster.reschedule.accepted` audit event.
* Updates the affected staff's `slot_assignment` rows.
* Dispatches notifications to the cover staff.

If none of the proposals is acceptable, click **None fit — mark uncovered**. The sub-window transitions to `uncovered` state; the responsible admin sees this on the dashboard and can arrange cover out-of-band.

## 9. Close the batch

When every affected sub-window has an outcome (accepted or uncovered), the batch state transitions from `open → resolving → closed` automatically.

You can also manually close a batch: click **Close** on the batch detail page. This is used when a batch was created but the staff turned out to not be sick (e.g. false-alarm text at 06:00).

## Cross-cutting: split-shift composability

Since P27, sickness batches compose with split shifts via the `find_sub_windows_for_sickness_batch(cur, tenant_id, staff_ids, absence_date_iso)` helper. When an absent staff had a split-shift slot on the absence date, the reschedule proposals cover only the sub-windows the absent staff was assigned to — the other sub-windows in the same slot are unaffected.

This is the F9 composability pin from the split-shifts phase.

## Common patterns

**Pattern A: single-staff self-report joining an open batch.** Worker at `/ui/my-roster` clicks **Report sick** → picks date → submits. If an admin already opened a batch for the same area + overlapping dates, the worker's absence joins that batch. If not, a new batch opens with K=3 stub.

**Pattern B: pre-triage before the day.** Admin knows on Sunday evening that four A\&E staff are down with flu. Opens the wizard, groups all four, sets Monday-Wednesday. Reschedule proposals arrive within a minute. Admin accepts covers before Monday 08:00.

**Pattern C: escalating batch.** Batch opens with three staff. Over the morning, two more self-report and auto-join. The reschedule worker re-runs when new members join; new proposals reflect the updated total.

## Common issues

* **"No proposals appearing"** — either no candidates hold the required competency for the affected activity, or every candidate is themselves in an approved-leave or open-sickness state. Escalate to cross-department cover (P18) or mark uncovered.
* **"Same staff proposed for multiple slots"** — check the candidate's contracted hours + working-pattern constraints; the reschedule worker doesn't over-allocate but a same-day candidate for a same-day-off sub-window is a real edge case.
* **"Batch stuck in `resolving`"** — one or more sub-windows have no outcome yet. Check for reschedule proposals in `pending` state on that batch and either accept or mark uncovered.

## What comes next

* Understand the reschedule state machine → [Roster lifecycle](/how-it-works/roster-lifecycle.md#post-publish-disruption).
* Understand why specific staff were proposed → [Equity and fairness model](/how-it-works/equity-model.md).
* Configure sickness-related notifications → **Settings → Notifications** in the admin UI.


---

# 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/run-the-roster/report-a-sickness-batch.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.
