Skip to content
Kestrel Ridge HealthKestrel Ridge Health

Product

A scheduler's morning, and the five places the system argues back.

Most of what makes this defensible is not the forecast. It is what happens when someone tries to do something the rules do not allow, and what is left behind afterwards.

The loop

What a Tuesday actually looks like

Five steps, and a person in the ones that matter.
  1. 01

    Before clinic

    The day board shows every session with its forecast minutes, the range around it, the recommended technician count and what the fixed ratio would have said. Sessions the forecast is least sure about are flagged so they get a second look.

  2. 02

    Build

    One action produces a draft plan under the eight hard rules. Generating it staffs nobody. Sessions that cannot be filled inside the rules are listed with the shortfall and the solver's own suggestion, rather than filled by bending something.

  3. 03

    Argue with it

    Open any session to see why the forecast landed where it did, which competencies the session needs and why, and the reason each assigned technician was chosen. Override anything, with a reason.

  4. 04

    Approve, separately

    A second person accepts and publishes. Until they do, there is no plan of record. The account that built the plan cannot be the one that approves it.

  5. 05

    When the day changes

    Record a call-off or an add-on and replan. The solver is told to minimise churn against what was already published, so a small change to the facts does not reshuffle the whole day.

The moments worth seeing

Seven things it does that a schedule cannot

Each of these is built, reachable and covered by tests.
  1. 01Session Detail

    The system refuses an override and names the rule you broke

    Pick a technician the picker has marked blocked, give a reason, and submit. The override is refused, nothing is stored, and the failing hard constraints come back by name, with the detail for each. Try a technician who is not blocked and the override is accepted, creating a new plan version whose parent is the one it replaced.

    Covered by a test that asserts the refusal names SITE_ELIGIBILITY.

  2. 02Session Detail

    Every assignment can be second-guessed

    Open the counterfactual for any assigned technician and the system names the next feasible alternative, then re-validates the swapped plan and reports the real metric differences rather than estimating them.

    Backed by the plan comparison and counterfactual services.

  3. 03Scenario Lab

    Stress the roster before the day does

    Thirteen scenarios, two of them infeasible by design, applied as real state changes through the same machinery a live event uses. Apply a technician call-off and read which checks on the current plan now fail, before deciding whether to reoptimize. Reset returns the date to its snapshot, and the reset is itself in the audit log.

    Thirteen scenarios verified in the scenario catalogue.

  4. 04Optimization

    See which rule the solver ran out of room on

    Pass, warning or fail for each of the eight hard constraints, with a plain-language explanation and the sessions each one affects, plus the solver's own account of where it stopped and the diagnostics for every session left unresolved.

    One check per rule, re-derived by the independent validator.

  5. 05Plan History

    Nothing is overwritten, and any two versions can be compared

    A version timeline built from plan lineage, with status, override reasons and what changed. Compare any two versions, or compare a version against the fixed-ratio baseline staffed under the same eight rules and scored with the same metrics.

    Plan lineage carries a parent on every override and replan.

  6. 06Local validation

    Score the model on your own data, with nothing stored

    There is a documented column contract and an endpoint that scores rows a clinic exports. The rows are parsed in memory, scored, and dropped: the module opens no database connection and writes nothing. A file with fewer than twenty usable rows is refused rather than scored.

    The validation module has no database write path.

  7. 07Economics

    An economics calculator that will not guess

    It computes cost, payback and a break-even threshold from rates you supply. There is no default rate, no benchmark and no industry figure anywhere in it. An input you do not supply comes back marked for you to confirm, and every figure that needed it returns as not computed rather than as a filled-in guess.

    Every line is computed only when the caller supplied every rate it needs.

Source README.md, The eleven screens and Three-minute demo; backend/app/{scenarios,validation,economics}/; backend/tests/test_solver.py
Verified Scenario count and the override-refusal test were checked against the code on 2026-09-07.

The one to watch

The refusal is the feature

Any staffing tool can produce a schedule. The question a practice administrator should ask is what happens when someone overrules it, because that is what will happen at six in the morning when a technician calls off.

What most tools do

Accept the change. The rule was a preference, the schedule is a suggestion, and the record of what happened is whatever the person typed into a notes field. Nobody finds out that an unqualified technician covered an imaging list until something goes wrong.

What this does

Re-check all eight hard rules against the proposed change. If it breaks one, refuse it, store nothing, and return the rules it broke by name. If it breaks none, accept it, record who made the change and why, and keep the version it replaced. The refusal path is covered by a test that asserts the response names the specific constraint.

Source backend/app/solver/validator.py; backend/tests/test_solver.py, test_override_breaking_site_eligibility_is_rejected

Where the record goes

An auditor can reconstruct the day without asking anyone

Every plan generated, override attempted, decision recorded, scenario applied and plan exported is written to an append-only log with the actor, the timestamp and a readable detail. The log is hash chained, so an edited or deleted entry is detectable, and a verification endpoint reports the first break by sequence number. A plan leaving the system as a file is itself recorded, because a plan leaving the system is a disclosure.

Source backend/app/db.py; docs/governance.md section 3; docs/security-architecture.md section 6

Boundaries

What this is not

Four things it is routinely mistaken for, and what it does instead.
  • Not an EHR

    It holds no chart, no diagnosis and no note. It reads counts about a clinic session and forecasts the technician minutes that session will consume.

  • Not appointment scheduling

    It does not book, move or cancel a patient. It takes the schedule you already built as given and staffs the technician side of it.

  • Not a staffing agency

    It supplies nobody and hires nobody. It assigns the technicians already on your roster, under your own rules, for a person to approve.

  • Not credentialing software

    It does not verify, issue or track a credential. It reads the competencies and site approvals you maintain elsewhere and refuses any assignment that would violate them.

Try it against your own numbers

There is a documented column contract and an endpoint that scores the model on sessions you export. Rows are parsed in memory and dropped. Nothing is written, and nothing is kept.