diff --git a/docs/BACKEND_CONTRACT_BLOCKERS_SESSION_PROMPT.md b/docs/BACKEND_CONTRACT_BLOCKERS_SESSION_PROMPT.md new file mode 100644 index 00000000..d03120f5 --- /dev/null +++ b/docs/BACKEND_CONTRACT_BLOCKERS_SESSION_PROMPT.md @@ -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.4–1.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` + ФОРМА артефакта (пример вывода) · девиации с причинами · чего не сделал и почему. **СТОП — приёмка оркестратора** (адверсариальная, клеймы пере-проверяются исполнением). diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index ae314601..eb3c2cdd 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -1,8 +1,9 @@ # Журнал прогресса -> **⟶ ТЕКУЩЕЕ СОСТОЯНИЕ** (на 2026-08-08, голова D39.118; хендофф №14→№15 — D39.107). ⚠⚠ **ИНЦИДЕНТ 08.08 00:13 (D39.113): агент моей панели откатил незакоммиченные правки СЕМИ файлов чужих сессий** — `git checkout -- .` в реальном дереве вместо песочницы. Пинг полигона в этом файле ВОССТАНОВЛЕН из бэкапа 00:08; безвозвратно потеряны правки отчёта эксп-21, промта полигона, Приложения А контракта и трёх скриптов `eval/role_topology/`. Коммиты целы. Инвентарь и норма изоляции панелей — D39.113. ⚠ **Оркестраторов сейчас ДВА, зоны разведены явно (решение владельца 07.08):** №15 — приёмка ПЛАТФОРМЫ (исполнена, D39.109–D39.114: P1+P2 приняты, фикс-пак P3 принят и заленден `99f049c` — девять строк регистра закрыты, 8/8 моих посадок поймано, PD-80 и PD-91 пере-проверены исполнением; записи верифицированы независимым агентом, поправки — D39.112) · ВТОРОЙ, параллельный — приёмка ПОЛИГОНА (эксп-21 ПРИНЯТ — D39.117; промт эксп-22 выдан). **Номер второму НЕ выдан намеренно:** канонический счётчик один и живёт в `ORCHESTRATOR_SESSION_PROMPT.md`, а выдавать номер сессии, которой я не писал промт, — второй носитель состояния. Одновременно не запускаются; CURRENT-STATE ведут оба, каждый пишет про свою зону и чужую строку не трогает. +> **⟶ ТЕКУЩЕЕ СОСТОЯНИЕ** (на 2026-08-08, голова D39.119; хендофф №14→№15 — D39.107). ⚠⚠ **ИНЦИДЕНТ 08.08 00:13 (D39.113): агент моей панели откатил незакоммиченные правки СЕМИ файлов чужих сессий** — `git checkout -- .` в реальном дереве вместо песочницы. Пинг полигона в этом файле ВОССТАНОВЛЕН из бэкапа 00:08; безвозвратно потеряны правки отчёта эксп-21, промта полигона, Приложения А контракта и трёх скриптов `eval/role_topology/`. Коммиты целы. Инвентарь и норма изоляции панелей — D39.113. ⚠ **Оркестраторов сейчас ДВА, зоны разведены явно (решение владельца 07.08):** №15 — приёмка ПЛАТФОРМЫ (исполнена, D39.109–D39.114: P1+P2 приняты, фикс-пак P3 принят и заленден `99f049c` — девять строк регистра закрыты, 8/8 моих посадок поймано, PD-80 и PD-91 пере-проверены исполнением; записи верифицированы независимым агентом, поправки — D39.112) · ВТОРОЙ, параллельный — приёмка ПОЛИГОНА (эксп-21 ПРИНЯТ — D39.117; промт эксп-22 выдан). **Номер второму НЕ выдан намеренно:** канонический счётчик один и живёт в `ORCHESTRATOR_SESSION_PROMPT.md`, а выдавать номер сессии, которой я не писал промт, — второй носитель состояния. Одновременно не запускаются; CURRENT-STATE ведут оба, каждый пишет про свою зону и чужую строку не трогает. > - **Сессия №15 (07.08, ИСПОЛНЕНА):** **приёмка платформы P1+P2 — ПРИНЯТО и ЗАЛЕНДЕНО `fcdab81`** (62 файла, +7066/−252; D39.109). Адверсариально: своя батарея с живым PostgreSQL 18.4 (скипов ноль) · 45 СВОИХ мутаций (33 поймано, 8 выжило, 4 моих посадки негодны и разобраны) · живые пробы на боевом бинаре (PD-2 отпускает на 30.0 с; RFC 9207 сверен у Google) · панель 7 линз с опровергателем на каждую находку. Ратифицировано 6 решений (срок сессии 30 суток — **CONFIRM владельца 07.08 получен** · `iss` авторизационного ответа + миграция 00008 · §13 политики сессий · ломающие изменения зоны · `MemoryMax=80%`+`OOMPolicy=continue` · PD-71 риском). Регистр зоны доведён до **PD-107**. На момент приёмки открытыми были тридцать семь строк, весом major — три: PD-80 (вход выключается ~3 rps, и 429 колбэка добивает начатые входы) плюс PD-95 и PD-105, поднятые эрратой как задание эмиттеру. ⚠ **Числа здесь ИСТОРИЧЕСКИЕ — это то, что нашла приёмка;** живой счёт регистра меняется с каждым фиксом зоны и берётся командой `python3 docs/scripts/counts.py`, а не из этой строки (норма D39.112: один носитель на факт). **Живой уязвимости нет.** ⚠ **ЭРРАТА 07.08 (поймано вопросом владельца, не процессом):** приёмка пропустила, что **D39.106 п.3 снял пайп-транспорт** («PD-59 superseded; пайп-путь `supervisor.go` P1 = дев-режим»), и приняла зонную секцию «канал остаётся stdout» как живое решение. Ратифицированная форма — транзиентный systemd-юнит на прогон, платформа НЕ родитель, события = `events.jsonl` каталога книги, платформа ТЕЙЛИТ с курсором (`research/25` §Форма; родитель+пайп 0/15 голосов). Исправлено: секция журнала помечена superseded, PD-95 переписан и поднят в вес, PD-92 понижен до info, PD-105 повышен, PD-60 пере-диспозиционирован; вердикт лендинга не меняется (код и был дев-путём по D39.107 п.3). ⚠ Пять строк реестра — движковые по существу и должны быть разрулены ДО промта эмиттера (строка 103): PD-95 (транспортная история зоны устарела против D39.106 в двух местах — эмиттер-сессия прочтёт её как задание) · PD-105 (дубль `seq` = убитый платный прогон против норматива «дубль не ошибка»; при тейле файла повторная доставка — норма) · PD-79 (строковый `"null"` в цене = ноль денег) · PD-99 (argv на INFO — деньги/book-id при воркере) · PD-107 (удаление аккаунта обходит гарантию PD-25) · **PD-60 и PD-61** (обратное давление и сброс буфера — свойства эмиттера, задаются дешевле ДО постройки, чем миграцией после; PD-60 переформулируется под файл-транспорт). **Потолок прогона РЕШЁН владельцем 07.08 и ратифицирован формой (D39.110):** шкала в интерфейсе от минимума (ноль нельзя) до баланса аккаунта ⇒ Р7 не амендируется, «выключено» не существует как состояние. Добор: единица шкалы — ГЛАВЫ, не доллары (иначе амендмент D39.84) · потолок в `book.yaml` НЕ пишется, движку нужен приём на прогон — НОВАЯ строка **145** · максимум шкалы = баланс минус открытые холды. **Фри-тир:** ответ дан нормой (автогрант без якоря — не стандарт; `email_verified` Google якорем не является), предложение оркестратора — на бете дефолт в НОЛЬ и начисление руками, при платежах $5 вместе с суточным потолком; **ждёт слова владельца** (PD-104, там же расхождение док↔код: реестр обещает ноль, код начисляет $5) · **приёмка экспов 18/19/20 ИСПОЛНЕНА и залендена** (D39.108: приняты с ревью-шапками; §5.2 экспа 20 — «со слов»; деньги сессии полигона $2.0720; квирк §3б отозван, §3а в силе; D21.4/D21.10 закрыты) · **эксп-21 «топология ролей» — промт выдан** (`POLYGON_ROLE_TOPOLOGY_SESSION_PROMPT.md`: скрин моделей по 7 ключам → бейк-офф топологий на невиданном срезе; потолки ПРЕДВАРИТЕЛЬНЫЕ ≈$7.3 стадиями; **ЗАПУСК = слово владельца**) · строки 135–144 заведены, 103/106/134/65/55/12 пере-диспозиционированы · дальше по D39.107 п.3: промты эмиттера (бэкенд) и денег шва (платформа) — по команде · **S3 «слой данных» ПРИНЯТ и заленден `60595f6` (D39.115): контракт 0.2.0 в каноне, копии байт-равны, блоки компаньона 2.14–2.16 внесены; сессия нашла ТРИ ошибки оркестратора — «баланс минус холды» (вычитание дважды, пере-мерено), `nullable: true` невалиден в 3.1, инструкция внутри нормативного дока протухла от исполнения; норма «не ходить в чужую зону» амендирована: не ПИСАТЬ, а читать код для сверки — можно и нужно** · вахта deepseek-v4-pro — пере-проба маппинга вшита в Ф1 эксп-21 · мини-проба флора 44 — одобрена, промт не выдан. **Открыто на владельце:** прогон Sol-пакетов руками (строка 150) · кредиты xAI (арбитр grok + судья 18+) · запуск эксп-22 (промт выдан, D39.117) · передача платформы · Приложение А `14-api-contract` (незакоммичено) · **НОВОЕ 08.08 (D39.115, фронт):** продуктовое слово «остановлена: лимиты» (сжатие вашей фразы сделала сессия, В-3) · **К-13/Ф-31:** упереться в СВОЙ потолок прогона и остаться без кредита сегодня неразличимо — `paused_reason` имеет одно значение, и первому фраза врёт · **В-4/Ф-30:** глава без заголовка показана голым номером, синтез «Глава N» запрещён К-3 · **фри-тир (PD-104):** дефолт в ноль и начисление руками против автогранта $5 с суточным потолком · **Приложение А (строка 148):** брать реконструкцию с баннером или заполнять заново · 116 (порог подан) · мини-проба 44 · подпись денежного шага 46 · лист В-3+К-6 · вопрос платформы (авто-резюме `paused`). > - **Сессия №15 (08.08, приёмка бэкенда): фикс-пак банка (128+129+130-минимум) ПРИНЯТ и ЗАЛЕНДЕН `bccf2d8` (D39.118).** Приёмка четырёхконтурным воркфлоу (слепой дифф · пере-ран заявлений · 8 посадок в копии зоны · охота вне карты) + дофикс-раунд: блокер lint (клейм «батарея зелёная» был ложным — признано) · мёртвый WARN 130 (само-исключение сырого seed) · 2 дыры пинов space-run · инертный `bankParseVersion` · 3 тихих отказа канала семей — ВСЕ закрыты; ре-чек: battery EXIT=0 целиком, 685→717 тестов, пере-посадки 3/3 CAUGHT. Ратифицировано D39.118: сдвиг edit-волны bank-only принят (слово владельца) · bankdata-плоскость вне волнового фолда · лог вместо миграции для эвиктнутых. Строки 128/129 закрыты, 130 пере-скоуплена, заведены 154–159. Верификация эффекта — §6 отчёта, гейт: первый холодный прогон. **АКТИВНОГО промта бэкенда нет** — следующий (эмиттер 103 + деньги шва 135/145) по слову владельца (D39.107 п.3). +> - **Сессия №15 (08.08, курс D39.119): эмиттер ОТЛОЖЕН словом владельца — выданы ДВА промта:** бэкенд «блокеры контракта» (`BACKEND_CONTRACT_BLOCKERS_SESSION_PROMPT.md`: строки 99+100+101+125+145 — движковые поверхности для платформы/фронта; 49 — следующим) · платформа «раннер» (`platform/docs/PLATFORM_RUNNER_SESSION_PROMPT.md`: юниты D39.106 · River+воркер+холд-до-спавна · реконсилятор · тейлер наготове · ручки /v0 П-1/П-5; **PD-105 ратифицирован**: at-least-once, дубль seq = норма). Запуск обоих = владелец. **Фронт: S4 ГЕЙЧЕН** — слово владельца о качестве оболочки (вкладки = логика VS Code; полный список претензий следует); форма: «S3.5 фикс-пак оболочки» → S4 (D39.119 п.4, запись в зонном журнале). Эмиттер (103) — бэкенд-промтом после блокеров. > - **Сессия параллельного оркестратора (приёмка полигона, 08.08, D39.117):** **эксп-21 ПРИНЯТ** — гейты пере-гнаны исполнением (`verify_report.py` 90/90 код 0 · `itog.py` код 0); подтверждения владельца по тратам и агент-судейству получены, риг-девиация ратифицирована (девиация от промта оркестратора, не решение владельца). Несущее (числа — ИТОГ отчёта 21 и D39.117, здесь не дублируются): **работает ТОПОЛОГИЯ, а не жилец** (нога 2×2) · **черновик — главный рычаг качества финала**, самая недоинвестированная роль · закон-блок ОБЯЗАТЕЛЕН (двойное подтверждение) · роутинг/обратная связка/ремонт-как-замена — отклонены. Диспозиции: 65 ЗАКРЫТА (жилец = цена) · 142 принята формой «пре-гейт перед редактором» · 106 не закрыта (довод, не опровержение) · 55 частично (остаток = чистый zh-срез, заказ повторён). **Промт эксп-22 «панель жильцов» выдан** (149) · Sol-арбитраж вместо слепого чтения (150) · строки 151–153 заведены · три провод-факта в quirks 00. ⚠ Величины эксп-21 предварительны до чистого zh-среза. > - **Сделано (сводно; детали — D-лог и архив-слайсы):** Ф0 ✅ · Ф1-инфра ✅ · арх-ресет D39 (7 слоёв, паки 11–16) ✅ · паки 17 «канал B» · 18 «долги» · 19 «голос/состояние» · 20 «банк+терминолог» ✅ (D39.26–28/31/41–56) · мини-прогон (D39.37) и ХОЛОДНЫЙ прогон (D39.58: recall банка 0.918/0.980, банк приходит переведённым) приняты · полигон-пакеты 5–8, ToS-речек (D39.57), Р6+P4 (D39.61) закрыты · **карта языковой привязки движка (D39.60): 149 сайтов/45 файлов, книго-ось чиста (4), ja→ru безопасно без правки Go, en→ru — нет** · Р1–Р4 закрыты целиком (D39.63: Р2 = ЗНАЧЕНИЕ, Р4 = норма потолка recall) · **ФАЗА 2 ОБЩНОСТИ ✅ (D39.64: П0 эмбед-хеш · П1 цель-шов · П2 скрипт-шов, ko-баг закрыт · П3 нарезка · П4 манифест-по-каналам; голден вердикт-нейтрален 0/172, майнер-парити EXACT)** · жанровый словарь отменён как класс (D39.47) · петля ремонта построена и НЕ включена (D39.38). > - **Курс:** ОБЩНОСТЬ ✅ → КАЧЕСТВО БАНКА ✅ → ПАКЕТ-ЧЕКЕРОВ ✅ (D39.59–78) → **ФРОНТ-ЭРА открыта** (D39.81–100: зоны `frontend/`+`platform/` живые, контракт API ратифицирован). Развилка блокера 0731 решена вариантом (б) и ИСПОЛНЕНА (D39.87/91: `reasoning_effort:"low"` черновику + ручка эффорта бэнк-ролям, код `553f1a3`); отладочный прогон C не стартовал ⇒ **строка 16 жива и оси голоса 13б без данных**; пак экрана 46 — дизайн заморожен (D39.92 п.1 + D39.93), промт ждёт выдачи; coldrun-b фаза C заморожена чекпойнтом — легитимный исход (D39.86); эталон денег/поведения — coldrun-a (read-only). Числа и хроника закрытых паков — D-лог D39.79–97, сюда НЕ дублируются. @@ -219,7 +220,7 @@ S3 упёрлась в замок (контракта нет) — по слов ## Бэкенд -**⟶ Свежее состояние бэкенда: ФИКС-ПАК БАНКА принят и заленден (D39.118, `bccf2d8`; ревью-шапка отчёта первична); АКТИВНОГО промта бэкенда НЕТ — следующий (эмиттер строки 103 + денежные строки шва) по слову владельца (D39.107 п.3); точка входа `make battery`; ниже — пинг пака и хроника до №11.** **⟶ Приёмка №11 (D39.91, 02.08): пак ниже ПРИНЯТ, код заленден `553f1a3`; поправки приёмки (метка flash+pro · хеш по эквивалентности · `capability.go:78`) — в ревью-шапке отчёта и D39.91.** +**⟶ Свежее состояние бэкенда: ФИКС-ПАК БАНКА принят и заленден (D39.118, `bccf2d8`; ревью-шапка отчёта первична); АКТИВНЫЙ промт — `docs/BACKEND_CONTRACT_BLOCKERS_SESSION_PROMPT.md` (блокеры контракта 99/100/101/125/145, D39.119; запуск = владелец); эмиттер 103 — следующим промтом; точка входа `make battery`; ниже — пинг пака банка и хроника до №11.** **⟶ Приёмка №11 (D39.91, 02.08): пак ниже ПРИНЯТ, код заленден `553f1a3`; поправки приёмки (метка flash+pro · хеш по эквивалентности · `capability.go:78`) — в ревью-шапке отчёта и D39.91.** **ФИКС-ПАК БАНКА «КЛАСТЕРЫ + НАБЛЮДАЕМОСТЬ» (строка 128 + хвост 129 + $0-минимум 130) — ИСПОЛНЕН 08.08, ждёт приёмки.** Отчёт: [archive/reports/BANK_CLUSTER_FIXPACK_2026-08-08.md](archive/reports/BANK_CLUSTER_FIXPACK_2026-08-08.md). Деньги $0 (платных вызовов ноль), дерево НЕ коммичено, чужая зона (`eval/`) не тронута. Сделано: **G1** — `DetectFamilies`+`MergeUnits` рядом с `DetectSeries`, батчи ЮНИТАМИ (серия ⊕ семья ⊕ containment-пара), параметры семей — данные скрипта; критерий промта выполнен (линейка `一转…十二转` держится одним юнитом, равнодлинные серии не регрессируют); на реальном корпусе банка coldrun-a — 150 поверхностей → 16 юнитов, наибольший 20, отказов 0 · **G2** `ConsolidationConflicts` (прогон против САМОГО СЕБЯ — класс, которого канон-проверка не видит) · **G3** стоп-таблица += сигналы/`invented`/уверенность/конвенций/противоречия, третье поле уверенности в промпт zh-ru, alias-джойн подписной карты (карта строится из тех же кандидатов, что таблица), имена эвиктнутых, per-batch «спросили/ответили» + WARN на пустой ответ рендера И классификатора, честный `TestTerminologistEmptyReplyIsLoud` · **G5** голос по фолду целевой формы при показе сырых форм + честная агрегация Via · **129** ре-джойн многословного dst в парсере банкноты · **130** дифф авто-банка с именами выпавших (без накопительного мерджа — граница владельца) · опции: `BanknoteTruncated` (колонка была структурно недостижима) и мятый `⟦TM-NO-DST⟧`. **Два адверсариальных ревью исполнены** по санкции владельца — одиночное и МНОГОАГЕНТНОЕ (13 опусов: шесть линз → опровергатели → синтез, $0). Второе нашло четыре major, которых не увидели ни соло-проход, ни первое: **измеренный регресс парсера банкноты на замороженном эталоне coldrun-a** (реплей 56 блоков: −6 строк, +0, при неизменном `parse_fail` — тихо; трактовка «неизвестное последнее поле = часть перевода» портила строки с типом вне словаря и роняла обратный порядок) · **перевод АЛИАСА становился dst терма и ехал на провод** на $0-пути при выключенном гейте — ровно тот вред, ради которого заводился `Via` · **третье поле не-число молча приклеивалось к переводу** («наставник 95%» как канон при `bad_lines=0`) · **`Held` считался по попытке**, и отчёт трижды называл ценой гарда несуществующий случай. Плюс: ordinal-очередь ревью (единственная разрешённая D39.102 форма уверенности) была обещана и не реализована; WARN строки 130 бил ложной тревогой по штатному циклу подписи; `bankParseVersion` не был поднят при изменённом правиле парса. Всё закрыто; одиннадцать мутаций пере-проверены исполнением и убиты. Первое ревью: нашло 1 major (гард «серия сильнее семьи» растворял семью ЦЕЛИКОМ, включая не-серийных членов — та же химера §B4 через гард, который её должен был предотвращать), переусердствовавший тест родства (5 ложных придержаний на корпусе), задвоенный счётчик, `Conf=0` неотличимый от «нет уверенности», мёртвый параметр парсера и 4 выжившие мутации; **всё закрыто, мутации пере-проверены исполнением и убиты**. **`make battery` зелёная ЦЕЛИКОМ** (build·vet·fmt·**lint**·test) + `-race` на затронутых пакетах. ⚠ Первая редакция заявляла «батарея зелёная», прогнав только build/vet/test — гейт lint был КРАСНЫЙ (3× errcheck), поймано приёмкой. Фикс-лист приёмки исполнен целиком: блокер lint · **MAJOR: WARN строки 130 был структурно МЁРТВ в проде** (`ownerHandled` получал сырой seed, а тот со второго прогона содержит собственные строки движка ⇒ дифф всегда пуст; risk-2 self-exclusion, который файл обходит в двух других местах; мой тест это маскировал рукодельной map) · две дыры пинов на space-run-форме · `bankParseVersion` теперь реально логируется с прогоном · три тихих отказа канала семей (опечатка в script-колонке, пол-таблица, рассинхрон словаря типов с `nickname`) · неназванная девиация ранжирования дописана в §4. тестов 685 → 717 (+33, удалён 1 вместе с недостижимой веткой, которую он пинил). **Фолд (ИСПРАВЛЕНО ревью):** ДРАФТ-волна не двинулась (голден прошёл без пере-захвата, `Source:"mined"` исключён из BASE), а **edit-волна двигается bank-only** — пак меняет поле dst дельты, значит `memory_version`; сдвиг громкий (`--resnapshot`) и репинится за $0 для единиц без терма, но для частотного терма это почти вся книга ⇒ **решение владельца, вопрос в §7 отчёта**. ⚠ **Девиация, требующая слова оркестратора:** данные семей положены НЕ в `internal/lang/data/script-series.txt`, как предлагал промт, а в отдельную bank-плоскость `internal/lang/bankdata/` — иначе `EmbeddedVersion` сдвинул бы снапшот ОБЕИХ волн (и без права на $0-репин), что прямо противоречит §3 промта. **§7 отчёта разделён на ДВА списка:** три пункта требуют решения (принимается ли сдвиг edit-волны bank-only · durable-хранение имён эвиктнутых = миграция · двойной пробел в `coldrun-a`), и пять предложены СТРОКАМИ БЭКЛОГА для оркестратора (одноруновая голова семьи — включается строкой данных, гейт замер · скрипт-слепой резолв семей/серий на кану и хангыль — долг общности к преп ja→ru · `banknote_truncated` как пол, а не счёт · пере-подтверждение `family_max_members=24` и `families_held` на длинной книге · уверенность не гейтится данными пары). В таблицу бэклога сам не писал — её ведёт оркестратор. diff --git a/docs/README.md b/docs/README.md index 4feddc5d..2cb2df6e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,7 +16,7 @@ - `research/` — фактура ресёрчей 01–25; у принятых — ревью-шапки, часть тел под ⚠ 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/) — веб-интерфейс: промт фронт-сессий S0–S7 + [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). diff --git a/docs/architecture/05-decisions-log.md b/docs/architecture/05-decisions-log.md index ccce79eb..783131de 100644 --- a/docs/architecture/05-decisions-log.md +++ b/docs/architecture/05-decisions-log.md @@ -1,4 +1,4 @@ -# Журнал решений оркестратора — контракт D1–D39.118 (развязки 04.07 · пакеты 09–10.07 · приёмка/качество-первым/пивот/эмпирика 11–12.07 · арх-ресет+стройка пере-прогонного стека 13–19.07) +# Журнал решений оркестратора — контракт D1–D39.119 (развязки 04.07 · пакеты 09–10.07 · приёмка/качество-первым/пивот/эмпирика 11–12.07 · арх-ресет+стройка пере-прогонного стека 13–19.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 со второго прогона) · **заведены 154–159** (одноруновая голова семьи · скрипт-слепой резолв к 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; ПТ-строка в продуктовый реестр — при полном списке. Бэкенд/платформа фронт не ждут. diff --git a/docs/scripts/counts.py b/docs/scripts/counts.py index 307cccbf..8f857383 100644 --- a/docs/scripts/counts.py +++ b/docs/scripts/counts.py @@ -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"]: diff --git a/platform/docs/PLATFORM_RUNNER_SESSION_PROMPT.md b/platform/docs/PLATFORM_RUNNER_SESSION_PROMPT.md new file mode 100644 index 00000000..bdb8908c --- /dev/null +++ b/platform/docs/PLATFORM_RUNNER_SESSION_PROMPT.md @@ -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 уже стоят (P0–P3 приняты, 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` + зонный журнал (шапка; там же — отчёты P0–P3, вкл. замер 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.14–2.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-строки после пака (счёт скриптом) · каждое ЧИСЛО отчёта — с командой, которой получено (приёмка пере-ранит). **СТОП — приёмка оркестратора** (адверсариальная, со своими посадками).