Issue the contract-blockers and platform-runner prompts per owner course D39.119, gate S4 on shell quality, ratify PD-105 at-least-once

This commit is contained in:
Claude (backend session) 2026-08-08 22:53:27 +03:00
parent ef797101c1
commit 943eed7ec0
6 changed files with 72 additions and 6 deletions

View file

@ -0,0 +1,25 @@
# Промт бэкенд-сессии: ДВИЖКОВЫЕ БЛОКЕРЫ КОНТРАКТА API (строки 99 · 100 · 101 · 125 · 145)
**Выдан 08.08.2026, оркестратор №15, по слову владельца 08.08 (D39.119).** Ты — бэкенд-сессия. Зона записи: `backend/` (код+тесты+puml тем же паком) + отчёт `docs/archive/reports/CONTRACT_BLOCKERS_2026-08-XX.md` (дату проставь сам) + пинг в `docs/PROGRESS.md` секция «Бэкенд» (ТОЛЬКО append своей секции; CURRENT-STATE и чужие секции не касаться; `git status` до и после). «Строка N» = ID строки ЕДИНОГО БЭКЛОГА (таблица «Бэклог» в `docs/PROGRESS.md`). **НЕ коммитишь** — дерево готовишь, лендит оркестратор. **Деньги: $0** — платных вызовов нет вообще. ⚠ Живую параллельную зону определяй `git status` + CURRENT-STATE в начале сессии; на выдачу промта живой сосед — полигон эксп-22 (`eval/tenant_panel/`, `docs/experiments/22-tenant-panel.md`, секция «Полигон»). Чужого не трогать и не «прибирать» (инцидент D39.113 стоил семи файлов).
**Первый деливерабл — эхо-блок ≤10 строк ПЕРВЫМ СООБЩЕНИЕМ сессии** (как понял: пять работ · инварианты · что вне скоупа; подтверждения не жди — работай дальше).
## Онбординг: какую проблему решаем и что решит твой результат
TextMachine — движок художественного перевода больших книг (Go, `backend/`), поверх которого строятся платформа (SaaS control plane, `platform/`, отдельный процесс — движок дёргается процессами, D39.81) и веб-фронт (ридер-IDE). Контракт API фронт↔платформа ратифицирован (OpenAPI 0.2.0, `docs/architecture/14-api-contract/`), но пять поверхностей ДВИЖКА, из которых платформа должна собирать ответы, не существуют — и это гейтит первые реальные экраны фронта (библиотека/прогресс/подпись банка) и управляемый потолок прогона. Твой пак строит ровно эти пять поверхностей. Всё — файлы/CLI движка, которые платформа ЧИТАЕТ: **сетевых поверхностей в движке НЕ появляется** (сервер не пишется — инвариант D39.81, строка 96).
Карта чтения (≤5, СВЕРХ стандартного онбординга роли по CLAUDE.md — `backend/README.md` + `03-implementation-notes.md` через баннер): CURRENT-STATE → строки 99/100/101/125/145 бэклога (тела строк несут замеры и якоря; этот промт их не дублирует) → `docs/architecture/14-api-contract/openapi.yaml` + компаньон-README (какие ответы платформа собирает из твоих поверхностей) → `12-go-style-notes.md` §0. Жаргон — `docs/glossary.md`. **Стенд:** описание и книги — `backend/README.md`; замер строки 100 — на большой книге стенда (та же, что в замере строки: 23 МБ, ~2284 раздела); `~/books/gu-zhenren/coldrun-a/` — замороженный эталон, ТОЛЬКО чтение.
## Работы (форму КАЖДОГО артефакта фиксируешь в отчёте; «реши сам» = реши и аргументируй; ⚠ все `file:line` ниже — ОТПРАВНЫЕ ТОЧКИ, код первичен: протухший якорь — сверка, не блокер)
1. **Строка 99 — пофазный прогресс.** Индикатор «готово N/M» стоит 0% всю черновую волну: unit=done только при всех draft-строках + edit-строке. Данные уже есть (`chunk_status` — строка-на-стадию; status уже делит стадии по волнам). Вывести пофазные счётчики — ДВА отдельных: draft N/M и edit N/M (текстовая форма вывода — реши сам) — в StatusReport И в `tmctl status --json`, БЕЗ миграции схемы. Форма JSON-полей — реши сам, но так, чтобы платформа могла собрать `progress` контракта без домыслов; назови её в отчёте явно.
2. **Строка 100 — персист манифеста глав/чанков.** Сейчас каждый read-вызов заново ингестит и режет книгу (`status.go` `bookChunks`, ~1.41.5 с CPU на книге 23 МБ; redrive — дважды за вызов). Нужен персист манифеста (главы/чанки + `chunker_version` из снапшота + хеш источника) со СТАБИЛЬНЫМ id главы — фундамент дерева глав фронта (книга ~2284 раздела). Дизайн реши сам с двумя жёсткими требованиями: (а) манифест обязан пережить смену чанкера — `--resnapshot` его пере-строит, а стабильность id главы через пере-чанковку либо гарантируется, либо ЧЕСТНО объявляется границей (что именно инвалидируется — в отчёт); (б) read-пути (`status`/`report`) перестают резать книгу заново.
3. **Строка 101 — машиночитаемая таблица подписи банка.** Сейчас: кап-20 в stdout (`bankStopStdoutCap`, `cmd/tmctl/render.go`) + текстовый сайдкар `.bank-stop.txt`. Нужен машиночитаемый сайдкар ПОЛНОЙ таблицы (JSON; поля = те же, что текстовая, включая новые Signals/Invented/Conf/Conventions/Contradicts из D39.118). ⚠ Ловушка «подпись ≠ UPDATE»: контракт подписи пишет в файлы-источники, банк пересобирается (`seeding.go`, `glossary.go`) — сайдкар это ЧТЕНИЕ, семантику подписи не менять.
4. **Строка 125 — экспорт-артефакт банка.** Банк живёт в приватном SQLite движка, платформе он закрыт (D39.85). Нужен экспорт-файл ПОЛНОГО банка тремя статусами (approved/draft/auto) в каталоге книги — источник канала `/bank` контракта. Момент записи: МИНИМУМ — на каждом банк-стопе и на завершении прогона; чаще (границы стадий) — реши сам по цене. Форму (один файл/пер-статус, поля) реши сам по контракту 14; отличие от п.3 держи явным: 101 — таблица ПОДПИСИ (решения владельцу), 125 — экспорт СОСТОЯНИЯ банка.
5. **Строка 145 — потолок НА ПРОГОН аргументом.** Сегодня потолок приходит только из `book.yaml` (`Ceilings.BookUSD``stagerun.go:480`); платформа для управляемого потолка (D39.110) была бы вынуждена править конфиг книги — смешение зон против D39.81. Сделай приём потолка аргументом запуска (флаг `tmctl translate` и/или ENV — реши сам; вход через `parseInvocation`), семантика: значение в USD, действует ТОЛЬКО на этот прогон, `book.yaml` НЕ пишется, аргумент ПЕРЕКРЫВАЕТ книжный `book_usd`. Валидатор Р7 (`internal/config/book.go:251`) не правится — ноль/отрицательное аргументом = отказ запуска. Цена нулевая: `Ceilings` в BriefHash не входит — предъяви это тестом/грепом в отчёте (снапшоты и ре-билл не двигаются). Приор (опровергается кодом): resume после ceiling-стопа с БОЛЬШИМ аргументом = штатное «поднятие потолка» (`stagerun.go` ждёт ровно этого) — проверь, что путь работает, отдельной правки не жди.
**Вне скоупа:** строка 49 (annot-v1 экспорт замечаний — следующий пак) · строка 102 (внешний TraceID) · любые сетевые поверхности · правки семантики подписи/банка. **Инварианты:** движок = процесс-на-прогон, EXCLUSIVE flock; голден без пере-захвата (эти работы wire не двигают — если что-то захотело двинуть снапшот/RequestHash, это СТОП и пинг, не решение).
## Самопроверка и СТОП
Гардрейлы: `backend/.env` НЕ читать · PUML не рендерить. Мандат 12.07: ревью ИСПОЛНЕНИЕМ кода+артефактов — каждый новый файл-артефакт открой и прочитай глазами. **Генерация артефактов — только $0-путями:** read-пути (`status`/`report`) на стенд-книге · тесты с mock-провайдером (образец — e2e-тесты банк-пака) · реплей существующих чекпойнтов; платный прогон ЗАПРЕЩЁН, `coldrun-a` — только чтение. Дифф `^func Test` до/после — ИСПОЛНЕНИЕМ (grep), не памятью; список в отчёт. `make battery` зелёная ЦЕЛИКОМ (вкл. lint — урок D39.118). Перф-клейм строки 100 — замером до (HEAD-поведение в начале сессии) / после, на стенд-книге. Каждое ЧИСЛО отчёта — с командой, которой оно получено (приёмка пере-ранит). **Канал вопросов:** непонятно / промт противоречит коду-докам / форма артефакта не однозначна по контракту 14 → СТОП по ЭТОМУ пункту (остальные работы продолжай) и вопрос — строкой в свой пинг PROGRESS «Бэкенд» плюс устно владельцу (он релеит оркестратору); НЕ тихая интерпретация. Отчёт: по каждой работе — что сделано с `file:line` + ФОРМА артефакта (пример вывода) · девиации с причинами · чего не сделал и почему. **СТОП — приёмка оркестратора** (адверсариальная, клеймы пере-проверяются исполнением).

File diff suppressed because one or more lines are too long

View file

@ -16,7 +16,7 @@
- `research/` — фактура ресёрчей 0125; у принятых — ревью-шапки, часть тел под ⚠ superseded: **читай баннер прежде содержимого**. Ключевые для навигации: 15 голос · 16 ридер-IDE · 17 внешняя критика · 18 рычаги качества · 19 нарезка · 20 банк-майнинг · 21 обзор транспорта · 22 доменные харнессы · 23 шов движок↔платформа (транспорт superseded D39.106) · 25 холодное ревью шва — форма D39.106, отвергнутые альтернативы, требования к эмиттеру (читать перед любым кодом стыка) · 24 арбитраж банка (ПРИНЯТ D39.102: консилиум закрыт классом, вход фикс-пака банка — §G).
- [PROGRESS.md](PROGRESS.md) — журнал: CURRENT-STATE + **ЕДИНЫЙ БЭКЛОГ** (единственный трекер) + живой хвост хроники. НЕ источник решений.
- `scripts/counts.py`**производные числа доков считаются им, а не руками** (голова по трём носителям · счёт очереди и зон · вес открытых строк регистра платформы); `--check` даёт ненулевой код на расхождении. Его же зовёт зонный хук `scripts/githooks/pre-commit` при коммите, задевающем D-лог или PROGRESS — предупреждает, не блокирует. Заведено по D39.112 п.5б: голова отставала трижды у трёх разных оркестраторов.
- Активные хендофф-промты сессий (состав обновляется при каждом лендинге — норма D39.80): [ORCHESTRATOR_SESSION_PROMPT.md](ORCHESTRATOR_SESSION_PROMPT.md) (роль/нормы; состояния не дублирует) · [POLYGON_PACKAGE4_SESSION_PROMPT.md](POLYGON_PACKAGE4_SESSION_PROMPT.md) (полигон, отложен) · **платформа: ОТРАБОТАН ЦЕЛИКОМ** — четыре сессии (P0 D39.107 · P1+P2 D39.109 · фикс-пак P3 D39.114); текст в архиве, [`archive/prompts/PLATFORM_P0_SESSION_PROMPT_2026-08-04.md`](archive/prompts/PLATFORM_P0_SESSION_PROMPT_2026-08-04.md), копия с баннером ещё лежит в зоне. Следующий промт платформы — по слову владельца (реконсилятор/тейлер/юниты, D39.107 п.3(3)) · **фронт: S3 ОТРАБОТАН и ПРИНЯТ D39.115** (контракт 0.2.0 в каноне, копии байт-равны, слой данных построен); текст в архиве, [`archive/prompts/FRONTEND_S3_SESSION_PROMPT_2026-08-04.md`](archive/prompts/FRONTEND_S3_SESSION_PROMPT_2026-08-04.md). Промт S4 — по слову владельца. Зонные журналы фронта/платформы — `frontend-PROGRESS.md` / `platform-PROGRESS.md` в их зонах (решение владельца 04.08: прогресс зон только там). **бэкенд: фикс-пак банка ОТРАБОТАН и ПРИНЯТ D39.118** (код `bccf2d8`; отчёт с ревью-шапкой — [`archive/reports/BANK_CLUSTER_FIXPACK_2026-08-08.md`](archive/reports/BANK_CLUSTER_FIXPACK_2026-08-08.md); текст промта в архиве — [`archive/prompts/BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT_2026-08-04.md`](archive/prompts/BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT_2026-08-04.md)); следующий промт бэкенда (эмиттер строки 103 + деньги шва) — по слову владельца · **Полигон: [POLYGON_TENANT_PANEL_SESSION_PROMPT.md](POLYGON_TENANT_PANEL_SESSION_PROMPT.md)** (эксп-22 «панель жильцов»; санкция D39.117, ЗАПУЩЕН 08.08 — сессия живая) · **эксп-21 ОТРАБОТАН и ПРИНЯТ** (D39.117; отчёт `experiments/21-role-topology.md`), текст промта в архиве — [`archive/prompts/POLYGON_ROLE_TOPOLOGY_SESSION_PROMPT_2026-08-06.md`](archive/prompts/POLYGON_ROLE_TOPOLOGY_SESSION_PROMPT_2026-08-06.md). Очередь и состояние — только CURRENT-STATE.
- Активные хендофф-промты сессий (состав обновляется при каждом лендинге — норма D39.80): [ORCHESTRATOR_SESSION_PROMPT.md](ORCHESTRATOR_SESSION_PROMPT.md) (роль/нормы; состояния не дублирует) · [POLYGON_PACKAGE4_SESSION_PROMPT.md](POLYGON_PACKAGE4_SESSION_PROMPT.md) (полигон, отложен) · **платформа: ОТРАБОТАН ЦЕЛИКОМ** — четыре сессии (P0 D39.107 · P1+P2 D39.109 · фикс-пак P3 D39.114); текст в архиве, [`archive/prompts/PLATFORM_P0_SESSION_PROMPT_2026-08-04.md`](archive/prompts/PLATFORM_P0_SESSION_PROMPT_2026-08-04.md), копия с баннером ещё лежит в зоне. **Платформа: [`../platform/docs/PLATFORM_RUNNER_SESSION_PROMPT.md`](../platform/docs/PLATFORM_RUNNER_SESSION_PROMPT.md)** (раннер: юниты/River/реконсилятор/тейлер + первые ручки /v0; D39.119, запуск = владелец) · **фронт: S3 ОТРАБОТАН и ПРИНЯТ D39.115** (контракт 0.2.0 в каноне, копии байт-равны, слой данных построен); текст в архиве, [`archive/prompts/FRONTEND_S3_SESSION_PROMPT_2026-08-04.md`](archive/prompts/FRONTEND_S3_SESSION_PROMPT_2026-08-04.md). **S4 ГЕЙЧЕН словом владельца о качестве оболочки (D39.119 п.4):** сначала список претензий → «S3.5 фикс-пак оболочки» (VS Code-вкладки + Ф-19) → S4. Зонные журналы фронта/платформы — `frontend-PROGRESS.md` / `platform-PROGRESS.md` в их зонах (решение владельца 04.08: прогресс зон только там). **бэкенд: фикс-пак банка ОТРАБОТАН и ПРИНЯТ D39.118** (код `bccf2d8`; отчёт с ревью-шапкой — [`archive/reports/BANK_CLUSTER_FIXPACK_2026-08-08.md`](archive/reports/BANK_CLUSTER_FIXPACK_2026-08-08.md); текст промта в архиве — [`archive/prompts/BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT_2026-08-04.md`](archive/prompts/BACKEND_BANK_CLUSTER_FIXPACK_SESSION_PROMPT_2026-08-04.md)); **Бэкенд: [BACKEND_CONTRACT_BLOCKERS_SESSION_PROMPT.md](BACKEND_CONTRACT_BLOCKERS_SESSION_PROMPT.md)** (движковые блокеры контракта 99/100/101/125/145; D39.119, запуск = владелец; эмиттер 103 — следующим промтом) · **Полигон: [POLYGON_TENANT_PANEL_SESSION_PROMPT.md](POLYGON_TENANT_PANEL_SESSION_PROMPT.md)** (эксп-22 «панель жильцов»; санкция D39.117, ЗАПУЩЕН 08.08 — сессия живая) · **эксп-21 ОТРАБОТАН и ПРИНЯТ** (D39.117; отчёт `experiments/21-role-topology.md`), текст промта в архиве — [`archive/prompts/POLYGON_ROLE_TOPOLOGY_SESSION_PROMPT_2026-08-06.md`](archive/prompts/POLYGON_ROLE_TOPOLOGY_SESSION_PROMPT_2026-08-06.md). Очередь и состояние — только CURRENT-STATE.
- Зоны фронта (чужие, читать при касании стыка; каждая ведёт СВОЙ зонный бэклог — единый бэклог их строк не принимает, D39.84): [../frontend/](../frontend/) — веб-интерфейс: промт фронт-сессий S0S7 + [STACK_DECISIONS.md](../frontend/docs/STACK_DECISIONS.md) (пины версий точными числами и ловушки, сверены с вебом 02.08) + [BACKLOG.md](../frontend/docs/BACKLOG.md) · [../platform/](../platform/) — SaaS control plane: README + [BACKLOG.md](../platform/BACKLOG.md) (П-1..П-5) + `docs/` (промт P0 · зонный журнал `platform-PROGRESS.md`).
- `archive/` — история ([правила архива](archive/README.md)): закрытые промты (`prompts/`) · отчёты с ревью-шапками (`reports/` — на них ссылаются приёмки) · исполненные арх-доки (`architecture/`) · слайсы хроники `PROGRESS-*.md`. Инструкции оттуда не исполнять.
- Диаграммы: [../backend/docs/components.puml](../backend/docs/components.puml) · [../backend/docs/pipeline.puml](../backend/docs/pipeline.puml) — дом рядом с кодом (D39.80), правятся бэкендом одним коммитом с кодом; вручную НЕ рендерить (владелец смотрит PlantUML-расширением VS Code).

View file

@ -1,4 +1,4 @@
# Журнал решений оркестратора — контракт D1D39.118 (развязки 04.07 · пакеты 0910.07 · приёмка/качество-первым/пивот/эмпирика 1112.07 · арх-ресет+стройка пере-прогонного стека 1319.07)
# Журнал решений оркестратора — контракт D1D39.119 (развязки 04.07 · пакеты 0910.07 · приёмка/качество-первым/пивот/эмпирика 1112.07 · арх-ресет+стройка пере-прогонного стека 1319.07)
> **КАРТА АКТУАЛЬНОСТИ (ревизия D31, продлена до D38.2 [12.07]; исторические записи ниже НЕ переписываются — дисциплина D23.3).** Читая контракт целиком, держи под рукой, что чем перекрыто:
> ⚠ **Навигация (актуализация 07.08, эра D39.1xx):** append-only-дисциплина (D23.3) означает, что
@ -1685,4 +1685,14 @@ API-529-долг закрыт: 8-осевой refute-by-default воркфлоу
**4. Строки трекера:** **128 и 129 ЗАКРЫТЫ** · **130 пере-скоуплена** (минимум исполнен; остаток = накопительный мердж/слоты — СТОП-решение владельца, материал даст WARN со второго прогона) · **заведены 154159** (одноруновая голова семьи · скрипт-слепой резолв к ja→ru · `banknote_truncated`-пол за гейтом канала · пере-подтверждение `family_max_members=24` · conf без гейта данных пары · durable-имена эвиктнутых) · дописаны 37 (вынос Aho-Corasick = рефакторинг слоя, «чисто не ложится») · 38 (ординальная механика подтверждена кодом: G1 двигает состав юнитов — на первом прогоне после пака перекупаются все бэнк-батчи, центы) · 57 (ссылка на фикс-пак закрыта). Остаточный принятый риск: пин покрытия типов работает по зеркальной фикстуре `zhFamily` — рассинхрон зеркала со shipped-строками пином не ловится.
**5. Верификация эффекта** — §6 отчёта (10 конкретных проверок по артефактам, $0); гейт — первый холодный прогон: `families=`/`families_held=` · химера 古月/转 в стоп-таблице · `self_conflicts=` · колонка `confidence` при не выросшем `bad_lines` · WARN диффа авто-банка со второго прогона. Активного промта бэкенда после этого лендинга НЕТ — следующий (эмиттер строки 103 + денежные строки шва) по слову владельца (D39.107 п.3).
**5. Верификация эффекта** — §6 отчёта (10 конкретных проверок по артефактам, $0); гейт — первый холодный прогон: `families=`/`families_held=` · химера 古月/转 в стоп-таблице · `self_conflicts=` · колонка `confidence` при не выросшем `bad_lines` · WARN диффа авто-банка со второго прогона. Активного промта бэкенда после этого лендинга НЕТ — следующий (эмиттер строки 103 + денежные строки шва) по слову владельца (D39.107 п.3). *(⚠ поправка курса тем же днём: следующим выдан пак «блокеры контракта», эмиттер — за ним; слово владельца — D39.119 п.1.)*
## D39.119 — КУРС ВЛАДЕЛЬЦА 08.08: эмиттер отложен, выданы ДВА промта (бэкенд «блокеры контракта» · платформа «раннер»); S4 гейчен качеством оболочки; PD-105 ратифицирован (08.08). ✅
**1. Слово владельца 08.08 (пересказ):** с эмиттером jsonl подождать — вокруг него техдолг бэклога; но платформу и фронт пора разблокировать. Разбор оркестратора, подтверждённый владельцем формой «пиши»: настоящие разблокираторы фронта/платформы — движковые строки контракта **99/100/101/125/145** (строка 49 annot-v1 — следующим паком) и платформенный раннер с ручками; эмиттер нужен СВЕЖЕСТИ статуса и деньгам шва, не первым экранам — резерв на это время = периодический `status --json`-резюнк (построен в P1). Поправка к D39.118 п.5: эмиттер идёт бэкенд-промтом ПОСЛЕ пака блокеров.
**2. Выданы два промта** (оба аудированы перед выдачей: два холодных читателя + фактчекер, 35 опор подтверждено, поправки внесены): **бэкенд**`docs/BACKEND_CONTRACT_BLOCKERS_SESSION_PROMPT.md` (строки 99+100+101+125+145; $0; сетевых поверхностей в движке не появляется — D39.81) · **платформа**`platform/docs/PLATFORM_RUNNER_SESSION_PROMPT.md` (транзиентные юниты D39.106 · River+воркер+холд-до-спавна · реконсилятор 138 · тейлер наготове · первые ручки /v0 по контракту 0.2.0 (П-1/П-5) · PD-99; координация с бэкенд-паком — узкие интерфейсы с дев-стабами, форма только из HEAD). Запуск сессий — владелец.
**3. Ратификация PD-105:** доставка событий шва = at-least-once; ДУБЛЬ `seq` — норма повторного чтения, декодер обязан принимать идемпотентно без фатала; тот же `seq` с ДРУГИМ payload = карантин прогона (research/25). Девиация от буквы реестра («ратифицировать вместе с промтом эмиттера») осознанная — тейлер-сторона строится сейчас; строку реестра обновляет платформа-сессия паком.
**4. Слово владельца о КАЧЕСТВЕ ФРОНТА — гейт на S4.** Владельцу не нравится «логика спама вкладками»: вкладки обязаны работать как в VS Code (preview-вкладка от одиночного клика, замещение её следующим, пин по двойному клику/взаимодействию). Полный список претензий владелец сформулирует отдельным входом. Диспозиция: **S4 не стартует до списка**; форма — «S3.5 фикс-пак оболочки» (VS Code-вкладки + Ф-19 + список владельца) → S4 на починенной оболочке. Носитель — запись оркестратора в `frontend/docs/frontend-PROGRESS.md` 08.08; ПТ-строка в продуктовый реестр — при полном списке. Бэкенд/платформа фронт не ждут.

View file

@ -197,7 +197,7 @@ def main() -> int:
bad = []
if not h["сходится"]:
bad.append(
f"голова разошлась: последняя нота {h['последняя нота D-лога']}, "
f"голова разошлась: максимум по номеру {h['максимум по номеру']}, "
f"шапка D-лога {h['шапка D-лога']}, CURRENT-STATE {h['голова в CURRENT-STATE']}"
)
if b["дубли ID"]:

View file

@ -0,0 +1,30 @@
# Промт платформа-сессии: РАННЕР — транзиентные юниты · реконсилятор · очередь · первые ручки /v0
**Выдан 08.08.2026, оркестратор №15, по слову владельца 08.08 (D39.119; санкция направления — D39.107 п.3(3)).** Ты — платформа-сессия. Зона записи: `platform/` + зонный журнал `platform/docs/platform-PROGRESS.md` (итоги/пинги ТОЛЬКО туда, в `docs/PROGRESS.md` не пишешь — D39.100). **НЕ коммитишь** — дерево готовишь, лендит оркестратор; своё в git-индексе не держи (стейдж = риск чужого коммита). **Деньги: $0** — LLM-вызовов нет; PostgreSQL стенда — рецепт без root в `platform/docs/STACK_DECISIONS.md`. ⚠ Живые соседи по дереву: полигон эксп-22 (`eval/`, `docs/experiments/22-*`) и, возможно, бэкенд-пак «блокеры контракта» (см. §Координация) — чужого не трогать и не «прибирать» (инцидент D39.113: откачено семь файлов, шесть потеряны). **Пространства имён:** «строка N» = ЕДИНЫЙ БЭКЛОГ `docs/PROGRESS.md` (таблица «Бэклог») · «PD-N» = `platform/docs/DEFECT_REGISTER.md` · «П-N» = `platform/BACKLOG.md`.
**Первый деливерабл — эхо-блок ≤10 строк ПЕРВЫМ СООБЩЕНИЕМ сессии** (скоуп · инварианты · не-делать; подтверждения не жди — работай дальше). ⚠ Все `file:line`/якоря промта — ОТПРАВНЫЕ ТОЧКИ, код первичен: протухший якорь — сверка, не блокер.
## Онбординг: какую проблему решаем и что решит твой результат
Платформа — SaaS control plane над движком перевода: пользователи/кредиты/HTTP уже стоят (P0P3 приняты, D39.107/109/114), но ПРОГОН движка платформа пока умеет запускать только дев-пайпом (`internal/ingest/supervisor.go` — явный DEV MODE). Ратифицированная форма шва — D39.106: движок = **транзиентный systemd-юнит на прогон** (платформа НЕ родитель), события — `events.jsonl` каталога книги (эмиттер движка ещё НЕ построен — строка 103, промт будет отдельно), платформа ТЕЙЛИТ с курсором, а ремонт-канал — `tmctl status --json` (уже существует и читается твоим `resync.go`). Твой пак строит ПРОДОВУЮ половину раннера и первые контрактные ручки — после него фронт сможет говорить с живой платформой, а не моками, не дожидаясь эмиттера.
Карта чтения (≤5): `platform/README.md` + зонный журнал (шапка; там же — отчёты P0P3, вкл. замер PD-91) → `docs/research/25-*.md` (§Форма · §Обязательные механизмы, включая абзац «Опс:» внутри неё — читать ПЕРЕД любым кодом стыка) → D-лог грепом: D39.106 · D39.110 · D39.115 п.4 (форма run-options/CeilingBounds) → контракт `docs/architecture/14-api-contract/` (openapi 0.2.0 + компаньон 2.142.16) → реестр `platform/docs/DEFECT_REGISTER.md` (открытые PD-строки твоих поверхностей; счёт — `python3 docs/scripts/counts.py`).
## Работы
1. **Транзиентный systemd-юнит на прогон**: `Restart=no`, SIGTERM (D39.106 §2); щедрый `TimeoutStopSec` (research/25 §Форма); cgroup-лимиты прогона — ответ PD-13 живёт здесь (D39.106 §3). **Privilege-модель реши ДО постройки** — research/25 называет два варианта: linger-пользователь либо узкое polkit-правило; зафиксируй выбор в `STACK_DECISIONS`. Свойства юнита меряй исполнением на стенде без root — метод замера `systemd-run --user` уже отработан на PD-91 (P3, зонный журнал). Пиннинг прогона к версионированному пути бинаря движка + резюм другой версией только явным флагом (строка 139).
2. **Очередь River + воркер** (П-3/П-7): пин подтверждён — добавь в go.mod; гард «один живой прогон на книгу» (`runs_one_live_per_book`) — исполнением; **холд ДО спавна** на сумму потолка (PD-79 закрыт в P3 — путь открыт), интеграция с юнитом п.1.
3. **Реконсилятор** (строка 138): на КАЖДЫЙ выход юнита (ExecStopPost-маркер/D-Bus — реши сам) и на БУТЕ — перезапуск прерванных прогонов; источник истины на буте = каталоги книг + Postgres, НЕ состояние systemd (research/25). До появления эмиттера live-статус добирается периодическим `status --json`-резюнком (твой `resync.go`) — честно, с меткой давности.
4. **Тейлер `events.jsonl`** — строится против словаря `platform/internal/ingest/events.go` (словарь = ПРЕДЛОЖЕНИЕ платформы движку; сам ТРАНСПОРТ ратифицирован D39.106) и лежит наготове: курсор `(engine_run_id, seq)` коммитится в ОДНОЙ транзакции с эффектом (контракт `Sink` + `run_attempts.last_seq` уже это предвосхищают); файла пока нет — тейлер обязан спокойно ждать его появления. **Ратификация PD-105 (этим промтом, D39.119): доставка at-least-once, ДУБЛЬ `seq` = НОРМА повторного чтения — декодер принимает его идемпотентно, БЕЗ фатала;** тот же `seq` с ДРУГИМ payload = карантин прогона (research/25). Реестр предписывал ратифицировать это «вместе с промтом эмиттера» — девиация осознанная (тейлер-сторона строится сейчас); строку PD-105 реестра обнови этим паком. Дев-пайп `platform/internal/ingest/supervisor.go` не удаляется — остаётся дев-режимом; `resync.go` — твой резюнк-канал.
5. **Первые ручки `/v0` по контракту 0.2.0** (П-1/П-5; гейт «ждёт ратификации» снят D39.115): библиотека/карточка книги · `GET /books/{id}/run-options``CeilingBounds` (максимум = `Balance` КАК ЕСТЬ — ⚠ НЕ «минус Reserved», это вычитание дважды, D39.115 п.2а; `max_chapters` отдаётся УЖЕ подрезанным, клиенту подрезать второй раз запрещено) · старт прогона с обязательным `ceiling_chapters` (потолок в USD передаётся движку аргументом прогона — см. §Координация) · `GET /usage` · статус/прогресс прогона из read-model. Формы ответов — СТРОГО спека; расхождение спеки с твоим кодом = вопрос оркестратору, не правка спеки. **Две границы, размеченные явно:** (а) **интейк книг** — библиотека обязана читать книги, заведённые ЛЮБЫМ путём (дев-скрипт/руками в каталоге + строка read-model; заведи такой скрипт как дев-инструмент); сам `POST /books` (multipart-загрузка) бери ТОЛЬКО если ложится чисто, иначе — явная строка зонного бэклога с обоснованием, ручки сдаются без него; (б) **пересчёт «главы→доллары»**: движковой поверхности оценки $/глава НЕ СУЩЕСТВУЕТ — на бету источник = конфиг-константа платформы (правит оператор; дефолт возьми из cost-model `docs/experiments/08-cost-model-v2.md`, поделив на главы, с комментом-провенансом), НЕ выдумывай движковую поверхность и НЕ ходи в SQLite движка; потребность в честной движковой оценке — строкой зонного бэклога, оркестратор заведёт её движку.
6. **Реестр PD:** возьми строки, чья латентность снимается ЭТИМ паком (PD-99 — argv с деньгами/book-id на INFO при появлении воркера — обязательно; остальные сверь сам по реестру и возьми/оставь с обоснованием). Строки эмиттер-стороны (PD-60/61) НЕ трогать — они задание движку.
**Вне скоупа:** эмиттер (движок, строка 103) · uncertain-эскроу/ночная сверка (строки 136/137 — следующий денежный промт) · SSE на фронт · SPA-отдача. **Инварианты:** движок дёргается ТОЛЬКО процессами (никаких импортов backend) · живой SQLite движка не читать (D39.85) · `book.yaml` платформа НЕ правит (D39.110).
## §Координация с бэкенд-паком (живой шов)
Параллельно (возможно) идёт бэкенд-пак «блокеры контракта» (промт `docs/BACKEND_CONTRACT_BLOCKERS_SESSION_PROMPT.md`): он строит потолок-аргумент прогона (строка 145), пофазный прогресс в `status --json` (99), манифест глав (100) и экспорт банка (125). Правило до его лендинга: свою логику доводи ДО шва целиком, сам шов — за узким интерфейсом с дев-стабом и пометкой `TODO(145)`/`TODO(99)`… (стаб = заглушка твоего интерфейса, НЕ имитация wire-формы движка — форму молча не выдумывай). Ручка старта прогона сдаётся полной, передача потолка движку — через такой интерфейс. Форму ПРИНИМАТЬ только из HEAD (залендённого); чужое незакоммиченное дерево `backend/` читать для сверки МОЖНО (норма D39.115 п.3), но копировать его форму нельзя — расхождение твоего стаба с их черновиком = вопрос, не молчаливая подгонка. Писать в `backend/` нельзя.
## Самопроверка и СТОП
Мандат 12.07: ревью ИСПОЛНЕНИЕМ (код + живые пробы на собранном бинаре + systemd-run-замеры). Дифф `^func Test` до/после — исполнением, не памятью; батарея `make check` зелёная целиком с живым PG (скипов ноль — рецепт в STACK_DECISIONS); `make vuln` чист. По правилу зоны: закрытая PD-строка = запиненное свойство (тест поимённо). **Канал вопросов:** непонятно / конфликт промта с кодом-доками-спекой / privilege-модель упирается в стенд → СТОП по ЭТОМУ пункту (остальные продолжай), вопрос — строкой в зонный журнал плюс устно владельцу (он релеит оркестратору); НЕ тихая интерпретация. Отчёт в зонный журнал: по работам с `file:line` · девиации · открытые PD-строки после пака (счёт скриптом) · каждое ЧИСЛО отчёта — с командой, которой получено (приёмка пере-ранит). **СТОП — приёмка оркестратора** (адверсариальная, со своими посадками).