29 KiB
Промт: фронт-сессия S4 — библиотека, загрузка, разбор, прогресс (+ спек-правка 0.2.3)
Выдан оркестратором №16 14.08.2026 по D39.130 («гейт S4 пал»). Запуск — по слову владельца.
0. Какую проблему решаем и что даст твой результат
Продукт — веб-сервис художественного перевода книг: пользователь загружает книгу, запускает
перевод, подписывает словарь терминов, читает результат. Фронт строится этапами S0–S7; пройдено
всё до S3.7 включительно: оболочка трёх панелей по референсу Fleet, слой данных на контракте
OpenAPI (MSW как сетевой мок), i18n-каталог, гейты. Чего до сих пор НЕ существует —
пути пользователя от «у меня есть файл» до «книга переводится»: форма добавления книги есть
как вид (модал S3.5 по antigravity_add_folder.png), но никуда не отправляет; статусы
uploading/parsing/rejected в контракте есть, а экраном не прожиты; запустить прогон с
экрана нельзя. До сих пор это было честно: серверной ручки загрузки не существовало. 14.08
платформа P5 принята (D39.130) — POST /books построен и жив, и вместе с его приёмкой владелец
контракта ратифицировал пакет правок спеки (0.2.3), которые вносишь ты. Твой результат =
пользовательский путь загрузки и запуска работает на форме контракта 0.2.3, и следующая сессия
(S5, подпись банка) строится на книге, которую в интерфейсе можно завести, а не только замокать.
Ты — девятая фронт-сессия. Промт — твой ЕДИНСТВЕННЫЙ контекст: ты не видишь чужих переписок; всё несущее — здесь или в названных доках. Дом фронта остаётся миром моков (MSW по контракту); живой стенд платформы — только опциональная проба, §10.
1. Онбординг (порядок чтения, до кода)
CLAUDE.md(корень) — гардрейлы проекта; из них жёсткие для тебя: зона записи ТОЛЬКОfrontend/, ты НЕ коммитишь,.envне читать, чужие незакоммиченные файлы не трогать.frontend/docs/FRONTEND_SESSION_PROMPT.md— живой носитель норм зоны: §«Зона и git», §3 сценарий (тебе — §3.1–3.4), §4 жёсткие ограничения, §5.1 поддерживаемость, §7 «как работать». Статусные абзацы там частично исторические — статус этапов только вfrontend-PROGRESS.md.frontend/docs/frontend-PROGRESS.md— шапка «Текущее состояние» + раздел «Решения владельца по продукту» (перевешивает всё в старых промтах) + записи S3.5–S3.7 и приёмок.frontend/docs/BACKLOG.md(Ф-строки) иfrontend/docs/STACK_DECISIONS.md(пины — не двигать).- Контракт: зонная копия
frontend/docs/api-contract/openapi.yaml(0.2.2, байт-зеркало канонаdocs/architecture/14-api-contract/openapi.yaml) + компаньон-README рядом с каноном (провенанс, К-вопросы, §2.15 — потолок прогона). - Референсы
frontend/references/*.png— открой глазами, если трогаешь вид.
Эхо-протокол: первый деливерабл — ≤10 строк «что я понял: скоуп / инварианты / не-делать» ДО работы. Расхождение чинится на минуте пять, не на приёмке.
2. Задача 1 — спек-правка 0.2.3 (делай РОВНО так; ратифицировано D39.130 п.2в + ратификация ниже)
Правишь ЗОННУЮ копию frontend/docs/api-contract/openapi.yaml, бампаешь info.version до
0.2.3, перегенерируешь типы (npm run contract), spectral зелёный. Канон правит оркестратор
диффом при лендинге — байт-сверку не выравнивай сам, расхождение с каноном на время сессии
легально (прецедент Ф-47/0.2.2). Пять правок:
- PD-172: у
createBookзаписать проводное правило — частьfileидёт последней в multipart-форме; поля после файла = 400. Причина (одной строкой в описание): платформа читает форму потоково и обязана увидеть языки до тела файла. - PD-173: у отклонённой книги появляется машинная причина — поле с закрытым enum по
словарю платформы (
source_unreadable·not_configured·parser_unavailable; её колонкаbooks.reject_reason, миграция 00013 — сверь имена значений поplatform/read-only, код первичен). Продуктовые фразы различения пишешь ТЫ (слово владельца 14.08: «пусть сам придумает, только над хорошими вариантами подумает»). Рамки: фразы должны честно ложиться на РЕАЛЬНЫЙ флоу отказов (движок отдаёт платформе классы отказа, платформа сводит их в этот enum — прочитай маппинг read-only, чтобы фраза не врала о причине), при этом НЕ раскрывать внутреннее устройство (ПТ-33: ни стадий, ни моделей, ни слов вроде «манифест»/«парсер движка»; та же дисциплина, что уProblem.title) и не звучать тревожно (§3.8). Разное следующее действие — разные фразы: «файл не тот» → проверить файл; «сервис недоступен» → повторить позже. В UI — через словарь с веткой неизвестного, как все enum; свои фразы вынеси в отчёте отдельным списком на утверждение владельцем. - PD-174: назвать классы ответов, которые провод уже даёт, а спека молчит: 404 на
POST /booksу инстанса без интейка; 503 уresumeна деплое без маркер-команды/шаблона потолка (0.2.1 ратифицировала 503 только для СТАРТА). - PD-180: описание
createBookчестное: 201 несётparsing, не «responds immediately … enters uploading» (uploadingнаблюдаем только параллельным чтением библиотеки); плюс перечень отказов интейка: 400 (>16 частей формы; текстовое поле >1 КиБ), 413 (потолок тела — порог принадлежит деплою, числа в спеку не зашивать), 408 (тело не успело за дедлайн маршрута — медленный клиент, лечение повтором). titleвBookIntake— необязательное поле: пустое/отсутствующее = «название даст разбор» (сегодня платформа берёт имя загруженного файла), заполненное = задано вручную и разбор его не перепишет. Ратифицировано оркестратором 14.08 как исполнение замечания 12 владельца (S3.5: «автор вводит название руками ЛИБО скипает — источники различать»; форма это уже разводит, а отправить рукописное название до сих пор некуда — черновик S3.5 висел без ратификации). Владелец промт ревьюит — отмена этого пункта одной репликой; дошла отмена аддендумом → эхо-подтверди и отрази в отчёте.
3. Задача 2 — загрузка книги (форма → createBook)
Половина Ф-26. Модал «Добавить книгу» отправляет форму через слой src/api/ (типы createBook
уже сгенерены), MSW-хендлер — по форме 0.2.3, включая порядок частей (file последним) и ветки
отказов. Экранный путь по §3.2–3.3 сценария:
- Прогресс отправки файла видимый (книги бывают десятки МиБ).
fetchпрогресса отправки не даёт — механизм выбери сам (XHR либо иное) и аргументируй в отчёте; слой данных остаётся одним входом, гейт транспорта (src/api/**only) в силе. - После 201 книга в библиотеке в
parsing— разбор это отдельный видимый шаг, не часть перевода. ⚠ Числового прогресса разбора у контракта НЕТ — процент не выдумывать, честное состояние «разбирается»; по завершении главы появляются в дереве, статусnot_started. - Отказ (
rejected) — с причиной по PD-173 и советом, различимым по классу (файл не тот ≠ сервис недоступен), фразы — как в задаче 1. Отказные ветки (400/408/413/404) — честные состояния формы, не алерты; тон — §3.8 («если экран выглядит тревожным — он неправильный»). - Подтверждение успешной загрузки видимое: размер/объём/язык (§3.2) — из данных контракта
(
character_count,chapter_count, языки), не выдумывая полей.
4. Задача 3 — запуск прогона с ручкой потолка (остаток строки 126 единого бэклога)
Форма запуска перевода. Ратифицировано (D39.110/115, компаньон §2.15 — не переоткрывать):
- Перед показом формы читается
GET /books/{id}/run-options; шкала потолка строится изCeilingBoundsв ГЛАВАХ — никаких долларов, сумм и оценок стоимости на экране (§4.8 в силе; пересчёт «главы→деньги» — целиком платформа). ceiling_chaptersобязателен, ноль выбрать нельзя; предустановка шкалы =default_chaptersот платформы (клиент своё значение не выбирает — это продуктовая политика);max_chapters: 0= старт недоступен, честное исчерпанное состояние вместо шкалы.- Bounds приходят готовыми и уже подрезанными — клиент не клампит второй раз и не выводит свои; между чтением и стартом они могут уехать — 409 на старте обрабатывается пере-чтением run-options и честной фразой, не ретраем втихую.
- Галочка «остановиться на подписи банка» (
verify_bank) — параметр ЭТОГО запуска, не глобальная настройка (решение владельца 02.08, §4 п.11 промта зоны). paused— прожитое состояние прогресса (ПТ-35: стоп по потолку = статусpaused+ оповещение). Фраза «остановлена: лимиты» зарезервирована за владельцем (В-3/В-6) — берёшь существующую из каталога, не переписываешь; механизм оповещения (статус-полоса/бейдж уже несут состояние — нужен ли отдельный тост) реши сам и аргументируй. После потолочного стопаresumeсам по себе прогон не двигает — resume как «продолжить после потолка» не предлагать (описаниеresumeв спеке); различение «свой потолок vs нет кредита» — К-13, на владельце, не решай. Страница лимитовGET /usageостаётся в настройках = S7 (Ф-27) — эту диспозицию не двигай.- ⚠ На ЖИВОЙ платформе потолочный стоп сегодня приезжает
failed— потребительская половина шва (П-15 зоны платформы) ещё не построена, PD-113 открыт. В мире моков строй ПО КОНТРАКТУ (paused,EventCeiling); от живого стенда правильного поведения не жди и не подгоняй под него ни код, ни тесты.
Прогресс во время прогона — по построенному useRunStream: пер-главные индикаторы в дереве и
общий прогресс в статус-полосе уже живут на фикстурах (одна доля без названий фаз, ETA из
eta_seconds — ратифицировано); доведи их до пути «книга, заведённая формой, переводится» в
мире моков. Внутренности конвейера не раскрывать (§4.1).
5. Задача 4 — библиотека на настоящем масштабе
- Хвост Ф-12: дерево глав ПЛОСКОЕ — на 2284 разделах нужна группировка (по сотням или иная —
реши сам по референсу и замеру на
/scale, аргументируй). - Все статусы
BookStatusпрожиты в дереве и карточке книги — включаяuploading(виден параллельным чтением),parsing,rejectedс причиной. Метки состояния — из словаря с веткой неизвестного; слова, зарезервированные за владельцем (В-3/В-8), НЕ трогать и не укорачивать. - Ф-42 (потолок keep-alive вкладок) — по замеру: реши сам, чинить или отложить с записью.
6. Задача 5 — находки приёмки S3.7 (все получают диспозицию)
Ревью приёмки: 12 подтверждённых (1 high) + 16 минорных. Из подтверждённых 9 несущих — список
ниже; остальные 3 — поправки к записи S3.7 (цена бандла, дрейф ширин hidden, счёт «106 из
119»), их носители — запись оркестратора 14.08 в журнале и задача 7. Каждой — диспозиция в
записке-плане (починено с тестом / не воспроизводится с замером / отложено со строкой):
- (high) Дубль подстановки строк: запись S3.7 ложно клеймила «заполнение вынесено в
src/i18n/fill.ts, его импортируют и приложение, и сцены» —scenes.mjsдержит собственный инлайн-филлерsay()с ДРУГОЙ семантикой пропуска, добавленный самой S3.7. Сведи к одному носителю. - Отметка «перечитывание в пути» ставится без старта чтения и глушит следующие кадры ключа
(
useRunStream.ts:146на момент приёмки). onResyncне чиститasked— отметки прежней эпохи съедают кадр в окне ресинка (:42).- Клейм «resync не рвёт живой поток» — принять только по живому инструментированному прогону с
задержкой ответа (статика
resetQueriesговорит обратное). - Сцена
hidden: прекондиция «ушли до прихода банка» не ассертится (гонка с синхронным моком), сторож дифференциальный — симметричная регрессия замера пройдёт; и «таблица вообще нарисована» не проверяется (два пустых замера равны). - Дырка ESLint-гейта строк: вычисленный литерал (
?? 'Word', тернарник) в читаемом атрибуте и литерал в expression-child проходят — живой экземплярShowcase.tsx:134. - Perf-оседание может проходить вакуумно: заходы 2–5 ждут 300 мс против конвенции 700.
- Zoom-ассерт «в ряд» не запрещает стопку (сравнивает left с left, не с right).
- Кадр
statusне перечитывает список глав — по собственной посылке Ф-49 его счётчики на границе стадии тоже протухают.
Минорные (актуальный остаток свода; часть уже закрыта попутно — сверь и диспозиционируй
коротко): свип языка catalogue.test.ts не метёт package.json и безрасширенный
scripts/githooks/pre-commit · гейт вызовов каталога держится на имени локальной переменной
text · шапка ru.ts ссылается на несуществующий src/i18n.test.ts · perf: удлинение запроса
с 3 до 5 символов само занижает мс/клавишу · защёлка флага съёмки — эвристика окна 150 мс
(знать, не чинить без замера).
file:line — ориентиры на момент приёмки, код первичен. Несогласие с находкой = диспозиция с
замером, не молчание (образец: арбитраж 8.1, где права оказалась сессия).
7. Задача 6 — гигиена зонных доков и арбитраж двух чисел
Стейлы (аудит-свип 14.08), чинить по факту кода:
FRONTEND_PLAN.md:42-43— «платформа = ноль строк кода» устарело (P5 принята, D39.130);:26-30— таблица §0.1 подаёт строки 95/99–103 как «чего ещё нет» (95 ратифицирована D39.99, 99/100/103 построены D39.122/131) и шлёт читатьAPI_CONTRACT_INPUT.mdкак живой вход (он под баннером «исполнено»);: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 принята и залендена.frontend/README.md:63-66— зонная копия спеки названа «черновик на ратификацию» — она давно байт-зеркало ратифицированного канона (D39.99/115).
Арбитраж чисел ЗАМЕРОМ (два носителя врозь, оба претендуют на факт): цена бандла i18n —
запись S3.7 говорит «724130 (+7999)», Ф-35 говорит «723102 (+6971)»; ключей каталога — запись
«147», Ф-35 и живой ru.ts — «157» (верно 157). Прогони сборку и счёт ключей на текущем дереве,
живые носители (BACKLOG/план) приведи к замеру; записи хроники НЕ правятся — расхождение назови
попуткой в своей записи.
8. Задача 7 — завести Ф-строки (долги без носителя, найдены свипом 14.08)
- RTL-проверка: триггер «появление I18nProvider» НАСТУПИЛ в S3.7 — строка с честной ценой.
- Спойлер достаётся в обход: размытие глифов не прячет текст от поиска по странице (Ctrl+F) и печати в PDF — продуктовое слово нужно, строка + В-вопрос владельцу.
- Канвас-замер ширин не знает
lang: при двух CJK-лицах один код-пойнт рендерится по-разному — строка с условием срабатывания.
Плюс одно закрытие по слову владельца 14.08 — Ф-52: поднять --color-danger на ступень до
≥3:1 на полотне панели (тот же приём, что у --color-note 2.98→3.07 в S3.7 — минимальный сдвиг
тона, не редизайн), пере-прогнать axe, закрыть строку замером.
9. На владельце — НЕ решать и не трогать
В-7 (плотность интерфейса; держит Ф-54 — обрезку центра на зуме: ЧИСЛО печатай, не чини) ·
В-8 (слово состояния в дереве) · В-9 (языки интерфейса) · В-4/Ф-30 (глава без заголовка — «на
экране ничего не менять», ждёт и строку 160 движка) · Ф-38 (вкладка «Замечания») · К-13/Ф-31
(различение причин паузы) · В-3/В-6 (фразы ступени и паузы) · граница ПТ-33 (добавочные поля
BankTerm — форм не выдумывать). Фразы PD-173 — исключение: их пишешь ты (§2), владелец
утверждает по отчёту. Пины STACK_DECISIONS не двигать (Ф-28 — измерено и передано, не патчить).
10. Границы скоупа
Подпись банка и его редактирование — S5. Читалка — S6. Экспорт, настройки (вкл. страницу
лимитов), светлая тема — S7. Живого канала банка нет (строка 169 единого — гейт S5).
Добавление ГЛАВЫ (§3.10 промта зоны) не строить: ручки в контракте не существует — кнопка
без действия запрещена нормой зоны; счёл нужным — предложи черновиком правки спеки с пингом, не
кодом. Мок-слой остаётся домом фронта (Ф-29 — триггер сноса не наступил); опционально, если
локальный стенд платформы поднимется без боя — smoke живого POST /books через dev-прокси
(same-origin, В-кватер; переключатель TM_PLATFORM дев-сервера уже существует — S3 чинила его
достижимость) с честным отчётом; это НЕ гейт сдачи, со стендом не воюй, и помни каветы §4 про
П-15: живой стенд местами отстаёт от контракта — эталон формы всегда спека, не стенд.
11. Самопроверка и сдача (мандат, не пожелание)
- Ревью исполнением: каждый экранный путь прогнан живым браузером (скриншот-цикл/сценарии), каждый новый гейт и тест проверен ЖИВЫМ нарушением, тесты фиксов падают на до-фиксном коде. Вердикт о поведении браузера без живого прогона = PLAUSIBLE, не факт (D39.129).
- Адверсариальное ревью диффа — механизмом, author≠reviewer: независимые ревью-агенты по диффу с установкой опровергать; субагенты/параллельные агенты для этого разрешены явно — дефолт-запреты харнесса на этот пункт не распространяются. Артефакт — таблица «находка → диспозиция» в записи журнала; «перечитал внимательно сам» исполнением НЕ считается.
- Предметные оси ревью этого пака (вправе добавить свою или аргументированно снять): (1) контракт — каждая форма данных из спеки, новая потребность = черновик правки спеки, не фикстура (класс «фикстура выдумала форму» ловился четырежды); (2) доступность — axe на новых экранах/сценах, полный путь загрузки и шкала потолка проходимы клавиатурой; (3) статусные ветки — каждая (uploading/parsing/rejected по причинам/404/408/413/409/paused) показана сценой или кадром, не только тестом.
- Заявление = команда: каждое число отчёта — с командой, которой получено; «сделано» без прогона не писать; чего НЕ сделал/не удалось — отдельным явным списком.
- Гейты не подгонять: порог/проверку не двигать ради зелени; несогласие с гейтом — пинг.
- Сдача:
npm run checkиnpm run check:fullзелёные; новые сцены в батарее; запись вfrontend/docs/frontend-PROGRESS.md(механика, замеры, диспозиции всех находок §6, В-вопросы); BACKLOG обновлён; дерево НЕ коммитить — лендит оркестратор.
12. Канал вопросов
Непонятно / промт конфликтует с кодом или доками / нужна правка вне frontend/ → пинг
оркестратору через владельца и запись в зонный журнал; НЕ интерпретация и НЕ правка чужой зоны.
Настоящие развилки эскалируй быстро — это норма, а не слабость.