22 KiB
Промт: фронт-сессия S3 — слой данных (вход под замком)
Ты — фронтенд-сессия TextMachine, четвёртая по счёту. Зона записи — только frontend/;
сессия не коммитит — лендит оркестратор (протокол — стоящий промт FRONTEND_SESSION_PROMPT.md
§«Зона и git», он в силе целиком). Пре-коммит хук стоит и самоустанавливается при npm install.
Промт написан сессией S2 по просьбе владельца — как передача с той точки, где S2 встала. Ратифицирует и правит его оркестратор; при расхождении с его хендофф-промтом побеждает тот.
Входное состояние (04.08, проверено исполнением, а не заявлено)
- Пройдено S0–S2: план · инструменты и скриншот-цикл ·
tokens.cssпо замерам референса · оболочка трёх панелей (src/shell/) · примитивыsrc/ui/наreact-aria-components· витрина/showcaseи нагрузочный/scale(2284 раздела, 1200 терминов). npm run check— 5 гейтов (prettier · eslint тип-осведомлённый · stylelint · tsc · vitest, 77 тестов),npm run check:full— + сборка + три скриншота с гейтом доступности axe. Всё зелёное на 04.08.- Данные всё ещё синхронная фикстура:
src/api/отдаёт объекты изsrc/mock/напрямую. Это диспозиция Ф-15, а не недосмотр: асинхронность приезжает вместе с MSW, то есть в S3. - Гейты, которые ты застаёшь: одно место для цвета и размера (TSX-половина в
eslint.config.js, CSS-половина вstylelint.config.js) · три шва — фикстуры видит толькоsrc/api/, глобальный CSS толькоsrc/main.tsx,react-aria-componentsтолькоsrc/ui/— закрытые и для статического, и для динамического импорта · сеть запрещена внеsrc/api/во всех транспортах (fetch/EventSource/WebSocket/XMLHttpRequest, включаяwindow.*) · тест общности: код языка не зашивается в разметку, стили не ветвятся по:lang(…)· контракт-тест токенов и структурные тесты CSS-модулей. - ⚠ На момент написания промта в дереве лежали незакоммиченные правки по ревью оркестратора
(
frontend/src/{api/types.ts,generality.test.ts,mock/book.ts,mock/scale.ts,showcase/Context.tsx, showcase/Reader.module.css,tokens/tokens.css,tokens/tokens.test.ts},eslint.config.js,frontend/docs/*). Их лендит оркестратор. Первым делом сверься сgit logиgit status: если правок в дереве нет — они уже уехали, ничего восстанавливать не нужно.
Замок на входе — первое действие сессии
Проверь сам, промту не верь (он написан 04.08 и мог устареть):
- Существует ли
docs/architecture/14-api-contract/(спека + компаньон)? — на 04.08 вечера: ДА, ратифицирован (D39.99), замок ОТКРЫТ; - Строки 95 в таблице единого бэклога больше НЕТ — она ЗАКРЫТА (D39.99, закрытые строки уходят в D-лог); если видишь её живой — дерево старее канона, стоп и пинг.
Открыт (контракт есть и ратифицирован) → скоуп S3 ниже. Закрыт → раздел «Если замок закрыт» (контингенция; на вечер 04.08 замок ОТКРЫТ — D39.99). Не начинай S3 «пока на своих типах, потом поправим»: моки, снятые не с того контракта, разойдутся с API — ровно то, ради чего строка 95 заведена.
Обязательное чтение до кода (порядок)
frontend/docs/FRONTEND_SESSION_PROMPT.md— стоящий промт: сценарий §3, жёсткие ограничения §4, «как работать» §7. Его не редактировать. ⚠ Раскладка §2 частично устарела — её перевешивают решения владельца из журнала зоны.frontend/docs/frontend-PROGRESS.mdцеликом: «Текущее состояние» · «Решения владельца по продукту» · «Открытые вопросы» · хронику 04.08 (в ней — что S2 построила, где отошла от референса и что поправило ревью оркестратора).frontend/docs/FRONTEND_PLAN.md— §0.1 (карта канона: что читать перед чем), §0.2 (транспорт: с движком фронт не разговаривает никогда — это ратифицированный анти-паттерн, D39.81/D39.85), §5.4 и §5.4.1 (формы обхода гейтов и названные границы), §6 (что уже известно про движок и как это меняет форму данных — читать до первой строки типов).frontend/docs/STACK_DECISIONS.md— §2 пины (там уже названы@tanstack/react-queryиmsw), §5 транспорт и правила стрима, §7 риск ре-ингеста. Библиотеки сам не выбирай и версии по памяти не «обновляй»: твои знания об экосистеме устарели, сверка — live по npm.docs/research/23-engine-platform-seam.md—docs/README.mdтребует читать его перед любым кодом стыка; форма событий и правило ре-синка оттуда.frontend/docs/BACKLOG.md— строки Ф-14 (вход фронта в контракт), Ф-15 (закрывается этой сессией), Ф-19, Ф-21.references/*.pngи.shots/*.png— открой и посмотри до первой правки.
Решения владельца 04.08 вечер (D39.100) — правки спеки ПЕРВЫМ шагом S3
Контракт ратифицирован, четыре К-вопроса закрыты владельцем; спеку правишь ты (минорный бамп версии, регенерация типов, батарея), компаньон-К-таблицу — статусами «решено»:
- К-1 закрыт: десять статусов приняты.
- К-8 закрыт механизмом «как Claude Code» (ПТ-35, П-5):
BookStatusполучает 11-е значениеpaused(стоп по потолку; резюмируемый; вfailedне мапить — уже запрещено спекой); пользователь видит оповещение «перевод остановлен: лимиты исчерпаны», сами лимиты — страница в настройках (СТАТУС использования, не суммы: запрет денег на проводе в силе). API лимитов проектирует платформа (П-5) — поле/эндпоинт в спеку НЕ выдумывать, только статус и семантику оповещения. - К-5 закрыт: ETA показывать —
eta_secondsв прогресс-модель (движок отдаёт,status.go:112; поле опциональное — оценка бывает недоступна). - К-3 закрыт с канон-уточнением: метка главы — ИЗ ДАННЫХ книги, зашитых форм нет. «Глава N» — это шаблон langpack-ДАННЫХ, не закон: легальна книга вовсе без номеров и глав. Дерево рендерит label, который дал манифест (строка 100)/heading (К-2), внутренний порядок — непрозрачный индекс. Проверь спеку и фикстуры на зашитую форму «Глава N».
- После правок: байт-сверка зонной спеки с ратифицированной копией
(
docs/architecture/14-api-contract/openapi.yaml) — расхождение отдай оркестратору на пере-ратификацию диффом, сам канон не правь.
Скоуп S3 — слой данных, и ни шагом дальше
src/api/становится асинхронным: MSW как сетевой мок + серверное состояние на пинах из STACK_DECISIONS §2 (версии сверить live на дату сессии;.npmrcдержитsave-exact). Каждый новый пин — строкой в таблицуFRONTEND_PLAN.mdс датой релиза и «зачем нам».- Фикстуры всех состояний, а не одного счастливого: ожидание · ошибка · пусто · частично · длинный хвост · потеря соединения на стриме. Правило S1/S2, которое здесь действует сильнее всего: фикстура по умолчанию — трудный случай. Наивный счётчик глав должен на ней давать ноль (идёт черновая волна), иначе скриншот-цикл смотрит на удобное.
- Живой прогресс —
EventSourceза швомsrc/api/(STACK_DECISIONS §5; гейт сети уже запрещает его где-либо ещё). Докачка поLast-Event-ID/ревизии — часть контракта, не выдумка. - Ф-15 закрывается здесь: ветки ожидания/ошибки/пустоты появляются вместе с MSW, а не после первого продуктового экрана.
- Типы
src/api/types.tsприводятся к контракту. Что в них сегодня заведомо временное: булевsignedвместо трёхзначногоauto|draft|approved· ключ строки банка, собранный из (src,dst,type), — у движка термин уникален по (src,sense,since_ch,until_ch) · отсутствие ревизии для докачки. Всё это перечислено строкой Ф-14. Закрытые юнионы получают явную ветку неизвестного значения (строка Ф-22) — сегодня её нет ни у одного, и строгость тайпчека здесь НЕ страхует:runStates[book.state](showcase/Library.tsx:103) — обращение кRecordпо КОНЕЧНОМУ юниону, аnoUncheckedIndexedAccessдобавляетundefinedтолько индексным сигнатурам (провереноtscна пробе: обращение по юниону компилируется молча, ругается толькоRecord<string, …>). Значит состояние прогона из будущего контракта даётundefined.tone— падение дерева библиотеки, а не пустую метку;noteToneтем же классом тихо уводит незнакомую ступень замечания в СПОКОЙНУЮ ветку. Место ветки — шовsrc/api/, где значение входит, а не каждый компонент: перевод «вердикт → вид» уже расползался по экранам, и контрольный вопрос владельца требует, чтобы новое значение правило один файл. - Поля не выдумывать. Нет в контракте — это вопрос владельцу/оркестратору в «Открытые вопросы» журнала зоны, а не догадка в типе. Дефект «фикстура выдумала поле» в этой зоне случался дважды и оба раза стоил экрана.
Не в скоупе: экраны S4–S7 · редактор текста · светлая тема · мобильная раскладка · React Compiler (Ф-2) · Tauri (Ф-5).
Если замок закрыт
Контингенция на случай, если проверка замка даст «закрыт» (на вечер 04.08 замок ОТКРЫТ); тогда правильный ход — не ждать молча и не строить экраны на синхронных моках (порядок этапов Ф-1 стоит именно на слое данных).
- Доведи Ф-14 до артефакта, который можно отдать автору контракта: не список намерений,
а перечень с обоснованием на каждый пункт — язык кодами · состояние прогона отдельно от
выполнения главы · прогресс пофазно по ЮНИТАМ · ревизия/
Last-Event-ID· трёхзначный статус подписи · поля банка (type/sense/since_ch) и ключ строки · продуктовый словарь вердиктов (ПТ-33; §4.1 запрещает протечку внутренностей конвейера на экран). Половина уже написана в строке Ф-14 и в §6 плана — собери, а не сочиняй заново. - Отдай его оркестратору пингом в
frontend/docs/frontend-PROGRESS.mdи остановись: заводить контракт своим решением фронт не может (шапкаBACKLOG.md). ⚠ Испр. сессией S3 04.08 по слову владельца: здесь стояло «пингом вdocs/PROGRESS.md» — это чужая зона, и шапка журнала фронта фиксирует решение владельца 02.08 «вdocs/PROGRESS.mdоркестратора не пишут». Канал передачи — журнал своей зоны; оркестратор пишет туда же. - Ф-16, Ф-17, Ф-18, Ф-20 — не трогать: у каждой в бэклоге стоит свой триггер, и ни один из них не наступил.
Ловушки, купленные S2 — не переоткрывать
react-aria-components:Tabне принимает клавиатурных обработчиков (обработчик живёт на ряду вкладок) · у ролиtabдети презентационные, поэтому крестик закрытия — не кнопка (axe роняетnested-interactive), закрытие с клавиатуры —Delete, объявить его нечем (Ф-17) · невыбраннаяTabPanelне рендерится вовсе (dist/private/Tabs.mjs:276), отсюда потеря прокрутки при переключении вкладки (Ф-19, замерено дважды) ·Tree— этоtreegrid/row, а неtreeitem; раскрытие —<Button slot="chevron">·renderEmptyStateобёрнут вrole="option"(зонд S2 принял это за дефект кода).react-resizable-panelsv4:className/styleпанели уезжают во ВЛОЖЕННЫЙ div, у него всегда inlineoverflow:auto·Separatorобязан быть прямым ребёнкомGroup· ключ хранилища раскладки содержит состав видимых панелей, поэтому сворачивание удалением панели меняет ключ (сделано осознанно: так поле оболочки остаётся ровно замеренным).- Скриншот-цикл:
vite buildиpreviewв один момент дают пустой экран — это гонка, а не регрессия; перезапусти прогон, прежде чем «чинить» рабочий код. - Зонды и живые нарушения: файлы зондов удалять за собой (в S2 агенты ревью оставили свои
в чужом дереве), правленые файлы восстанавливать из памяти процесса, а не
git checkout— в дереве могут лежать незакоммиченные правки параллельных сессий. - Первому красному результату зонда не верить: три «находки» первого прогона S2 оказались дефектами зонда (селектор бил по трём панелям сразу), и соблазн «починить» рабочий код был вполне реальный.
- esquery: селектор вида
Property[key.value=/^--/] > Literal[…]ловит собственный ключ свойства — в TSX-гейте это записано комментарием, не убирай его.
Технические рамки
- Новый маршрут → сразу в
KNOWN_ROUTES(scripts/shot.mjs); тест сверяет списки и упадёт. - Гейты не ослаблять. Точечное подавление — только именованное правило с причиной.
- Файл = компонент + модуль стилей рядом; >150 строк — делить. Комментарии — одна-две строки «почему», не «что».
- Тексты фикстур — настоящие пропорции кириллицы и иероглифов, объём минимальный: вопрос авторского права (В-2) у владельца, цитаты не расширять.
Как работать
- Ревью исполнением — мандат проекта, не пожелание: приложение поднимается, скриншоты
сняты и ПРОСМОТРЕНЫ, каждый гейт проверен живым нарушением с перечнем форм,
npm run check:fullзелёный. «Должно работать» ревью не является. - Скриншот-цикл — с первого изменения, критерий сведения — не растровое совпадение, а плотность и впечатление (стоящий промт §8).
- Адверсариальная самопроверка перед финишем (author≠reviewer): пройди по своим правкам с установкой опровергать. S1 так поймала пять дефектов в собственных гейтах, S2 — восемь.
- Спорное с каноном или новое продуктовое решение не принимай сам: вопрос в «Открытые вопросы к владельцу» журнала зоны, и продолжай то, что вопроса не требует.
Готово — это когда
- Замок проверен и результат записан: либо S3 сделана, либо в журнале лежит, чем сессия занималась вместо неё и почему.
- Если S3 сделана:
src/api/асинхронен, MSW отдаёт все состояния, ветки ожидания/ошибки/пустоты живые, Ф-15 закрыта, типы сведены с контрактом, а расхождения — не «поправим потом», а строки бэклога с триггером. npm run check:fullзелёный; новые маршруты вshot.mjs; скриншоты просмотрены.frontend/docs/frontend-PROGRESS.md: обновлено «Текущее состояние», добавлена хроника сессии (что построено · что видно на снимках · где отошёл от канона и почему · что осталось); строки бэклога получили диспозиции.- Ничего не закоммичено: дерево подготовлено и передано оркестратору.
Что ждёт не тебя (не решай сам)
В-1 данные привязаны к одной машине (вопрос на движок/платформу) · В-2 копирайт фикстур · В-3/Ф-21 каким словом называть ступень замечания (словарь продуктовый, ПТ-33) · Ф-11 контраст палитры ниже WCAG на четырёх узлах — принято как есть до слова владельца.