From 99eca80d6da0c310724719e63dc028b41079cb2b Mon Sep 17 00:00:00 2001 From: Leonid Pershin Date: Fri, 21 Aug 2026 09:26:06 +0300 Subject: [PATCH] Register slice 12 and mark phase 68 in progress. EOF Co-authored-by: Cursor --- AGENTS.md | 1 + docs/design/12-office/office.md | 185 +++++++++++++++++++ docs/design/README.md | 1 + docs/phases/12-office/68-class-teacher.md | 40 ++++ docs/phases/12-office/69-offense-memory.md | 36 ++++ docs/phases/12-office/70-director-summons.md | 46 +++++ docs/phases/12-office/71-summons-notices.md | 38 ++++ docs/phases/12-office/72-parent-meetings.md | 44 +++++ docs/phases/12-office/README.md | 34 ++++ docs/phases/README.md | 1 + 10 files changed, 426 insertions(+) create mode 100644 docs/design/12-office/office.md create mode 100644 docs/phases/12-office/68-class-teacher.md create mode 100644 docs/phases/12-office/69-offense-memory.md create mode 100644 docs/phases/12-office/70-director-summons.md create mode 100644 docs/phases/12-office/71-summons-notices.md create mode 100644 docs/phases/12-office/72-parent-meetings.md create mode 100644 docs/phases/12-office/README.md diff --git a/AGENTS.md b/AGENTS.md index 13e5011..dcf0354 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -27,6 +27,7 @@ way; this file is *how to work in them*. | lesson consequences (teacher present, skill, warmth, textbook, weather commute) | [`docs/design/off-queue/lesson-consequences.md`](docs/design/off-queue/lesson-consequences.md) — phases 48, 50–53 | | layer tests, client tsc-in-test, worker/card splits, dump nodes | [`docs/design/10-craft/`](docs/design/10-craft/craft.md) — slice 10, phases 56–59 | | notices, toasts, scene prompt contributions, Krea-only catalog | [`docs/design/11-events/`](docs/design/11-events/events.md) — slice 11, phases 63–67 | +| class teachers, director summons queue, parent meetings | [`docs/design/12-office/`](docs/design/12-office/office.md) — slice 12, phases 68–72 | | a bug in already-shipped behaviour | `.claude/skills/bug-work` — document in `docs/bugs/`, discuss only if the fix has a fork, then patch | | a task that is not in any slice | `.claude/skills/side-work` — discuss, document in [`docs/phases/off-queue/`](docs/phases/off-queue/README.md), then implement | | a new named slice of the game | `.claude/skills/slice-work` — discuss, write design and phases, then `/phase-orch` | diff --git a/docs/design/12-office/office.md b/docs/design/12-office/office.md new file mode 100644 index 0000000..4b0ddfb --- /dev/null +++ b/docs/design/12-office/office.md @@ -0,0 +1,185 @@ +# Кабинет директора и классный + +Договорённость на срез после событий и общения, не текущий код. +Люди: [`people.md`](../02-people/people.md). Штат: [`staffing.md`](../03-staffing/staffing.md). +ИИ: [`ai.md`](../05-ai/ai.md). Общение: [`social.md`](../09-social/social.md). +События: [`events.md`](../11-events/events.md). Урок: [`lesson-consequences.md`](../off-queue/lesson-consequences.md). + +У школы появляется **власть на карте**: проступок помнится коротко, ученика **сами** гонят к +директору — с очередью у кабинета и ожиданием в коридоре. У класса появляется **классный** +(учитель из Управления); он редко оставляет класс после уроков на родительское собрание, и +родители **реально входят** на карту. + +Игрок **назначает классных** и **смотрит**. Кнопки «вызвать к директору» и «назначить собрание» +нет: авто и ИИ классного. + +## Что увидит игрок + +- В **Управлении** — у каждого класса слот «классный»: только из нанятых учителей; снять / + переназначить. +- На карточке ученика — **небольшой список** недавних проступков (несколько последних), не + шкала дисциплины и не журнал оценок. +- После драки / выговора система может отправить ученика к директору: он идёт, если кабинет + занят — **ждёт в коридоре** у входа, внутри — **очередь по одному**. +- Редко после последнего урока класса: классный и часть родителей в кабинете класса; тост, что + собрание идёт. + +## На какие вопросы отвечает + +- Как приказ «к директору» живёт в том же ИИ, что урок (сильная обязанность), без телепорта. +- Как очередь у `PrincipalsOffice` не ломает присутствие и детерминизм. +- Кто такой классный без нового `PositionDef`. +- Как родитель впервые получает узел на карте и уходит после собрания. +- Что видит игрок без кнопки вмешательства. + +## Чего нет + +- Кнопки игрока «вызвать» / «на собрание». +- Шкалы дисциплины 0…100 и дневника оценок. +- Травм, медкабинета как больницы, выговора в отдельной вкладке «Правила». +- Еженедельного календаря собраний и явки 100%. +- Завуча как отдельной роли в этом срезе. +- Оценок и приказов «отправить домой». + +## Что меняется в уже принятом + +| Было | Стало | Почему | +| --- | --- | --- | +| Игрок только наблюдает; приказов нет ([`ai.md`](../05-ai/ai.md)) | Наблюдает вызовы; **назначает** классного | Классный — единственное решение игрока в срезе | +| Драка → выговор на месте; кабинет директора не заводим ([`social.md`](../09-social/social.md)) | Часть проступков → авто-вызов, очередь | Иначе выговор пустой | +| Родители без места на карте ([`people.md`](../02-people/people.md)) | На собрании получают узел и цель | Задел с ростера наконец используется | +| `SchoolClass` — id, год, литера, кабинет, ученики | Плюс `classTeacherId` (учитель или пусто) | Не должность, слот на классе | +| `EventDef`: утро, звонок, сбой генерации | Плюс вызов / собрание (info) | Игрок видит факт, не только строку в локации | +| «Родителя вызвать — отдельный сюжет» | Собрание классного; **не** вызов одного родителя к директору | Узкий scope | + +## Этап A — классный + +У `SchoolClass` опциональный id учителя. Назначить / снять — HTTP через мейлбокс школы (как +предметы), только хозяин. Кандидаты: нанятые с должностью `Teacher`. Один учитель — классный у +нескольких классов (ваниль не запрещает). Пустой слот: собраний нет, класс живёт как сейчас. + +Карточка класса / строка в Управлении показывает имя. Сейв — в `people.json` / ростере рядом с +классами. + +После этапа школа целая: классных можно расставить, вызовов ещё нет. + +## Этап B — проступки и кабинет + +### Память + +На человеке **короткий список** недавних проступков (ваниль: несколько последних, потолок в +`BehaviorDef`, старые вытесняются). Запись: вид (ссора / драка / выговор / …), когда (игровые +часы или день+слот), опционально id второго участника. Не шкала. Писать при содержательном +событии (тот же шов, что мнения), не каждый тик. + +Карточка ученика (вкладка «Сейчас» или рядом) показывает список. HTTP через мейлбокс. + +### Вызов — только авто + +Игрок не жмёт. Триггер из уже живых фактов: обрыв драки сотрудником, выговор учителя, при +необходимости грубый срыв с политикой речи — веса и пороги в `BehaviorDef`, не `if` по фамилии. + +Состояние «вызван» — **временное** (флаг / обязанность), пока не дошёл, не отбыл приём и не +Sorвался день. Без долгой шкалы «дисциплина». + +### Путь и очередь + +Кабинет — `PrincipalsOffice` (уже в `core`). Вызванный идёт обычной ходьбой. + +- Директор занят приёмом или отсутствует → очередь: ждут в **коридоре** у связанного узла (ребро + карты к кабинету), не толпятся внутри. +- В кабинете — **один** на приём. Очередь FIFO по id вызова (детерминизм: стабильный порядок). +- Приём — короткое действие (выговор / разговор), мнение о директоре падает, проступок может + дописаться; затем ученик свободен (обязанность урока снова тянет). +- Skip пустого времени не оставляет вечный «вызван» без разрешения: утро сбрасывает зависшее + или доигрывает по правилу в фазе. + +Директор без найма: вызов не стартует (или гаснет) — порог в данных, не паника. + +Тост info: кого вызвали (через `EventDef`). Протокол присутствия: действие / узел достаточно; +отдельное поле «очередь» в кадре — только если без него UI врёт. Версию сокета бампит **коммит +фазы**, не этот документ. + +После этапа школа целая без собраний: драки гонят к директору, очередь видна в коридоре. + +## Этап C — родительские собрания + +Только **ИИ классного**, редко. Условия (числа в `BehaviorDef`): + +- у класса есть классный; +- рабочий день, после **последнего** урока этого класса; +- классный сегодня в школе; +- бросок редкости от сида класса и дня. + +Классный остаётся в кабинете класса (homeroom). Часть родителей учеников класса приходит: +получают место (двор → путь → кабинет), как обычная ходьба. Не 100% семей — доля и «кто» из +сида. Учитель-родитель этого класса, если уже в школе, может войти в собрание без второго +человека. + +Собрание — действие/кружок ограниченной длины; мнения семья↔классный слегка двигаются; тост +info. После — родители уходят с карты (снова «вне школы»), классный свободен. + +Игрок собрание не назначает и не отменяет. + +После этапа школа целая целиком по срезу. + +## Поток данных + +| Что | Где | +| --- | --- | +| `classTeacherId` | ростер / сейв; HTTP Управление | +| Список проступков | на человеке; сейв; карточка HTTP | +| Очередь вызовов | состояние школы на потоке воркера; не клиент | +| Выбор «вызвать» / «собрание» | `HSchool.Ai` + адаптер симуляции | +| Ходьба родителей | те же узлы и `travelMinutes`, что у всех | +| Тосты | `EventDef` + доска уведомлений среза 11 | +| Назначение классного | намерение HTTP → мейлбокс (инвариант 3, 7) | + +Инвариант 1: клиент не решает, кого вызвать. Инвариант 4: симуляция не знает тосты и ASP.NET. + +## Где живёт код + +Нового проекта нет. + +| Что | Куда | +| --- | --- | +| Поля `BehaviorDef`, триггеры, потолки списка | `HSchool.Content` + JSONC `core` | +| `SchoolClass` + классный | `HSchool.People` + сейв | +| Обязанность вызова, очередь, собрание | `HSchool.Ai` + адаптер в `HSchool.Simulation` | +| HTTP назначение, карточка проступков | `HSchool.Server` + клиент Управление / карточка | +| `EventDef` вызова и собрания | `core` + шов среза 11 | +| Присутствие | уже есть; бамп протокола только если нужен новый статус | + +## Советы, которые стоит принять сразу + +- Не заводить `PositionDef` «классный» — слот на классе, как предметы у учителя. +- Не телепортировать к директору и не пихать очередь внутрь кабинета. +- Не давать игроку кнопку вызова: согласие на «только авто». +- Не шкалу дисциплины рядом со списком — два представления одной идеи путают. +- Родитель на карте только на время собрания (этот срез), не «живёт в школе». +- Очередь и вызовы считает поток школы; HTTP их не трогает. +- Редкость собраний — данные, не магическая константа в UI. + +## Заведомо не сейчас + +- Кнопка «вызвать к директору» / «назначить собрание». +- Вызов одного родителя к директору по проступку. +- Оценки, журнал посещаемости, «отправить домой». +- Травмы, медпункт как лечение после драки. +- Завуч, рассадка, настроение-нужда. +- Календарь собраний на четверть. + +## Зафиксировано этим разговором + +| Тема | Решение | +| --- | --- | +| Форма | Именованный срез 12, не off-queue | +| Вызов | Только авто; игрок не жмёт | +| Поведение | Временный «вызван» + короткий список недавних проступков | +| Классный | Только из учителей; Управление | +| Собрание | Только ИИ классного, редко, после последнего урока класса | +| Родители / вызов | Реально ходят по карте; у директора очередь, ждут в коридоре | +| Ваниль | `core`, не отдельный пак | +| Стоп | После A — классные; после B — кабинет без собраний | +| Протокол | Бамп только если фазе нужен новый статус присутствия | +| Оценки / шкала дисциплины | Не в срезе | diff --git a/docs/design/README.md b/docs/design/README.md index 9179871..aea4962 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -15,4 +15,5 @@ | 9. Общение и романтический пак | [09-social](09-social/social.md) | | 10. Ремесло | [10-craft](10-craft/craft.md) | | 11. События и сцена | [11-events](11-events/events.md) | +| 12. Кабинет и классный | [12-office](12-office/office.md) | | Вне очереди | [off-queue](off-queue/) | diff --git a/docs/phases/12-office/68-class-teacher.md b/docs/phases/12-office/68-class-teacher.md new file mode 100644 index 0000000..479329c --- /dev/null +++ b/docs/phases/12-office/68-class-teacher.md @@ -0,0 +1,40 @@ +# Фаза 68. Классный руководитель + +## Зависимости + +- [Фаза 13](../03-staffing/13-management-tab.md) +- [Фаза 7](../02-people/07-people-in-school.md) + +## Зачем + +У класса появляется учитель-классный. Без него собраниям некого инициировать; игрок впервые +в этом срезе что-то решает. + +## Задачи + +- [ ] У `SchoolClass` опциональный `classTeacherId` (или эквивалент); сейв в ростере +- [ ] Назначить / снять — HTTP через мейлбокс школы; только хозяин; гость `403` +- [ ] Кандидат — нанятый с должностью `Teacher`; иначе отказ с текстом, не молчание +- [ ] Один учитель может быть классным у нескольких классов +- [ ] UI в «Управлении»: список классов со слотом классного (выбор / снять) +- [ ] Имя классного видно там, где уже показывают класс (карточка ученика / управление) +- [ ] Строки через `t(...)`, обе локали +- [ ] Пустой слот — школа живёт как сейчас; собраний ещё нет + +## Тесты, без которых фаза не закрыта + +- [ ] Назначение учителя класса пишет id в ростер и переживает сейв / reload +- [ ] Не-учитель и чужой id отклоняются +- [ ] Гость не назначает (API) +- [ ] Снятие очищает слот; класс без классного валиден +- [ ] Два класса могут указать одного и того же учителя + +## Критерий готовности + +- В Управлении назначить классного 5А, открыть карточку ученика / список — имя видно; F5 / reload + сохраняет +- Отфильтрованные тесты проекта по Testing policy проходят + +## Стоп + +Не вызов к директору. Не проступки. Не собрания. Не новый `PositionDef`. diff --git a/docs/phases/12-office/69-offense-memory.md b/docs/phases/12-office/69-offense-memory.md new file mode 100644 index 0000000..aeaa87d --- /dev/null +++ b/docs/phases/12-office/69-offense-memory.md @@ -0,0 +1,36 @@ +# Фаза 69. Память проступков + +## Зависимости + +- [Фаза 44](../09-social/44-quarrel-fight.md) + +## Зачем + +Вызов и карточка опираются на короткий список недавних событий, не на шкалу дисциплины. + +## Задачи + +- [ ] На человеке разреженный список проступков: вид, игровое время (или день+слот), опционально + второй участник +- [ ] Потолок длины и какие факты пишут — поля `BehaviorDef` / данные `core`, не константы в UI +- [ ] Писать при ссоре, драке, выговоре (обрыв драки сотрудником); старые вытесняются +- [ ] Сейв вместе с человеком; ноль записей не хранить раздуто +- [ ] Карточка ученика показывает несколько последних (HTTP через мейлбокс) +- [ ] Строки видов через локаль мода / `t(...)` по договорённости фазы; обе локали клиента для UI + +## Тесты, без которых фаза не закрыта + +- [ ] Драка с выговором добавляет запись жертве и/или задире по правилам фазы +- [ ] Сверх потолка старая запись исчезает +- [ ] Список переживает сейв +- [ ] Карточка отдает тот же порядок, что в мире (не клиентская фантазия) + +## Критерий готовности + +- После драки с сотрудником в узле на карточке ученика виден проступок; перезагрузка школы не + стирает +- Отфильтрованные тесты по Testing policy проходят + +## Стоп + +Не шкала 0…100. Не авто-вызов (фаза 70). Не журнал оценок. Не кнопка игрока. diff --git a/docs/phases/12-office/70-director-summons.md b/docs/phases/12-office/70-director-summons.md new file mode 100644 index 0000000..aca9274 --- /dev/null +++ b/docs/phases/12-office/70-director-summons.md @@ -0,0 +1,46 @@ +# Фаза 70. Вызов к директору и очередь + +## Зависимости + +- [Фаза 69](69-offense-memory.md) +- [Фаза 21](../05-ai/21-decisions.md) +- [Фаза 18](../05-ai/18-presence-walking.md) + +## Зачем + +Проступок гонит ученика к директору сам: ходьба, ожидание в коридоре, один в кабинете. + +## Задачи + +- [ ] Авто-триггер вызова из фактов (обрыв драки / выговор и пороги в `BehaviorDef`); кнопки + игрока нет +- [ ] Временное состояние «вызван» — сильная обязанность дойти до `PrincipalsOffice`, пройти + приём, сняться +- [ ] Нет директора в штате или нет узла кабинета — вызов не стартует / гаснет по правилу в данных +- [ ] Кабинет занят приёмом → ждут в коридорном узле у ребра к кабинету, не внутри +- [ ] В кабинете один на приём; очередь FIFO с детерминированным порядком +- [ ] Приём — короткое действие; мнение о директоре падает; при необходимости допись в список + проступков (69) +- [ ] Обычная ходьба и `travelMinutes`; телепорта нет +- [ ] Skip / утро не оставляют вечный «вызван» без разрешения (явное правило в коде фазы) +- [ ] Очередь и вызовы только на потоке школы (инвариант 3) + +## Тесты, без которых фаза не закрыта + +- [ ] После qualifying-проступка ученик получает обязанность к кабинету (при живом директоре) +- [ ] Двое вызванных: один в кабинете, второй в коридоре у входа, не оба внутри +- [ ] Освобождение кабинета впускает следующего из очереди +- [ ] Тот же сид и те же события → тот же порядок очереди +- [ ] Без директора вызов не зависает навечно +- [ ] Игрок не может послать вызов по HTTP/сокету (нет такого намерения) + +## Критерий готовности + +- Драка с обрывом → ученик идёт к директору; второй вызванный ждёт в коридоре; после приёма + оба снова живут обычным днём +- Отфильтрованные тесты по Testing policy проходят + +## Стоп + +Не собрания. Не тосты (если нужны — фаза 71). Не присутствие-протокол без нужды — только если +без нового статуса UI врёт; бамп версии тогда в этом коммите. diff --git a/docs/phases/12-office/71-summons-notices.md b/docs/phases/12-office/71-summons-notices.md new file mode 100644 index 0000000..46174f3 --- /dev/null +++ b/docs/phases/12-office/71-summons-notices.md @@ -0,0 +1,38 @@ +# Фаза 71. Тосты вызова и очередь на экране + +## Зависимости + +- [Фаза 70](70-director-summons.md) +- [Фаза 64](../11-events/64-event-defs.md) + +## Зачем + +Игрок видит, что кого-то вызвали, не вычисляя очередь глазами по всему дереву. + +## Задачи + +- [ ] `EventDef` info на авто-вызов (ваниль в `core`); факт из симуляции → доска уведомлений + среза 11 +- [ ] Тост не паузит часы; не в сейве sticky +- [ ] В панели локации / присутствии понятно «идёт к директору» / «ждёт у кабинета» / «на приёме» + — через действие и узел; новый байт в кадре присутствия — только если иначе нельзя; тогда + протокол +1 в этом коммите (`ProtocolCodec`, `protocol.ts`, `docs/protocol.md`) +- [ ] Гость видит те же info; ничего не назначает +- [ ] Локали RU/EN + +## Тесты, без которых фаза не закрыта + +- [ ] Qualifying-вызов эмитит notice с ожидаемым `EventDef` +- [ ] Info не пишет sticky в сейв +- [ ] Если бамп протокола — round-trip и byte-layout на C# и TS +- [ ] Без открытого клиента очередь в мире всё равно двигается (подписка не обязательна для сима) + +## Критерий готовности + +- Вызов → тост; в коридоре у кабинета видно ожидающих; старый клиент при бампе отваливается на + Hello +- Отфильтрованные тесты по Testing policy проходят + +## Стоп + +Не собрания. Не warning-пауза на каждый вызов. diff --git a/docs/phases/12-office/72-parent-meetings.md b/docs/phases/12-office/72-parent-meetings.md new file mode 100644 index 0000000..87e50de --- /dev/null +++ b/docs/phases/12-office/72-parent-meetings.md @@ -0,0 +1,44 @@ +# Фаза 72. Родительские собрания + +## Зависимости + +- [Фаза 68](68-class-teacher.md) +- [Фаза 71](71-summons-notices.md) +- [Фаза 18](../05-ai/18-presence-walking.md) + +## Зачем + +Классный редко оставляет класс после уроков; родители впервые ходят по карте. + +## Задачи + +- [ ] Только ИИ: редкий бросок от сида класса и дня; кнопки игрока нет +- [ ] Условия: есть классный, рабочий день, после последнего урока **этого** класса, классный в + школе; пороги в `BehaviorDef` +- [ ] Классный остаётся в homeroom класса +- [ ] Доля родителей класса приходит: получают узел (двор → путь → кабинет), обычная ходьба +- [ ] Учитель-родитель ученика класса, уже в школе, может участвовать без второго инстанса +- [ ] Собрание — ограниченное по времени действие/занятость узла; лёгкий сдвиг мнений + семья↔классный +- [ ] После — родители снова «вне школы»; классный свободен +- [ ] `EventDef` info «собрание»; локали +- [ ] Нет классного — собрание не планируется + +## Тесты, без которых фаза не закрыта + +- [ ] Без `classTeacherId` собрание не стартует при том же сиде дня +- [ ] С классным и прохождением редкости родители появляются на карте и уходят после +- [ ] Собрание не раньше последнего урока класса +- [ ] Тот же сид класса/дня → те же «кто пришёл» (детерминизм доли) +- [ ] Игрок не назначает собрание по API +- [ ] Skip ночи не оставляет родителей вечно в кабинете + +## Критерий готовности + +- Назначить классного, дождаться редкого собрания: родители в кабинете класса, тост, потом + снова вне школы +- Отфильтрованные тесты по Testing policy проходят + +## Стоп + +Не вызов одного родителя к директору. Не календарь на четверть. Не явка 100%. Не оценки. diff --git a/docs/phases/12-office/README.md b/docs/phases/12-office/README.md new file mode 100644 index 0000000..4585bfc --- /dev/null +++ b/docs/phases/12-office/README.md @@ -0,0 +1,34 @@ +Индекс срезов: [`../README.md`](../README.md). + +## Срез 12. Кабинет директора и классный + +Дизайн: [`office.md`](../../design/12-office/office.md). + +Проступок помнится коротко, ученика самих гонят к директору (очередь, коридор). Классный — +учитель из Управления; редко собирает родителей после уроков, и они ходят по карте. Игрок +назначает классных и смотрит. Срез можно остановить после этапа A — классные стоят, даже если +кабинета ещё нет. + +**Этап A — классный.** Слот на классе. + +| Фаза | Статус | Зачем | +| --- | --- | --- | +| [68. Классный руководитель](68-class-teacher.md) | 🔄 | Назначение в Управлении, только учителя | + +**Этап B — проступки и кабинет.** Память, авто-вызов, экран. + +| Фаза | Статус | Зачем | +| --- | --- | --- | +| [69. Память проступков](69-offense-memory.md) | ⬜ | Короткий список на человеке и карточке | +| [70. Вызов и очередь](70-director-summons.md) | ⬜ | Авто, ходьба, коридор, один в кабинете | +| [71. Тосты вызова](71-summons-notices.md) | ⬜ | `EventDef` info; очередь видна | + +69 стоит на 44; 70 — на 69 и ходьбу/решения; 71 — на 70 и 64. + +**Этап C — собрания.** + +| Фаза | Статус | Зачем | +| --- | --- | --- | +| [72. Родительские собрания](72-parent-meetings.md) | ⬜ | ИИ классного, родители на карте | + +72 стоит на 68 и 71. diff --git a/docs/phases/README.md b/docs/phases/README.md index 37c7e2c..1339f87 100644 --- a/docs/phases/README.md +++ b/docs/phases/README.md @@ -22,4 +22,5 @@ | 9. Общение и романтический пак | 41–47 | [09-social](09-social/README.md) | [social](../design/09-social/social.md) | | 10. Ремесло | 56–59 | [10-craft](10-craft/README.md) | [craft](../design/10-craft/craft.md) | | 11. События и сцена | 63–67 | [11-events](11-events/README.md) | [events](../design/11-events/events.md) | +| 12. Кабинет и классный | 68–72 | [12-office](12-office/README.md) | [office](../design/12-office/office.md) | | Вне очереди | 48–55 | [off-queue](off-queue/README.md) | [off-queue](../design/off-queue/) |