This document defines the guiding principles for building call and rotation scheduling in Guava. These principles establish a conceptual framework that all scheduling features should follow.
Scheduling is organized around three distinct systems that interact but don’t conflate:
Principle: The solver is a tool, not an authority.
The solver produces proposals, not mandates. Humans evaluate and adopt them.
Solve at any time — Run the solver whenever needed: fresh, incremental, what-if scenarios. The system never says “you already solved this.”
Solve with constraints — Lock specific assignments, date ranges, or residents. Example: “Keep everything before March 15, re-solve the rest.”
Multiple proposals can coexist — Run different scenarios (with/without a resident, different constraint weights) and compare before committing.
Proposals don’t automatically become reality — An admin explicitly promotes a proposal to the operational schedule.
Principle: The operational schedule reflects reality, not intentions.
The Record is the source of truth for what actually happened (or will happen). It answers “what actually happened?” not “what should have happened?”
The Record is editable — When reality changes (swap, dropout, sick call), the Record updates to match. No fighting the system to record truth.
The Record is distinct from proposals — A proposal gets promoted to the Record, but after that, the Record lives independently. Re-running the solver doesn’t automatically change the Record.
The Record can contain rule violations — If a resident worked a shift that violated a constraint, the Record captures that it happened. Reality trumps rules.
Every mutation is attributed (including creation):
Full history is preserved — Any assignment can be traced back to its origin and every modification since. No assignment appears in The Record without knowing who put it there and why.
Principle: Rules are hard or soft, never mushy.
Rules guide the solver and validate the schedule. But rules serve the program, not the other way around.
Hard constraints — Solver will not violate these. To allow a violation, you must explicitly override that specific instance.
Soft constraints — Solver optimizes toward these but can trade them off against each other. Violations aren’t errors; they’re optimization outcomes with costs.
There is no “warn but allow” middle ground that erodes rule integrity over time.
Hard constraints are configurable at granular levels through a cascading override system. More specific scopes override broader ones:
Global default (constraint definition)
└── Program-level override
└── Schedule-level override
└── Time-range override (e.g., "July 2025")
└── Resident-level override
└── Specific instance override (resident + time)
Example: “Max night calls per month” defaults to 4. Dr. Smith has an override for July 2025 allowing 6 (covering for resident on leave). The base rule stays clean; the override documents the exception.
Explicit overrides — When a rule must be violated, an admin explicitly acknowledges it. This creates a record: “Night call limit exceeded for Dr. Smith on 3/15 — approved by Jane (emergency coverage).”
Overrides attach to specific violations — You’re not disabling a rule globally; you’re approving a specific exception.
Post-hoc overrides are valid — If something already happened that violated a rule, you can record it with an override explanation.
Rules don’t block recording reality — The Record always accepts what happened. Rules flag violations for visibility.
These principles govern how The Plan, The Record, and The Rules interact:
| System | Purpose | Key Property |
|---|---|---|
| The Plan | Solver proposals | Advisory, explorable, comparable |
| The Record | Operational truth | Sovereign, auditable, reality-accepting |
| The Rules | Constraints | Hard or soft, overridable at granular levels |
These principles ensure that scheduling remains a tool that serves the program’s needs while maintaining clear accountability and the flexibility to handle real-world complexity.