§ 01 Problem
In the store's evening peak, traffic is highest and conversion is lowest — the floor is full and the outcome is worst. It's not understaffing; it's placement: the right person standing in the wrong zone. Meanwhile development runs on paper booklets that get shelved, and a veteran's know-how walks out the door with them. Schedules, KPIs, fitting-room counters, booklets — the data all exists, and none of it talks to each other.
§ 02 Approach
- A closed loop — diagnose, develop, place, measure, update — maintains a living, deliberately scoreless profile for each of ~30 employees, fed by three evidence channels instead of a single manager's impression.
- Every suggestion carries a four-step provenance chain (signal → evidence channel → inference → confidence band). The coach can apply, edit, or reject with a reason — and a justified rejection is written back as training signal, so disagreement makes the system better instead of being silently overridden.
- The placement engine formulates the floor as CP-SAT: binary variables x[p,r,t] under hard constraints (full coverage, availability, competence floor) and soft costs (fatigue, fairness) — plus the most opinionated term, a development bonus that pays the solver to give new people practice slots instead of quietly riding its two best people all day.
- The solver core is served over FastAPI on Railway; a React 19 + Neon Postgres web app fronts it in TR/EN/ES, keeping the optimization engine a small, testable JSON-in/JSON-out service.
§ 03 Outcome
Over a ten-period backtest the solver reproduced existing human rosters with ~64% overlap and scored 79/100 on rule-based self-evaluation — enough agreement to be trusted, enough divergence to be worth arguing with. The more durable outcome: the placement engine outlived the hackathon and became the shift solver my section actually uses (see project 02).
~64%
overlap with human rosters, 10-period backtest
79/100
solver self-evaluation score





