519 lines
91 KiB
Markdown
519 lines
91 KiB
Markdown
# Журнал зоны «Фронт»
|
||
|
||
## ПИНГ оркестратора №20 → зоне фронта (30.08, аудит доков; зона ЗАМОРОЖЕНА — это к первому касанию при разморозке)
|
||
|
||
Зона заморожена, работы не заказываю: перечисленное ждёт разморозки и правится ТВОЕЙ сессией (её журнал и бэклог — твоя зона).
|
||
1. **В-3 (каким словом называть ступень замечания) — с листа владельца СНЯТ.** 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 и прошла паки P0–P11 плюс sqlc; половина вопроса снята фактом.
|
||
4. **Состояние зеркала контракта — 0.2.3 против канона 0.8.0** (и 0.9.0 придёт с лендингом P12): шесть миноров, первый из них ломающий, 16 операций против 20. Синк зеркала + перегенерация типов — первое касание при разморозке, ОДНОЙ перегенерацией.
|
||
|
||
|
||
> **Файл переименован 04.08 по слову владельца: был `PROGRESS.md`, стал `frontend-PROGRESS.md`.**
|
||
> Причина — путаница с `docs/PROGRESS.md` оркестратора: два файла с одним именем в одном
|
||
> дереве, и ссылка «PROGRESS.md» без пути читалась по-разному в разных доках.
|
||
>
|
||
> **Оркестратору:** прогресс фронта пишется СЮДА же, в этот файл, а не в `docs/PROGRESS.md` —
|
||
> так у зоны один журнал и конфликтов правок в общем файле не возникает (слово владельца 04.08).
|
||
>
|
||
> Зонный журнал: сессии фронта пишут сюда сами и работают независимо (решение владельца 02.08).
|
||
> Хвосты — `BACKLOG.md`, план и замеры — `FRONTEND_PLAN.md`, ратифицированные пины —
|
||
> `STACK_DECISIONS.md`, контракт API — спека `api-contract/openapi.yaml` и спутник
|
||
> `API_CONTRACT_DRAFT.md` (`API_CONTRACT_INPUT.md` — исполненный вход, под ⚠-баннером).
|
||
> Сверху — текущее состояние, ниже — хроника по сессиям.
|
||
|
||
## 📌 ПИНГ ОРКЕСТРАТОРА (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`.
|
||
|
||
## Текущее состояние
|
||
|
||
> **Запись оркестратора №15, 07.08.** Абзацы ниже — состояние на 04.08, и первый из них с тех пор
|
||
> УСТАРЕЛ: «замок на входе закрыт, контракта API v0 нет» больше не так. Контракт ратифицирован
|
||
> **D39.99**, канон — `docs/architecture/14-api-contract/` (спека + компаньон-README), зонная копия
|
||
> `api-contract/openapi.yaml` — байт-зеркало канона. Вторая сторона контракта, платформа, **написана,
|
||
> принята и залендена** (D39.109): вход через OIDC, сессии, кредитный леджер, админ-CLI. Строка 95
|
||
> единого бэклога закрыта.
|
||
>
|
||
> **S3 ИСПОЛНЕН и ПРИНЯТ D39.115** (`60595f6`); промт отработан и заархивирован. Было в этой строке до 08.08: «запускается по слову владельца, промт готов» (`S3_SESSION_PROMPT.md`) и с 07.08 несёт три
|
||
> новых пункта списка правок спеки: **А-нуль** — шапка `info` спеки исправлена мной (три дня она
|
||
> называла себя нератифицированным черновиком S3 и ссылалась на несуществующий рядом компаньон;
|
||
> S3 остаётся бампнуть `version`) · **В-трис** — управляемый потолок прогона, решение владельца
|
||
> 07.08 (шкала в ИНТЕРФЕЙСЕ от минимума до доступного остатка, единица — ГЛАВЫ, не доллары, иначе
|
||
> это амендмент D39.84; максимум = баланс минус открытые холды ⚠ ФОРМУЛА ОШИБОЧНА, superseded D39.115 п.2(а): максимум = Balance КАК ЕСТЬ, холд уже дебет (вычитание дважды резало шкалу; испр. D39.125); носитель пересчёта «главы → деньги»
|
||
> — платформа, ручка объявляется правкой спеки) · **В-кватер** — фронт живёт на ТОМ ЖЕ origin, что
|
||
> платформа: CORS-слоя в ней нет вовсе, preflight `OPTIONS` с чужим `Origin` получает 401 от гарда
|
||
> сессии (замер на живом бинаре, PD-96 регистра платформы) ⇒ в деве ходить через прокси
|
||
> dev-сервера, кросс-origin не проектировать.
|
||
>
|
||
> **Мелочь зоны, которую стоит закрыть при следующем касании:** `API_CONTRACT_DRAFT.md` — второй
|
||
> экземпляр компаньона; канон компаньона теперь `docs/architecture/14-api-contract/README.md`,
|
||
> поэтому зонному файлу нужен баннер-указатель, иначе это второй носитель одного состояния.
|
||
|
||
|
||
> **Запись оркестратора №15, 08.08 (после приёмки S3) — СЛОВО ВЛАДЕЛЬЦА О КАЧЕСТВЕ, гейт на S4.**
|
||
> Владельцу НЕ нравится текущее качество фронта; названная претензия — «логика спама вкладками»:
|
||
> вкладки обязаны работать **ровно как в VS Code** — одиночный клик открывает PREVIEW-вкладку,
|
||
> следующий одиночный клик ЗАМЕЩАЕТ её содержимое (новая вкладка не плодится), пин вкладки — по
|
||
> двойному клику/взаимодействию с содержимым. Полный список претензий владелец сформулирует
|
||
> отдельным входом — этот абзац лишь первый пункт, НЕ весь список. **Диспозиция оркестратора:**
|
||
> S4 НЕ стартует до списка; когда список придёт — сначала «S3.5 фикс-пак оболочки» (вкладки
|
||
> по VS Code-модели + Ф-19 прокрутка + список владельца), затем S4 на починенной оболочке.
|
||
> Промт S3.5 выдаёт оркестратор по слову владельца.
|
||
|
||
> **Запись оркестратора №16, 09.08 — список владельца ПРИШЁЛ, промт S3.5 ВЫДАН.** Абзац выше
|
||
> исполнен: полный список претензий (24 замечания, снятые владельцем с живого прогона витрины)
|
||
> получен 09.08 и завёрнут в промт **`S35_SESSION_PROMPT.md`** (эта папка): VS Code-модель
|
||
> вкладок + Ф-19 + все 24 номера блоками, приёмка кадрами ДО/ПОСЛЕ и playwright-сценариями,
|
||
> референс драг-ручки — vojo (`src/app/components/page/Page.tsx:191-300`, `style.css.ts:11-70`).
|
||
> Запуск сессии — по слову владельца; S4 остаётся гейчен до приёмки S3.5. Попутное: замечание
|
||
> (10) владельца независимо подтвердило Ф-21 — полоска замечания нечитаема без слова; само
|
||
> слово ступени — по-прежнему В-3 на владельце. Референс `antigravity_add_folder.png` докинут
|
||
> владельцем 09.08 (модал добавления книги, замечание (12)).
|
||
|
||
> **Запись фронт-сессии S3, 08.08.** Абзац «S3 НЕ сделана: замок закрыт» ниже — состояние на
|
||
> 04.08, и он УСТАРЕЛ целиком: замок открыт, **S3 сделана**. Хроника — первым разделом ниже.
|
||
> Коротко: `src/api/` асинхронен и разговаривает HTTP; MSW стоит СЕТЕВЫМ моком, поэтому приложение
|
||
> делает настоящий `fetch` и настоящий `EventSource`; фикстур шесть миров, по маршруту на каждый;
|
||
> живой прогресс идёт по SSE и двигает счётчик в браузере (замерено, не предположено); `types.ts`
|
||
> удалён, экраны живут на типах контракта; ветка неизвестного значения стоит на шве. Спека
|
||
> бампнута до **0.2.0** со всем списком правок промта — канон правит оркестратор по
|
||
> канон `docs/architecture/14-api-contract/` (патч ПРИМЕНЁН и удалён, D39.115). Ф-15 и Ф-22 закрыты, заведены Ф-26..Ф-31.
|
||
> `npm run check` — 7 шагов, **108 тестов** на 08.08 (число живёт в батарее, а не здесь: сверяется прогоном), зелёный; `npm run shot` — шесть маршрутов, гейт
|
||
> доступности зелёный на всех.
|
||
|
||
> **Запись фронт-сессии S3.5, 09.08.** Фикс-пак оболочки по 24 замечаниям владельца ИСПОЛНЕН —
|
||
> прогон по всем номерам первым разделом хроники ниже. Коротко: вкладки живут по модели VS Code
|
||
> (предпросмотр/закрепление), Ф-19 закрыта keep-alive панелей, полоска ресайза больше не залипает
|
||
> (причина найдена в коде библиотеки), настройки и добавление книги открываются модальными окнами,
|
||
> лупа стала палитрой быстрого перехода, банк перепридуман со спойлерами по окну применимости,
|
||
> кнопка-заглушка «Подписать банк» снята в пользу честного состояния, палитра ушла в тёплый подтон
|
||
> (три варианта кадрами), причина «шакальных» иконок найдена в сетке набора и вылечена. Гейты
|
||
> зелёные, **контраст axe — ноль узлов на всех семи маршрутах** (Ф-11 закрыта замером).
|
||
> Адверсариальное ревью тремя линзами исполнено, находки и диспозиции — там же; две из них были
|
||
> моими дефектами по существу (правка полос увела ОТ референса; тронуто слово паузы, закреплённое
|
||
> за владельцем) и откачены.
|
||
> Ждут владельца: В-7 (масштаб интерфейса), В-8 (слово состояния в дереве), Ф-38 (защита вкладки
|
||
> «Замечания»), выбор палитры. Ждёт оркестратора: два черновика правки спеки — поля банка и
|
||
> `BookIntake.title` (в конце записи S3.5).
|
||
|
||
> **Запись фронт-сессии S3.6, 10.08.** Второй круг замечаний владельца (10 пунктов, снятых
|
||
> с прогона после S3.5) отработан. Коротко: палитра переведена на НЕЙТРАЛЬНЫЙ ряд, снятый
|
||
> замером с `fleet_2.png` и `antigravity_*.png` (тёплый подтон S3.5 был моей отсебятиной
|
||
> ПРОТИВ этих же референсов); вкладки перестроены по замеру fleet_2 — полоса вкладок это ХРОМ,
|
||
> активная вкладка вырезана из него цветом полотна; найдена и починена причина обрезки коротких
|
||
> названий; ручка ресайза перенесена из vojo дословно, включая числа упоров; линия жёлоба
|
||
> читалки — в цвет оболочки, ширина набора отпущена по окну; **банк памяти переделан в таблицу**
|
||
> и открывается вкладкой в центре, спойлер снят с ПЕРЕВОДА и поставлен на описание; иконки книги
|
||
> и главы разведены и несут состояние цветом. Первым разделом записи — АУДИТ всех 24 буллетов
|
||
> S3.5 по коду (просьба владельца), с честными вердиктами второго круга.
|
||
> Ждут не меня: две дыры платформы/контракта под банк (ниже, «Жалобы») и подписной механизм S5.
|
||
|
||
> **Сессия S3.6 ЗАКРЫТА 10.08 (разделы 12–15 хроники).** Дерево готово к лендингу, фронт не
|
||
> коммитит. Гейты: `npm run check:full` зелёный — 160 тестов, 7 маршрутов, 7 сценариев, ноль
|
||
> блокирующих нарушений axe, драг панели p90 17 мс. Новые строки бэклога Ф-49…Ф-51 (свежесть
|
||
> текста главы · потерянные кадры потока · resync сбрасывает один гард из двух) заведены по
|
||
> ресёрчу отдельным агентом и проверены по коду; два моих собственных предложения тот же ресёрч
|
||
> опроверг, и это записано в разделе 15 вместе с долгами сессии.
|
||
|
||
> **Запись оркестратора, 14.08 — ГЕЙТ S4 ПАЛ (платформа P5 принята, D39.130): живой `POST /books`
|
||
> существует; S4-промт выдаёт оркестратор по слову владельца** (вход: экраны библиотеки/загрузки +
|
||
> находки приёмки S3.7 + спек-правка 0.2.3). Попутно аудит-свип корпуса 14.08 — стейлы зонных доков,
|
||
> закрыть S4-сессией (или раньше): `FRONTEND_PLAN.md:42-43` «платформа = ноль строк кода» и `:207-208`
|
||
> ссылка на удалённый `src/api/types.ts`; `STACK_DECISIONS.md:179` «тулчейн ≥1.26.5» → ратифицирован
|
||
> **1.26.6** (D39.130), там же `:144` состав `npm run check` отстал (4 шага против нынешних 7);
|
||
> `FRONTEND_SESSION_PROMPT.md:62` «скелет P0 ждёт приёмки» → P5 принята. Два числа живут в двух
|
||
> версиях без арбитража: ключей i18n — 147 (запись S3.7 ниже) против 157 (Ф-35 и живой `ru.ts`;
|
||
> верно **157**) · цена бандла +7999 (запись) против +6971 (Ф-35). Долги без Ф-строки: RTL-проверка
|
||
> (триггер «появление I18nProvider» НАСТУПИЛ в S3.7) · спойлер достаётся поиском по странице/печатью
|
||
> в PDF (продуктовое слово) · канвас-замер не знает `lang` при двух CJK-лицах — завести Ф-строки
|
||
> S4-сессией. Промты S3/S3.5/S3.7 архивированы с баннерами-исходами (`docs/archive/prompts/FRONTEND_S3*`),
|
||
> зонные копии сняты.
|
||
>
|
||
> **Дописка 14.08 (вечер): S4-промт ВЫДАН** — `S4_SESSION_PROMPT.md` (эта папка), запуск одобрен
|
||
> владельцем. Его решения того же дня, внесённые в промт: (1) `BookIntake.title` — в спек-правку
|
||
> 0.2.3 (ратификация оркестратора как исполнение замечания 12 S3.5, владелец подтвердил);
|
||
> (2) продуктовые фразы причин отказа PD-173 пишет S4-сессия сама — по реальному флоу отказов
|
||
> платформы, в границах ПТ-33, на утверждение владельцем по отчёту; (3) Ф-52 — `--color-danger`
|
||
> осветлить на ступень до ≥3:1 силами S4 (закрыть замером).
|
||
|
||
> **Запись фронт-сессии S4, 14.08.** Путь «у меня есть файл → книга переводится» построен и прожит
|
||
> в мире моков: форма загрузки отправляет книгу (XHR — `fetch` прогресса ТЕЛА запроса не даёт вовсе),
|
||
> 201 приносит `parsing`, разбор — отдельный видимый шаг БЕЗ выдуманного процента, отказы интейка
|
||
> (400/404/408/413) и отказ книги (три причины PD-173 с разными советами) — состояния формы и
|
||
> карточки, а не алерты. Форма запуска даёт потолок в ГЛАВАХ из `CeilingBounds`; потолочный стоп
|
||
> прожит по контракту (`EventCeiling` + `paused`), и оповещение — не тост, а несъезжающая фраза в
|
||
> статус-полосе и на карточке (аргумент в записи). Библиотека: дерево свыше 200 разделов
|
||
> складывается по сотням, книга в дереве стала ВЫБИРАЕМОЙ (без этого половина статусов была
|
||
> недостижима на карточке), все одиннадцать состояний прожиты. Контракт зонной копии бампнут до
|
||
> **0.2.3** (PD-172/173/174/180 + `BookIntake.title`); ⚠ по коду платформы `not_configured` на
|
||
> отклонённую книгу сегодня не попадает вовсе — названо в записи. Девять несущих находок приёмки
|
||
> S3.7 разобраны, и одна из них ОПРОВЕРГЛА клейм S3.7 замером (resync рвал живой поток, когда
|
||
> чтение медленное).
|
||
>
|
||
> ⚠ **Три ошибки в самом промте S4, найденные вторым проходом ревью и исправленные** (промт писала
|
||
> нейросеть, и это ровно тот случай): (1) «поле после файла = 400» — платформа так НЕ делает, она
|
||
> перестаёт читать на файле, и необязательное поле за ним просто теряется (спека и фикстура
|
||
> исправлены, два теста); (2) §7 велит записать «7 шагов у `npm run check`» — их шесть, и первая
|
||
> редакция моей правки повторила ошибку промта; (3) §4 сводит 409 на старте к «уехал потолок», а
|
||
> платформа отвечает им на пять разных состояний — совет на экране сделан причинно-нейтральным.
|
||
> Ждут владельца: **В-10** (спойлер — защита или вежливость) и **В-11** (фразы отказа PD-173 на
|
||
> утверждение).
|
||
|
||
> **Запись фронт-сессии S3.7, 10.08.** Долги слоя данных закрыты тестами, падающими на до-фиксном
|
||
> коде (Ф-49…Ф-51), контракт зонной копии бампнут до **0.2.2** (`BankTerm.sense` обязателен),
|
||
> строки интерфейса уехали в КАТАЛОГ (`src/i18n/`, 147 ключей, механизм — `@internationalized/string`,
|
||
> уже лежавший в дереве под react-aria-components), и весь код зоны переведён на английский:
|
||
> комментарии, имена тестов, сообщения ошибок, логи скриптов. Держат это два гейта, и каждый
|
||
> проверен ЖИВЫМ нарушением — ESLint ловит текст в разметке МЕСТОМ, а не алфавитом (ловит и русский,
|
||
> и английский литерал), `src/i18n/catalogue.test.ts` подметает комментарии, CSS и python.
|
||
> `npm run check` зелёный: **266 тестов** (было 160), `npm run check:full` — 7 маршрутов и
|
||
> **9 сценариев** (добавлены `hidden` и `zoom`: раскладка при 125/150/200% с прогоном axe).
|
||
> ⚠ Находка приёмки 8.1 (HIGH) **не воспроизвелась** — замер в браузере в записи ниже, механизм,
|
||
> написанный было под неё, снят; сценарий на тот же путь оставлен сторожем (Ф-53).
|
||
|
||
> **Запись оркестратора, 10.08 — ПРИЁМКА S3.7: принято и залендено (D39.129).** Гейты
|
||
> пере-прогнаны исполнением (279 тестов, 9 сценариев, EXIT=0); **арбитраж по 8.1 — права
|
||
> СЕССИЯ, HIGH приёмки S3.6 снята как моя ложноположительная** (разбор — приёмочной записью
|
||
> хроники). 12 находок ревью (1 high: ложный клейм про импорт `fill.ts` сценами) — носитель:
|
||
> блок находок следующего фронт-промта (S4). Канон контракта догнал 0.2.2 диффом при лендинге,
|
||
> зеркало байт-равно. **S4 — следующий этап; промт выдаёт оркестратор** (после приёмки
|
||
> платформы P5 — экран загрузки стоит на её `POST /books`).
|
||
|
||
> **Четвёртый круг замечаний, 10.08 (раздел 12 хроники).** Четыре бага владельца по таблице банка
|
||
> закрыты, и один из них был МОЙ механизм: заморозка ширин (`useSettledWidth`) оставляла таблицу
|
||
> сжатой после драга, а перезамер показал, что она ничего не покупала — драг держит p90 17 мс и
|
||
> без неё. Ширины отданы алгоритму библиотеки, содержимое меряется канвасом по всему банку и идёт
|
||
> ПОТОЛКОМ столбца. Спойлер описания переделан с фильтра на боксе на размытие глифов. Сверх списка
|
||
> владельца найдено шесть дефектов того же класса — в том числе замер по запасному шрифту (−4.7%
|
||
> ширины) и живой `getComputedStyle`, обнулявшийся за время загрузки шрифтов. Приёмка: 158 тестов,
|
||
> 7 сценариев, 4 новые проверки, каждая падает на откате своего фикса.
|
||
|
||
> **Запись оркестратора, 10.08 — ПРИЁМКА S3.6: принято и залендено (D39.127).** Гейты
|
||
> пере-прогнаны исполнением, 12 находок ревью (1 high) и поправки к записи S3.6 — первой записью
|
||
> хроники ниже. Промт **S3.7** выдан (`S37_SESSION_PROMPT.md`: Ф-49…Ф-51, Ф-47 ратифицирован,
|
||
> Ф-40, Ф-25, Ф-35 — словарь строк + гейт против хардкода русского; ⚠ Ф-35 в первой редакции
|
||
> промта отсутствовала — пропуск поймал владелец при ревью промта, D39.127 п.2г), запуск
|
||
> по слову владельца; **S4 — после приёмки S3.7.** Экспорт банка заведён строкой 169
|
||
> единого бэклога (Ф-43).
|
||
|
||
- **Пройдено:** 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 — ждёт приёмки)**.
|
||
- ⚠ **АБЗАЦ НИЖЕ ИСТОРИЧЕСКИЙ (04.08), читать как хронику:** замок с тех пор открыт (контракт ратифицирован D39.99), S3 исполнен и принят D39.115. Оставлен, потому что объясняет, ПОЧЕМУ S3 однажды остановилась, а не как диспозиция.
|
||
- **S3 НЕ сделана: замок на входе закрыт, проверено исполнением 04.08.** Контракта API v0
|
||
по-прежнему нет (`docs/architecture/14-api-contract.md` отсутствует; строка 95 единого
|
||
бэклога — статус «дизайн-промт по слову владельца», то есть не исполнена). Вместо S3 сессия
|
||
сделала то, что предписывает её же промт на этот случай: **довела Ф-14 до артефакта
|
||
`API_CONTRACT_INPUT.md`** и остановилась. Кода не написано ни строки — это диспозиция,
|
||
а не недоделка: моки, снятые не с того контракта, разойдутся с API, ровно ради чего
|
||
строка 95 и заведена.
|
||
- **Написан черновик контракта, принят в работу ревью оркестратора и ДОФИКШЕН (04.08).**
|
||
Форма сменена решением владельца: нормативная поверхность — **OpenAPI 3.1
|
||
`docs/api-contract/openapi.yaml`**, `API_CONTRACT_DRAFT.md` стал обязательным спутником
|
||
(провенанс ✓/◆/○, обоснования, К-вопросы — то, чего YAML не выражает). Дом ратифицированной
|
||
копии — `docs/architecture/14-api-contract/`, зона оркестратора; после ратификации типы
|
||
генерятся из перенесённой копии — контракт первичен.
|
||
- **Гейт контракта живой:** `npm run check` стал шестишаговым (spectral на строгом пороге),
|
||
`openapi-typescript` генерит `src/api/schema.ts`, тест дрифта не даёт спеке и типам
|
||
разъехаться, ветка неизвестного значения стоит на шве (`src/api/contract.ts`), MSW отдаёт
|
||
тело в форме контракта. Четыре формы нарушения проверены живьём (`FRONTEND_PLAN.md` §5.4.2).
|
||
- **Ждёт оркестратора, четыре вещи:** (1) ратифицировать спеку и перенести в
|
||
`docs/architecture/14-api-contract/`, либо вернуть с правками; (2) три зависимости, которых
|
||
фронт заводить не может — **артефакт экспорта БАНКА** (строки в едином бэклоге нет вовсе:
|
||
101 даёт таблицу подписи, не банк), **механизм поднятия потолка** (без него `resume` после
|
||
стопа по потолку прогон не двигает) и правка устаревшего комментария провенанса
|
||
`store/migrate.go:193`; (3) залендить дерево сессии; (4) вопросы владельцу — В-4, В-5 ниже
|
||
и К-1..К-12 спутника, из них продуктовых пять, остальные — автору контракта и платформе.
|
||
- **Ждёт владельца:** контраст палитры (`BACKLOG.md` Ф-11) и два вопроса ниже — В-1 диск,
|
||
В-2 копирайт.
|
||
- **Ждёт движка:** манифест глав и пофазный прогресс (единый бэклог, строки 99–100),
|
||
к S5 — машиночитаемая таблица подписи банка (строка 101).
|
||
- `npm run check` зелёный (6 шагов, 80 тестов), `npm run check:full` зелёный, гейт доступности
|
||
зелёный на обоих маршрутах. Гейтов стало больше: включён Ф-4 (отступы), закрыты Ф-9 и Ф-10,
|
||
по ревью оркестратора 04.08 добавлены динамические импорты швов и языковая ветка в CSS.
|
||
- **Карта канона для фронт-сессии — `FRONTEND_PLAN.md` §0.1, транспорт — §0.2.** Заведены
|
||
после того, как две ошибки S1 пришли из непрочитанного канона; читать до кода, не после.
|
||
- **Передача следующей сессии написана — `S3_SESSION_PROMPT.md`** (сессией S2 по просьбе
|
||
владельца; ратифицирует оркестратор): вход в S3 под замком контракта API, который сессия
|
||
проверяет сама, плюс фолбэк на Ф-14, если замок закрыт, и перечень ловушек, купленных S2.
|
||
- **Гейты стоят и на коммите:** pre-commit хук (02.08, вторая сессия) гоняет `npm run check`
|
||
для коммитов с frontend-путями и блокирует смесь зон и файлы «никогда не коммитить»;
|
||
ставится сам при `npm install`. Обход — только осознанный `git commit --no-verify`.
|
||
|
||
## Решения владельца по продукту
|
||
|
||
Записываю здесь, потому что они меняют раскладку из §2 промта, а промт правит не фронт-сессия.
|
||
|
||
### 04.08 — где стоит «+» в рядах вкладок (закрывает половину Ф-7)
|
||
|
||
Вопрос был поставлен так: промт требует «+» **вместе с действием**, которое он запускает, а наборы
|
||
вкладок у нас фиксированные (слева `Книги · Поиск`, справа `О книге · Замечания · Банк`) —
|
||
пользователь их не расширяет, и fleet-овский смысл «+» («добавить инструмент») к ним не применим.
|
||
|
||
Владелец: **«+» слева = «Добавить книгу»**. Отсюда:
|
||
|
||
| Было | Стало | Почему |
|
||
|---|---|---|
|
||
| «+ Добавить книгу» строкой в дереве, «+» в рядах вкладок нет | «+» в ряду вкладок ЛЕВОЙ панели, строка из дерева убрана | одна вещь — одно место; в референсе «+» стоит ровно там |
|
||
| — | в центре и справа «+» нет | добавлять в фиксированный набор нечего, кнопка вышла бы декоративной |
|
||
|
||
В 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. Формы переписаны по настоящим:
|
||
|
||
- банк — таблица `glossary` (`backend/internal/store/migrate.go:176`): `src · dst · type · sense ·
|
||
status · source · since_ch/until_ch`. Статусы подписи ровно три: `auto|draft|approved`,
|
||
провенанс — `seed|ruby|mined` (⚠ **испр. 04.08 по ревью оркестратора:** здесь стояло
|
||
`seed|ruby|auto` плюс `mined` по комментарию схемы; комментарий устарел, а литералы `"auto"`
|
||
в коде пишут СТАТУС, не провенанс — `membank/memseed.go:328`).
|
||
**Типы — исправлено 04.08 по ревью оркестратора:** сама колонка `type` в схеме свободный текст,
|
||
и её комментарий перечень не закрывает («name|term|title|…»), поэтому истина — гейты в Go:
|
||
классификатор знает четыре (`terminology/classify.go:15`), банкнота принимает их же плюс
|
||
`nickname` (`pipeline/banknote.go:74`). Итого пять: `name|place|title|term|nickname`.
|
||
`org` и `fullname` движок не знает вовсе — они приехали в тип фронта из этой самой строки;
|
||
- пары — `ChunkExport` из `tmctl export --pairs` (`backend/internal/pipeline/export.go:25`):
|
||
`chapter · chunk_idx · disposition · flag_reason · detail · final_text · source`;
|
||
- причины замечаний — enum из `backend/internal/pipeline/disposition.go:56-104`.
|
||
|
||
**Следствие для интерфейса, которое из этого выросло:** движок говорит своим языком —
|
||
`sanitizer_stripped`, «CJK leak in the ru output: 第一节». Промт §4.1 запрещает показывать это
|
||
пользователю. Значит между движком и экраном обязан стоять **слой перевода вердиктов
|
||
в продуктовые понятия**, и он заведён одной картой в данных: причина → человеческая фраза;
|
||
поле `detail` не показывается никогда. Это же ПТ-33 реестра требований.
|
||
|
||
### 02.08 — шов данных заведён: моки выкидываются одной папкой
|
||
|
||
Владелец: **«все моки рано или поздно придётся выкинуть; нужна минимальность моков,
|
||
минимальная инвазивность в код и изолированность»**. На вопрос «соблюдаешь ли» честный ответ
|
||
был «нет»: правило «данные только через `src/api/`» стояло в плане, а в коде компонент
|
||
импортировал фикстуру напрямую — шва не было вовсе. Радиус поражения был мал (один экран),
|
||
но образец для S2–S7 задавался неправильный.
|
||
|
||
Заведено: `src/api/` — типы и функции, единственный вход; `src/mock/` — фикстура, которую
|
||
видит только `api/`. Правило теперь машинное, а не на совести ревьюера: `no-restricted-imports`
|
||
на `**/mock/**` и запрет сетевых вызовов, с исключением для `src/api/**`.
|
||
|
||
**Две поправки к этой записи, обе от ревью 02.08 (№3) — исходные формулировки были сильнее
|
||
сделанного:**
|
||
|
||
- «Доменных значений в разметке не осталось» — **было неверно**: в JSX оставались четыре
|
||
литерала языка (`lang="zh"`, `lang="ru"`, подпись пары `zh → ru`), и тот же проход,
|
||
который вынес числа в `book.*`, прошёл мимо них в той же строке. Починено: язык — код
|
||
в данных, имя считается `Intl.DisplayNames`, `lang` берётся из книги; правило закрыто
|
||
тестом (`src/generality.test.ts`), а не обещанием.
|
||
- «В день HTTP правится тело функций, экраны не трогаются» — **переобещание**. Верно только
|
||
про день замены MSW настоящим сервером. Асинхронность приезжает раньше, на S3, вместе
|
||
с MSW и TanStack Query — то есть ДО первого продуктового экрана (S4–S7), поэтому
|
||
переписывать экраны и правда не придётся. Но четыре вызова витрины на S3 изменятся.
|
||
|
||
### 02.08 — что дал разбор канона: фронт мокает не тот контракт
|
||
|
||
`docs/README.md` прямо требует читать `research/23` перед любым кодом стыка. Не читал,
|
||
и это стоило двух вещей.
|
||
|
||
1. **D39.85 (`research/23` §0): фронт читает ТОЛЬКО read-модель платформы в Postgres,
|
||
материализованную из NDJSON-потока событий; движок не опрашивается никогда, чтение живого
|
||
SQLite движка — запрещённый анти-паттерн.** Значит формы `glossary`/`ChunkExport` — словарь
|
||
предметной области, но НЕ форма API. Типы фронта переписаны так, чтобы это было видно:
|
||
`src/api/types.ts` объявлен рабочей гипотезой до появления контракта.
|
||
2. **Единый бэклог, строка 95:** «Контракт API v0 + продуктовый словарь статусов, ранняя
|
||
вставка, зафиксировать артефактом ДО большого кода обеих сторон — фронт пишется на моках,
|
||
без пришпиленного контракта моки и API разойдутся». Дом — `docs/architecture/14-api-contract.md`,
|
||
**файла нет**. То есть фронт делает ровно то, ради предотвращения чего строка заведена.
|
||
Для S2 (оболочка, `src/ui/`) это не помеха. **Для S3 (слой данных) — вход, которого нет.**
|
||
|
||
### 02.08 — инверсия смысла двух вердиктов (дефект, внесённый фронтом)
|
||
|
||
Продуктовые фразы к замечаниям были написаны по ИМЕНИ причины, а не по её доккомменту,
|
||
и две из пяти получились наоборот:
|
||
|
||
- `glossary_miss` — «Термин не подписан в банке» ⟶ **неверно**. `disposition.go:78-85`:
|
||
«an **approved** term's src fired in the chunk but no accepted dst form appears in the
|
||
output — the model ignored the glossary». Термин подписан, его проигнорировал перевод.
|
||
Фраза посылала человека подписывать уже подписанное — по банку, который в каноне
|
||
центральная ценность.
|
||
- `sanitizer_stripped` — «Часть блока не переведена» ⟶ **неверно**. `disposition.go:96-104`:
|
||
«the chunk is NOT lost — the cleaned text is committed as the export»; `status.go:165-170`:
|
||
«the **least alarming** flag». Самый безобидный флаг из восьми подан как потеря текста.
|
||
|
||
Заодно вскрылось, что у движка есть **ратифицированная лестница важности вердиктов**
|
||
(`status.go:150-175`, ранги 1..8), а интерфейс красил все замечания одинаково — то есть
|
||
терял единственный сигнал приоритета. Введены две ступени: `attention` и `glance`.
|
||
|
||
**Правило на будущее:** фраза к вердикту пишется по доккомменту `disposition.go`, а не по имени
|
||
причины, и рядом кладётся цитата. Соответствие целиком — в шапке `src/mock/book.ts`; его
|
||
настоящий дом — контракт API (строка 95), не фронт.
|
||
|
||
### 02.08 — ревью №3 на полном каноне: что оно поменяло
|
||
|
||
Владелец разрешил читать весь корпус доков и потребовал прогнать ревью после чтения.
|
||
Прочитано: `CLAUDE.md` · `docs/README.md` · CURRENT-STATE и единый бэклог · `research/23` ·
|
||
`product-requirements.md` · карта D-лога. **Ответ на вопрос владельца о способе связи:
|
||
NDJSON — это шов ДВИЖОК↔ПЛАТФОРМА (D39.85), а фронту принадлежит JSON поверх HTTP плюс SSE
|
||
от платформы (D39.84). Разведено в `FRONTEND_PLAN.md` §0.2, потому что путал их я сам.**
|
||
|
||
Ревью: 5 линз × находки, на каждую независимый скептик с установкой опровергать.
|
||
15 находок → 12 проверено → **5 выжило, 7 опровергнуто**. Хардблокеров нет; S2 не блокирован ничем.
|
||
|
||
| Что | Диспозиция |
|
||
|---|---|
|
||
| Язык зашит в разметку (`lang="zh"`), а в типе — русское слово | починено: коды в данных + `Intl.DisplayNames` + тест-замок |
|
||
| Девять состояний нарисованы на ГЛАВАХ, хотя это состояния ПРОГОНА над книгой | починено: состояние → книга, у главы выполнение по юнитам; библиотека из нескольких книг |
|
||
| Прогресс — наивное «N из M глав», прямо запрещённое собственным планом | починено: две пары по юнитам, фикстура поставлена в середину черновой волны (наивный счётчик дал бы 0) |
|
||
| Сетевой гейт ловил только `fetch` — `EventSource` (ратифицированный транспорт) проходил молча | починено: восемь форм, все проверены живым нарушением |
|
||
| `npm run shot` зелен, когда экран не попал в список маршрутов скрипта | починено: тест сверяет `routes.tsx` и `shot.mjs` |
|
||
|
||
**Опровергнуто (и это ценнее половины находок):** гипотеза «синхронный `src/api/` — хардблокер,
|
||
нужен свой хук уже сегодня». Два независимых скептика показали, что S2 данных не читает вовсе,
|
||
а асинхронность приезжает на S3 вместе с MSW и TanStack Query — то есть самодельный хук был бы
|
||
работой S3, которую S3 же и выбросит. Правку я не делал; переобещание в журнале поправил.
|
||
|
||
**Что нашла не ревьюшница, а снимок:** после переноса состояний на книгу три пары из девяти
|
||
рисовались одинаково (готова ≡ не начата, перевод ≡ финал, ошибка ≡ не разобрана) — точка
|
||
не различает девять значений. Метка стала словом; цвет остался вторым каналом и живёт
|
||
на точке, а не на тексте (цвета замечания и отказа не проходят порог контраста для текста —
|
||
проверено axe: было 5 узлов, стало 14, вернулось к 5).
|
||
|
||
**⛔ ПИНГ ОРКЕСТРАТОРА №19 — 23.08, при разморозке зоны (сейчас действий не требует).**
|
||
Аудит доков нашёл два расхождения внутри зоны; рукой не лезу, зона заморожена.
|
||
1. **Три из одиннадцати вопросов ниже уже ОТВЕЧЕНЫ каноном** и просто не погашены — при разморозке
|
||
сверить каждый против D-лога прежде, чем нести владельцу повторно.
|
||
2а. **Ключ `prepare` вашего `package.json` — единственный бутстрап РЕПО-ШИРОКОГО гейта доков (дописано 24.08, строка 220).**
|
||
`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 как на ДРУГИЕ вопросы, чем одноимённые строки здесь.
|
||
Пока номера двусмысленны, ссылка «см. В-6» указывает в два разных места.
|
||
|
||
## Открытые вопросы к владельцу
|
||
|
||
| # | Вопрос | Почему это его вопрос |
|
||
|---|---|---|
|
||
| В-1 | **Данные привязаны к одной машине.** Вся фактура — прогоны, экспорты, банки — лежит в `/home/ubuntu/books/gu-zhenren/` вне git; оба `backend/example/sample-*.db` пустые (только схема); пути стенда зашиты в тесты (`miner_parity_test.go:33-35`, `labelharness_test.go:43`) и в `book.yaml` абсолютными путями. Владелец сказал: «мне не нравится, что это живёт конкретно на моём диске». Лечение — платформа (`platform/README.md:20-29`: библиотека книг, хранение исходников и экспортов), но платформы ещё нет ни строки. Фронт от этого не зависит (работает на моках), но **вопрос на движок/платформу, а не на фронт** | скоуп-решение и порядок работ |
|
||
| В-3 | **Каким словом называть ступень замечания.** Сейчас `attention` и `glance` различаются только цветом полоски: синяя и серая. Зрячему разница читается ещё и светлотой, скринридеру — никак. Лечение то же, что уже применено к состоянию прогона книги: слово рядом с цветом. Но словарь замечаний продуктовый (ПТ-33), а §3.8 требует, чтобы экран не выглядел тревожным, — «важно / неважно» и «ошибка / предупреждение» не годятся. Строка Ф-21 | продуктовая формулировка, которую видит пользователь |
|
||
| В-6 | **Упёрся в свой потолок ≠ кончились деньги, а интерфейс их не различает.** Владелец 07.08 дал человеку поставить перед стартом колпак в ГЛАВАХ; платформа берёт холд на его сумму. Но машинная причина паузы в контракте ровно одна — `credit_exhausted`, и она про кредит. Значит прогон, честно доехавший до выбранной человеком границы, и прогон, у которого кончился баланс, приходят на экран одной фразой «перевод остановлен: лимиты исчерпаны». Первому она врёт: лимит не исчерпан, человек сам так решил, и следующее действие у него другое — поднять колпак, а не пополнить счёт. Нужно ли второе значение и какая у него фраза — продуктовое. Заведено К-13, строка Ф-31 | продуктовая формулировка, которую видит пользователь, и разное следующее действие |
|
||
| В-8 | **Какое слово о состоянии книги стоит в дереве.** Замечание 23 потребовало бейджу ФИКС-место, и оно сделано; но две метки словаря в него не помещаются и усекаются с тултипом — «остановлена: лимиты» (19 знаков) и ветка неизвестного «неизвестное состояние» (21). Укоротить их сессия НЕ вправе: фраза паузы зарезервирована за владельцем (В-6), и первый заход S3.5 её укоротил и был откачен собственным ревью. Варианты: (а) оставить усечение с тултипом, (б) владелец даёт короткое слово для дерева, а полная фраза остаётся в статус-полосе, (в) расширить колонку бейджа за счёт названия книги | продуктовая формулировка, которую видит пользователь |
|
||
| В-7 | **Физический масштаб интерфейса на мониторе.** Замечание 1 говорит «масштабы великоваты, особенно на 27″ 2K, на 24″ терпимее». Замер при вьюпорте референса расхождения с Fleet не нашёл (§5.5 плана): промежутки, ширины панелей, шаг строки и высота вкладки совпадают. Значит речь про физический размер на конкретном экране, а он зависит от масштабирования ОС, и «просто уменьшить токены» означало бы уехать от референса, который владелец принял. Правильное лекарство — ручка «плотность интерфейса» в настройках (3 ступени), но она требует перевода ВСЕХ размерных токенов в rem и пере-замера, то есть отдельного прохода (Ф-36). Вопрос: нужна ли ручка, и какой масштаб ОС стоит на 27″ 2K — по нему видно, во сколько раз расходится физика | продуктовое решение и цена отдельного пакета |
|
||
| В-9 | **Какие языки интерфейса продукт обещает.** Механизм переводимости построен (S3.7, Ф-35): слова интерфейса живут в каталоге `src/i18n/ru.ts`, второй язык — второй файл того же вида плюс строка в `src/i18n/language.ts`, ни один компонент при этом не трогается. Чего фронт сделать не может и не должен: решить, какие языки продукт обещает, и выдумать сами переводы. Пока список из одного значения (`ru`), и каркасный пункт настроек честно говорит «сейчас интерфейс только русский» | продуктовое решение и обещание пользователю |
|
||
| В-10 | **Спойлер банка — это защита или вежливость?** Замер S4: закрытое описание лежит в тексте страницы, `window.find()` его находит, то есть Ctrl+F подсвечивает закрытую ячейку; под `@media print` размытие сохраняется, но текстовый слой PDF строится из DOM. Если спойлер — ЗАЩИТА от спойлера сюжета, описание не должно приезжать в браузер до раскрытия, а это правка контракта (признак «показывать смыслы» на чтении банка). Если ВЕЖЛИВОСТЬ («не мозолит глаза, но достать можно») — сделанного достаточно, и цена названа. Строка Ф-59 | продуктовое решение и правка контракта |
|
||
| В-11 | **Фразы отказа книги (PD-173) — на утверждение.** Контракт 0.2.3 несёт машинную причину (`source_unreadable` · `not_configured` · `parser_unavailable`), а слова пишет клиент — их сочинила эта сессия по слову владельца 14.08 и они ждут его «да»: «Файл не удалось разобрать на разделы» / «Проверьте файл — возможно, это не текст книги — и добавьте её заново»; «Сервис пока не готов принять эту книгу» / «Файл здесь ни при чём: повторная загрузка поможет не раньше, чем мы это наладим»; «Не удалось обработать файл на нашей стороне» / «Файл здесь ни при чём: попробуйте добавить книгу позже»; неизвестная причина — «Книгу не удалось принять» / «Причина не названа. Попробуйте добавить книгу заново или позже» | продуктовая формулировка, которую видит пользователь |
|
||
| В-2 | **Авторское право на текст фикстур.** Витрина использует короткую выдержку из настоящего прогона (蛊真人). Правило проекта уже есть: `eval/.gitignore:4` держит копирайтные тексты вне git. Сейчас взят объём под проверку плотности и не больше; нужно ли убрать совсем и заменить синтетикой — решать владельцу | юридика |
|
||
| В-4 | **Чем подписывать главу в дереве, если заголовок — ровно «Глава N».** Титул движок рендерит детерминистически из шаблона пары (`configs/langpacks/zh-ru/heading.txt`: `template Глава {n}`), а подзаголовок остаётся телом текста и названием НЕ является. На 2284 разделах это дерево из 2284 одинаковых по форме строк. Оставить так, показывать номер иначе или просить у контракта что-то ещё — продуктовое решение. Артефакт §1.4 и К-3 | продуктовая формулировка, которую видит пользователь |
|
||
| В-5 | **Показывать ли оценку времени до конца прогона.** У движка поле есть (`status.go` `eta_seconds`, «secondary: mean fresh-call throughput × remaining»), запретом §4.8 оно не покрыто (это не деньги), но и не запрошено ни одним разделом промта. Решать ДО формы прогресса, иначе поле придётся вводить задним числом в уже нарисованную полосу. Артефакт К-6, резерв строки 54 единого бэклога | продуктовое: обещание срока пользователю |
|
||
|
||
## Хроника
|
||
|
||
### 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 два дока «spectral шестым шагом» (`STACK_DECISIONS.md:116`, `FRONTEND_PLAN.md:124`) — spectral четвёртый из шести · ФС-7 мок считает части формы по ВСЕЙ форме (платформа — до файла) и меряет 413 по file.size (платформа — по всему телу) — мок строже провода · ФС-8 флейк сцены refusals: closeModal не дождался закрытия за 5000 мс (1 из 3 на тихой машине) · ФС-9 `role="status"` оборачивает байтовый прогресс отправки — на живом XHR скринридер зачитывает каждое обновление (в регионе — только смены состояний) · ФС-10 группа из одного раздела подписывается «разделы 201–201» · ФС-11 интейк-мир: ПЕРВОЕ нажатие «Перевести» всегда 409 (счётчик; кандидат — маркер) · ФС-12 после-пакные числа Ф-35 слегка отстают от дерева (пересборка: 800293 / 246670 gzip против записанных 800219 / 243446).
|
||
|
||
**Поправки к записи S4 (чужой текст не редактирую):** «словарь платформы — четыре значения» → в коде ПЯТЬ (пропущен `schema_mismatch`) · «одна из трёх фраз сегодня недостижима» → недостижимы ВСЕ ТРИ: платформа `reject_reason` вообще не проецирует (`v0.go:497` «never projected») — доезжает только ветка неизвестного · §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 (носитель там, дефекта сессии нет — фиксирую для полноты).
|
||
|
||
*(Записи сессий S0–S4 и их приёмок (02–14.08) — в [archive/frontend-PROGRESS-S0-S4.md](archive/frontend-PROGRESS-S0-S4.md); вынесено 16.08 по слову владельца. Запись приёмки S4 с фикс-листом ФС — ВЫШЕ, она живая.)*
|
||
|
||
## Пинг оркестратора №15 (09.08): контракт 0.2.1 — `503` на старте прогона; платформа-раннер заленден
|
||
|
||
- **Контракт бампнут 0.2.0 → 0.2.1** (D39.123): `POST /books/{bookId}/runs` получил ответ **`503`**
|
||
(`ServiceUnavailable`, problem+json) — старт прогона на деплое, где шов движка не сконфигурирован;
|
||
временное состояние, ретрай позже, `Retry-After` не обещан. Зеркало `frontend/docs/api-contract/`
|
||
синхронизировано байт-в-байт этим же лендингом. При следующей сессии — перегенерировать типы из
|
||
спеки; других изменений форм нет, правка аддитивная.
|
||
- **Платформа-раннер заленден** (`d29e30c`): пять ручек `/v0` контракта живые — библиотека ·
|
||
карточка · run-options · старт прогона · usage; прогресс прогона пофазный (draft/edit) в карточке.
|
||
Фронт может говорить с живой платформой вместо моков — стык проверен 47 wire-проверками приёмки.
|
||
- Известное ограничение до эмиттера (строка 103): стоп по потолку и штатный останов приезжают как
|
||
`failed` (PD-113/двойник) — на экране не строить различение этих состояний до строки 165 движка.
|
||
|
||
## Пинг оркестратора №16 — 09.08.2026 (кросс-ссылка зонных половинок, строка 167)
|
||
|
||
Движковая половина темы Ф-30/В-4 («глава без заголовка») — **строка 160 единого бэклога** (`titleRaw` в манифест · provenance у heading · тип chapter/fragment; research/27 §6 Этап 0). До её лендинга `heading` манифеста = ВРЕМЕННЫЙ рендер движка (D39.122 п.2д) — честный заголовок из данных приедет строкой 160, продуктовое слово — В-4 на владельце. На экране ничего не менять до обоих.
|
||
|
||
## Пинг оркестратора №17 — 16.08.2026 (зона во фризе; контракт-ревью принято D39.138 — четыре ваших вопроса ОТВЕЧЕНЫ, входы разморозки)
|
||
|
||
Контракт-ревью API v0 отработало отдельной сессией и ПРИНЯТО (отчёт — `docs/research/28-contract-review.md`; решения владельца — его §8, ратификация D39.138). Заказан ЛОМАЮЩИЙ батч 0.3.0 (строка 183 единого бэклога) — типы перегенерируются после его лендинга; до него нормативной остаётся 0.2.3. ⚠ Читать ОРИГИНАЛ отчёта, не пересказ. По вашим строкам:
|
||
1. **Ф-56 (конец интейка):** Б-6(а) — поток перевешивается на КНИГУ (`GET /books/{id}/events`) с кадрами конца разбора и конца прогона и `204` на завершённом; ваш опрос — легитимное лечение до батча.
|
||
2. **Ф-57 (пары):** Б-2 — `GET /capabilities` (пары со статусом · порог интейка · форматы · размеры страниц · версия контракта); `languages.ts` станет чтением.
|
||
3. **Ф-61 (английские фразы):** В-1 решён владельцем вариантом B (§8 п.4): машинный `code` + `request_id`; `title`/`detail` — developer-facing, **фразу рисует клиент по словарю кодов** (ваша таблица `AddBook.tsx:282-288` становится нормой); после батча строка `AddBook.tsx:289` (`problem?.detail ?? problem?.title`) и её сёстры `Loaded.tsx:66`, `RunStart.tsx:188` СНИМАЮТСЯ.
|
||
4. **Ф-62 (переименование):** Б-5 — `PATCH /books/{id}` ТОЛЬКО с `title` (409 при живом прогоне) + `DELETE`; правка — отображение, до движкового брифа не доезжает. Жанр из продукта УХОДИТ совсем (Б-23, слово владельца 16.08) — поле формы снимется при разморозке.
|
||
5. **Ф-43 протух текстом:** движковая половина банка ПОСТРОЕНА ещё D39.122 (сайдкар `<db>.bank.json` + `bank-stop.json`), не хватает платформенной проекции (строка 169 единого бэклога, вход P7) — обновите текст строки.
|
||
6. **Решение владельца К-6 (§8 п.11):** замечания показывать ВСЕ; в тексте — сворачивать и раскрывать кнопкой; словарь ступеней заранее НЕ проектировать; зависимость `Note.id` закрывает батч. **Зарегистрируйте зонной строкой при разморозке.**
|
||
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, свип планировочных доков D39.139):** (1) Три носителя зоны учат ПОФАЗНОМУ прогрессу «draft N/M ∥ edit N/M» — `FRONTEND_SESSION_PROMPT.md` §9 п.1, `FRONTEND_PLAN.md` §6 п.1, `STACK_DECISIONS.md` §8 п.1; после батча 0.3.0 это устареет (Б-0/D39.138: на проводе ОДИН счётчик до ближайшей остановки, знаменатель — купленный объём) — при разморозке обновить все три, не только код. (2) `STACK_DECISIONS.md` §8 протух целиком: все четыре пункта «достроить в движке» ПОСТРОЕНЫ (пофазные счётчики и манифест — D39.122; JSON таблицы подписи — `bank-stop.json` D39.122; TM_TRACE_ID — P6/D39.132). (3) Диспозиции строк: **Ф-59** — В-10 закрыт владельцем 16.08 «вежливость» (D39.138 п.2к: всё правильно, цена названа — строку закрыть); **Ф-37** — К-10 отвечен «НЕ строить» (поправка приёмки ревью: фазы уходят с провода и у главы — пометка черновика остаётся книжной, хвост пере-диспозиционировать); **Ф-39** — закрыта ещё словом владельца 15.08 (D39.136 п.4б: полей BankTerm не заводить, sense хватает; его калибровка — строка 178 единого). Вопросы — через владельца.
|
||
|
||
**Дописка к аддендуму (16.08):** гейт на утечку конвейера в провод — «на проводе нет имён стадий/волн и движковых словарей», машинный тест по образцу `generality.test.ts` — назначен вашей зоне (D39.138 п.2а; спек-сессия батча запишет правило в компаньон контракта). Строить при первом касании зоны вместе с синком зеркала и перегенерацией типов.
|
||
|
||
**Пинг оркестратора №17 — 16.08 (модель подписи банка, слово владельца; читать ПЕРЕД S5):** подписывается ВЕСЬ банк ОДНИМ действием юзера — черновой перевод + черновой банк появляются вместе после черновой волны, юзер смотрит банк, правит ТОЛЬКО то, что захотел, и жмёт один ОК (= resume) — перевод уходит в доработку; нерешённые термины едут как предложил сервис. Пер-термная масс-подпись сотен строк НЕ строится — это была инерция (владелец уже говорил зоне 10.08, снимая счётчики «подписано N»; теперь снята и из контракта: 409-гейт полноты убран, `pending_decisions`/`complete` информационные — D39.144). Строки Ф-44/Ф-45/Ф-46 при разморозке читать через эту модель: «действие подписи» = один ОК + опциональные точечные правки, НЕ проход по строкам. Пост-ридинговые правки банка («поправить/добавить термин → пере-генерация по вхождениям») — направление, механика не спроектирована нигде (полигон работает над точечным редактором) — экранов под неё не строить до отдельного слова. Вопросы — через владельца.
|
||
|
||
**Дописка к пингам №17 (16.08, по аудиту готовности зоны — ЧЕТЫРЕ нормы зоны сменили знак, читать ДО всего остального):** (1) **Канон контракта = 0.3.0, ЗАЛЕНДЕН (D39.142/143); ваше зеркало `docs/api-contract/` осталось на 0.2.3 РАТИФИЦИРОВАННО** (D39.142 п.5, на время фриза) — «зеркало = байт-копия» временно НЕ действует, нормативен только канон в `docs/architecture/14-api-contract/`; синк + перегенерация типов = первое касание зоны. (2) **Запрет клиентской метки «Глава {n}» СНЯТ каноном 0.3.0** — клиент теперь ОБЯЗАН сам рисовать порядковый в локали интерфейса, когда `heading`/`number` = null (Ф-30 и пинг №16 «на экране ничего не менять» — устарели; движковая строка 160 остаётся про НАСТОЯЩИЕ названия). (3) **Ф-31/В-6 закрыты ещё D39.132 п.2а** (`null` на проводе ратифицирован), а кадр `EventCeiling`, на который они опирались, снят 0.3.0 целиком — строки закрыть при разморозке. (4) **В-11 (фразы) пере-собрать на словарь 0.3.0**: карта «код → фраза» — приложение А компаньона; `parser_unavailable` переименован в `processing_failed`, добавлен `content_refused`. Плюс: **дев-стенд платформы СУЩЕСТВУЕТ с P6** (`tmplatformctl seed` + дев-вход, D39.132) — Ф-29 (снос моков) и Ф-18 (вес бандла) читать через него; статус зоны: ФРИЗ (D39.136 п.2), снятие = лендинг P7. Вопросы — через владельца.
|
||
|
||
**Пинг оркестратора №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 — канон 0.4.0 РАТИФИЦИРОВАН** (D39.152). Зеркало зоны отстаёт ратифицированно и остаётся на 0.2.3 до разморозки; при первом касании — синк зеркала БАЙТ-В-БАЙТ (`cmp`) и перегенерация типов, как и было в перечне. Ломающее против 0.3.0: обязательное `Run.stop_requested` (плюс три поведенческих расхождения, тела — D39.152 п.5). Что это даёт экрану: кнопка «стоп» перестаёт врать — прогон помнит, что его просили остановить, и переживает перезагрузку страницы, поэтому «остановлено — работа на подписи банка, продолжить дёшево» рисуется по признаку, а не по догадке. И `resume` теперь отвечает двумя РАЗНЫМИ причинами: «прогон закончен, купите новый» против «пополните счёт» — фразы В-3 по словарю кодов пишутся уже под это.
|
||
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 на архивный путь. До тех пор оба файла живут по старым путям законно.
|