Skip to content

Агент и солвер ​

Два решения: солвер для первой версии (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 мс.

НеделяYALPSHiGHS
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
501 180отказ1,4 с, лучший найденный, та же цена0,5 с, доказано
1002 345отказ6,4 с, лучший найденный, цена 139,9, 96 ч ниже договора0,8 с, доказано, цена 132,0, 88 ч ниже договора
1202 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 смен.

YALPSHiGHS
Вызов инструмента / солвер127 мс / 74 мс198 мс / 143 мс
Результатлучший найденный (суженный поиск)доказанно лучший
Цена22,8622,86
Смены92: 45 × 07–15, 42 × 15–23, 3 × 17–23, 2 × 07–13те же
Нарушенные правила (скрипт)нетнет
Не закрыто: кассы, правила магазина, дежурный менеджер, никого на смене00
Переработканетнет
Ниже договораАлина −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 человек, без обычных смен (до распределения)
Передано ограничений212116
Возможных смен237461406
Время через инструмент0,3 с0,5 с0,4 с
Перенесено распределением (ниже)635—
Шаг поискасуженныйсуженныйсуженный
Смен55105105
Из них свои часы0050
Сверхурочныенетнетнет
Меньше договораниктониктоникто
Выходныепо 2 у всехпо 2 у всехпо 2 у всех
Каждое правило выполнено, по получасамдадада
Совпадает с эталонной неделей31 из 5533 из 5531 из 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–1111–1515–1919–23
Пн10,5 → 6,512,5 → 8,54,5 → 8,52,5 → 6,5
Вт12,8 → 5,815,5 → 8,57,3 → 9,34,5 → 6,5
Ср13,8 → 6,816,5 → 8,57,3 → 8,34,5 → 6,5
Чт13,8 → 6,816,5 → 87,3 → 8,34,5 → 7
Пт10,8 → 6,813,5 → 8,55,3 → 8,32,5 → 6,5
Сб3,3 → 7,34 → 82,8 → 7,82 → 7
Вс3,3 → 7,34 → 82,8 → 7,82 → 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): правило человека — только с человеком («работает только в будни» → noDays sat, 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_week6,2 КБ10,1 КБ508 смен за 0,7 с; ни одного часа нехватки — ни по кассам, ни по правилам магазина, ни по дежурному менеджеру, ни по «хоть кто-то на смене»296 личных правил и правил должностей, ни одно не нарушено; у каждого одна смена в день; каждое правило minStaff выполнено в каждую четверть часа
MyCity, 20 человекsolve_week → needsRules (20 из 21; 4 должности уже сохранены для MyMega — компания та же); 2 × save_rules; solve_week4,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 возможных смен, меньше секунды. Та же проверка оставлена тестом.

Как он взвешивает запрос ​

  1. Запрос, который не ждёт решения этого управляющего, рекомендации не получает.
  2. Изменение, которое нарушает жёсткое правило — собственные проверки запросов в API или меньше 11 ч отдыха, — отклонить.
  3. Изменение, которое оставляет кассы или дежурного управляющего в худшем положении, чем сейчас, или (с 28 октября 2026) час работы без людей на смене: солвер ищет замену в дни запроса, добавляя как можно меньше смен и никогда не двигая чужие. Если замена закрывает пробел — одобрить и назвать замену; если нет — отклонить и назвать часы и почему их никто не может взять.
  4. Иначе одобрить; переработка затронутых людей отмечается.

Рекомендация — солвера; решение — управляющего.

Ограничения ​

Этот раздел — о 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 часа переработки, потому что правила магазина весят больше переработки. Тот же вопрос, что и правило должности против договорных часов выше. Для владельца.
  • Как посещаемость превращается в нужное число людей помимо чеков на кассира.
  • Работает ли разделение на агента и солвер для управляющих. Это гипотеза, пока управляющие не попробуют его на данных настоящего магазина.

Что читать дальше ​