Skip to content
Back to Rosie

How it decides.

The scheduler is a constraint solver, not a language model. Everything below is what it is given, what it may not break, and what it weighs when more than one roster would work. Written for anyone who wants to check our work.

CP-SAT

Solver

Google OR-Tools, pinned at 9.8.3296. A constraint solver, not a language model.

22

Rules it cannot break

Published in full below, with 8 more it weighs rather than forbids.

6

Jurisdictions

Break, rest, young-worker and leave rules, per country and per site.

1–5s

Typical solve

Around 50 staff and 70 shifts. Longer problems get a longer budget.

04 — The register

The rules, in full.

22 it cannot break. 8 it weighs. Grouped by how each one is enforced.

Engine
OR-Tools CP-SAT
Version
9.8.3296

Open any rule for the detail and where it lives in the source.

PrepKitchen

Role Conflict

Rostered to a role they do not hold.

OpenFloor

Warning

Inside the minimum rest gap after the night before.

CloseBar

Backdated

Placed on a date that has already passed.

Rest day

Unavailable

Outside the days this person can work.

Four of them, as the grid draws them. The rest of the register is below.

Group A

Who is even a candidate

12

Applied before the search. Each returns the reason you saw above.

  • Only active staff enter the search

    Employment status

    Only ACTIVE staff enter the search at all.

    scheduler.py:224

  • Trainees only fill shadow slots, and vice versa

    Training segregation

    Both directions are enforced, so a trainee cannot quietly become the coverage.

    scheduler.py:231-235

  • Must hold the role the slot asks for

    Role held

    The person must hold the role the slot asks for.

    scheduler.py:238-243

  • Must be assigned to that site

    Location assignment

    The person must be assigned to that site.

    scheduler.py:241-244

  • Every certification the role needs, current

    Role-required certifications

    A lapsed certificate removes the person from the slot, not from a warning list.

    scheduler.py:246-250

  • Inside their start and end dates

    Employment date window

    Both are checked per shift date, not once per roster.

    scheduler.py:256-264

  • Week-on/week-off cycles, from an anchor date

    Multi-week roster pattern

    Longer cycles too, computed from a cycle length and an anchor date, so an off-week person is never offered.

    scheduler.py:266-275

  • A specific date beats the usual pattern

    Date-specific override

    UNAVAILABLE blocks the day or just the overlapping hours. AVAILABLE replaces the recurring window for that date rather than adding to it.

    scheduler.py:279-317

  • Shift sits entirely inside a declared window

    Recurring availability

    Partly-inside is not eligible.

    scheduler.py:319-334

  • Full days, and half days by morning or afternoon

    Approved leave

    Half-day leave blocks only the matching half — AM blocks starts before noon, PM blocks starts from noon.

    scheduler.py:336-351

  • Minimum and maximum length, overridable per site

    Shift length by employment type

    A per-location override outranks the org default, so a three-hour engagement minimum at one site does not have to become the rule everywhere.

    scheduler.py:353-362

  • Curfews and shift caps, per age band, per country

    Young-worker rules

    Curfew start, curfew end and maximum shift length. Bands are configurable per organisation and default from the country preset.

    scheduler.py:364-394 · lib/minor-work-rules.ts

Group B

What the model will not allow

10

A roster breaking one of these is not scored badly. It cannot be represented.

  • Minimum, ideal and maximum headcount per slot

    Staffing ceiling

    The maximum is a hard ceiling the model cannot exceed. Slots between ideal and maximum are allowed but scored against.

    scheduler.py:626-656 (CONSTRAINT 1)

  • No mentor on the floor, no shadow shift

    Mentor pairing

    A trainee in a shadow slot requires a non-trainee working an overlapping shift at the same site and role.

    scheduler.py:668 (CONSTRAINT 1a)

  • A slot can require several certified people

    Certification coverage

    Not merely one.

    scheduler.py:751 (CONSTRAINT 1b)

  • A first-aider on the floor every operating hour

    Certification time-coverage

    Enforced by hour, not by day. Not simply someone certified rostered somewhere that day.

    scheduler.py:781 (CONSTRAINT 1c)

  • One person cannot be in two places

    No overlapping shifts

    No two shifts that overlap in time on the same date.

    scheduler.py:846 (CONSTRAINT 2)

  • Always hard, never a warning

    Maximum hours per day

    Not a preference, not a flag after the fact.

    scheduler.py:895 (CONSTRAINT 3)

  • Week, fortnight or month — whichever you run

    Maximum hours per pay period

    Scaled to the organisation’s pay period rather than assumed weekly. A fortnightly cap is enforced fortnightly.

    scheduler.py:943 (CONSTRAINT 4)

  • No close followed by an open

    Minimum rest between shifts

    Reads shifts outside the range being filled, so the gap is still enforced across the boundary into the week you already published.

    scheduler.py:1008 (CONSTRAINT 5)

  • Counts days already worked before this roster

    Maximum consecutive days

    Boundary-aware, so a run does not reset when a new roster starts.

    scheduler.py:1079 (CONSTRAINT 6)

  • Two days off means two together

    Minimum consecutive days off

    A rolling-window check, so two separate single days do not satisfy a requirement for two consecutive.

    scheduler.py:1139 (CONSTRAINT 6b)

Group C

What the model weighs

8

Genuine trade-offs. A higher tier can never be outbid by a lower one.

  • The core goal, and nothing outbids itMEDIUM

    Fill every slot

    The tier every other consideration sits beneath.

    scheduler.py:1714

  • Allowed to the maximum, scored past idealMEDIUM

    Overstaffing above ideal

    Every slot past ideal costs the solver something.

    scheduler.py:1753

  • Heavy reward for giving everyone a shiftMEDIUM

    Nobody sent home with nothing

    In hospitality a casual rostered zero hours is a retention problem before it is a scheduling one.

    scheduler.py:1794

  • Shortfall against a contracted commitmentMEDIUM

    Minimum hours per period

    For staff whose agreement is expressed in hours.

    scheduler.py:1355 (CONSTRAINT 7)

  • For agreements written in days, not hoursMEDIUM

    Minimum days per week

    Tracked separately from the hours commitment.

    scheduler.py:1206 (CONSTRAINT 8)

  • Grouped days beat a fragmented weekMEDIUM

    Consecutive working days

    Prefers a run over single shifts scattered with gaps between them.

    scheduler.py:1311 (CONSTRAINT 9)

  • Under-hours penalised three times as hard as overSOFT

    Asymmetric fairness

    Short-changing someone is treated as the worse error, and that is a constant in the source rather than a claim in a brochure.

    scheduler.py:1734-1735 · W_UNDER_TARGET = -3, W_OVER_TARGET = -1

  • Multi-site staff stay where they usually workSOFT

    Home-site preference

    Where the rest of the roster allows it.

    scheduler.py:1750-1830

Scope

Where Rosie stops.

A specification is only worth reading if it says what is outside it.

Inside

Rostering, time and the rules between them.

  • Rosters and auto-fill
  • Clock-ins and timesheets
  • Leave and swaps
  • Compliance rules

Outside, and the seam

  • Payroll

    Rosie hands over hours and rates. It does not calculate tax or pay anyone.

  • Award advice

    It applies the rules you configure. That is not the same as advice.

  • Point of sale

    It does not read your sales, so it will not forecast labour against revenue.

  • Agentic AI

    A constraint solver. It has no opinion about your team.

Jurisdictions

Six countries, and the gaps left visible.

Filled means there is a requirement and Rosie enforces it. Hollow means there is none — not missing data.
Default scheduling and leave rules by country
RuleNZAUUKIEUSCA
Rest and meal breaks
10m at 2h 30m at 4h 10m at 6h
10m at 4h 30m at 5h 10m at 7.5h
20m at 6h
15m at 4.5h 30m at 6h
No requirement
30m at 5h
Minimum rest between shifts
10h
12h
11h
11h
No requirement
11h
Maximum consecutive days
6
6
6
6
7
6
Young-worker bands1
2 bands, from 21:00
2 bands, from 21:00
3 bands, from 19:00
2 bands, from 20:00
2 bands, from 00:00
2 bands, from 21:00
Annual leave (days, full-time)
20
20
28
20
No requirement
10
Sick leave (days per year)2
10
10
No requirement
5
No requirement
10
Right to disconnect
No requirement
In force
No requirement
In force
No requirement
No requirement
Predictive scheduling
No requirement
No requirement
No requirement
No requirement
By jurisdiction
No requirement
  1. 1New Zealand does set a youth night limit — Health and Safety at Work (General Risk and Workplace Management) Regulations 2016 reg 48 bars under-16s from work between 22:00 and 06:00 — and Rosie defaults one hour stricter than that. Australia has no federal youth curfew at all: child employment is state and territory law, and neither MA000004 nor MA000009 contains one. All of these are editable per organisation.
  2. 2The UK runs Statutory Sick Pay rather than a day entitlement.

Rates and rules

Dated, versioned, and replaceable.

A roster worked in May and paid in August has to cost against May’s rates.

United States · loadings

Full-time

1x
Saturday
1x
Sunday
1x
Night
1x
Public holiday
after 40h · 1.5x
Overtime

Full-time defaults. Part-time and casual are configured per employment type. Rule changes are dated rather than overwritten — fair Workweek laws in NYC, SF, Seattle, Chicago, Philadelphia, Oregon, LA, Berkeley, Emeryville.

Predictive scheduling

Advance-notice rules are modelled per jurisdiction, because they are city and state law rather than federal.

  • New York City
  • Chicago
  • Philadelphia
  • Seattle
  • San Francisco
  • Los Angeles
  • Berkeley
  • Emeryville
  • Oregon

Changelog

Every rule change, in full.

Appended whenever a preset changes. Dates are when the change took effect, not when it was authored.

  1. AU Modern Award library v1 addedAU

    Top-5 AU Modern Awards now available as installable presets: HIGA (Hospitality), GRIA (Retail), SCHADS, RIA (Restaurant), Aged Care MA000018. Apply via Settings → Compliance → Awards. Rates are best-known midpoints for the 2026-07-01 effective date — verify against the Fair Work pay tool before relying on for payroll.

  2. Extended leave typesAll countries

    Added PARENTAL, BEREAVEMENT, JURY_DUTY, FAMILY_VIOLENCE, STUDY, IN_LIEU to the LeaveType enum. Statutory entitlements per country surfaced via `getStatutoryEntitlement(country, type)`.

  3. US Predictive Scheduling / Fair Workweek presetsUS

    10 city presets added (NYC fast-food / NYC retail, Chicago, Philadelphia, Seattle, San Francisco, Oregon statewide, LA, Berkeley, Emeryville). Apply per-Location via Settings → Compliance → [Location] → Predictive. Compares Shift.publishedAt vs the configured advance-notice window.

  4. AU Right to Disconnect supportAU · IE

    Per-Location quiet hours config; `sendPushToStaff()` now filters out recipients whose home location is in quiet hours. Default RTD config off — opt-in per Location. AU large-business law in force from 26 Aug 2024, small-business from 26 Aug 2025.

  5. Per-location compliance engineAll countries

    New `LocationComplianceProfile` model + `lib/compliance-context.ts` resolver: every jurisdictional rule (breaks, minors, penalty rates, RTD, predictive scheduling, geofence, award) now resolves per-location with org-default fallback. Multi-jurisdiction orgs (e.g. Sydney + Auckland + London) supported end-to-end.

  6. AU Right to Disconnect extended to small businessAU

    Right to refuse out-of-hours contact extended to employees of small business employers (under 15 employees). Awards updated to include RTD term. (Reference event — Rosie support shipped 2026-04-19.)

  7. AU Right to Disconnect commenced (large business)AU

    Closing Loopholes Act provisions came into force for non-small-business employers. Employees can refuse to monitor / read / respond to contact outside their working hours, unless that refusal is unreasonable. (Reference event — Rosie support shipped 2026-04-19.)