§ 01 Problem
Every morning someone has to decide, hour by hour, who stands where on the women's section floor: fitting room, welcome, sprinter, four zones. The chart has to respect Orquest shift times, half-hour breaks, blocking HR/training tasks, a five-level competency matrix, a buddy rule for people in their first month, and the store's physical topology of which roles can be merged. Done by hand this took the coordinator around two hours a day (self-reported) — and the rules lived in one person's head.
§ 02 Approach
- The core model is the same shape as PUSULA's: binary variables x[p,r,t] with hard constraints (exact coverage from a discrete n→capacity table, one role per person per hour, availability including half-hour breaks and blocking HR/TR/ISG tasks, zero-competency ban) and a soft cost blending competency, rotation fatigue, fairness, and a development bonus (solver/cp_sat_scheduler.py, 1,847 lines).
- The decisive engineering fix was sequential per-hour solving: the monolithic 12-hour model stalled at FEASIBLE with ~30 people on Railway's slow CPUs. solve_sequential() solves each hour as its own tiny model — provably OPTIMAL in milliseconds — while cross-hour rules (rotation limits, cumulative fairness, closing-hours stability) are injected from the already-solved history. Deterministic, ~1–2 s per day.
- Floor reality is encoded as first-class constraints, each traceable to a dated decision in the code comments: five area teams with soft home-area pull, a hard buddy rule for 0–1-month staff with partner priority COACH > FT > CX, a dual-role topology of which cells one person may legally cover, and half-hour 'Name 1/2' notation with explicit bridge-handover warnings instead of silently faking coverage.
- It ships as a small FastAPI service: POST /solve, a deterministic /solve/area-based v2 path, /health for Railway, CORS locked to the zaratraining.online frontend; output also exports to Excel in the store's existing paper-chart format, so adoption cost nothing.
- Validation is built in rather than bolted on: a rule-based self-evaluator scores every chart 0–100 against the domain rules, and an offline backtest module compared solver output against 10 real historical charts — 63.8% personnel overlap, 78.8/100 average self-score.
§ 03 Outcome
This is the one project on this page that runs in production for real users — me and my section. Planning the women's section's roughly 10-hour day dropped from about two hours of manual work to minutes, and the system is still in use (operational, self-reported). Inside the repo, the regression baseline on the real June 2026 roster shows the quality score climbing from 83.6 to 89.2 and the objective cost falling from 2.50M to 527k across development phases.
2 h → min
daily planning time, women's section (operational, self-reported)
100
charts produced in production (Shift Organizer report, Jul 2026)
93.7
average quality score across those 100 charts (report screen)
63.8%
personnel overlap vs 10 real historical charts (parsers/backtest.py)

