textmachine/frontend/docs/frontend-PROGRESS.md

225 lines
46 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Журнал зоны «Фронт»
## ПИНГ оркестратора №20 → зоне фронта (30.08, аудит доков; зона ЗАМОРОЖЕНА — это к первому касанию при разморозке)
Зона заморожена, работы не заказываю: перечисленное ждёт разморозки и правится ТВОЕЙ сессией (её журнал и бэклог — твоя зона).
1. **В-3 (каким словом называть ступень замечания) — с листа владельца СНЯТ.** ⚠ Строка В-3 удалена из таблицы вопросов 02.09, поэтому предмет ищется носителями: `docs/research/28-contract-review.md:1443`=`К-6 (ступени замечания)` и `docs/research/28-contract-review.md:1547`=`К-6, ступени замечаний`, хвост зоны — `frontend/docs/BACKLOG.md:25`=`Ф-21 | **Ступень замечания`. D39.176 п.4 (30.08): фразы В-3 · К-6 · Приложение А ДЕЛЕГИРОВАНЫ проекту, подписи владельца не ждём. Требование ИНЖЕНЕРНОЕ: фраза не литерал ни в Go платформы, ни в TSX фронта, а ДАННЫЕ по машинному коду причины и локали; словарь — один на продукт. То же снимает развилку **Ф-61** («платформа отвечает по-английски») — направление задано, выбор «кто и чем» больше не открыт.
2. **Ф-43 протухла обеими половинами** (сверено деревом 30.08): движковый сайдкар банка построен (`backend/internal/pipeline/bankexport.go`), платформа его декодирует и отдаёт проекцией. Основание «S5 непостроим» и зависимости Ф-44/Ф-46 «после Ф-43» больше не держатся. Первый пинг об этом был 16.08 и не исполнен — потому повторяю.
3. **В-1** утверждал «платформы ещё нет ни строки» — платформа живёт с 04.08 и прошла паки P0P11 плюс sqlc; половина вопроса снята фактом (текст строки В-1 поправлен 02.09 при чистке журнала).
4. **Состояние зеркала контракта — 0.2.3 против канона 0.9.0** (0.9.0 ЗАЛЕНДЖЕН 31.08 с паком P12, D39.180): СЕМЬ миноров, первый из них ломающий, 16 операций против 20. Синк зеркала + перегенерация типов — первое касание при разморозке, ОДНОЙ перегенерацией.
> **Зонный журнал** (решение владельца 02.08): сюда пишут и фронт-сессии, и оркестратор; в
> `docs/PROGRESS.md` фронт не пишет (роль-таблица `CLAUDE.md`). Хвосты — `BACKLOG.md`, план и
> замеры — `FRONTEND_PLAN.md`, ратифицированные пины — `STACK_DECISIONS.md`. Контракт: канон —
> `docs/architecture/14-api-contract/` (спека + компаньон-README), зонное зеркало —
> `api-contract/openapi.yaml` (отстаёт РАТИФИЦИРОВАННО, см. пинг №20 п.4); `API_CONTRACT_DRAFT.md`
> и `API_CONTRACT_INPUT.md` — исполненные входы под ⚠-баннерами, не поддерживаются.
> Сверху — состояние и пинги, ниже — хроника. Записи сессий S0S4 и их приёмок (0214.08) вынесены
> в [archive/frontend-PROGRESS-S0-S4.md](archive/frontend-PROGRESS-S0-S4.md) (слово владельца 16.08).
## 📌 ПИНГ ОРКЕСТРАТОРА (29.08, D39.169) — новый терминальный кадр SSE `session_ended`, зоне при разморозке
Канон **0.8.0** объявил девятый кадр потока: `session_ended`, payload — ровно `EventBase`.
**Почему он появился.** Закрыта единственная открытая уязвимость платформы (`PD-379`): отзыв сессии
не выключал уже открытый поток событий — «выйти везде» не работало, поток жил ещё сорок секунд после
отзыва. Теперь сервер гасит поток и шлёт этот кадр.
**Половина, которую сервер закрыть НЕ МОЖЕТ, и она ваша.** Без обработчика на клиенте отзыв
неотличим от обрыва сети: браузер увидит закрытое соединение и пойдёт переподключаться — в `401`,
объяснить который ему нечем. То есть для ЧЕЛОВЕКА уязвимость остаётся наполовину открытой.
**Что нужно при разморозке:** обработать `session_ended` отдельно от `end` и `resync_required`
`end` значит «книга кончилась, возвращаться незачем», `resync_required` — «спроси заново», а здесь
единственное верное действие **войти заново**. Переподключение без входа бессмысленно.
Носитель — `docs/architecture/14-api-contract/openapi.yaml`, схема `EventSessionEnded`.
## Текущее состояние
- **Пройдено:** S0 (план), S1 (инструменты, скриншот-цикл, `tokens.css`, витрина),
S2 (оболочка трёх панелей, слой `src/ui/`, масштаб списков, хвосты гейтов),
S3 (слой данных: контракт 0.2.0, MSW, фикстуры всех состояний, живой поток, типы контракта),
S3.5 (фикс-пак оболочки: 24 замечания владельца, сценарии интеракций, пере-замер полос),
**S3.6 (второй круг: палитра по замеру референсов, модель вкладок fleet_2, банк таблицей,
ручка из vojo дословно)**, **S3.7 (долги слоя данных: контракт 0.2.2, каталог i18n 157 ключей,
код зоны на английском; D39.129)**, **S4 (загрузка книги и запуск прогона на контракте 0.2.3,
библиотека на масштабе, находки приёмки S3.7) — ПРИНЯТ 15.08, D39.135; фикс-лист ФС-1…ФС-12
остаётся входом первого касания**.
- **Карта канона для фронт-сессии — `FRONTEND_PLAN.md` §0.1, транспорт — §0.2.** Заведены
после того, как две ошибки S1 пришли из непрочитанного канона; читать до кода, не после.
- **Гейты стоят и на коммите:** pre-commit хук (02.08, вторая сессия) гоняет `npm run check`
для коммитов с frontend-путями и блокирует смесь зон и файлы «никогда не коммитить»;
ставится сам при `npm install`. Обход — только осознанный `git commit --no-verify`.
## Решения владельца по продукту
Записываю здесь, потому что они меняют раскладку из §2 промта, а промт правит не фронт-сессия.
### 04.08 — где стоит «+» в рядах вкладок (закрывает половину Ф-7)
Вопрос был поставлен так: промт требует «+» **вместе с действием**, которое он запускает, а наборы
вкладок у нас фиксированные (слева `Книги · Поиск`, справа `О книге · Замечания · Банк`) —
пользователь их не расширяет, и fleet-овский смысл «+» («добавить инструмент») к ним не применим.
Владелец: **«+» слева = «Добавить книгу»**. Отсюда: «+» стоит в ряду вкладок ЛЕВОЙ панели и
запускает добавление, дублирующая строка «+ Добавить книгу» из дерева убрана (одна вещь — одно
место, и в референсе «+» стоит ровно там); в центре и справа «+» нет — там кнопка вышла бы
декоративной. Остаток строки — Ф-7.
В S2 действие открывает вкладку-документ «Добавить книгу»; содержимое экрана (§3.1) делает S4.
### 04.08 — референсы вернулись на диск
`frontend/references/*.png` в `.gitignore` и в git никогда не заезжали, поэтому в третьей сессии
их на диске не оказалось вовсе. Владелец положил файлы обратно. **Следствие для будущих сессий:
не считать наличие референсов данностью — если папки нет, это не «их отменили», а спросить.**
### 02.08 — раскладка: банк памяти переезжает в правую панель
Владелец, глядя на витрину: **«банк памяти перенёс бы в правую вкладку, чтоб можно было
параллельно вертикально смотреть и оригинал, и главу, и банк памяти, а не горизонтально»**.
Плюс три дефекта структуры в той же реплике: две кнопки настроек, банк продублирован
(вкладка слева + отдельная карточка внизу), окно главы слишком мало.
Сделано: настройки — только внизу левой панели (второй вход из верхней полосы снят, промт §3.12),
банк — одной вкладкой в правой панели вместо «вкладка слева + карточка в центре», центр — одна
панель во всю высоту (нижняя карточка была скопирована с терминала Fleet и не несла задачи),
кнопки сворачивания — у двух панелей, а не трёх.
**Вертикальный параллелизм — суть решения:** рабочий цикл читателя это «читаю перевод → спотыкаюсь
о термин → проверяю его в банке». Все три вещи обязаны быть видны одновременно, поэтому колонки:
навигация · оригинал+перевод · справочное о читаемой главе. Правая панель становится панелью
контекста, и её вкладки — `О книге · Замечания · Банк`.
**Что при этом надо развести (иначе §3.5 ломается):** у банка две разные работы.
Справочная — «что это за термин», ей хватает 320px правой панели. Подписная — сотни терминов
подряд, клавиатура важнее мыши, массовые действия — в 320px не помещается. Поэтому подписной
экран открывается **вкладкой в центре**, как документ, а правая панель ведёт в него действием
«Подписать банк». В витрине эта связка показана.
### 02.08 — данные: моки берут форму от движка
Владелец: **«всё на диске лежит, и главы, и банки памяти»**. Разбор бэкенда подтвердил: моя
первая фикстура выдумывала поля (`kind: 'имя'`, `state: 'подписан'`), а промт прямо запрещает
изобретать API. Формы были переписаны по настоящим.
⚠ Сам перечень форм (банк · пары · причины замечаний) снят отсюда чисткой 02.09 и здесь НЕ
пересказывается: один факт — один носитель. Действующие формы — канон компаньона
`docs/architecture/14-api-contract/README.md`, греп `### 2.8. Банк` (словари банка, включая
поправку «`auto` пишет СТАТУС, а не провенанс») и греп `### 2.7. Состояние пары`. Первичные
структуры движка ищутся символами: `backend/internal/store/migrate.go` греп `glossary`,
`backend/internal/pipeline/export.go` греп `ChunkExport`,
`backend/internal/pipeline/disposition.go` греп `FlagReason`.
### 02.08 — шов данных заведён: моки выкидываются одной папкой
Владелец: **«все моки рано или поздно придётся выкинуть; нужна минимальность моков,
минимальная инвазивность в код и изолированность»**.
Заведено: `src/api/` — типы и функции, единственный вход; `src/mock/` — фикстура, которую
видит только `api/`. Правило теперь машинное, а не на совести ревьюера: `no-restricted-imports`
на `**/mock/**` и запрет сетевых вызовов, с исключением для `src/api/**`.
### 02.08 — что дал разбор канона: фронт мокает не тот контракт
**D39.85 (`research/23` §0): фронт читает ТОЛЬКО read-модель платформы в Postgres, материализованную
из NDJSON-потока событий; движок не опрашивается никогда, чтение живого SQLite движка — запрещённый
анти-паттерн.** Значит движковые формы (таблица `glossary`, `ChunkExport`) — словарь предметной
области, но НЕ форма API: форма API живёт только в каноне `docs/architecture/14-api-contract/`.
Оттуда же берётся и запрет показывать пользователю язык конвейера (`sanitizer_stripped` и подобное) —
это ПТ-33 реестра требований: `detail` не показывается никогда, а вердикт превращается в фразу по
словарю машинных кодов (карта — приложение А компаньона контракта).
**Ответ на вопрос владельца о способе связи:** NDJSON — это шов ДВИЖОК↔ПЛАТФОРМА (D39.85), а фронту
принадлежит JSON поверх HTTP плюс SSE от платформы (D39.84). Разведено в `FRONTEND_PLAN.md` §0.2.
**⛔ ПИНГ ОРКЕСТРАТОРА №19 — 23.08, при разморозке зоны (сейчас действий не требует).**
Аудит доков нашёл два расхождения внутри зоны; рукой не лезу, зона заморожена.
1. **Семь оставшихся вопросов листа — сверить каждый против D-лога прежде, чем нести владельцу
повторно.** Четыре из одиннадцати каноном уже отвечены и с листа сняты: В-3 (D39.176 п.4), В-6
(D39.132 п.2а), В-10 (D39.138 п.2к), В-5 «показывать ли ETA» (D39.100 п.1: К-5 закрыт
«показывать», `eta_seconds` — обязательное поле канонической спеки).
2а. **Ключ `prepare` вашего `package.json` — единственный бутстрап РЕПО-ШИРОКОГО гейта доков (дописано 24.08; см. буллет «Гейты стоят и на коммите» в «Текущем состоянии»).**
`frontend/scripts/githooks/install.mjs` — единственный в дереве установщик диспетчера `.git/hooks/pre-commit`, а тот
судит `CLAUDE.md` и доки трёх зон, не только ваши. Следствие проверено исполнением: на свежем клоне без `npm install`
гейт молча выключен. Просьба при разморозке: перевести `prepare` на зоно-нейтральный установщик, который заведут в
`docs/scripts/githooks/`, чтобы единственным писателем диспетчера был он. Сам ваш ФРАГМЕНТ хука менять не надо.
2. **Пространство номеров «В-N» разъехалось** между этим журналом и `docs/research/28-contract-review.md`:
доклад ссылается на В-1/В-2/В-5/В-6/В-7 как на ДРУГИЕ вопросы, чем одноимённые строки здесь
(В-5 и В-6 с листа уже сняты, но их номера в докладе живы). Пока номера двусмысленны, ссылка
«см. В-6» указывает в два разных места.
## Открытые вопросы к владельцу
| # | Вопрос | Почему это его вопрос |
|---|---|---|
| В-1 | **Данные привязаны к одной машине.** Вся фактура — прогоны, экспорты, банки — лежит вне внешнего git. ⚠ Грунт строки пере-сверен деревом 02.09 и наполовину протух: книги с 24.08 живут в `<репозиторий>/books` под СВОИМ origin (D39.157 п.2), образцовых БД в `backend/example/` нет вовсе, а жёсткие пути стенда из тестов сняты — они берутся из окружения и тест пропускается при отсутствии (`backend/internal/miner/miner_parity_test.go:37`=`All three stay overridable`). Владелец сказал: «мне не нравится, что это живёт конкретно на моём диске». Лечение — платформа (`platform/README.md`, раздел библиотеки книг: хранение исходников и экспортов); она с тех пор построена и принята (D39.109), поэтому половина вопроса снята фактом — пинг №20 п.3. Фронт от этого не зависит (работает на моках), но **вопрос на движок/платформу, а не на фронт** | скоуп-решение и порядок работ |
| В-8 | **Какое слово о состоянии книги стоит в дереве.** Замечание 23 потребовало бейджу ФИКС-место, и оно сделано; но две метки словаря в него не помещаются и усекаются с тултипом — «остановлена: лимиты» (19 знаков) и ветка неизвестного «неизвестное состояние» (21). Укоротить их сессия НЕ вправе: фраза паузы зарезервирована за владельцем (прежний В-6 снят с листа 02.09 как ЗАКРЫТЫЙ; носитель — `docs/architecture/14-api-contract/README.md:972`=`не различает две беды`, закрыт D39.132 п.2а), и первый заход S3.5 её укоротил и был откачен собственным ревью. Варианты: (а) оставить усечение с тултипом, (б) владелец даёт короткое слово для дерева, а полная фраза остаётся в статус-полосе, (в) расширить колонку бейджа за счёт названия книги. ⚠ Сверить с D39.176 п.4 (30.08): фразы, которые видит пользователь, ДЕЛЕГИРОВАНЫ проекту — вопрос к владельцу может сузиться до раскладки (а)/(в) | продуктовая формулировка, которую видит пользователь |
| В-7 | **Физический масштаб интерфейса на мониторе.** Замечание 1 говорит «масштабы великоваты, особенно на 27″ 2K, на 24″ терпимее». Замер при вьюпорте референса расхождения с Fleet не нашёл (§5.5 плана): промежутки, ширины панелей, шаг строки и высота вкладки совпадают. Значит речь про физический размер на конкретном экране, а он зависит от масштабирования ОС, и «просто уменьшить токены» означало бы уехать от референса, который владелец принял. Правильное лекарство — ручка «плотность интерфейса» в настройках (3 ступени), но она требует перевода ВСЕХ размерных токенов в rem и пере-замера, то есть отдельного прохода (Ф-36). Вопрос: нужна ли ручка, и какой масштаб ОС стоит на 27″ 2K — по нему видно, во сколько раз расходится физика | продуктовое решение и цена отдельного пакета |
| В-9 | **Какие языки интерфейса продукт обещает.** Механизм переводимости построен (S3.7; устройство и границы — `STACK_DECISIONS.md` §1, числа — строка Ф-35). Чего фронт сделать не может и не должен: решить, какие языки продукт обещает, и выдумать сами переводы. Пока список из одного значения (`ru`), и каркасный пункт настроек честно говорит «сейчас интерфейс только русский» | продуктовое решение и обещание пользователю |
| В-11 | **Фразы отказа книги (PD-173) — на утверждение.** Машинную причину несёт контракт, слова пишет клиент. ⚠ **Словарь с тех пор сменился, фразы ниже собраны на 0.2.3 и при разморозке пере-собираются:** канон даёт ЧЕТЫРЕ причины — `parser_unavailable` переименован в `processing_failed`, добавлен `content_refused` (`docs/architecture/14-api-contract/openapi.yaml:1492`=`enum: [source_unreadable, not_configured, processing_failed, content_refused]`), а карта «код → фраза» живёт приложением А компаньона. Фразы сочинила сессия S4 по слову владельца 14.08 и они ждут его «да»: «Файл не удалось разобрать на разделы» / «Проверьте файл — возможно, это не текст книги — и добавьте её заново»; «Сервис пока не готов принять эту книгу» / «Файл здесь ни при чём: повторная загрузка поможет не раньше, чем мы это наладим»; «Не удалось обработать файл на нашей стороне» / «Файл здесь ни при чём: попробуйте добавить книгу позже»; неизвестная причина — «Книгу не удалось принять» / «Причина не названа. Попробуйте добавить книгу заново или позже» | продуктовая формулировка, которую видит пользователь |
| В-2 | **Авторское право на текст фикстур.** Витрина использует короткую выдержку из настоящего прогона (蛊真人). Правило проекта уже есть: `eval/.gitignore:4` держит копирайтные тексты вне git. Сейчас взят объём под проверку плотности и не больше; нужно ли убрать совсем и заменить синтетикой — решать владельцу | юридика |
| В-4 | **Чем подписывать главу в дереве, если заголовок — ровно «Глава N».** Титул движок рендерит детерминистически из шаблона пары (`configs/langpacks/zh-ru/heading.txt`: `template Глава {n}`), а подзаголовок остаётся телом текста и названием НЕ является. На 2284 разделах это дерево из 2284 одинаковых по форме строк. Оставить так, показывать номер иначе или просить у контракта что-то ещё — продуктовое решение. Артефакт §1.4 и К-3 | продуктовая формулировка, которую видит пользователь |
## Хроника
### 15.08 — приёмка S4 оркестратором №17: ПРИНЯТО и залендено (`267aa35`); контракт 0.2.3 в каноне (D39.135)
Панель 5 линз в изолированных копиях (слепой вердикт по заказу+диффу · охота вне карты · пере-ран гейтов · линза истинности спеки против кода платформы · кросс-модельный текст-аудит Opus). Пере-ран: `check` 335/335 · `check:full` EXIT=0 (8 маршрутов, 11 сценариев, axe 0 блокирующих) · spectral/типы/дрейф зелёные · до-пакные 157 ключей и чанк 724130 подтверждены обратным применением диффа байт-в-байт · живые нарушения гейтов — красные. Ратификации и confirm-лист владельцу — D39.135.
**Фикс-лист ФС (носитель состава — эта запись; вход промта S5):** ФС-1 (major, мир intake) прогон над загруженной книгой стартует с `begin(0)` — общий прогресс 0/0 весь прогон, ETA = NaN (лечение: begin суммой units_total глав); путь заказа §4 «книга из формы переводится» в мок-мире добить · ФС-2 showcase: принятый старт прогона не меняет мир — следующее чтение отдаёт прежнее состояние, «Перевести» выглядит как ничего · ФС-3 мир intake: повторный старт переиспользует id прогона — поток не переподписывается, translating вечно (verify_bank тем же кластером: наблюдаемого эффекта в моках нет, awaiting_bank недостижим) · ФС-4 `BookIntake.title` maxLength 200 не держит никто на клиенте (TextField без лимита — собственная спека нарушаема своим клиентом) · ФС-5 докблок `upload.ts` несёт СНЯТОЕ правило «field after file → 400» (неверно для необязательного) · ФС-6 ИСПОЛНЕНО 02.09: порядковый номер шага spectral убран из обоих доков (греп `шестым шагом` по зоне пуст; состав шагов сверяется по `package.json`, `STACK_DECISIONS.md` §3) · ФС-7 мок считает части формы по ВСЕЙ форме (платформа — до файла) и меряет 413 по file.size (платформа — по всему телу) — мок строже провода · ФС-8 флейк сцены refusals: closeModal не дождался закрытия за 5000 мс (1 из 3 на тихой машине) · ФС-9 `role="status"` оборачивает байтовый прогресс отправки — на живом XHR скринридер зачитывает каждое обновление (в регионе — только смены состояний) · ФС-10 группа из одного раздела подписывается «разделы 201201» · ФС-11 интейк-мир: ПЕРВОЕ нажатие «Перевести» всегда 409 (счётчик; кандидат — маркер) · ФС-12 после-пакные числа Ф-35 слегка отстают от дерева (пересборка: 800293 / 246670 gzip против записанных 800219 / 243446).
**Поправки к записи S4** (сама запись — в [archive/frontend-PROGRESS-S0-S4.md](archive/frontend-PROGRESS-S0-S4.md); чужой текст не редактирую): «словарь платформы — четыре значения» → в коде ПЯТЬ (пропущен `schema_mismatch`) · «одна из трёх фраз сегодня недостижима» → на 15.08 недостижимы были ВСЕ ТРИ: платформа `reject_reason` не проецировала, доезжала только ветка неизвестного. ⚠ Пере-сверено 02.09: с тех пор проекция ПОСТРОЕНА — пять внутренних причин сводятся к трём проводным (`platform/internal/ingest/vocabulary.go:59`=`func ContractRejectReason`), то есть фразы В-11 стали достижимы и поправка касается только архивной записи · §1/§2 записи несут снятое правило PD-172 «поле после файла = 400», которое сама же §9а опровергла (код и спека исправлены, текст записи — нет) · «136 проверок» = 134 (наивный греп ловил 2 строки vite) · «31 строка DOM / 59 618px» — замер S2 04.08, не этого пака · «46 находок → 6 выжило» = 5 различных (одна — дубль) · три поправки к записи S3.7 из заказа §6: разобрана только цена бандла; «дрейф ширин hidden» и «счёт 106 из 119» остались на записи оркестратора 14.08 (носитель там, дефекта сессии нет — фиксирую для полноты).
*(Запись приёмки S4 с фикс-листом ФС — ВЫШЕ, она живая; всё остальное по S0S4 вынесено в архив, см. шапку.)*
## Пинг оркестратора №17 — 16.08.2026 (зона во фризе; контракт-ревью принято D39.138 — четыре ваших вопроса ОТВЕЧЕНЫ, входы разморозки)
Контракт-ревью API v0 отработало отдельной сессией и ПРИНЯТО (отчёт — `docs/research/28-contract-review.md`; решения владельца — его §8, ратификация D39.138). Заказан ЛОМАЮЩИЙ батч 0.3.0 (строка 183 единого бэклога) — типы перегенерируются после его лендинга; до него нормативной остаётся 0.2.3. ⚠ Читать ОРИГИНАЛ отчёта, не пересказ. По вашим строкам:
16. **Ф-56 · Ф-57 · Ф-61 · Ф-62 · Ф-43 — ответы ревью, вошедшие в канон** (0.3.0…0.9.0): ячейки бэклога переписаны по нему, при разморозке читаются они, а не этот пинг. **К-6** (§8 п.11 отчёта): замечания показывать ВСЕ, в тексте сворачивать и раскрывать кнопкой, словарь ступеней заранее НЕ проектировать — хвост зоны Ф-21.
7. **Мок-находки §9 (чинить при разморозке):** отказ интейка триггерится маркером в ИМЕНИ файла (`mock/intake.ts:238`) — переключатель без аналога на сервере; стоп игнорирует `runId` (`mock/handlers.ts:190`); мир `scale`: чтения на ревизии 4102, кадры с 1841 — расходятся по построению (`mock/worlds.ts:136`); в `loading` любой POST уходит МИМО мока в реальную сеть (`handlers.ts:59`); переполнение обхода страниц = статус 0 = неотличимо от «сервер недоступен» (`client.ts:114``Loaded.tsx:65`); мок интейка считает ВСЕ части формы, платформа — только до файла (`intake.ts:212` против `v0.go:337-360`).
8. **Перф-входы S5 (§5б/Б-11а):** снять `refetchOnWindowFocus` для тяжёлых коллекций (замер: самый частый трафик порождает переключение вкладок, не пайплайн — 12 вкладок = 562 КБ на фокус) и поднять `staleTime` после появления ETag/304 у платформы; ErrorBoundary в зоне нет ни одного (Б-0: TypeError рендера при смене словаря волн) — завести при разморозке; 401 сегодня тупик без ссылки на вход (§4 №27) — зонная строка. Вопросы — через владельца.
**Дописка к пингу №17 (16.08):** гейт на утечку конвейера в провод — «на проводе нет имён стадий/волн и движковых словарей», машинный тест по образцу `generality.test.ts` — назначен вашей зоне (D39.138 п.2а; спек-сессия батча запишет правило в компаньон контракта). Строить при первом касании зоны вместе с синком зеркала и перегенерацией типов.
**Пинг оркестратора №17 — 16.08 (модель подписи банка, слово владельца; читать ПЕРЕД S5):** модель целиком — **D39.144** (подписывается ВЕСЬ банк одним ОК; пер-термная масс-подпись сотен строк НЕ строится; 409-гейт полноты убран из канона, `pending_decisions`/`complete` информационные). Зоне отсюда два следствия. Строки Ф-44/Ф-45/Ф-46 при разморозке читать через эту модель: «действие подписи» = один ОК + опциональные точечные правки, НЕ проход по строкам. ⚠ Экранов под пост-ридинговые правки банка («поправить/добавить термин → пере-генерация по вхождениям») НЕ строить до отдельного слова: механика не спроектирована нигде, полигон работает над точечным редактором (D39.144 п.1). Вопросы — через владельца.
**Пинг оркестратора №18 — 17.08.2026: ФРИЗ ПРОДЛЁН, разморозка отвязана от P7 (слово владельца, D39.147).** Прежнее условие «разморозка = лендинг P7 + гейт S5» БОЛЬШЕ НЕ ДЕЙСТВУЕТ: владелец 17.08 сказал морозить зону дальше — сначала движок и платформа доводятся до состояния «работают и отдают результат», и только потом фронт накручивается на готовую функциональность. Практически: **лендинг P7 зону не размораживает, промт S5 не выдаётся**, разморозка — отдельным словом владельца. Всё, что было записано как первое касание зоны (синк зеркала контракта 0.3.0 · перегенерация типов · моки · гейт утечки конвейера · фикс-лист ФС-1..12 · Ф-63/Ф-28 · пере-сборка фраз В-11 по словарю кодов), НЕ отменено — оно ждёт разморозки, а не P7. Направление, которое стоит знать заранее: моки при разморозке уступают реальному источнику — дев-стенд платформы существует с P6 (`tmplatformctl seed` + дев-вход), а форму «держать моки на уровне бэкендов или отдельно» владелец назвал направлением, но механику проектировать пока не просил. Живой smoke против дев-стенда остаётся легитимным и во фризе. Вопросы — через владельца.
**Пинг оркестратора №18 (второй) — 20.08.2026: фриз в силе, но зоне прилетели ДВЕ вещи из лендинга P7 и одно предложение по норме.**
1. **Контракт API — зеркало зоны синкается ОДНОЙ перегенерацией на ТЕКУЩИЙ канон** (пинг №20 п.4), а не по минорам; тела ломающих правок лежат в своих нотах (0.4.0 — D39.152 п.5). Что из них видно ЭКРАНУ: `Run.stop_requested` обязателен — прогон помнит, что его просили остановить, и переживает перезагрузку, поэтому «остановлено — работа на подписи банка, продолжить дёшево» рисуется по признаку, а не по догадке; `resume` отвечает двумя РАЗНЫМИ причинами — «прогон закончен, купите новый» против «пополните счёт» (фразы — В-11 по словарю кодов, приложение А компаньона).
2. **Читающая поверхность ПОСТРОЕНА и заленджена** (P7, D39.153): главы, юниты, замечания, проекция банка, поток событий SSE, модель ошибок с машинным `code`, условные чтения и сжатие, `Idempotency-Key`, `structure_version`. То есть триггер Ф-29 («полный снос `frontend/src/mock/`») по данным наступил — но РАЗМОРОЗКА ОТДЕЛЬНЫМ СЛОВОМ владельца, пинг №18 от 17.08 в силе, S5 не выдаётся. ⚠ Живой дев-стенд платформы существует и работает — при разморозке моки уступают ему, а не наоборот.
3. **Предложение по норме pre-commit хука (владелец не отвечал, поэтому это ПРЕДЛОЖЕНИЕ, а не решение).** В док-фрагмент хука 17.08 внесена строка «жалобы на хук — писать ВЛАДЕЛЬЦУ, а не тихо деградировать на воркэраунд или хак» (D39.148). Во фронтовом фрагменте хука такой строки нет. Смысл нормы: сессия, которой гейт мешает, обязана эскалировать, а не обходить — тихий обход выглядит как зелёный прогон и не виден ничем. Внести при первом касании зоны, если владелец не скажет иначе. ⚠ Записано здесь потому, что обязательство к ЧУЖОЙ зоне, живущее только в моей прозе, гейтами не видно по построению — поймано ревьюером полноты выгрузки на лендинге P7.
**Дописка к пингу №18-второму (20.08, свип доков при лендинге P7):** `frontend/docs/API_CONTRACT_INPUT.md` несёт собственный баннер «место такому — в архиве, перенос при ратификации делает оркестратор», а ратификация была ещё 04.08 — то есть перенос просрочен. ⚠ Испр. 21.08 по аудиту: первая редакция приписывала тот же баннер и `API_CONTRACT_DRAFT.md`НЕВЕРНО, его баннер говорит противоположное («ИСПОЛНЕНО, канон живёт не здесь»), живых якорей D-нот в него нет, и довод про якорь на него не распространяется — он переносим хоть сейчас. **Не переношу и объясняю почему:** нота D39.153 п.7(б) цитирует `API_CONTRACT_INPUT.md:258-264` как первоисточник провенанса пер-термного гейта, а D-ноты append-only — перенос убьёт живой якорь и линт якорей покраснеет. Диспозиция: переносить при разморозке зоны ТЕМ ЖЕ касанием, что правит якорь в D39.153 на архивный путь. До тех пор оба файла живут по старым путям законно.
## Записи оркестратора
### Правки доков ИЗВНЕ зоны — 0102.09.2026 (прямая санкция владельца 01.09 на документацию всех зон)
**Правила НЕ фронт-сессия:** ревизия оркестратора №22 (01.09) и проходы реза доков (02.09)
трогали `frontend/README.md` и `frontend/docs/*.md`. Зона остаётся ЗАМОРОЖЕННОЙ (D39.147), нового
заказа здесь нет. Находки ревизии — реестр `docs/DOC_REVISION_FINDINGS.md`.
**Не тронуто ни одним проходом:** `frontend/src/**` (код зоны), `frontend/docs/api-contract/**`
(зеркало 0.2.3 — ратифицированное отставание, D39.142 п.5), `frontend/docs/API_CONTRACT_INPUT.md`
(⚠ его строки НЕ сдвигать — причина в дописке к пингу №18-второму) и `frontend/docs/archive/**`.
**Факт, купленный проверкой исполнением:** носители В-3/К-6 в докладе
`docs/research/28-contract-review.md`**§6 и §8**, а НЕ §5 (§5 это «Предложение состава батча
0.3.0» и материала вопроса не несёт). Наряд дофикса указывал §5; ссылки в журнале стоят на §6/§8.
### Пинг оркестратора №22 — 02.09.2026 (закрытие смены: чистка доков)
**В вашей замороженной зоне тронуты только ДОКИ** (санкция владельца 0102.09). НЕ тронуты:
зеркало `frontend/docs/api-contract/**` (отставание ратифицировано D39.142 п.5), `src/**`.
Разбор — нота **D39.186**.
**Остаток, который чинит зона:** `frontend/src/showcase/languages.ts` — мёртвый указатель, найден
ревизией (`N060`); кода я не касаюсь.
**Содержательная находка сверх наряда:** строка В-8 журнала обосновывает запрет укорачивать фразу
паузы тем, что «фраза зарезервирована за владельцем» — но К-13, на который эта резервация ссылалась,
закрыт D39.132 п.2а. Обоснование В-8 держится на закрытом носителе; проверьте при разморозке.