Агент і розв'язувач
Два рішення: розв'язувач для першої версії (2 жовтня 2026) і те, як інструменти доходять до агента (5 жовтня 2026) · перший розв'язувач створено в API 19 жовтня 2026: перевірено на маленьких тижнях, порахованих уручну, і на демо-магазинах із початкових даних, три його інструменти в каталозі агента, один раз перевірено з локальним Agentfy, не розгорнуто · обмеження людей з їхніх описів додано 20 жовтня 2026 (рішення власника того ж дня): перевірено на маленьких тижнях, порахованих уручну, і через справжній /mcp з Agentfy в пам'яті, один раз перевірено з локальним Agentfy, не розгорнуто · описи враховуються в кожному плані без прохання, з 20 жовтня 2026 (рішення власника того ж дня): інструменти розв'язувача самі передають їх агентові, перевірено через справжній /mcp з Agentfy в пам'яті, один раз перевірено з локальним Agentfy, не розгорнуто · власні правила магазину з його опису додано того ж дня (власник): перевірено на маленьких тижнях, порахованих уручну, і через справжній /mcp з Agentfy в пам'яті, один раз перевірено з локальним Agentfy, не розгорнуто · факти про бібліотеки перевірено 19 жовтня 2026 · без рівня чергового керівника в магазині без керівника, 23 жовтня 2026, перевірено на невеликому тижні, розрахованому вручну, і на магазині, створеному тестом, не розгорнуто · власні години — розв'язувач сам задає години зміни, коли не підходить ні шаблон, ні звична зміна, — додано 26 жовтня 2026 (рішення власника того ж дня): перевірено на маленьких тижнях, порахованих вручну, на демо-магазинах із початкових даних і через інструмент з Agentfy в пам'яті, з локальним Agentfy не перевірено, не розгорнуто · кожну годину роботи закрито за замовчуванням — хоча б одна людина на зміні — додано 28 жовтня 2026 (рішення власника того ж дня): перевірено на маленьких тижнях, порахованих вручну, на демо-магазинах із початкових даних і через інструмент на магазині, який створює тест, з локальним Agentfy не перевірено, не розгорнуто · правила магазину, що рахують лише людей однієї посади або керівників, додано 30 жовтня 2026 (прохання власника того дня): перевірено на малих тижнях, порахованих вручну, і через інструмент на магазині, який тест створює за зразком магазину власника Test, не перевірено з локальним Agentfy, не розгорнуто · дні на тиждень (maxDaysPerWeek, «п'ять змін на тиждень і два вихідні») додано того ж дня (прохання власника): перевірено на малих тижнях, порахованих вручну, через інструмент на магазині, який тест створює за зразком Test, і на демо-магазинах, не перевірено з локальним Agentfy, не розгорнуто · одне правило для всіх, хто обіймає посаду, і звичайні зміни посади (usualShifts) додано того ж дня (прохання власника): перевірено на малих тижнях, порахованих вручну, і через інструмент на магазинах, які тест створює за зразком Test, з 11 і з 21 людиною, демо-магазини без змін, не перевірено з локальним Agentfy, не розгорнуто · розподіл по дню і тижню додано того ж дня (рішення власника): перевірено на малих тижнях, порахованих вручну, через інструмент на магазинах, які тест створює за зразком Test, з 11 і з 21 людиною, і на демо-магазинах, не перевірено з локальним Agentfy, не розгорнуто · обмеження лише з відбитком відданих описів, і непорожні теж, з 30 жовтня 2026 (рішення власника того ж дня): перевірено на малих випадках, які пише тест, і через інструменти на демо-магазинах, не перевірено з локальним Agentfy, не розгорнуто · з 5 листопада 2026 (рішення власника того ж дня) перерви закриваються звичайними змінами внахлест, звичайні зміни замість шаблонів магазину, нічиї розбиваються, тож симплекс більше не ходить по колу, понаднормові знімаються після пошуку, і цифри кожного правила у відповіді: перевірено на маленьких тижнях, розібраних вручну, на магазині, який тест пише як MyTest, і через інструмент на копії локальних даних власника, не перевірено з локальним Agentfy, не розгорнуто · з того самого дня (рішення власника) жодне обмеження не губиться мовчки — непридатне зупиняє план, правило людини з посадою — правило людини — і розв'язувач у межах 15 секунд інструмента: перевірено на маленьких випадках, розібраних вручну, через інструмент на магазині, який тест пише як Test, і на копії локальних даних власника, не перевірено з локальним Agentfy, не розгорнуто · з того самого дня (рішення власника) кожен опис ураховано, одна зміна на день, якщо розділені зміни не допустимі, і менеджери чергують: перевірено на маленьких тижнях, розібраних вручну, через інструмент на магазині, який пише тест, і на копії локальних даних власника, не перевірено з локальним Agentfy, не розгорнуто · з 10 листопада 2026 (прохання власника того дня) тиждень розв'язує HiGHS, YALPS лишено запасним: перевірено на маленьких тижнях, розібраних вручну, через інструмент на магазинах, які пише тест, — Test, MyTest, MyCity, демо-магазини з початкових даних і вигадані магазини на 50, 100 і 120 людей, — і на копії локальних даних власника, не перевірено з локальним Agentfy, не розгорнуто · з 10 листопада 2026 (на прохання власника того дня) правила, прочитані в описах, зберігаються поруч із ними (save_rules, needsRules), і вид onlyDays: перевірено на маленьких випадках, розібраних вручну, через інструменти на магазині, створеному тестом, і на копії локальних даних власника (MyMega, MyCity) зі скриптом замість асистента, з живим агентом не перевірено, не розгорнуто
Арифметика тримається подалі від мовної моделі: розв'язувач — звичайна детермінована програма всередині API Shiffty — будує та перевіряє тиждень, а агент лише перекладає між людьми та цією програмою. З 19 жовтня 2026 є перша версія: вона пропонує тиждень для команди магазину й зважує запит на зміну, а керівник підтверджує те й інше в застосунку.
Агент говорить, розв'язувач рахує, а останнє слово щодо правил лишається за API.
Що таке розв'язувач
Це програма, яка розставляє людей по змінах за заданих правил. Задача класична — того самого типу, що й розклад медсестер у лікарні, який бібліотека оптимізації Google наводить як навчальний приклад, — і розв'язується готовими бібліотеками оптимізації, а не мовною моделлю.
- На вході дані, а не текст. Команда з ролями й годинами за договором, години роботи магазину, шаблони змін і те, скільки кас потрібно щогодини. Це поля зі сторінки Вхідні дані.
- На виході тиждень — і що лишається відкритим: які години не закрито, яке правило заважає і що це виправить.
- Зміна, яку додає розв'язувач, ніколи не порушує жорстких правил.
- М'які правила зважуються. Спершу покриття, потім переробки, потім те, наскільки змінюється тиждень, потім справедливий розподіл годин.
Мовна модель погано дає раду такій арифметиці й не гарантує, що дотримано кожного правила. Її роль інша: зрозуміти, про що просить людина, викликати розв'язувач і пояснити результат звичайними словами.
Про що агент його просить
Чотири інструменти, запропоновані 2 жовтня 2026, і що відповідає на кожен тепер:
| Запропонований інструмент | Що на нього відповідає |
|---|---|
| Побудувати графік | solve_week, розв'язувач (створено 19 жовтня 2026) |
| Перевірити зміну | check_change, перевірки запитів в API (з 13 жовтня 2026); для керівника, який вирішує, — evaluate_request |
| Знайти заміну | find_cover для власної зміни людини; evaluate_request називає заміну, потрібну запиту |
| Пояснити відмову | explain_refusal; крім того, кожен план пояснює кожен незакритий відрізок |
Два правила важливіші за те, як інструменти підключено:
- Агент заповнює фіксовану форму, а не пише правила сам. Інакше він може просто забути правило відпочинку, і ніхто цього не помітить.
- API перевіряє кожну зміну за тими самими правилами, хоч від кого вона надійшла — від агента, асистента працівника чи керівника. Підтверджений план і підтверджене рішення перевіряються ще раз у момент підтвердження.
Що створено
Створено 19 жовтня 2026 в API, окремою частиною (solver). Перевірено тестами; не розгорнуто; жоден керівник ним не користувався.
- Побудувати тиждень. Для магазину й тижня розв'язувач пропонує зміни кожного, кого той, хто питає, може планувати, і каже, що змінюється порівняно з тижнем, яким він є: додані, прибрані й залишені зміни, каса-години без касира зараз і з планом, відрізки без чергового керівника, години кожного проти договору, а для кожного незакритого відрізка — чому і що це виправить. Він нічого не записує.
- Записати в чернетку. Коли керівник підтверджує, план записується в тиждень — лише в чернетку або в тиждень, якого ще немає: тоді його створюють порожнім, як чернетку. Він ніколи не публікує: публікація лишається дією людини в застосунку. Запис перевіряє права й правила такими, якими вони є в цю мить, і відбувається, лише якщо ніхто не змінював тиждень відтоді, як план зроблено; у нових змін походження «assistant».
- Зважити запит. Для запиту на зміну, який чекає на керівника, розв'язувач застосовує зміну до його тижня й порівнює: каси без касира, прогалини без чергового керівника, відпочинок і години за договором у зачеплених людей. Якщо зміна щось лишає незакритим, він шукає заміну лише в ці дні. Він повертає рекомендацію — схвалити чи відхилити — з причинами й заміною, яку взяв би. Схвалення заміну не додає.
- Вирішити щодо запиту. Схвалення чи відхилення керівника, з причиною для відхилення, готується як картка; її підтвердження виконує звичайне схвалення чи відхилення з правами керівника.
Хто може ним користуватися: власник і керівники магазину, з тими самими правами, що й на екранах графіків. План керівника не чіпає рядків керівників — вони належать власникові, — тож прогалину без чергового керівника називають, але не закривають. Працівник ним користуватися не може.
Як до нього доходить агент — на сторінці Інструменти агента. 19 жовтня 2026 у робочій копії з локальним Agentfy Daniel (демо-керівник) попросив наступний тиждень (опубліковано: порада, без картки), потім чорновий тиждень після нього (картка; підтверджено; чернетка прийняла план) і спитав, чи схвалювати обмін Maya (розв'язувач радив схвалити; картка, підтверджена, схвалила його від імені Daniel).
Як він будує тиждень
Тиждень як рішення «так/ні». Для кожного, кого можна планувати, кожного дня й кожної форми — шаблону зміни магазину або зміни, яку ця людина працює цього тижня чи працювала минулого, а з 26 жовтня 2026 — годин, які розв'язувач задає сам, коли нічого з цього не підходить (власні години), — у розв'язувача одне рішення: дати чи ні. Зміни, яких він змінювати не може, закріплені й лише враховуються: зміни керівника для керівника, зміна, на якій відкритий запит, зміни того, хто там більше не працює.
Жорсткі правила: зміна, яку додає розв'язувач, ніколи їх не порушує.
- у години роботи магазину — такі, якими вони є в момент плану, однакові щодня: у магазину один час відкриття й один час закриття, і кожен день вважається робочим (чи може магазин не працювати в якісь дні, не вирішено);
- одна зміна в людини на день; з 5 листопада 2026 до 3 — лише там, де опис допускає розділені зміни, і ніколи дві, що торкаються або перетинаються (нижче), — вручну редактор і далі допускає 3 без перетинів;
- жодної нової зміни у вихідний — за схваленим запитом на вихідний або за тим, що ще чекає;
- не менше 11 год відпочинку від останньої зміни дня до першої зміни наступного, включно з днями довкола тижня. Уручну це саме правило — лише попередження; розв'язувач тримає його як жорстке (рішення для власника, нижче);
- ділянка «черговий керівник» — лише для керівників;
- з 20 жовтня 2026 — жорсткі обмеження, які агент прочитав в описах людей (нижче).
Потрібні каси — ті самі, що на екрані дня: звичайна кількість чеків за годину, поділена на кількість чеків, яку касир обробляє за годину, з округленням угору, не менше 1, поки магазин відчинений. Людина рахується на касі ту частку години, що вона на касовій зміні, мінус перерва з відомим початком. Шаблон без ділянки може стати касовою зміною чи зміною в залі: розв'язувач ставить його на касу лише там, де це потрібно касам.
М'які правила, за вагами. Розв'язувач шукає тиждень із найменшою сумою:
| Що | Вага |
|---|---|
| Каса-година без касира | 10 000 |
| Година без чергового керівника (лише в магазині з активним керівником, з 23 жовтня 2026: у магазині без нього чергування заповнювати нікому) | 10 000 |
| Людино-година нестачі за правилами магазину: хоча б одна людина на зміні щогодини роботи, у будь-якому магазині, з 28 жовтня 2026 (нижче), і правила з його опису (нижче) | 10 000 |
| Година понад договір людини | 100 |
| Зміна, додана чи прибрана порівняно з тижнем, яким він є (лише коли в тижні вже є зміни, які той, хто питає, може змінювати) | 40 |
| Найбільша частка договору, яку хтось недопрацьовує | 8 |
| Зміна з власними годинами, з 26 жовтня 2026 (нижче) | 3 |
| Зміна всупереч м'якому побажанню людини з її опису (нижче) | 1,5 |
| Година недопрацювання за договором | 1 |
| Кожна година зміни (щоб ніхто не отримував зміну просто так) | 0,01 |
Ваги тримають порядок, про який просив власник: одна каса-година без касира переважує будь-яку переробку, яку може дати одна зміна, а одна змінена зміна переважує все, що одна зміна дає справедливості. Це ваги, а не суворі пріоритети, і їхні числа — наш вибір, а не вимірювання. Нижче за всі них, з 30 жовтня 2026, — розподіл по дню і тижню: не вага, а останній крок після пошуку, який нічого з цього не погіршує.
Детермінованість там, де доведено. Бюджет розв'язувача — 10 секунд (8 до 5 листопада 2026; рішення власника того дня: кращий план важливіший за швидкий, у межах 15 секунд, які платформа дає виклику інструмента). З YALPS кожен бюджет пошуку — кількість кроків, а обмеження за часом — страховка. З HiGHS, рушієм з 10 листопада 2026 (нижче), обмеження — час: тиждень, який він доводить найкращим, виходить однаковим щоразу; тиждень, на якому він зупиняється, може вийти трохи іншим від прогону до прогону, і план так і каже.
Рушій: HiGHS
З 10 листопада 2026, на прохання власника того дня («Может сразу попробуем перейти на более мощный солвер? Я хочу проверить как система будет работать с магазином на 100-120 сотрудников»). Перевірено на маленьких тижнях, розібраних вручну, через інструмент на магазинах, які пише тест (Test, MyTest, MyCity, демо-магазини з початкових даних і вигадані магазини на 50, 100 і 120 людей), і на копії локальних даних власника; не перевірено з локальним Agentfy; не розгорнуто; жоден менеджер цим не користувався.
Що змінилося. Та сама програма, але розв'язує її HiGHS, а не YALPS. HiGHS — розв'язувач оптимізаційних задач із відкритим кодом з Единбурзького університету. Він працює всередині API через highs-js, який збирає його у WebAssembly: ні другої мови, ні окремого сервісу. Він розв'язує весь тиждень одразу, кожна можлива зміна — рішення «так/ні», власним методом гілок і відсічень (попереднє спрощення, відсічення, евристики). Тиждень, який він доводить до кінця, доведено найкращий за цих ваг. Тиждень, який він не встигає закінчити, отримує найкращий знайдений план, і план каже, наскільки щонайбільше цей план може бути гіршим за найкращий (розрив, gap). YALPS лишається запасним: SOLVER_ENGINE=yalps в оточенні API, за замовчуванням highs.
Пакет, перевірено 10 листопада 2026: npm highs 1.15.4 (16 жовтня 2026), усередині HiGHS 1.15.1; ліцензія MIT, як у самого HiGHS. 4,0 МБ у розпакованому вигляді, з них файл WebAssembly — 3,5 МБ; залежностей немає. Один супровідник (lovasoa), випуски 11 вересня і 16 жовтня 2026. Однопотоковий. Завантажується приблизно за 20 мс під час першого розв'язання і працює в jest так само, як в API: на відміну від YALPS (#87), його не треба завантажувати поза пісочницею jest.
Як він запускається. HiGHS може взяти 75 % 10-секундного бюджету; побудові програми до нього і розподілу після нього потрібна решта (120 людей: 0,3 с і 0,1 с; 360 людей: 1,1 с і 0,8 с). Він зупиняється, щойно його план доведено не далі ніж 0,04 від найкращого. Це ціна годин 4-годинної зміни, нижче за будь-яку іншу вагу; власне значення HiGHS за замовчуванням, 0,01 % від суми, на тижні з кількома незакритими годинами було б цілим побажанням або зміненою зміною. План записує рушій, whole як крок пошуку і розрив.
На що перетворилися обхідні шляхи YALPS:
| Обхідний шлях | З HiGHS |
|---|---|
| Межа в 600 можливих змін | 10 000 для HiGHS (360 людей — це 8 406, сплановано за 2,7–3,2 с); у YALPS лишається 600 |
| Спершу точний пошук, потім звужений пошук, занурення, пачки закріплених змін | Не використовуються: HiGHS шукає по всій програмі. Лишено для YALPS |
| Добавка, що розбиває нічиї (5 листопада 2026) | Лишено. HiGHS не ходить по колу, але добавка вирішує, який із двох однаково добрих планів повернеться: без неї Test зберігав 20 з 55 змін еталона за 11 людей (38 з нею) і 16 за 21 (36 з нею) |
| Понаднормові знімаються після пошуку (вище) | Лишено. Працює, лише коли HiGHS зупиняється, не довівши свій план; у вимірюваннях нижче цього не сталося жодного разу |
| Розподіл (вище) | Лишено, без змін |
| YALPS завантажується поза пісочницею jest (#87) | Лишається для YALPS; HiGHS це не потрібно |
Сьогоднішні магазини: так само або краще. Власні тести розв'язувача складають 29 тижнів: Test з 11 і 21 людиною, MyTest, MyCity, наступні й чорнові тижні чотирьох демо-магазинів і тести описів. Усі тести розв'язувача в API проходять з будь-яким рушієм. Потім обидва рушії розв'язали кожен із цих тижнів, і кожен план оцінено однаково: його зміни закріплено, ціна програми без добавок. HiGHS був дешевшим на 16 і таким самим на 13, жодного разу не дорожчим. 28 з них він довів найкращими (YALPS — 7); один не має плану з жодним рушієм, навмисно (тест із межею в 1 мс). Час у звичайному node: HiGHS від 22 мс до 6,6 с, медіана 0,15 с; YALPS від 16 до 774 мс.
| Тиждень | YALPS | HiGHS |
|---|---|---|
| Test, 21 людина, новий тиждень | ціна 17,9; Галина на 8 год нижче договору; збережено 35 з 55 змін еталона | ціна 8,4, доведено; ніхто не нижче договору; збережено 36 з 55 |
| Test, 11 людей | ціна 4,4; збережено 38 з 55 | той самий план, доведено |
| MyTest, перше формулювання | ціна 1 035; 10 год понаднормових; 56 змін | ціна 525, доведено; 5 год понаднормових; 53 зміни |
| Harbor Street, чорновий тиждень | ціна −232; 9 змін додано, 9 прибрано | ціна −330, доведено; 9 додано, 7 прибрано |
| Riverside Market, чорновий тиждень | ціна −759; 10 додано, 10 прибрано | ціна −810, доведено; 11 додано, 8 прибрано |
| Central Station, наступний тиждень | ціна −242, найкращий знайдений | ціна −292, доведено, 1,3 с |
| MyCity (магазин e2e, 9 людей) | ціна 3,36, доведено | те саме, доведено |
З жодним рушієм нічого не лишилося незакритим там, де інший це закрив. Очікування наявних тестів не змінилися, з одним винятком: тест власних годин тепер перевіряє, що YALPS відкидає власні години на своїй межі в 600, а HiGHS бере їх усі.
Ще не створені демо-тижні й п'ять днів для всіх — досі обидва випадки повільні (Не вирішено). Виміряно знову 10 листопада 2026 на наступних і чорнових тижнях чотирьох демо-магазинів, із сьогоднішнім кодом. Тиждень ще без змін: HiGHS був дешевшим на всіх восьми (Old Town 23,4 проти 44,2, Harbor Street 23,0 проти 39,9). YALPS займав 0,06–0,3 с, HiGHS 0,09–5,1 с, крім Central Station: там HiGHS зупинився на своїй межі, 7,5 с, з розривом 5,4 і 5,7 %. Його план тоді коштував 64,15 і 64,19, а найкращий план, доведений за 28–30 с, коштує 64,15; плани YALPS — 77,6 і 73,0. Тож розрив там — те, що HiGHS ще не встиг довести, а не те, чого бракує плану. З п'ятьма днями на тиждень для всіх YALPS займав 0,05–0,12 с (172 с від 30 жовтня 2026 на сьогоднішньому коді більше не трапляються), а HiGHS 0,08–1,9 с; HiGHS був дешевшим на шести тижнях і таким самим на двох.
Магазин на 50, 100 і 120 людей. Вигаданий магазин, зібраний через маршрути API, як MyCity, скриптом api/test/bench/storeScale.bench.ts: відкритий 07:00–23:00; черговий менеджер і менеджери в магазині весь день; касири на касі весь день, більше 17:00–21:00 у будні; мінімум у залі 09:00–21:00; вантажники лише 07:00–15:00, більше у вівторок і п'ятницю 07:00–11:00; звичайні зміни 07:00–15:00 і 15:00–23:00; п'ять днів на тиждень для кожної посади. У двох з кожних п'яти людей в описі є особисте правило, види по черзі: noDays, timeWindow, maxHoursPerDay, maxDaysPerWeek і prefer. Договори — від 20 до 40 годин. solve_week власника планує порожній наступний тиждень з усіма правилами, які передав би агент. Потім скрипт перевіряє кожне правило за змінами плану, а не за підсумком розв'язувача: одна зміна на день, 11 год відпочинку, кожне особисте правило і правило посади та кожне правило магазину погодинно. Два навантаження: правила як вище і ті самі правила, що вимагають у 1,6 раза більше людей, — приблизно стільки, скільки можуть дати договори.
| Людей | Можливих змін | YALPS як працює (межа 600) | YALPS без межі | HiGHS |
|---|---|---|---|---|
| 50 | 1 180 | відмова | 1,4 с, найкращий знайдений, та сама ціна | 0,5 с, доведено |
| 100 | 2 345 | відмова | 6,4 с, найкращий знайдений, ціна 139,9, 96 год нижче договору | 0,8 с, доведено, ціна 132,0, 88 год нижче договору |
| 120 | 2 802 | відмова | 6,8 с, найкращий знайдений, та сама ціна | 1,1 с, доведено |
| 50, 1,6× | 1 180 | відмова | 2,0 с, та сама ціна | 0,5 с, доведено |
| 100, 1,6× | 2 345 | відмова | 8,1 с, та сама ціна | 0,8 с, доведено |
| 120, 1,6× | 2 802 | відмова | 10,3 с, на 4 год більше понаднормових і на 4 год більше нижче договору | 0,9 с, доведено |
Час — розв'язувач у звичайному node, як його запускає API; увесь виклик інструмента через jest зайняв 0,9, 1,4 і 1,9 с з HiGHS. У жодному плані HiGHS скрипт не знайшов порушеного правила. З першим навантаженням нічого не лишається незакритим, ніхто не працює понаднормово, а 9, 16 і 19 людей лишаються нижче договору на 52, 88 і 104 години: ті, кому їхні власні правила (чотири дні, дні без роботи, лише ранок або лише вечір) більше не лишають. З 1,6× у залі бракує 66, 204 і 192 людино-годин — стільки ж, скільки нараховує сам розв'язувач. 9, 18 і 22 людини тоді працюють 100, 216 і 232 години понаднормово: правила магазину важать більше за понаднормові (Не вирішено). Той самий тиждень на 120 людей, спланований знову після того, як десять людей отримали вихідний: HiGHS 0,6–0,7 с, доведено (4 зміни додано і 4 прибрано; з 1,6× — 13 додано і 5 прибрано). Дві й три копії цього магазину (240 і 360 людей, 5 604 і 8 406 можливих змін) доведено найкращими за 2,0 і 2,7–3,2 с. Тож 100–120 людей уміщаються в 10 секунд із запасом, і розв'язувати для них у фоні не потрібно.
MyCity власника, тиждень 16 листопада 2026. На копії локальних даних власника, відновленій у власну базу цієї робочої копії, через справжній solve_week від імені власника, з повним набором: шість правил магазину, правила чотирьох посад (звичайні зміни, п'ять днів, вантажники 07:00–15:00, касир і менеджер весь день) і особисті — Степан noDays Пн, Ср, Чт, Сб, Нд. Застосовано 30 обмежень, 2 пропущено; 20 людей, 272 можливі зміни. Тижня ще не було; у попередньому було 90 змін.
| YALPS | HiGHS | |
|---|---|---|
| Виклик інструмента / розв'язувач | 127 мс / 74 мс | 198 мс / 143 мс |
| Результат | найкращий знайдений (звужений пошук) | доведено найкращий |
| Ціна | 22,86 | 22,86 |
| Зміни | 92: 45 × 07–15, 42 × 15–23, 3 × 17–23, 2 × 07–13 | ті самі |
| Порушені правила (скрипт) | немає | немає |
| Не закрито: каси, правила магазину, черговий менеджер, нікого на зміні | 0 | 0 |
| Понаднормові | немає | немає |
| Нижче договору | Алина −6 год, Дарья −4 год, Степан −4 год | те саме |
План той самий; HiGHS доводить, що він найкращий. Троє нижче договору — ті, кого стримують їхні власні правила (чотири дні й не раніше 14:00; лише вихідні; лише вівторок і п'ятниця). Дані власника не змінено: нічого не підтверджувалося, а копія — власна база цієї робочої копії.
Детермінованість не та сама. Бюджети YALPS — кроки. Обмеження HiGHS — час: тиждень, який він доводить, виходить однаковим щоразу, а тиждень, на якому він зупиняється (порожній тиждень Central Station вище), може вийти трохи іншим на повільнішій машині або завантаженішому API. План тоді каже «the best plan the solver found in the time it has», з розривом.
Обмеження людей з їхніх описів
Додано 20 жовтня 2026 за рішенням власника того ж дня. Перевірено на маленьких тижнях, порахованих уручну, і через справжній /mcp з Agentfy в пам'яті, один раз перевірено з локальним Agentfy; не розгорнуто; жоден керівник цим не користувався.
Магазин і кожна людина мають опис звичайними словами. Розв'язувач тексту не читає: агент читає описи й перетворює те, що в описі сказано прямо, на обмеження — разом зі словами, з яких його взято, і передає його в solve_week (а також в evaluate_request і decide_request, щоб заміна його дотримувалася). Керівник бачить на картці, до підтвердження, кожне застосоване обмеження з його джерелом і те, що агент залишив осторонь, бо жоден вид цього не виражає, — з причиною. Якщо агент прочитав хибно, виправити це може керівник: попросити ще раз без цього обмеження або з виправленим.
| Вид | Приклад в описі | Що робить розв'язувач |
|---|---|---|
Дні без роботи (noDays) | «Не працює по середах» | Жорстко: жодної нової зміни в ці дні тижня |
Лише ці дні (onlyDays) | «Лише вівторок і п'ятниця» | Жорстко: жодної нової зміни в інші дні тижня (з 10 листопада 2026, нижче) |
Одна ділянка (onlyArea) | «Лише в торговій залі» | Жорстко: жодної нової зміни на іншій ділянці; шаблон без ділянки стає цією ділянкою |
Години (timeWindow) | «Не раніше 10:00», «у п'ятницю йде о 15:00» | Жорстко: жодна нова зміна не починається раніше й не закінчується пізніше — щодня або в названі дні |
Години на день (maxHoursPerDay) | «Не більше 6 годин на день» | Жорстко: зміни людини за один день, без перерв, ніколи не дають більше |
Дні на тиждень (maxDaysPerWeek) | «П'ять змін на тиждень і два вихідні» (5) | Жорстко: жодної нової зміни в день понад це число днів зі зміною за тиждень (нижче) |
Побажання (prefer) | «Надає перевагу ранку», «краще без вихідних» | М'яко: зміна всупереч йому коштує 1,5 — ранок (зміна, що починається до 12:00), день і вечір, менше вихідних або названі дні |
Звичайні зміни (usualShifts) | «Звичайні зміни 07:00–15:00, 10:00–18:00» | Не обмеження: кожна пропонується на кожен день як шаблон, зокрема тому, хто ще не має змін, з 5 листопада 2026 — замість шаблонів магазину (нижче, перерви) |
З 30 жовтня 2026 кожен із цих видів може називати посаду замість людини: тоді він діє для кожного, хто її обіймає (нижче).
- Побажання лише розв'язує нічию. Його вага нижча за змінену зміну (40) і за години договору двогодинної зміни, тож заради нього розв'язувач ніколи не залишить касу без касира, нікого не залишить із недопрацюванням за договором і не посуне зміну, яка в тижні вже є. Воно обирає між змінами, однаково добрими для кас і договорів.
- Поточну зміну, що порушує жорстке обмеження, план прибирає, і попередження на картці її називає («Removes Maya Wed 08:00–16:00 (checkout): Maya: not on Wed (description)»). Зміна, яку план змінювати не може — на ній відкритий запит або це рядок керівника, а план робить керівник, — лишається, і попередження каже чому. Мовчки нічого не прибирається.
- Перевіряються по одному; непридатне зупиняє план (з 5 листопада 2026, нижче). Людина не з діючої команди магазину, людина, чиї зміни той, хто питає, планувати не може (рядок керівника для керівника), час, що не є часом, вікно, яке закінчується раніше за початок: розв'язувач нічого не планує й повертає агентові кожне таке обмеження з причиною, щоб той виправив його й надіслав знову в тому самому ході. До цього дня воно пропускалося з причиною, і план будувався без нього.
- Це не правила магазину. Ніде не зберігаються: це вибір керівника для цього плану, і під час підтвердження картки їх не перевіряють знову — знову перевіряються лише правила змін (години, відпочинок, права), як і раніше. Запис картки зберігає їх разом із планом. З 10 листопада 2026 правила, прочитані в описах, зберігаються поруч із ними (нижче); під час підтвердження картки їх, як і раніше, не перевіряють знову.
- Ті самі дані дають той самий тиждень, обмеження теж.
- Читає мовна модель, і вона може помилятися. 20 жовтня 2026, у робочій копії з локальним Agentfy, в опис Maya записали «Does not work on Wednesdays», і Daniel попросив чорновий тиждень: на картці було «Maya: not on Wed — from “Does not work on Wednesdays”», план прибрав її зміну в середу й сказав про це, а після підтвердження в чернетці в неї зміни в середу не було. У тій самій перевірці агент спершу взагалі не прочитав описів, а потім прочитав зайве: «веде п'ятничне приймання» — як «не по п'ятницях», «добре розбирається в збоях кас самообслуговування» — як «лише каса». Інструкції зробили суворішими, і ці два більше не з'являлися; «рідко раніше 14:00» усе одно стало жорстким «не раніше 14:00». Тому кожне обмеження стоїть на картці зі своїм джерелом.
- Описи враховуються щоразу, без прохання (власник, 20 жовтня 2026; опис магазину важить стільки ж, скільки опис людини, нижче). У першій перевірці агент часто пропускав їх, якщо керівник не казав «врахуй описи». Відтоді за цим стежить API, а не лише інструкції агента: якщо в людей, яких план охопив би, є описи, а виклик агента взагалі не несе обмежень, розв'язувач не планує. Він віддає агентові ці описи й опис магазину і просить знову — з обмеженнями, прочитаними в них, або з явним «жодних», якщо ніщо в них не обмежує, коли чи де хтось працює. «Люди, яких він спланував би» — за правами того, хто питає: для керівника працівники магазину, ніколи не опис іншого керівника чи його власний; для власника всі, керівники теж. Те саме під час оцінки й рішення запиту — для людей, яких може спланувати пошук заміни. Люди без описів плануються як раніше, без зайвого кроку.
- Картка показує, що описи прочитано. З обмеженнями кожне вказано, як вище, і рядок називає людей, чиї описи нічого не обмежують; із «жодних» картка каже «Descriptions read: nothing in them limits when or where people work», тож керівник бачить, що їх враховано.
- «Жодних» має показати, що описи прочитано. Описи приходять із коротким відбитком. Порожній список обмежень зараховується лише разом із цим відбитком; без нього розв'язувач знову віддає описи. У першій живій перевірці агент надіслав «жодних» у найпершому виклику, ще нічого не прочитавши, і картка стверджувала, що описи прочитано; це правило закриває прогалину.
- Ніколи з пам'яті (власник, 30 жовтня 2026). До цього дня непорожні обмеження приймалися без відбитка: вони називають людей і цитують їхні описи. У магазині власника Test наступне повідомлення («не бачу картки») змусило асистента компанії планувати тиждень заново: він уже не бачив свого попереднього виклику, передрукував обмеження з пам'яті без відбитка — посади, яких ні в кого немає, правило лише для однієї посади, без межі годин на день — і розв'язувач поставив одну людину сім днів поспіль. Відтоді будь-який список, порожній чи ні, зараховується лише з відбитком описів у їхньому теперішньому вигляді; без нього чи зі старим розв'язувач нічого не планує й знову віддає описи — з магазином, тижнем, описом кожної посади й тими, хто її обіймає, описами людей і магазину — і один рядок, чому: обмеження треба прочитати з цих описів у цьому ході. Інструкції асистентів кажуть те саме: щоразу, коли тиждень будується чи перебудовується, починати з описів, а якщо людина не побачила картки — вказати на неї, а не планувати знову.
- Читання, зроблене до правки, ловиться за відбитком: якщо опис відтоді змінився, розв'язувач віддає нові замість плану.
- Перевірено 20 жовтня 2026 у робочій копії з локальним Agentfy: у Маї «Does not work on Wednesdays», у Йонаса «Only on the checkout», решта описів демо як є. Деніел попросив «Plan the draft week starting 2026-11-02», не згадуючи описів. Агент викликав розв'язувач, отримав описи й викликав знову з обмеженнями. Картка перелічила «Maya: not on Wed», «Jonas: checkout only», «Leo: not before 14:00 (Mon–Fri)» із джерелами та «Descriptions read: nothing in the description of Chloe limits when or where they work». Запит власника для того самого магазину дав ті самі три й назвав Хлою та Ганну — керівницю — як нічим не обмежених. «Rarely before 14:00» у Лео все ще стало жорстким правилом усупереч інструкціям; картка це показує, і керівник виправляє.
Правила магазину з його опису
Додано 20 жовтня 2026, за рішенням власника того ж дня. Перевірено на маленьких тижнях, порахованих уручну, на демо-магазинах і через справжній /mcp з Agentfy в пам'яті, один раз перевірено з локальним Agentfy; не розгорнуто; жоден керівник цим не користувався.
Опис магазину читається так само, як опис людини: агент перетворює те, що він прямо каже про те, скільки людей потрібно магазину або скільки в нього кас, на правило магазину — зі словами, з яких його взято. Самого опису магазину досить, щоб розв'язувач віддав описи й попросив обмеження, як вище; якщо описів немає ніде, нічого не питається. Людина без опису ніколи не потрапляє до списку й нічого не потребує.
| Вид | Приклад в описі | Що робить розв'язувач |
|---|---|---|
Люди на ділянці (minStaff) | «У торговій залі завжди має бути одна людина», «щонайменше 3 людини з 17:00 до 20:00 у будні» | Щонайменше стільки на касі, у торговій залі або будь-де (черговий керівник теж рахується), у названі години й дні; увесь день, якщо години не названо |
Каси магазину (maxTills) | «4 каси» | Потрібних кас із погодинного навантаження ніколи не більше за це число |
Додаткові люди (extraStaff) | «На приймання у вівторок і п'ятницю 08:00–11:00 потрібна ще одна людина» | Стільки людей понад те, що потрібно інакше, у ці години й дні; будь-де, якщо ділянку не названо |
- Зважуються як каси, ніколи не відхиляються. Година нестачі за правилом коштує стільки ж, скільки каса-година без касира (10 000 за людино-годину), тому тиждень ніколи не стає неможливим. Те, чого бракує, перелічується з правилом і причиною — «1 person short in the store (Store: at least 3 people 17:00–20:00 (Mon–Fri)). Nobody can take it under the rules: …» — у попередженнях картки й у поясненні плану. Додаткові люди мають ту саму вагу: магазин каже, що вони йому потрібні, як навантаження каже про каси, а менша вага дозволила б переробці чи зміненій зміні переважити їх. Це наш вибір, на розгляд власника.
- Кожного рахують один раз. На кожну годину людей на касі потрібно стільки, скільки кас або скільки за правилом, що більше, плюс додаткові на касі; у залі — число за правилом плюс додаткові там; будь-де — більше з числа за правилом і двох попередніх, плюс додаткові. Людину, якої бракує, показують в одному місці: спершу на касах, потім на касі за правилом, потім у залі, потім будь-де. Шаблон без ділянки, коли залі потрібні люди, — це два варіанти, каса або зала, тож одна зміна ніколи не рахується двічі.
- Те, що вже є в даних магазину, — не правило. Години роботи (агент пропонує змінити години магазину), завантажений час без числа людей («пік 17–20»: щонайбільше порада щодо погодинного навантаження), форма зміни (шаблон). Години правила поза годинами роботи («приймання до відкриття») повертаються з причиною (до 5 листопада 2026 пропускалися); агент залишає правило осторонь і каже про це.
- На картці окремо від правил людей. Спершу правила магазину, кожне з джерелом; потім обмеження людей; потім те, що агент залишив осторонь, і чому; і рядок, якщо опис магазину нічого не задає («Descriptions read: nothing in the store's description sets how many people it needs.»).
- Запити теж. Під час оцінки запиту правила магазину враховуються: зміна, після якої їх бракує більше, зважується як зміна, після якої бракує касирів, і заміна, яку називає розв'язувач, їх дотримується.
- Перевірено 20 жовтня 2026 у робочій копії з локальним Agentfy, з описом Riverside «There must always be one person on the sales floor. 4 tills. At least 3 people from 17:00 to 20:00 on weekdays. Delivery on Tuesday and Friday mornings 08:00–11:00 needs one extra person.» Керівниця магазину попросила спланувати чорновий тиждень, не згадуючи описів. Картка першими перелічила «Store: at least 1 person on the sales floor 08:00–22:00», «Store: 4 tills at most», «Store: at least 3 people on the checkout 17:00–20:00 (Mon–Fri)» і «Store: 1 person extra 08:00–11:00 (Tue, Fri)», кожне з джерелом, потім обмеження людей. У зведенні було «Store's own rules: 32 → 14 person-hours short with the plan», а решта нестачі — у попередженнях із причиною. «Щонайменше 3 людини» агент прочитав як трьох на касі, а не будь-де — хибне читання, видне на картці, керівник його виправляє. Перевірку зроблено від імені Ганни, другої керівниці магазину: чат Деніела локальний Agentfy відхилив (409 на його участь у чаті) після скидання бази копії; до правил це стосунку не має.
Правила, що рахують посаду
Додано 30 жовтня 2026 на прохання власника того дня. Перевірено на малих тижнях, порахованих вручну, і через інструмент на магазині, який тест створює за зразком магазину власника Test; не перевірено з локальним Agentfy; не розгорнуто; жоден керівник ним не користувався.
Відколи команда має каталог посад з описами, опис посади може сказати, скільки її людей потрібно магазину: «щодня з 07:00 до 23:00 на касі щонайменше один касир», «Пн–Сб з 07:00 до 18:00 у магазині щонайменше один вантажник». Правило магазину (minStaff, extraStaff) може назвати посаду, і тоді враховуються лише ті, хто її обіймає — вантажник на касі не заміняє відсутнього касира. Правило може натомість рахувати лише керівників магазину. Те, що опис каже про кожного, хто обіймає посаду («зміна вантажника закінчується не пізніше 18:00»), лишається обмеженням людини — для кожного з них; з того ж дня це одне правило, яке називає посаду (нижче).
- Посада за назвою, у будь-якому регістрі, серед посад команди магазину. Посада, яку ніхто в команді не обіймає, повертається з причиною і переліком посад команди (до 5 листопада 2026 пропускалася).
- Формулювання з посадою. «Store: at least 1 Кассир on the checkout 07:00–23:00»; нестача: «no Грузчик in the store (…). Nobody can take it under the rules: …».
- Важить як каси, як і інші правила магазину, і рахується окремо від них: кожна посада й ділянка мають свій рахунок щогодини, який закривають лише зміни її людей на цій ділянці. Власні години під таку нестачу пропонуються лише їм.
- Скільки це коштує. На магазині за зразком Test (відкритий 07:00–23:00, одинадцять людей по 40 годин, без шаблонів, минулий тиждень власника як історія) тиждень зайняв 123 можливі зміни, 488 обмежень і близько 0,1 с розв'язування; демо-магазини, де таких правил немає, не змінилися (308–594 можливі зміни, до приблизно 3 с).
- Що вийшло на цьому магазині. Касир на касі щогодини, вантажник з понеділка по суботу 07:00–18:00 і жодної зміни вантажника пізніше, керівник на зміні щогодини, кожна зміна 8 годин, 32 з 55 змін еталонного тижня збіглися. Але не в усіх 5 змін і 2 вихідні: два вантажники по 40 годин не закривають 66 годин вантажника змінами, що закінчуються до 18:00, і оскільки правило важить більше за понаднормові, план дав кожному вантажникові шосту зміну; правило залу дало одній людині сім; а оскільки людина може працювати дві зміни на день (власник, 14 жовтня 2026), двоє отримали по дві зміни в один день. У тижні самого власника натомість понеділок і субота 15:00–18:00 лишаються без вантажника (див. Не вирішено).
Дні на тиждень
Додано 30 жовтня 2026 на прохання власника того дня. Перевірено на малих тижнях, порахованих вручну, через інструмент на магазині, який тест створює за зразком магазину власника Test, і на демо-магазинах; не перевірено з локальним Agentfy; не розгорнуто; жоден керівник цим не користувався.
30 жовтня 2026 власник попросив наступний тиждень Test, де в описі кожної посади сказано «Зміна 8 годин, п'ять змін на тиждень і два вихідні, не більше однієї зміни на день». Агент застосував правила посад і «не більше 8 годин на день», але виду для «п'яти змін на тиждень» не було, і воно зникло мовчки: у плані четверо людей працювали всі сім днів (по 16 годин понаднормово). Відтоді є обмеження людини, яке рахує дні зі зміною: maxDaysPerWeek, і агент передає «п'ять змін на тиждень і два вихідні» як 5 для кожного, хто обіймає посаду.
- Робочі дні, а не вихідні. Розв'язувач планує один тиждень і рахує те, що обирає сам: дні зі зміною. «Два вихідні» — це 7 − 2 = 5. Якщо рахувати вихідні, лишається неясним, чи є вихідним схвалений відгул або день поза частково планованим тижнем.
- Жорстко, як вихідний день. Жодна зміна, яку додає розв'язувач, не дає дня понад число. День рахується один раз, скільки б змін у ньому не було. Дні, у яких уже є зміна, яку план змінювати не може (заблокована, рядок керівника для керівника), рахуються першими; коли вони заповнюють число, в інший день нічого нового не пропонується, і план каже чому («Ann already works 5 days this week in shifts this plan may not change»). Якщо вони вже порушують правило, вони лишаються, і картка попереджає про кожен день понад число. У тижні, який план може змінювати, зайві дні прибираються.
- Назване в причинах. Година, яку ніхто не може взяти, називає того, хто вже відпрацював усе число днів («Ann already works 5 days that week: at most 5 (description)»).
- На Test. Магазин, створений як Test (відкритий 07:00–23:00, одинадцять людей на 40 год, тиждень власника з 26 жовтня як зразок, правила з картки агента, «не більше 8 годин на день» і 5 днів для всіх): 55 змін, ніхто не більше 5 днів і 40 годин, усі правила виконано, 29 з 55 змін зразка ті самі, 126 можливих змін, близько 0,15 с. План власника на 63 зміни на цьому магазині повторити не вдалося: без нового правила теж вийшло 55 змін без понаднормових — і з двома-трьома доданими шаблонами (402–552 можливі зміни), і з пошуком, одразу відправленим у занурення. Отже, понаднормові того плану прийшли з чогось, чого в нашій копії Test немає; щоб це знайти, потрібні картка власника й шаблони магазину.
- Скільки це коштує на великому тижні. У демо-магазинів такого правила немає, їхні плани не змінилися. З 5 днями для кожного працівника, як експеримент, усі вісім тижнів, як і раніше, закрито повністю, але наступний тиждень Central Station (584 можливі зміни) зайняв 172 секунди замість 0,9, а чернетка Riverside — 8,1 замість 0,7: звужений пошук не знаходить цілого плану, а повторні розв'язання занурення 8-секундною межею не обмежені (Не вирішено).
Одне правило на посаду і звичайні зміни
Додано 30 жовтня 2026 на прохання власника того дня. Перевірено на малих тижнях, порахованих вручну, і через інструмент на магазинах, які тест створює за зразком магазину власника Test, з 11 і з 21 людиною; не перевірено з локальним Agentfy; не розгорнуто; жоден керівник ним не користувався.
Власник запитав, чи отримає Test правильний тиждень, якщо людей стане на десять більше. Не отримав би. Агент писав «не більше 8 годин на день» і «5 днів на тиждень» окремо для кожної людини, тож 21 людині потрібно було близько 60 обмежень — більше за 50, які приймав виклик, і виклик відхилявся. А нові люди, які ще не мають змін у магазині без шаблонів, не мали своїх форм змін — лише власні години. З того дня обмеження людини може називати посаду замість людини, а звичайні зміни посади — окремий вид, usualShifts.
- Одне правило для всіх, хто обіймає посаду.
noDays,onlyArea,timeWindow,maxHoursPerDay,maxDaysPerWeek,preferіusualShiftsприймаютьpositionзамістьpersonId. Розв'язувач застосовує правило до кожного, хто обіймає посаду і чиї зміни той, хто питає, може планувати, і ні до кого більше. Картка показує його один раз: «every Кассир: at most 5 days a week». Посада, яку ніхто в команді не обіймає, або чиїх людей той, хто питає, не може планувати (рядки керівників для керівника), повертається з причиною (до 5 листопада 2026 ігнорувалася). Правила Test тепер — 21 обмеження за будь-якої кількості людей, а не 29 для 11 людей і близько 60 для 21. Власний опис людини, як і раніше, дає її власні обмеження. - До 100 обмежень у виклику (було 50), щоб магазин, люди якого мають власні описи, або агент, який усе ще пише правило на кожного, не отримував відмову через розмір.
- Звичайні зміни. «Звичайні зміни 07:00–15:00, 10:00–18:00» в описі посади стають
usualShifts {position, shifts ["07:00-15:00", "10:00-18:00"]}, або тим самим ізpersonIdз опису однієї людини. Розв'язувач пропонує кожну з них кожному, хто обіймає посаду, на кожен день — так само, як шаблон, з вагою шаблону, а не з додатковою ціною власних годин, — зокрема тому, хто ще не має змін. Це не обмеження: форми, в яких людина вже працює, лишаються можливими. Зміна поза годинами роботи або те, що не є часом, повертається з причиною (до 5 листопада 2026 ігнорувалася). - У кожної одне місце. Звичайна зміна йде в місце, яке називає правило. Інакше — в місце, яким людина обмежена, далі те, де вона працює найчастіше, далі те, де найчастіше працюють люди її посади і ролі, і лише потім — куди потрібно цього дня. Так звичайні зміни нового касира йдуть на касу, а нового заступника-керівника — на чергування. Одне місце на зміну, а не вибір із двох, лишає звичайну зміну однією можливою зміною, як шаблон із місцем. Саме це тримає магазин із 21 людини під межею.
- На Test. Магазин, створений за зразком Test (відкритий 07:00–23:00, без шаблонів, без погодинного навантаження), описи посад як на Test з їхніми звичайними змінами, у всіх 40 годин, тиждень власника з 26 жовтня — попередній тиждень для одинадцяти його людей. Десять нових ще не мають змін: три касири, старший касир-керівник, два вантажники, двоє в залі, заступник і заступник-керівник.
solve_weekвласника з правилами, які передав би агент (п'ять правил магазину і для кожної посади «не більше 8 годин на день», «5 днів на тиждень», 07:00–18:00 вантажників і звичайні зміни):
| 11 людей | 21 людина | 21 людина, без звичайних змін (до розподілу) | |
|---|---|---|---|
| Передано обмежень | 21 | 21 | 16 |
| Можливих змін | 237 | 461 | 406 |
| Час через інструмент | 0,3 с | 0,5 с | 0,4 с |
| Перенесено розподілом (нижче) | 6 | 35 | — |
| Крок пошуку | звужений | звужений | звужений |
| Змін | 55 | 105 | 105 |
| З них власні години | 0 | 0 | 50 |
| Понаднормові | немає | немає | немає |
| Менше за договір | ніхто | ніхто | ніхто |
| Вихідні | по 2 в усіх | по 2 в усіх | по 2 в усіх |
| Кожне правило виконано, по півгодинах | так | так | так |
| Збігається з еталонним тижнем | 31 з 55 | 33 з 55 | 31 з 55 |
- До розподілу. З 21 людиною план спершу ставив десять нових людей на будні, здебільшого 07:00–15:00: у понеділок о 07:00 починали десять людей, а ввечері працював один касир. Кожне правило виконувалося, але більше нічого не вимагалося. З того ж дня розв'язувач розподіляє людей по дню і тижню (нижче).
- Демо-магазини таких правил не передають, тож їхня модель не змінилася: 30 жовтня 2026 — ті самі плани, ті самі можливі зміни (308–594) і кроки пошуку, що й раніше, а час на 6–8 % більший, по одному прогону на одному ноутбуці (0,37–2,5 с). Тижні ще без змін — повільний випадок нижче — заново не вимірювалися; їхня модель теж не змінилася.
Розподіл по дню і тижню
Додано 30 жовтня 2026 за рішенням власника того дня. Перевірено на малих тижнях, порахованих вручну, через інструмент на магазинах, які тест створює за зразком магазину власника Test, з 11 і з 21 людиною, і на демо-магазинах; не перевірено з локальним Agentfy; не розгорнуто; жоден керівник ним не користувався.
З 21 людиною на Test кожне правило виконувалося, але десять нових людей скупчувалися вранці в будні (вище). З того дня розв'язувач розподіляє людей по дню і тижню. Кожна година роботи має справедливу частку людей тижня: договірні години людей, яких він планує, плюс зміни, які він не може змінювати, розподілені по годинах роботи пропорційно тому, скільки магазин відкритий у цю годину, — або, в магазині з погодинним навантаженням, пропорційно його звичайним чекам. План лишає якомога менше людино-годин нижче цих часток.
- В останню чергу. Розподіл нічого іншого не погіршує. Каси, правила магазину, черговий керівник, кожна закрита година роботи, понаднормові, договірні години, побажання, власні години і зміни тижня лишаються такими, якими їх зробив план; він лише вибирає між планами, рівними в усьому цьому. Це правило самого розв'язувача для кожного магазину: не обмеження, яке передає агент, і агентові нічого робити не потрібно.
- Як. Після пошуку нові зміни по одній переносяться — в іншу форму того ж дня або на вільний день людини, з тими самими годинами, — якщо це зменшує людино-години нижче справедливих часток і нічого вище не змінює. Зміна, яка вже є в тижні, не переноситься ніколи. Звичайна зміна в той день, коли людина працювала її минулого тижня, переноситься лише в порожнішу годину (з 5 листопада 2026; раніше — ніколи), а після цього нова зміна повертається до звичайної форми людини в її звичайний день скрізь, де нічого вище не змінюється і жодна година не стає порожнішою. Пояснення плану каже, скільки змін перенесено і скільки людино-годин було нижче часток до і після. Пошук заміни для запиту не розподіляє: він додає якомога менше.
- Чому не вага в програмі. Спершу спробували саме так: рядок на кожну годину роботи, «людей на зміні + нестача ≥ справедлива частка», з вагою нижче за все інше. Послаблена програма YALPS після цього застрягала. На тижні Test з 11 людьми 500 поворотів зайняли 9,6 секунди, а для розв'язання знадобилося 8000 поворотів і 215 секунд; без цих рядків вона розв'язується за 0,2 секунди. Тиждень із 21 людиною не розв'язався за кілька хвилин, і рядки на 4-годинні відрізки застрягали так само. Як прохід після пошуку він зайняв близько 0,1 секунди на тижні з 21 людиною і зберігає той самий порядок: нижче за все інше.
- На Test із 21 людиною. Людей на зміні в середньому за відрізками дня, до → після:
| 07–11 | 11–15 | 15–19 | 19–23 | |
|---|---|---|---|---|
| Пн | 10,5 → 6,5 | 12,5 → 8,5 | 4,5 → 8,5 | 2,5 → 6,5 |
| Вт | 12,8 → 5,8 | 15,5 → 8,5 | 7,3 → 9,3 | 4,5 → 6,5 |
| Ср | 13,8 → 6,8 | 16,5 → 8,5 | 7,3 → 8,3 | 4,5 → 6,5 |
| Чт | 13,8 → 6,8 | 16,5 → 8 | 7,3 → 8,3 | 4,5 → 7 |
| Пт | 10,8 → 6,8 | 13,5 → 8,5 | 5,3 → 8,3 | 2,5 → 6,5 |
| Сб | 3,3 → 7,3 | 4 → 8 | 2,8 → 7,8 | 2 → 7 |
| Нд | 3,3 → 7,3 | 4 → 8 | 2,8 → 7,8 | 2 → 7 |
Справедлива частка там — 7,5 людини щогодини (21 × 40 годин на 112 годин роботи). Розподіл переніс 35 змін. Усе інше збереглося: 105 змін, без понаднормових, ніхто не нижче договору, у кожного по два вихідні, кожне правило виконано по півгодинах, 461 можлива зміна, звужений пошук, 0,4 → 0,5 секунди через інструмент і 33 з 55 змін еталонного тижня збігаються (було 32). З одинадцятьма людьми зараз він переніс 6 змін, і збіжних змін еталонного тижня стало 31 замість 30.
- Демо-магазини. На жодному з восьми їхніх наступних і чернеткових тижнів розподіл не знайшов перенесення, яке зберегло б усе інше, тож їхні плани не змінилися; час той самий. У двох інших тижнях, які планують тести розв'язувача, він переніс 2 і 5 змін. Один тиждень ще без змін — повільний випадок нижче — зайняв 214 секунд без розподілу і 217 з ним (по одному прогону на одному ноутбуці).
Перерви закрито, і цифри, які агент цитує
Додано 5 листопада 2026 року, після того як магазин власника MyTest не отримав тижня, і за рішенням власника того ж дня: зміни можна зсувати або ставити внахлест, щоб перерву менеджера чи касира закривав інший. Перевірено на маленьких тижнях, розібраних вручну, на магазині, який тест пише як MyTest, і через інструмент на копії локальних даних власника; не перевірено з локальним Agentfy; не розгорнуто; жоден менеджер цим не користувався.
Власник попросив наступний тиждень для MyTest: відкритий 07:00–23:00, чотири менеджери на 40 годин, чотири касири на 40 і одна на 20, троє в залі, троє вантажників; щохвилини щонайменше один менеджер у магазині й один касир на касі; п’ять змін на тиждень. Агент відповів, що правила фізично нездійсненні, і порахував сам («160 год не вистачає менеджерам, потрібно 112»). Правила здійсненні: розв’язувач узагалі не склав план, а агент прочитав це як «неможливо».
- Чому плану не було. У магазині, де люди однакові — ті самі договори, ті самі шаблони, кожна зміна коштує стільки ж, — симплекс YALPS ходив по колу до своєї межі у 8 192 кроки («cycled», 6 секунд) і не повертав нічого. Правила проти цього в YALPS немає. Від того дня кожна вартість отримує свою добавку не більше мільйонної, значно меншу за найменшу вагу (0,01 за годину), щоразу ту саму: та сама послаблена задача розв’язується приблизно за 60 мілісекунд. Між планами однієї ціни добавка вирішує, який повернеться; у тестах розв’язувача одна така нічия повернулася іншим планом.
- Чому «8 годин на зміну» не сходилося. Восьмигодинні шаблони магазину задають перерву на певний час: уранці об 11:00, увечері о 18:00. Перерва з відомим початком вважається відсутністю, тож за двох змін на день менеджер на перерві залишає магазин без менеджера, двічі на день. Розрахунок власника «14 змін по 8 годин» перерв не враховує. З цими шаблонами, не більше 8 годин на день і п’ятьма днями розв’язувач довів, що 5,5 людино-години на тиждень лишаються неукомплектованими: нижня межа послабленої задачі дорівнює знайденому плану.
- Зміни внахлест на перерви. Де правило магазину рахує щохвилини власників посади або менеджерів (
minStaffзpositionабоmanagers), звичайна зміна, що передає наступній — 07:00–15:00 і 15:00–23:00, — пропонується як власні години з нахлестом на обидві перерви, кожна перерва всередині нахлесту: 07:00–15:30 з перервою о 15:00 і 14:30–23:00 з перервою о 14:30. Кожна — години звичайної зміни плюс її перерва, 8 відпрацьованих годин. Для цих людей вони замінюють звичайну зміну як є, перерву якої без початку підрахунок прийняв би за роботу. Зміна, що нікому не передає, без перерви або яка виходить за години роботи, лишається як є. - Звичайні зміни замість шаблонів магазину. Той, чий опис або опис посади називає звичайні зміни, отримує їх, а не шаблони магазину, — тож шістнадцятигодинний шаблон «повний день» більше не пропонується касиру з восьмигодинними звичайними змінами. Звичайна зміна менеджера, ділянки якої ніщо інше не задає, — чергування. На MyTest з новим формулюванням власника тиждень скоротився з 714 можливих змін (відмова: межа 600) до 189.
- Понаднормові знімаються після пошуку. Звужений пошук і занурення округлюють зміни вгору; на MyTest це дало понаднормові, які нікому не потрібні (24 з 20 годин, коли кожну годину було закрито). Для кожного, хто вище договору, розв’язувач потім у певному порядку пробує прибрати одну з його змін, дати їй іншу форму того ж дня або віддати її іншому в той самий день і години, який віддає те, що мав того дня, — і лишає зміну, тільки якщо весь план стає дешевшим і всіх правил дотримано. План каже, скільки він змінив.
- Цифри для цитати. У плані й у відповіді інструмента є
coverage: для кожного правила, що рахує посаду або менеджерів, і для чергового менеджера — скільки людино-годин воно вимагає за тиждень, скільки закриває план і скільки лишається, скільки людей може його закрити, їхні години за договорами разом і їхні години в плані. Де правило лишається неукомплектованим, пояснення каже це одним рядком: «Менеджер: the rules ask 112 person-hours this week; the plan covers 108, 4 short. The 4 people who may fill it have 160 contract hours together … — the hours are there, so what stays short comes from when they may work». Результат без плану каже на кожному відрізку «Not planned: no plan was made (…)» і «never call them impossible» замість «no manager can take it under the rules». Профілі агентів велять цитувати ці цифри й ніколи не рахувати самим (магазину — ревізія 16, власника — ревізія 12). - Того ж дня, після повного прогону тестів. Розбиття нічиїх вибирало між рівними планами довільно, і тиждень Test зберігав 10 змін еталонного тижня замість 30. Тепер варіанти, які зберігають тиждень таким, як люди його працюють, — зміна, що в ньому є, або власна форма людини в той день тижня, коли вона її працювала, — отримують менші добавки; тиждень, у якому нічого зберігати, отримує добавку як раніше. На Test зберігається 38 з 55 змін еталона за 11 людей і 36 за 21, і кожна година, як і раніше, не менше 60 % справедливої частки. Тести розв’язувача до того ж ганяли YALPS у сотні разів повільніше, ніж API (jest виконує код у пісочниці, де кожне звернення до глобального імені повільне, а YALPS звертається до нього на кожну клітинку матриці: послаблена задача MyTest там ішла 25–63 с проти 0,09 с), тож тести впиралися в обмеження за часом і давали інший результат; тепер вони запускають YALPS так само, як API. Перевірено на маленьких тижнях, розібраних вручну, і через інструмент на магазинах, які пише тест; не розгорнуто.
| MyTest, тиждень з 9 листопада 2026 | До | Після |
|---|---|---|
| Перше формулювання: менеджери й касири 07:00–23:00, п’ять днів, вантажники 07:00–15:00 | Немає плану («cycled»), 525 можливих змін, 6,3 с | Кожну хвилину закрито; один менеджер на 5 год вище договору (шістнадцятигодинні шаблони й перерви на певний час лишають мало іншого); 19 шістнадцятигодинних змін; 0,5–0,6 с |
| Те саме з «не більше 8 годин на день» | Немає плану («cycled») | 5,5 людино-години бракує, доведено; одна касирка на 17,5 год вище договору — правила магазину важать більше за понаднормові |
| Без обмежень узагалі | Відмова: 609 можливих змін за межі 600 | Так само; прогалини чергування тепер кажуть «Not planned» |
| Нове формулювання власника: звичайні зміни 07:00–15:00 і 15:00–23:00, можна внахлест | Відмова: 714 можливих змін | 72 зміни, менеджер і касир на касі щохвилини (перевірено похвилинно), ніхто вище договору, жодного шістнадцятигодинного дня, не більше п’яти днів у кожного; 189 можливих змін, 0,12–0,14 с через інструмент |
По одному прогону на одному ноутбуці, на копії локальних даних власника. Формулювання «Требуются на весь рабочий день магазина (7-23)» можна прочитати як шістнадцятигодинну зміну для кожного, а не одну людину в кожну мить; нове формулювання власника («Обычные смены: 07:00–15:00 и 15:00–23:00 … каждый день с 07:00 до 23:00 минимум один менеджер … можно сдвигать или ставить внахлёст») каже те, що малося на увазі.
Жодне обмеження не губиться мовчки
Додано 5 листопада 2026 року, після того як магазин власника MyCity отримав тиждень, що порушував описи восьми людей, за рішенням власника того самого дня. Перевірено на маленьких випадках, розібраних вручну, через інструмент на магазині, який тест пише як Test, і через інструмент на копії локальних даних власника; не перевірено з локальним Agentfy; не розгорнуто; жоден менеджер цим не користувався.
Власник попросив помічника компанії побудувати наступний тиждень для MyCity: 20 людей, у кожного опис, відкрито 07:00–23:00. Помічник надіслав правило кожної людини одразу і з людиною, і з її посадою. Розв'язувач сприйняв «людина або посада, не обидва» як причину відкинути кожне, перелічив їх на картці як пропущені й побудував тиждень без них: Андрей у неділю, коли він не працює, Роман у середу, Игорь у понеділок, Алина о 07:00, хоча починає не раніше 14:00, Максим 8 годин замість не більше 6, Полина в неділю, Евгений у четвер, Степан у суботу. «Доставка по вівторках і п'ятницях 07:00–11:00: потрібен один додатковий вантажник» прийшла без посади, і додатковим міг бути будь-хто. Правила магазину дотримано, усі особисті відкинуто, і сказано про це було лише на картці.
- Правило людини, у якої вказано й посаду, — правило цієї людини. Воно взяте з її опису, тож розв'язувач залишає людину, прибирає посаду й пише про це нотатку на картці та у відповіді («named both a person and the position “Менеджер”: read as Андрей's own rule, without the position»).
- Обмеження, яке розв'язувач не може застосувати, зупиняє план. Людина не з команди магазину, посада, яку ніхто не обіймає, рядок, який той, хто питає, не може планувати, час, що не є часом, правило магазину з людиною, вікно поза годинами роботи: розв'язувач нічого не планує й картки не робить. Він відповідає так само, як відповідь, що віддає описи (
needsConstraints, причинаrejected): кожне таке обмеження з його місцем у списку й причиною, описи та їхній відбиток, і вказівка виправити й викликати знову в тому самому ході. Те саме — під час оцінки й рішення заявки. - «Пропущено» — лише те, що агент залишив осторонь сам. Те, що сказано в описі, але не виражається жодним видом, — навичка, звичка, приймання до відкриття, — агент передає в
ignoredзі своєю причиною, і картка показує це як пропущене. Нічого з переданого як обмеження більше не пропускається. - Правило магазину, де названо посаду, її й несе. «Один додатковий вантажник» — це
extraStaffзpositionГрузчик; «два касири» —minStaffзpositionКассир. Коли правило магазину рахує будь-кого, а в його словах названо посаду команди, картка й відповідь отримують нотатку: чи не мають рахуватися лише її люди. Це збіг слів у самому правилі, не читання: «в зале» — місце, а не посада Зал, і його не чіпають. - Агентам сказано те саме, з прикладами (профіль магазину, ревізія 17, власника — 13): правило людини — лише з людиною («работает только в будни» →
noDayssat, sun; «не раньше 14:00» →timeWindowз 14:00), правило всіх людей посади — лише з посадою, а відповідьrejectedвиправляється й надсилається знову одразу.
На копії локальних даних власника, рішення власника на тиждень 9 листопада 2026, кожен набір обмежень надіслано так, як надіслав би агент. Правила магазину — шість, які прочитав помічник (менеджер щогодини, один касир на касі щогодини і два 17:00–21:00 у будні, одна людина в залі 09:00–21:00, 4 каси, один додатковий вантажник по вівторках і п'ятницях 07:00–11:00), зі звичайними змінами кожної посади.
| Тиждень 9 листопада 2026 | Що зробив розв'язувач | Особисті правила | Правила магазину | Години проти договорів | Час |
|---|---|---|---|---|---|
| Набір самого помічника (правило кожного з обома id) на чернетці, яку він записав | Прочитав кожне як правило людини, з нотаткою на кожне (13) і нотаткою, що додатковий вантажник рахував будь-кого | Усі 11 жорстких дотримано; 11 змін, що їх порушували, прибрано, 5 додано | Усі дотримано; нічого не коротше | Дев'ять людей нижче договору, від 4 до 12 годин: план змінює тиждень якомога менше, а зміна важить більше за години нижче договору | 0,2 с |
Те саме плюс одне зламане обмеження (noDays без днів) | Нічого не спланував; повернув його з місцем і причиною | — | — | — | менше 0,1 с |
| Виправлений набір, з порожнього тижня | Розв'язав, 92 зміни | Усі дотримано | Усі дотримано; нічого не коротше | Алина 24 з 30 (не більше чотирьох змін, жодної до 14:00, по 8 годин), Дарья і Степан 16 з 20 (по два дні змін по 8 годин) | 0,4 с |
| Те саме плюс «5 змін на тиждень» для кожної посади | Розв'язав, 92 зміни | Усі дотримано | Усі дотримано; нічого не коротше | Те саме | 0,5 с |
Один прогін кожного на одному ноутбуці, після #87 (YALPS у тестах — як в API). М'які побажання виконано там, де від них більше нічого не залежало (ранки Светланы, вечори Юлии). Чернетку й дані власника не змінювали: копія — власна база цієї робочої копії.
У межах часу інструмента. Agentfy дає виклику інструмента 15 секунд; бюджет розв'язувача — 10 секунд (рішення власника того самого дня, #87). YALPS зупиняє за часом лише точний пошук, а не послаблену задачу, тож занурення, що фіксує по одній частково вибраній зміні за раунд, могло тривати довше за бюджет. З цього дня звужений пошук може взяти не більше 40 % бюджету, а занурення фіксує зміни пачками, щойно по одній уже не вкластися в залишок, — не більше однієї на людину в пачці (на людину й день після бюджету), пачка ділиться навпіл, поки не дає відповіді, — і здається через 3 секунди після бюджету. На MyCity ці тижні займають набагато менше секунди, тож пачки тут — страховка; їх вимірювали до #87, коли тести запускали YALPS у багато разів повільніше, ніж API.
Кожен опис ураховано, одна зміна на день
Додано 5 листопада 2026 року за рішенням власника того самого дня, після другого тижня MyCity. Перевірено на маленьких тижнях, розібраних вручну, через інструмент на магазині, який тест пише як Test, і через інструмент на копії локальних даних власника; не перевірено з локальним Agentfy; не розгорнуто; жоден менеджер цим не користувався.
Після виправлення вище помічник компанії знову побудував тиждень MyCity. Він зберіг усі особисті правила і правила магазину, але не передав жодного правила з описів чотирьох посад — Менеджер, Кассир, Зал, Грузчик: ні звичайних змін 07:00–15:00 і 15:00–23:00, ні «вантажники працюють лише вранці, 07:00–15:00», ні «5 змін на тиждень, 2 вихідні». Розв'язувач тоді допускав до трьох змін на день, і багато хто отримав 07:00–15:00 і 15:00–23:00 одного дня — 16 годин — і виконав договір за три довгі дні; вантажники працювали ввечері; менеджери стояли в залі, а години чергового менеджера лишалися відкритими; а тиждень був настільки вільним, що власні години довелося відкинути, щоб вкластися в межу розміру розв'язувача.
- Кожен виданий опис рахується. Відповідь, що передає описи, перелічує опис магазину, кожної посади (того, кого план охоплює) і кожної людини. Тепер виклик має врахувати кожен: магазину — правилом без людини, посади — правилом із цією посадою, людини — правилом або записом в
ignoredіз цією людиною, — або назвати його в новому спискуnoConstraints({about: "store"},{about: "position", position},{about: "person", personId}, з коротким поясненням) для опису, в якому немає нічого, що виражає будь-який вид. Інакше нічого не розв'язується і картка не створюється: відповідь —needsConstraintsз причиноюincompleteі списком неврахованого (incomplete: магазин, посади, люди, кожне зі своїми словами), щоб прочитати і викликати знову в тому самому ході. Те саме — під час оцінки й рішення запиту. - Правило магазину, що рахує посаду, належить магазину, коли це слова магазину. «Один додатковий вантажник» рахує вантажників, але взятий з опису магазину, тому він не враховує власний опис посади Грузчик. Розв'язувач розрізняє їх за
sourceправила: опис, з яким у нього більше спільних слів, а за рівності — магазину. Збіг слів, не читання. - Для людей — прагматично. Опис лише з навичками («досвідчений, водить навантажувач») враховується через
noConstraintsабоignored; правило йому не потрібне. - Одна зміна на день за замовчуванням. Розв'язувач дає людині не більше однієї зміни на день. Лише там, де опис магазину, посади чи людини каже, що розділені зміни допустимі, агент передає новий вид
splitShifts(count 2 або 3; без людини — для магазину,positionабо людина) — тоді до стількох на день. Дві зміни, що торкаються або перетинаються, 07:00–15:00 і 15:00–23:00, — це один 16-годинний день і не допускаються ніколи, з розділеними змінами чи без. Зміна, яку план змінити не може, однаково рахується в цьому дні. День, у якому тиждень уже має більше змін, зберігає одну, і картка каже чому («one shift a day — no description allows split shifts»): у чернетці Riverside з демо-даних розділений понеділок Sara Lind (12:00–14:00 і 18:00–20:00) втрачає 12:00–14:00, коли розв'язувач планує цей тиждень, — перевірено один раз, від імені Daniel, на демо-даних у базі цієї робочої копії. Редактор розкладу вручну не змінився: до трьох без перетинів (Екрани). - Менеджер, що закриває години роботи, стоїть черговим. Звичайні зміни менеджера пропонуються як зміни чергового менеджера — і, якщо досі на тижні менеджер стояв в іншій зоні, ще й у цій зоні, на випадок, коли чергує вже інший менеджер. Власні години, вирізані під «менеджер у магазині» (правило, що рахує менеджерів будь-де), — зміни чергового менеджера, а не відкриті, що стали касою чи залом. Чому менеджери MyCity були в залі: без звичайних змін і шаблонів єдиними формами для цього правила були власні години без зони, і вони ставали змінами в залі чи на касі, а власні години чергового йшли пізніше проти межі розміру і відкидалися.
- «Один додатковий» посади — це на одного більше, ніж один.
extraStaff, що рахує посаду, у години, де не дієminStaffцієї посади, тепер рахується понад одну людину цієї посади, як правило магазину за замовчуванням — одна людина: «один додатковий вантажник по вівторках і п'ятницях 07:00–11:00» — тоді два вантажники. Раніше — один. Наше прочитання, на перегляд власнику. - Агентам сказано те саме (профіль магазину, ревізія 18, власника — 14): опис кожної посади дає свої правила, щоразу, з посадами MyCity як прикладом; що означає
incomplete;noConstraints; одна зміна на день.
На копії локальних даних власника — solve_week власника на тиждень 9 листопада 2026, так, як його викликає агент. Кожен результат перевірено по людях скриптом за самими змінами, а не за зведенням розв'язувача.
| Тиждень 9 листопада 2026 | Що зробив розв'язувач | Перевірено по людях | Години проти договорів | Час |
|---|---|---|---|---|
| Власний набір помічника (лише правила магазину й особисті) | Нічого не спланував; incomplete назвав чотири посади і вісім людей, чиї описи не врахувало жодне правило чи запис | — | — | — |
| Повний набір, на чернетці, яку написав помічник (98 змін, із 16-годинними днями) | Розв'язано: 17 додано, 30 прибрано, 68 залишено; 374 можливі зміни, жодна не відкинута | По одній зміні на день у кожного; вантажники лише 07:00–15:00; два й більше вантажників 07:00–11:00 у вівторок і п'ятницю; черговий менеджер щохвилини 07:00–23:00; касир на касі щохвилини, два 17:00–21:00 у будні; хтось у залі 09:00–21:00; усі особисті правила; ніде менше 11 год відпочинку; ніхто понад договір | Дев'ять людей нижче договору, на 6–16 годин: план змінює чернетку якомога менше, а зміна важить більше за години нижче договору | 0,13 с |
| Повний набір, з порожнього тижня | Розв'язано: 89 змін; 374 можливі зміни, жодна не відкинута; 4 із власними годинами (6-годинні дні Максима) | Ті самі перевірки, усі виконано | Вера 24 з 40, Алина 24 з 30, Дарья і Степан 16 з 20, Максим 24 з 30; решта за договором | 0,2 с |
По одному запуску на одному ноутбуці. Пошук — звужений (тиждень завеликий, щоб довести найкращий план), тож 24 години (Вера) — те, що він знайшов, а не доведена межа. Перерви: у змін цих посад їх немає, тому похвилинні перевірки рахують кожну зміну робочою. Чернетку й дані власника не змінено: копія — власна база цієї робочої копії, а запуск з порожнього тижня спорожнив чернетку цієї копії і потім відновив її.
Правила з описів зберігаються поруч із ними
Додано 10 листопада 2026 на прохання власника того дня. Перевірено на маленьких випадках, розібраних вручну, через інструменти на магазині, створеному тестом, і через інструменти на копії локальних даних власника (MyMega і MyCity) зі скриптом замість асистента; з живим агентом не перевірено; не розгорнуто; жоден керівник цим не користувався.
Асистент компанії не зміг побудувати тиждень для MyMega — магазину на 110 людей (8 менеджерів, 40 касирів, 42 у залі, 20 вантажників), у 47 із них в описі є особисті правила. Кожен план вимагав знову прочитати всі описи й одним викликом надіслати кожне правило — і позначку «нічого» для кожного іншого опису. На 20 людях він ледве впорався, і одного разу «лише вівторок і п'ятниця» загубила суботу; на 110 він здався. Сам розв'язувач планує такий магазин приблизно за секунду (HiGHS), а описи змінюються рідко. Тож прочитане тепер зберігається.
- Кожен опис зберігає правила, прочитані в ньому: магазину, кожної посади й кожної людини. Це обмеження видів, описаних вище, кожне зі словами, з яких його взято, — або «правил немає» з причиною («лише навички»), — разом із відбитком тексту, з якого їх прочитали. Правила, чий відбиток не збігається з нинішнім текстом опису, застаріли.
- Асистент зберігає їх через
save_rules, до 20 описів за виклик. Кожен запис перевіряється так само, як обмеження, передане вsolve_week, — людина й посада відомі, поля кожного виду, години роботи — і зберігається, замінюючи попереднє, або повертається з причиною. Правило магазину, чиї слова називають посаду, яку воно не рахує, зберігається з приміткою. Відповідь перелічує збережене й наступні описи без свіжих правил, з їхнім текстом. - Права — як на зміну опису: магазину — його керівники й власник; людини — власник і, для працівників магазину, його керівники; посади — лише власник, бо посади веде власник.
- Без картки. Правила беруться з описів, які людина вже підтвердила, тож збереження не просить підтвердження; натомість їх видно — у застосунку під кожним описом, лише для читання, і на картці тижня, як і раніше, кожне зі своїм джерелом. Це наш вибір, на перевірку власнику.
solve_weekними користується. Якщо викликати його без обмежень і в кожного опису, який він має врахувати, є свіжі правила, він одразу планує з ними. Інакше він відповідаєneedsRulesлише з описами без свіжих правил — ще не прочитаними, застарілими або вже не придатними в збереженому вигляді (наприклад, зсунулися години роботи) — не більше 20 за раз, і нічого не планує, доки їх не збережуть.evaluate_requestіdecide_requestроблять те саме.- Змінений опис читається знову, а не виводиться сам. В API немає мовної моделі: коли опис змінюється — у застосунку чи через картку — його правила лише позначаються застарілими, і наступний план просить асистента прочитати цей один опис.
- Керівник не може зберегти правила посади. У його
needsRulesправила посади позначено як справу власника; лише якщо керівник прямо скаже будувати без них, асистент викликає знову зwithoutRules, і картка називає, що лишилося без правил. - Список, переданий вручну, лишається — як заміна на один виклик, з колишніми перевірками: відбиток переданих описів, кожне обмеження придатне, кожен опис ураховано.
- «Лише вівторок і п'ятниця» має свій вид,
onlyDays: дні, у які людина працює; розв'язувач читає це як відсутність змін в інші п'ять. Асистентам сказано користуватися ним, а не перелічувати п'ять вихідних, і перевіряти, що дні разом дають 7, коли дні все ж перелічуються. - Агентам сказано те саме (профіль магазину, ревізія 19, власника — 15): викликати без обмежень, зберігати пачками те, що перелічує
needsRules, ніколи не передруковувати збережені правила.
На копії локальних даних власника, від імені власника (команда MyDemo), на тиждень із 16 листопада 2026. Асистента грав скрипт: він читав кожен опис за фіксованими фразами («не работает по средам» → noDays середа, «только вторник и пятница» → onlyDays вівторок і п'ятниця, лише навичка → правил немає) і викликав справжні інструменти. Потім кожен план перевірявся для кожної людини скриптом — за самими змінами, а не за зведенням розв'язувача.
| Магазин | Виклики | Найбільший виклик | Найбільша відповідь до плану | План | Перевірено для кожної людини |
|---|---|---|---|---|---|
| MyMega, 110 людей | solve_week → needsRules (20 із 115 у списку); 6 × save_rules (115 описів: 52 з правилами, 63 з «правил немає»); solve_week | 6,2 КБ | 10,1 КБ | 508 змін за 0,7 с; жодної години нестачі — ні на касах, ні за правилами магазину, ні за черговим менеджером, ні за «хоч хтось на зміні» | 296 особистих правил і правил посад, жодне не порушено; у кожного одна зміна на день; кожне правило minStaff виконано в кожну чверть години |
| MyCity, 20 людей | solve_week → needsRules (20 із 21; 4 посади вже збережено для MyMega — компанія та сама); 2 × save_rules; solve_week | 4,9 КБ | 7,2 КБ | 92 зміни за 0,18 с; нестачі немає | 57 правил, жодне не порушено — Степан лише у вівторок і п'ятницю, Дарья лише на вихідних; у кожного одна зміна на день |
Потім опис однієї людини в MyMega змінили так, як це робить застосунок (додали речення): solve_week відповів needsRules лише з цією людиною, як застарілою, і 114 свіжими; збереження зайняло один виклик у 0,4 КБ. Власна відповідь плану велика — 188 КБ для MyMega, майже все це 508 змін, які він додає; так було й раніше, тут це не змінювалося. По одному прогону на одному ноутбуці; дані власника не зачеплено: копія — власна база цієї робочої копії.
Кожну годину роботи закрито
Додано 28 жовтня 2026 за рішенням власника того ж дня. Перевірено на маленьких тижнях, порахованих вручну, на демо-магазинах із початкових даних і через solve_week на магазині, який створює тест; з локальним Agentfy не перевірено; не розгорнуто; жоден керівник цим не користувався.
До цього розв'язувач закривав лише те, про що йому сказано: каси за погодинним навантаженням, чергового керівника й правила з опису магазину. Новий магазин без навантаження й без опису не просив нічого, і ніщо не вимагало, щоб у годину роботи хтось був. 28 жовтня 2026 власник попросив наступний тиждень TestStore (відкритий 09:00–18:00, десять людей по 40 годин, без навантаження): усі зміни були за шаблоном 09:00–17:00, і з 17:00 до 18:00 не було нікого, щодня. Тепер у кожного магазину є правило за замовчуванням: хоча б одна людина на зміні щогодини роботи кожного дня — з навантаженням і описом чи без них.
- Важить як каси. Година без людей коштує стільки ж, скільки каса-година без касира (10 000), тож вона йде раніше за переробки, змінені зміни й години за договором. Де хтось може її взяти, він її отримує, навіть із переробкою, і переробка — попередження на картці.
- Рахується разом з іншими правилами, а не понад них. На зміні рахується будь-хто, черговий керівник теж. Де каси вже просять людину, це вона і є. Власне правило з опису бере більше число, а не суму: «у магазині завжди не менше двох» — це двоє, а не троє. Правило за замовчуванням — не обмеження, прочитане в описі, тому картка не перелічує його серед них.
- Прогалину закривають власні години. Де жоден шаблон не доходить до закриття, розв'язувач сам задає години зміни (власні години): для години перед закриттям — найкоротшу власну зміну до закриття (14:00–18:00), а з цього дня й зміну звичної тривалості людини (09:30–18:00 за договору на 40 годин і 30-хвилинної перерви магазину). Шаблон, який робить те саме, лишається.
- Пів години — це половина. У годину, коли магазин відкритий лише частково — зачиняється о 17:30, — правило просить людину на цю половину: решту часу там нікого бути не може.
- Що лишається порожнім, названо, з причиною. План перелічує кожен відрізок робочого часу, де на зміні нікого немає (
nobodyOnShift), з точністю до хвилини й без перерви з відомим початком. Попередження картки кажуть «Fri 17:00–18:00: nobody on shift — Nobody can take it under the rules: Ann has a day off; …», зведення — «Every opening hour has someone on shift.» або скільки годин лишається порожніми, зараз і з планом, і пояснення плану — те саме. Ці години входять і в людино-години нестачі за правилами магазину (staffShort). - Запити теж. Зміна, яка лишає годину роботи без людей, зважується як зміна, що лишає каси без касирів: розв'язувач шукає заміну в цей день і пише «It leaves Fri 09:00–18:00 with nobody on shift», коли взяти нікому.
- Перевірено 28 жовтня 2026 на тижні, влаштованому як у TestStore (відкритий 09:00–18:00, десять людей по 40 годин, один шаблон 09:00–17:00 з 30-хвилинною перервою, без навантаження, без опису), кодом самого розв'язувача. Без правила: усі зміни 09:00–17:00 і нікого з 17:00 до 18:00 жодного дня, як це побачив власник. З правилом: хтось на зміні щогодини з 09:00 до 18:00 усі сім днів, 7 із 62 змін — власні години до 18:00 («covers 17:00–18:00 short in the store, which no template does»); 210 можливих змін, менше 0,1 секунди у власному тесті розв'язувача; через інструмент, на магазині, який збирає тест, ті самі 210 зайняли 2,4 секунди — шлях пошуку залежить від порядку людей, і межу у 8 секунд не досягнуто. Але вісім із десяти людей виходять на 5 годин понад договір і одна — на 2 години: 42 години переробки там, де є план без неї. Точний пошук не знаходить для цього тижня цілого плану, а останній засіб, занурення, завжди округлює частково дану зміну вгору, тож 5⅓ зміни в кожного (40 ÷ 7,5) стають 6. Так було й до правила (50 годин на тому ж тижні без нього), і це не вирішено. Той самий тиждень перевіряє тест — і зібраний через власні маршрути API, записаний у чернетку карткою й прочитаний назад через рядки покриття розкладу.
Власні години
Додано 26 жовтня 2026 за рішенням власника того ж дня. Перевірено на маленьких тижнях, порахованих вручну, на демо-магазинах із початкових даних і через solve_week з Agentfy в пам'яті; з локальним Agentfy не перевірено; не розгорнуто; жоден керівник цим не користувався.
До цього розв'язувач обирав лише з готових форм: шаблонів магазину і змін, які люди вже працюють. Відрізок, який не покривав жоден шаблон, лишався без людей («No checkout or open-area template covers 12:00–16:00»); людина, якій опис дозволяє лише 12:00–18:00, не отримувала нової зміни, якщо жоден шаблон не вміщався в це вікно, — опис міг лише прибрати форми, але не створити нову; а магазину без шаблонів і без історії не було з чого будувати. Тепер, коли шаблони і звичні зміни не дають придатної зміни, розв'язувач сам задає години — за описом людини, її звичними змінами, договором, годинами роботи магазину і годинами, яких бракує.
- Де він їх робить. Для кожної людини і кожного дня, в який їй можна дати нову зміну, у двох випадках:
- Людині цього дня нічого іншого не підходить — кожен шаблон і кожна звична зміна порушують одне з її обмежень або правило, або в магазину їх немає. Тоді її вікно з опису або години роботи магазину, обрізані до її звичної тривалості: «fits Maya's 12:00–18:00».
- Відрізку потрібно більше людей, ніж шаблони і звичні зміни взагалі могли б туди поставити — на касах, за власними правилами магазину або як черговий керівник. Тоді цей відрізок, обрізаний за вікном і тривалостями людини: «covers 12:00–16:00 short on checkout, which no template does».
- Тривалість. Від 4 до 10 годин від початку до кінця, по цілих або половинних годинах; коротше — лише якщо менше лишає власне вікно людини або її години на день. Звична тривалість — медіана змін людини цього і минулого тижня; без них — тижневі години договору на 5 днів; без договору — 8 годин. Наш вибір, на перевірку власнику.
- Перерва. Правових правил про перерви в Shiffty немає, тож зміна з власними годинами отримує перерву, яку власні шаблони і зміни магазину дають зміні такої тривалості, — перерву найдовшої з них, що не довша, — без початку перерви. Шестигодинна зміна в магазині, де шаблони по 8 годин з перервою 30 хвилин, перерви не отримує.
- Зміна, прибрана через опис, замінюється, а не просто зникає. У тижні, де вже є зміни, нова зміна коштує зміни (40) — більше, ніж години договору, які дає одна зміна, — тож раніше людина, чиї зміни план прибирав через її опис, просто втрачала ці години. З 26 жовтня 2026 нова зміна в день, коли план прибирає зміну цієї людини через її опис, стає на її місце і не рахується ще однією зміною; для шаблонів так само.
- Усі жорсткі правила тримаються. Власні години проходять через ті самі правила, що й будь-яка інша форма: години роботи, одна зміна на день (до 3 з перервою між ними там, де розділені зміни допустимі), вихідні, 11 год відпочинку, обмеження людини, ділянка «черговий керівник» лише для керівників.
- Спершу шаблони. Зміна з власними годинами коштує 3. Це вище за побажання (1,5), тож шаблон ніколи не поступається заради побажання; нижче за години договору найкоротшої такої зміни (4 години по 1), тож там, де більше нічого не підходить, вони все ж можуть заповнити договір у новому тижні; і значно нижче за змінену зміну (40), годину понаднормової роботи (100) і годину нестачі (10 000). Тому шаблон або звична зміна, що роблять ту саму роботу, лишаються, а відрізок, який можуть закрити лише власні години, закривається. Нижче за змінену зміну ми поставили навмисно: при 40 і вище власні години ніколи не заповнили б договір, і людина на кшталт Майї вище досі нічого б не отримала. Наш вибір, на перевірку власнику.
- Межа розміру. Власні години йдуть останніми проти межі можливих змін (600 з YALPS; 10 000 з HiGHS з 10 листопада 2026, вище): не більше 4 на людину на день, жодна не збігається з шаблоном або звичною зміною, і лише в місці, яке лишають шаблони і звичні зміни. Що не вміщається, відкидається першим, і план каже скільки; усі шаблони і звичні зміни лишаються.
- Видно. План перелічує кожну зміну з власними годинами і чому (
customHours); на картці рядок такої зміни закінчується «Custom hours: fits Maya's 12:00–18:00», а підсумок їх рахує. Заміна за запитом теж це каже. Відрізок, що все одно лишився без людей, пояснює, чому і власні години його не закрили, — відпочинок, вихідний, опис, години на день або межа розміру, — а не лише «немає шаблону». - Перевірено 26 жовтня 2026 через
solve_weekпо справжньому/mcpз Agentfy в пам'яті (модель грає тест), на чорновому тижні Riverside Market із початкових даних від імені Даніеля, з Майєю, обмеженою 10:00–15:00 (жоден шаблон магазину — 08:00–16:00, 12:00–20:00, 16:00–22:00 — у це вікно не вміщається). До: план прибирав чотири її зміни, що порушували вікно, і нічого не давав натомість (0 з 32 год), а 43 з 63 каса-годин лишалися без касира, кожна з «No checkout or open-area template covers …». Після: чотири зміни 10:00–15:00 на місці прибраних, кожна на картці як «Custom hours: fits Maya's 10:00–15:00» (20 з 32 год), і жодної каса-години без касира; 455 можливих змін, менше секунди. Ту саму перевірку залишено тестом.
Як він зважує запит
- Запит, який не чекає на рішення цього керівника, рекомендації не отримує.
- Зміна, яка порушує жорстке правило — власні перевірки запитів в API або менше 11 год відпочинку, — відхилити.
- Зміна, яка лишає каси чи чергового керівника в гіршому становищі, ніж зараз, або (з 28 жовтня 2026) годину роботи без людей на зміні: розв'язувач шукає заміну в дні запиту, додаючи якомога менше змін і ніколи не рухаючи чужі. Якщо заміна закриває прогалину — схвалити й назвати заміну; якщо ні — відхилити й назвати години й чому їх ніхто не може взяти.
- Інакше схвалити; переробку зачеплених людей зазначено.
Рекомендація — розв'язувача; рішення — керівника.
Обмеження
Цей розділ — про YALPS, рушій до 10 листопада 2026 і запасний відтоді; обмеження HiGHS — вище.
YALPS маленький навмисно. Автори розраховують його на маленькі задачі: за їхнім власним орієнтиром — не більше кількох тисяч змінних і обмежень і не більше кількох сотень цілочислових рішень («так/ні»); усю задачу він тримає в пам'яті (YALPS, прочитано 19 жовтня 2026).
Що ми виміряли 19 жовтня 2026 на демо-компанії з початкових даних, на одному ноутбуці розробника, тестами API:
- Тиждень демо-магазину — від 224 до 398 можливих змін, у межах кількох сотень.
- Точний пошук YALPS сам по собі такого тижня не розв'язує: на вигаданому тижні такого розміру (8 людей, 4 шаблони, 224 можливі зміни) він за 20 секунд не знайшов жодного плану.
- Тому розв'язувач шукає кроками: спершу точний пошук із маленьким бюджетом (маленькі тижні розв'язуються тут, і тоді доведено, що план найкращий за цих ваг; з 26 жовтня 2026 — лише для тижнів до 200 можливих змін, нижче); інакше послаблена задача, де зміну можна «дати частково», — вона займає мілісекунди, — а потім точний пошук лише серед кількох десятків змін, які вона використала; в крайньому разі «занурення» — закріпити найбільш «дану» зміну й розв'язати знову. План із пізніх кроків — найкращий знайдений, але не доведено найкращий, і план так і каже.
- З цим наступний і чорновий тижні кожного з чотирьох демо-магазинів зайняли приблизно від 0,2 до 1,1 секунди.
Виміряно знову 26 жовтня 2026, з власними годинами, тим самим способом: тиждень демо-магазину тепер — від 266 до 594 можливих змін, усі в межах, і відкидати власні години не довелося жодного разу. Перший крок — точний пошук у 24 кроки — жодного з них більше не розв'язував і коштував від 0,5 до 8,2 секунди, бо кожен його крок розв'язує всю послаблену задачу, тепер більшу; на чорновому тижні Central Station він сам з'їв усю межу у 8 секунд. Тому з цього дня він запускається лише для тижнів до 200 можливих змін, а точний пошук серед змін, використаних послабленою задачею, має бюджет 512 кроків замість 4096 (ті займали до 6,5 секунди). На всіх восьми тижнях це дало ті самі плани, що й повні бюджети, за 0,2–1,9 секунди на виклик. Ті самі тижні до власних годин: від 224 до 398 можливих змін, 0,2–1,1 секунди.
Чи вміщається тиждень справжнього магазину? З YALPS невеликого — так: у демо-магазинах від 7 до 14 людей і 3–4 шаблони. Магазин зі значно більшою кількістю людей чи шаблонів перевищить поріг у 600 можливих змін, і YALPS тоді відмовить із цією причиною, а не намагатиметься; магазин на кшталт MyCity на 50 людей — це вже 1 180. З HiGHS магазини на 50–120 людей на кшталт MyCity плануються приблизно за секунду, а на 360 — приблизно за три (вище). Test із 21 людиною, без шаблонів і зі звичайними змінами його посад — це 461 (вище); кожен шаблон додає одну можливу зміну на людину і день (дві, де він не має місця, а залу потрібні люди), тож кілька шаблонів зверху перевищили б 600 — не виміряно. Це наші демо-дані, а не дані клієнта; що потрібно справжньому магазину, невідомо.
Що показують демо-дані. До 26 жовтня 2026 у демо-тижнях багато каса-годин лишалися без касира і з планом, і без нього — від 14 до 73 за тиждень із планом, — бо демо-магазини не мають касового шаблону чи касової звички на багато годин (наприклад, ранок у Riverside Market). З власними годинами план закриває кожну каса-годину всіх восьми тижнів. Для цього він сильно їх змінює — до 24 доданих і 20 прибраних змін у Central Station, — здебільшого переводячи людей зі змін у залі, яких у демо не вимагає жодне правило, на касові зміни з власними годинами. Це відповідає порядку, який задав власник (спершу каси); чи має план змінювати так багато — вирішує власник (нижче).
Розв'язувач — це MCP-сервер?
Ні. Розв'язувач — частина API. MCP — відкритий стандарт підключення ШІ-застосунків до зовнішніх систем — спосіб, яким Shiffty дає свої інструменти агентові, і чи він потрібен, залежить від того, де працює агент:
| Де працює агент | MCP? |
|---|---|
| Усередині нашого власного API | Не потрібен. Інструменти описуються просто у виклику моделі: менше ланок, простіші права, простіше розділення між магазинами. |
| На зовнішній платформі для агентів — Agentfy. Вибрано 5 жовтня 2026. | Так. Це стандартний спосіб під'єднати до такої платформи наші інструменти. |
| У власному ШІ-асистенті керівника | Так. Асистент під'єднується до наших інструментів так само. |
Вирішено 5 жовтня 2026: агент працює на Agentfy, тож інструменти доходять до нього через один MCP-сервер, який запускає Shiffty; розв'язувач стоїть за цим сервером. Платформа обмежує час виклику інструмента. 2 жовтня ми очікували, що тому побудову графіка запускатимуть із застосунку; виміряний вище час робить виклик інструмента можливим для демо-магазинів, а власна межа розв'язувача з 5 листопада 2026 — 10 секунд, у межах 15 секунд, які Agentfy дає виклику інструмента (вище).
Який розв'язувач
З 10 листопада 2026: HiGHS, на прохання власника того дня, створено того самого дня (вище); YALPS лишається запасним (SOLVER_ENGINE=yalps). Чи замінить HiGHS YALPS остаточно — приймати власникові (Не вирішено).
Для першої версії: YALPS — вирішено 2 жовтня 2026, створено 19 жовтня 2026. YALPS — розв'язувач лінійних і змішано-цілочислових задач на TypeScript; він працює всередині API на NestJS, тож першій версії не потрібні ні друга мова, ні окремий сервіс. Перевірено 19 жовтня 2026: пакет npm yalps, версія 0.6.4 (24 грудня 2025), ліцензія MIT; репозиторій переїхав з Ivordir/YALPS до IanManske/YALPS; автори підтримують його лише виправленнями й оновленнями безпеки, нових можливостей не планують.
За інтерфейсом. Тиждень описано як нейтральну змішано-цілочислову задачу; YALPS і, з 10 листопада 2026, HiGHS (як highs-js, у Node) — два адаптери до неї. Google OR-Tools (окремим сервісом) міг би стати на їхнє місце, не змінюючи ні моделі, ні інструментів, ні застосунку.
Пізніше, найімовірніше: Google OR-Tools, запущений як невеликий окремий сервіс у власному поді поруч з API в Kubernetes. Це намір, а не рішення; він залежить від того, що покаже перша версія. OR-Tools офіційно підтримує C++, Python, Java і C#, але не Node, тому це буде окремий сервіс.
Що ще розглядали 2 жовтня 2026 і не вибрали для першої версії:
| Бібліотека | Що це | Чому не зараз |
|---|---|---|
| highs-js | Розв'язувач HiGHS, зібраний у WebAssembly; працює всередині Node | Найближча альтернатива, якщо YALPS виявиться замалим раніше, ніж з'явиться OR-Tools. Узято 10 листопада 2026 (вище) |
| MiniZinc для JavaScript | Мова опису обмежень із кількома розв'язувачами | У Node потребує встановленого на сервері MiniZinc |
| OptalCP | Розв'язувач для задач розкладів з API на TypeScript | Пропрієтарний; безкоштовна версія не віддає сам графік |
YALPS і HiGHS ми використали лише так, як описано тут, решту — ні. Усе про них — зі сторінок самих проєктів.
Чого це нам коштуватиме
- Друга мова — пізніше. YALPS і highs-js тримають розв'язувач усередині API на TypeScript (HiGHS — як WebAssembly, 3,5 МБ). OR-Tools принесе другу мову й ще один сервіс, який треба запускати й розгортати.
- Пояснення не дається задарма. Розв'язувач повідомляє, що тижню чогось бракує, але не чому. Перша версія пояснює, дивлячись на зміни, яких не змогла дати, і на правило, яке виключило кожну; вона не доводить, що більше ніщо не допомогло б.
- Відвідуваність спершу має стати кількістю людей. Перша версія бере потрібні каси з екрана дня, із чеків за годину; як відвідуваність загалом перетворюється на кількість людей, досі не вирішено.
Не вирішено
- Правило посади проти годин за договором. Правила магазину важать більше за понаднормові, тож коли люди посади не закривають її правило в межах своїх годин за договором, план додає понаднормові; тиждень самого власника в Test натомість лишає ці години незакритими. Чи має таке правило поступатися годинам за договором — вирішує власник.
- Правило 11 год відпочинку як жорстке в розв'язувачі, тоді як уручну воно лишається попередженням. Запропоновано 19 жовтня 2026; підтверджує власник.
- Ваги вище й порядок їхніх рівнів на практиці.
- Найкоротша зміна. У Shiffty немає мінімальної тривалості зміни, тож розв'язувач може закрити прогалину короткою зміною, яку людина вже працює: під час живої перевірки він дав одній людині кілька двогодинних касових змін опівдні. Це запобігла б мінімальна тривалість або ціна за зміну. Власні години (26 жовтня 2026) — не менше 4 годин, якщо власні години людини не лишають менше; у шаблонів і звичних змін мінімуму досі немає.
- Наскільки план може змінювати тиждень. З власними годинами плани демо-тижнів переводять багато змін із залу на каси (до 20 прибраних і 24 доданих за тиждень), бо каси йдуть першими, а людей у залі в демо не вимагає ніщо. Магазин, якому потрібен зал, каже це в описі (
minStaff); чи має розв'язувач стримуватися й без цього — вирішує власник. - Занурення округлює лише вгору, тож там, де договір — не ціле число змін, кожен може отримати зміну зайву: 42 години переробки на тижні як у TestStore вище (50 без правила за замовчуванням). Першу правку — округлювати до найближчого — спробували 28 жовтня 2026 і повернули: на порожніх тижнях демо-магазинів їй треба було значно більше кроків, вона виходила за межу часу й лишала їх без плану. Для сильнішого пошуку або окремої правки.
- Дні на тиждень у великому магазині (додано 30 жовтня 2026): з
maxDaysPerWeekдля всіх наступний тиждень Central Station зайняв 172 секунди проти 0,9 без нього — те саме необмежене занурення, що нижче. Виміряно знову 10 листопада 2026 із сьогоднішнім кодом: 0,05–0,12 с з YALPS, 0,08–1,9 с з HiGHS (вище). - Розподіл (додано 30 жовтня 2026): справедливі частки з договірних годин по годинах роботи (або за чеками), і розподіл як останній рівень, тож він нічим вище не жертвує — де в тижні вже є зміни або зміна коштувала б дорожче, люди лишаються на місці. Чи має він важити більше, наприклад проти зміненої зміни, — вирішувати власникові.
- Звичайні зміни (додано 30 жовтня 2026): назва і форма виду та місце, яке займає звичайна зміна, коли правило його не називає (за минулими змінами людини та її посади). Для власника.
- «Одна зміна на день», про яку теж кажуть посади Test, власного виду не має: де кожна зміна 8 годин, її заміняє «не більше 8 годин на день». Для власника.
- Ще не створені тижні повільні. Виміряно 29 жовтня 2026 на демо-магазинах, тиждень без змін: від 1,2 до 7,9 секунди до правила за замовчуванням, від 1,7 до 13,1 з ним — а в Central Station, 560–596 можливих змін, 203 і 361 секунда до, 326 і 572 з ним, і весь цей час API більше нікому не відповідає (YALPS працює в процесі самого API). Межа у 8 секунд там не діяла: вона обмежує точний пошук YALPS, а не послаблені задачі, які повторюють пізні кроки. Було й до правила; з ним гірше. З 5 листопада 2026 занурення вкладається в бюджет (вище). Виміряно знову 10 листопада 2026 із сьогоднішнім кодом: 0,06–0,3 с з YALPS; з HiGHS 0,09–5,1 с, а в Central Station 7,5 с — зупинено на межі, коли його план уже був таким самим добрим, як найкращий (вище).
- Кожну годину роботи закрито (додано 28 жовтня 2026): що за замовчуванням це одна людина будь-де (а не, скажімо, одна на касі), що це важить як каси — тож розв'язувач візьме переробку, але не лишить годину порожньою, — і чи має магазин могти не працювати в якісь дні. Для власника.
- Власні години (додано 26 жовтня 2026): їхня тривалість (від 4 до 10 годин), звична тривалість із договору на 5 днів, перерва з власних шаблонів і змін магазину, їхня вага (3 за зміну, нижче за змінену зміну) і не більше 4 на людину на день. Вирішує власник.
- Обмеження з описів (додано 20 жовтня 2026): вага побажання (1,5 за зміну), де закінчується ранок (12:00) і чи має план прибирати поточну зміну всупереч жорсткому обмеженню, як зараз, чи лишати її з попередженням. І чи не варто згодом зробити доступність полями профілю людини замість читання її опису. Вирішує власник.
- Рішення через картку асистента записується як рішення самого керівника («вирішила людина»), а не «асистент»: підтвердив його керівник. Підтверджує власник.
- HiGHS остаточно (10 листопада 2026): чи замінить він YALPS, який лишається запасним, і чи потрібен ще OR-Tools. Його обмеження за часом, 75 % від 10 секунд, і його розрив, 0,04, — наш вибір. Для власника.
- Понаднормові в магазині, правила якого просять більше, ніж дають договори: на вигаданому магазині на 120 людей із правилами 1,6× 22 людини працюють 232 години понаднормово, бо правила магазину важать більше за понаднормові. Те саме питання, що й правило посади проти годин за договором вище. Для власника.
- Як відвідуваність перетворюється на потрібну кількість людей окрім чеків на касира.
- Чи працює розділення на агента й розв'язувач для керівників. Це гіпотеза, доки керівники не спробують його на даних справжнього магазину.
Куди далі
- Інструменти агента:
solve_week,evaluate_request,decide_request. - Складання графіка: та сама ідея словами керівника.
- Інтеграція з Agentfy: де працює агент і як до нього доходять інструменти.
- Огляд: застосунок і API довкола розв'язувача.
- Відкриті питання: що вирішено, а що ні.