diff --git a/docs/BACKEND_EMITTER_SESSION_PROMPT.md b/docs/BACKEND_EMITTER_SESSION_PROMPT.md index 63b033b2..d0c1d69a 100644 --- a/docs/BACKEND_EMITTER_SESSION_PROMPT.md +++ b/docs/BACKEND_EMITTER_SESSION_PROMPT.md @@ -83,10 +83,10 @@ финальные события (`finished`, `ceiling`) теряться не должны; краш-пути перечислить и покрыть. - Человеческие логи остаются на stderr как есть; эмиттер их не заменяет и не парсит. -### 3. Событие потолка + различимые exit-коды (строка 165, закрывает PD-113) +### 3. Событие потолка + различимые exit-коды (строка 165, закрывает PD-113 и PD-196) - `ceiling` — ФАКТ без цифр (деньги не выходят из движка нигде, кроме `spend`); эмитится на - `errReserveCeiling`-стопе (сейчас деньги только в тексте ошибки `stagerun.go:494-513`). + `errReserveCeiling`-стопе (сейчас деньги только в тексте ошибки `stagerun.go:489-513`). - Новые exit-коды tmctl: потолочная остановка и graceful stop (SIGTERM пойман, `NotifyContext`) обязаны стать различимы между собой и от infra-failure; 0/2/3 заняты (clean · completed-with-flags · банк-стоп) — выбрать значения, внести в shell-контракт `main.go` @@ -95,6 +95,12 @@ - День-потолок (`day_usd` из book.yaml) останавливает прогон невидимо для платформы (PD-157) — реши дёшево: причина потолка (book/day) внутри события `ceiling` либо диспозиция «не сейчас» с обоснованием. +- **PD-196 платформы (мандат D39.130 п.3, тем же паком):** exit 1 сегодня не различает и классы + отказа `manifest`-пути — «источник нечитаем» / «конфиг битый» / «лок занят»; платформенный интейк + чуть не удалил файл пользователя за опечатку оператора, потому что все трое выглядят одинаково. + Сделай классы отказа различимыми тем же shell-контрактом (exit-код или машиночитаемая причина + в событии/`status --json` — выбери форму и задокументируй в `main.go`); минимум — три названных + класса, расширяемость словарём, не перечислением в платформе. ### 4. Гейт потолка на каждый платный вызов (строка 135) diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index d994a5f8..f03fcd29 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -2,13 +2,13 @@ > **⟶ ТЕКУЩЕЕ СОСТОЯНИЕ** (на 2026-08-14, голова D39.130; приёмки S3.6/S3.7 — D39.127/129, промты эмиттера и P5 — D39.128, приёмка P5 — D39.130). Оркестраторов ДВА (решение владельца 07.08): этот — движок/платформа/фронт/доки; параллельный (РОЛЬЮ, без номера — счётчик один, D39.112 п.6) — приёмка полигона. Одновременно не запускаются; CURRENT-STATE ведут оба, чужие строки не трогают. Норма изоляции панелей после инцидента отката чужих файлов — D39.113, гардрейлы в CLAUDE.md. > - **Эра №15 закрыта — семь приёмок, все ПРИНЯТЫ и залендены**; лента, коммиты и разборы — D39.109–123 (D-лог) и реестр нот `architecture/05-decisions-index.md`; снимок прежних бюллетеней этой шапки — архив-слайс `-08-02-04`. -> - **ЖИВОЕ:** полигон эксп-22/23 — дерево ЗАЛЕНДЕНО 10.08 с ревью-шапками приёмки №16 (числа подтверждены независимым пересчётом; **выводы НЕ ратифицированы** — владелец 10.08 признал постановку неполной), **фаза Д заказана**: промт `docs/POLYGON_EXP2223_DOVODKA_SESSION_PROMPT.md`, запуск по слову владельца (санкция потолка $10.00 при запуске) · фронт: S3.5–S3.7 ИСПОЛНЕНЫ и ПРИНЯТЫ (D39.127/D39.129, лендинги `57e6bd1`/`3e465bd`), контракт **0.2.2** в каноне, i18n-механизм построен (ПТ-36 🔶) — **гейт S4 ПАЛ (P5 принят D39.130): S4-промт по слову владельца** (вход: экраны библиотеки/загрузки на живом `POST /books` · находки приёмки S3.7 · спек-правка 0.2.3) · **платформа P5 ИСПОЛНЕНА и ПРИНЯТА в три раунда (D39.130, `69d485a`)**: интейк книг `POST /books` с сентинелом хранилища · стоп/резюм с намерением в Postgres · Prometheus · Go-floor 1.26.6; развилка `book.yaml`: бета = форма Б (стройка следующим касанием зоны), движковая форма = строка 170 · **эмиттер** — промт ВЫДАН (`docs/BACKEND_EMITTER_SESSION_PROMPT.md`, D39.128 — строки 103+135+165+PD-196, закрывает PD-113), запуск по слову владельца · эскроу (136) — следующим денежным промтом. -> - **Открыто на владельце:** запуск фазы Д полигона (слово + санкция потолка $10.00) · Приложение А контракта (148: реконструкция с баннером или заново) · продуктовое слово «остановлена: лимиты» (В-3) · К-13/Ф-31 (paused_reason один — «свой потолок» и «нет кредита» неразличимы) · В-4/Ф-30 (глава без заголовка) · фри-тир PD-104 (ноль на бете против автогранта $5 с суточным потолком) · порог 116 · мини-проба флора 44 (одобрена, промт не выдан) · подпись денежного шага 46 · лист В-3+К-6 · авто-резюм paused (вопрос платформы) · запуск S3.7/эмиттера/следующего платформенного пака · фронт-вопросы зонного журнала: В-7 (плотность интерфейса; держит и Ф-54 — обрезку центра на зуме) · В-8 (слово состояния в дереве) · **В-9 (какие языки интерфейса обещает продукт — механизм готов, ПТ-36)** · Ф-38 (вкладка «Замечания») · граница ПТ-33 для добавочных полей `BankTerm` (черновик S3.5/S3.6, D39.127 п.2б). +> - **ЖИВОЕ:** полигон эксп-22/23 — дерево ЗАЛЕНДЕНО 10.08 с ревью-шапками приёмки №16 (числа подтверждены независимым пересчётом; **выводы НЕ ратифицированы** — владелец 10.08 признал постановку неполной), **фаза Д ИДЁТ (заказ 10.08)**: промт `docs/POLYGON_EXP2223_REDO_SESSION_PROMPT.md` (staged полигоном), потолок фазы $4.50 словом владельца (ход — секция «Полигон» ниже); при ратификации фазы Д в D-ноту: декой-правило + обязательный кросс-семейный опровергатель приёмки (одобрены владельцем 10.08) · фронт: S3.5–S3.7 ИСПОЛНЕНЫ и ПРИНЯТЫ (D39.127/D39.129, лендинги `57e6bd1`/`3e465bd`), контракт **0.2.2** в каноне, i18n-механизм построен (ПТ-36 🔶) — **гейт S4 ПАЛ (P5 принят D39.130): S4-промт по слову владельца** (вход: экраны библиотеки/загрузки на живом `POST /books` · находки приёмки S3.7 · спек-правка 0.2.3) · **платформа P5 ИСПОЛНЕНА и ПРИНЯТА в три раунда (D39.130, `69d485a`)**: интейк книг `POST /books` с сентинелом хранилища · стоп/резюм с намерением в Postgres · Prometheus · Go-floor 1.26.6; развилка `book.yaml`: бета = форма Б (стройка следующим касанием зоны), движковая форма = строка 170 · **эмиттер** — промт ВЫДАН (`docs/BACKEND_EMITTER_SESSION_PROMPT.md`, D39.128 — строки 103+135+165+PD-196, закрывает PD-113), запуск по слову владельца · эскроу (136) — следующим денежным промтом. +> - **Открыто на владельце:** Приложение А контракта (148: реконструкция с баннером или заново) · продуктовое слово «остановлена: лимиты» (В-3) · К-13/Ф-31 (paused_reason один — «свой потолок» и «нет кредита» неразличимы) · В-4/Ф-30 (глава без заголовка) · фри-тир PD-104 (ноль на бете против автогранта $5 с суточным потолком) · порог 116 · мини-проба флора 44 (одобрена, промт не выдан) · подпись денежного шага 46 · лист В-3+К-6 · авто-резюм paused (вопрос платформы) · запуск эмиттера / S4-промта фронта / следующего платформенного касания (стройка формы Б) · **СТОП ja-оси фазы Д** (гардрейл 18+ на `isekai_majutsushi_jp`, 3 чанка из 184: выбросить помеченное или сменить книгу) · **возражение Sol по проходу `tier` эксп-23** (пере-судить починенным ригом или оставить с записанным возражением — PROGRESS «Полигон») · поле `title` в `BookIntake` (сегодня заголовок = имя загруженного файла; поле в форме = правка спеки, кандидат 0.2.3 — вопрос P5) · фронт-вопросы зонного журнала: В-7 (плотность интерфейса; держит и Ф-54 — обрезку центра на зуме) · В-8 (слово состояния в дереве) · **В-9 (какие языки интерфейса обещает продукт — механизм готов, ПТ-36)** · Ф-38 (вкладка «Замечания») · граница ПТ-33 для добавочных полей `BankTerm` (черновик S3.5/S3.6, D39.127 п.2б). > - **Сделано (сводно)** — снимок ленты закрытых эр в [archive/PROGRESS-2026-08-04-09.md](archive/PROGRESS-2026-08-04-09.md); детали — D-лог и слайсы. > - **Курс:** ОБЩНОСТЬ ✅ → КАЧЕСТВО БАНКА ✅ → ПАКЕТ-ЧЕКЕРОВ ✅ (D39.59–78) → **ФРОНТ-ЭРА** (D39.81–100: зоны живые, контракт API ратифицирован) → **шов/платформа/движковые блокеры построены** (D39.106–123). Хвосты курса живут строками: 16 (edit-волна не гонялась НИ РАЗУ — держит и оси голоса 13б/24) · 46 (дизайн заморожен D39.92/93, промт ждёт выдачи) · coldrun-b фаза C заморожена чекпойнтом легитимно (D39.86; эталон денег/поведения — coldrun-a, read-only); развилка 0731 решена и исполнена (D39.87/91, код `553f1a3`). > - **Горизонт (D39.62/67, освежён D39.95):** **ДОБОР ИДЕАЛА** (первым прогоном: оси голоса 24 · авто-режим · цена 16; жильцы ролей решаются ДО прогона эксп-22 — строка 149 · веса K1–K12 13а · вне-претрейн чекпоинт 55; остаток арбитража банка = рецензент спорных кластеров при ре-пробе 74 — D39.102) → ВТОРАЯ ПАРА живьём (ja→ru; преп 81) → МАСШТАБ → пилот Ф2.5 (гейт резюме-строки 80; строки 62–68, 85) → Ф3 ридер-IDE (69–71). **Стоячие:** ToS-триггер 25.10 · Ш-2 до go1.27 (⚠ + x/text Unicode 17 тем же тулчейном — строка 119, реестр §Б-108 справочника якорей) · платные прогоны разблокированы (проба провода — D39.97, конфиги 112 залендены). > - **Стек (полная карта роль→модель→конфиг→квирки — [STACK.md](STACK.md), D39.126):** draft deepseek-v4-flash thinking-ON `low` **⚠0731** → терминолог (та же модель) → editor deepseek-v4-pro БИЛИНГВ ИНТЕРИМ (топология ПОДТВЕРЖДЕНА при неразличимости жильцов — D39.117; закон-блок ОБЯЗАТЕЛЕН — строка 134; glm-5 резерв; вахта маппинга эффорта pro — §Б-108) → судья gemini (Ф2, в движке НЕ построен — строка 33); канал B Mistral+grok; ~$0.85/ранобэ (D30.4, пере-калибровка при следующем платном прогоне). ⚠ **ВЕСЬ банковый контур (банкнота+терминолог+классификатор) в shipping-c1 НЕ включён** — жив ран-локальным конфигом книги (строка 140; сверка STACK.md 09.08 — факт шире прежней декларации «одна банкнота»); эскалация в shipping за `budget_usd: 0` (STACK.md §примечания). -> - **ЕДИНЫЙ БЭКЛОГ — секция «Бэклог» ниже** (одна таблица, единственный трекер; каждая петля обязана иметь диспозицию: решено / отложено-с-записью / отклонено; ведёт оркестратор). **СЧЁТ ОЧЕРЕДИ на 10.08 (скриптом по таблице — `python3 docs/scripts/counts.py`; обновлять при каждом лендинге):** всего **135** строк · зона бэкенд **69** строго / **92** широко (⚠ колонки счётчик читает С КОНЦА — испр. D39.116) · **блокеров очереди 0**, платные прогоны разблокированы · «скоро» **33** (перечень — грепом по таблице, рукописный список снят D39.126) · гейт-строки эксп-22: 55·153 (плюс 150 — руки владельца); строка 5 — остаток гейчен ре-пробой 74 (D39.102 п.2); остальное «когда-нибудь». ⚠ Счёт — НИЖНЯЯ граница долга, не потолок (разбор — легенда таблицы ниже). +> - **ЕДИНЫЙ БЭКЛОГ — секция «Бэклог» ниже** (одна таблица, единственный трекер; каждая петля обязана иметь диспозицию: решено / отложено-с-записью / отклонено; ведёт оркестратор). **СЧЁТ ОЧЕРЕДИ на 14.08 (скриптом по таблице — `python3 docs/scripts/counts.py`; обновлять при каждом лендинге):** всего **136** строк · зона бэкенд **70** строго / **93** широко (⚠ колонки счётчик читает С КОНЦА — испр. D39.116) · **блокеров очереди 0**, платные прогоны разблокированы · «скоро» **32** (перечень — грепом по таблице, рукописный список снят D39.126) · гейт-строки эксп-22: 55·153 (плюс 150 — руки владельца); строка 5 — остаток гейчен ре-пробой 74 (D39.102 п.2); остальное «когда-нибудь». ⚠ Счёт — НИЖНЯЯ граница долга, не потолок (разбор — легенда таблицы ниже). > - Архивы хроники: `archive/PROGRESS-2026-07-04-10.md` (D31) · `-10-13` (D39.6-гигиена) · `-13-25` (стройка паков 11–16, rerun2) · **`-25-31` (паки 17–20 · мини-прогон · полигон-пакеты 5–8 · ToS · холодный прогон; D39.26–58)** · **`-08-01-02` (сессии №9/№10: общность · качество банка · coldrun-b · открытие фронта/платформы; D39.59–90, срез D39.105)** · **`-08-02-04` (сессии №11–№13: ручки эффорта · стандарты · контракт API · платформа P0 · банк-арбитраж; D39.91–105 + снимок шапки эры №15)**. Записи ниже — живой хвост (№14+, эра D39.106+). ## Бэклог (ЕДИНЫЙ, собран 26.07, актуализация 04.08 D39.99/D39.101; правки — только через оркестратора) @@ -93,7 +93,7 @@ | 146 | **Два техдолга движка без строки трекера** (свип 08.08): `prices_checked` (120 д) гейтит read-only `report` и $0-resume — свежесть цен проверять только на ПЛАТНОМ пути (`03-implementation-notes:244`) · `cache_ttl` ↔ `cache_write_per_m`: цена записи в кэш задана под ОДИН TTL (5 м), при другом TTL расчёт врёт (`:246`). Оба жили только в справочнике якорей, то есть вне единственного трекера | бэкенд | когда-нибудь | малое касание | свип доков 08.08 | | 147 | **Транспортные частичные из research/21 без носителя** (свип 08.08): п.16 HTTP/1.1-escape на последней попытке как ДИАГНОСТИКА тихого усечения 2–8k [PARTIAL, GATED] · п.17 assistant-prefill continuation на `finish=length` вместо ре-рана всего вызова [PARTIAL, DEFER]. Оба помечены в ресёрче как отложенные и ни в одной строке трекера не появились | бэкенд/полигон | когда-нибудь | замер → решение | свип доков 08.08, research/21 §16–17 | | 148 | **Приложение А контракта потеряно инцидентом 08.08 и подлежит восстановлению** (D39.113): карта «вердикт движка → продуктовая фраза → ступень» была заполнена №14, откатилась к ЗАГОТОВКЕ с плейсхолдерами. Текст реконструкции держит оркестратор №15; решение владельца — брать реконструкцию черновиком С БАННЕРОМ «требует сверки» либо оставить заготовку и заполнять заново. Карта нужна фронту для замечаний (Ф-14) | владелец → оркестратор | скоро | решение владельца | D39.113, свип доков 08.08 | -| 149 | **Эксп-22 «панель жильцов»**: профиль-скрин (pass/fail пороги ДО замера; урок эксп-21 — скрин, убивший 2 из 12, скрином не был) → панель черновиков (слот несёт ~70% эффекта финала, мерился ТОЛЬКО flash за всю историю) → панель редакторов поверх замороженных черновиков (обязательный кандидат `gemini-3.1-pro` — аутлаер-гипотеза эксп-04) + шумовой пол + прямой `D_/A` довесками; агент-судейство под капом ≤60; невиданный zh-срез — повторный жёсткий заказ | полигон | скоро — ПРОМТ ВЫДАН (`docs/POLYGON_TENANT_PANEL_SESSION_PROMPT.md`), запуск = слово владельца | прогон по промту | **D39.117** | +| 149 | **Эксп-22 «панель жильцов»**: профиль-скрин (pass/fail пороги ДО замера; урок эксп-21 — скрин, убивший 2 из 12, скрином не был) → панель черновиков (слот несёт ~70% эффекта финала, мерился ТОЛЬКО flash за всю историю) → панель редакторов поверх замороженных черновиков (обязательный кандидат `gemini-3.1-pro` — аутлаер-гипотеза эксп-04) + шумовой пол + прямой `D_/A` довесками; агент-судейство под капом ≤60; невиданный zh-срез — повторный жёсткий заказ | полигон | **ИСПОЛНЕН и заленден 10.08** (приёмка №16; промт — `archive/prompts/POLYGON_TENANT_PANEL_SESSION_PROMPT_2026-08-08.md`); выводы заморожены до фазы Д — закрыть строку при ратификации | прогон по промту → ратификация | **D39.117**, приёмка №16 | | 150 | **Sol-арбитраж — внешний контур вместо слепого чтения владельца**: пере-суд расходящихся контрастов эксп-21 (`A/F`: luna +0.84 против gemini +3.03 — расхождение 14 sd шума судьи-замены) и слепых пар эксп-22 руками владельца через подписку (третье семейство, high reasoning); пакеты готовит эксп-22 Ф0.4 (слепые метки · оба порядка · декой), транскрипты персистятся как голоса внешнего судьи; luna-клетки Sol не судит (своё семейство) | владелец + полигон | скоро (пакет арбитража — из существующего сырья) | эксп-22 Ф0.4 + руки владельца | **D39.117** | | 151 | **Отказной режим связки**: эхо-мина черновика воспроизводима на материале (глава 11 — 3/3 попыток; частота 31% на zh), связка покрыла 9/10 подряд идущих глав против 10/10 у однопроходки — единственный довод ПРОТИВ связки во всём эксп-21; движку нужен fallback при невозможности годного черновика (вариация ре-гена · эскалация модели черновика · деградация в однопроходку) | владелец → бэкенд | когда-нибудь (до МАСШТАБА) | СТОП-решение | **D39.117**, exp21 §14 | | 152 | **Слипание абзацев — слепое пятно детерминированного контура**: батарея на тех же текстах даёт ДРУГОЙ порядок армов (`D` — худший по судье — лучший по правилам), расхождение локализовано в слипании, которого не проверяет ни одно правило; правило в батарею полигона + кандидат в гейты движка | бэкенд/полигон | когда-нибудь | малое касание + тест | **D39.117**, exp21 §13 | @@ -116,6 +116,7 @@ | 168 | **Состав волн пайплайна = пар-конфиг (данные), не общий хардкод**: вопрос владельца 10.08 «нормально ли под китайский строить весь бэкенд и конфиги?» — жильцы ролей и промпты уже конфиг/langpacks, но ТОПОЛОГИЯ волн (перепис · точечный edit-контур · без второго прохода) одна на всех пар; если фаза Д покажет разных победителей по парам (H-3/H-4: en-черновик+edit против zh-связки), состав волн уезжает в пар-конфиг данными; ревью-вопрос общности §0 `12-go-style-notes.md` | бэкенд | когда-нибудь (после данных фазы Д) | замер (фаза Д) → решение владельца → малое касание | слово владельца 10.08, промт фазы Д | | 169 | **Экспорт банка для чтения фронтом** — канала под `GET /books/{id}/bank` нет ВООБЩЕ: банк живёт в приватном SQLite движка, платформе читать его запрещено (D39.85), артефакта экспорта нет (строка 101 дала таблицу подписи, не банк); нужен движковый артефакт экспорта (машиночитаемый, по образцу стоп-таблицы `tm-bank-stop-v1`) + проекция платформы; без него витрина банка стоит на моке, а подписной экран S5 фронта строить не на чем | бэкенд → платформа | скоро (гейт S5 фронта) | отдельное решение → пак | Ф-43 фронта, компаньон контракта §3, **D39.127** | | 170 | **`tmctl init` — движок сам заводит книгу** (форма В развилки интейка): платформа зовёт $0-команду, движок пишет СВОЙ `book.yaml` — требования к полям живут там же, где проверяются (`config/book.go`); до неё бета живёт формой Б (рендер из деплой-шаблона платформой при создании книги, ратификация D39.130) | бэкенд | когда-нибудь (после беты формы Б) | малый пак | приёмка P5, **D39.130** | +| 171 | **Число символов книги — от движка** (PD-177 платформы: `character_count` интейка точен только для UTF-8; GB18030/UTF-16 движок декодирует сам — цифра платформы на них неверна, для UTF-16 занижена ~вдвое): счёт символов в манифест (рядом `source_bytes`/`encoding`) либо перерасчёт платформой после разбора | бэкенд | когда-нибудь | малое касание (манифест) | П-13 платформы, PD-177, приёмка P5 | | 49 | **Этапы Б+В спеки D15.2** (content-addressed resume / `guard_hash` — D39.31 сознательно не строил) ; этап В = tmctl export-контракт D29.1 (annot-v1 · цвет-мап+rollup · политика красных fail-closed) + операторский протокол-документ релиза гендер-твиста (D5.1): сам механизм УЖЕ построен — until_ch-правка → точечный re-edit со сметой и $0-пере-пином (`repin.go`/`rebill.go`, D39.42 п.5/D39.45) | бэкенд | скоро (ПОДТЯНУТА D39.81: annot-v1 = источник замечаний для фронта — критический путь подключения) | отдельное решение (annot-половина — по контракту 14, D39.99) | D39.34(4), D33 п.5, D39.81 | | 49а | **ALTER-шаги миграций v8–v14 не идемпотентны вопреки шапке `migrate.go:9-11`** (полу-применённая БД не сходится; счётчик версий скрывает) — находка критика полноты пака-19 | бэкенд | когда-нибудь | отдельное решение | D39.56, PACK19_BUILD §6.9 | | 50 | F3-остаток идемпотентности | бэкенд | когда-нибудь | отдельное решение | D39.34(4) | @@ -145,7 +146,7 @@ | 96 | **→ переехала в `platform/BACKLOG.md` П-1** (зонные бэклоги, D39.84: HTTP/SSE-слой, обвязка, аутентификация, порядок деплоя); здесь остаётся ратифицированным сам ИНВАРИАНТ D39.81 — движок = процесс-на-прогон (EXCLUSIVE flock `store.go:43`), сервер в backend НЕ пишется | платформа | — | зонный бэклог | D39.81, D39.84 | | 97 | **→ переехала в `platform/BACKLOG.md` П-2** (глобальный брокер рейт-лимитов; гейт «до второго параллельного пользователя» зафиксирован там же) | платформа | — | зонный бэклог | D39.81, D39.84 | | 102 | **Приём внешнего trace-контекста в tmctl**: TraceID минтится заново каждым вызовом (`main.go:67-70`; внутри вызова трасса цельная, `request_log.trace_id` есть) — прогон, запущенный платформой, должен быть одной трассой | бэкенд | когда-нибудь (Ф3, с 96) | малое касание | релей фронта 02.08, D39.84 | -| 103 | **NDJSON-эмиттер прогонных событий со стабильным словарём** (машинный канал живого статуса для платформы, `research/23` §2): NDJSON-логи уже есть (`LOG_FORMAT=json`, авто-оси trace/book/chapter/stage/role — `obs/logging.go:15-54`), но сообщения прозой, version-хендшейка нет, а **событие потолка отсутствует вовсе** (деньги только в тексте ошибки `stagerun.go:472-494`); нужен словарь-enum + version-хендшейк первой строкой (образец terraform -json: минор = ignore-unknown, мажор = reject) + событие потолка; все границы — единичные call-sites в pipeline рядом с готовыми slog; человеческие логи уже на stderr — stdout-дисциплина соблюдена. **Форма ратифицирована D39.106 (research/25 §эмиттер):** `events.jsonl` каталога книги = outbox-проекция коммитов SQLite (та же транзакция, что чекпойнт) · fsync/seq/hello-версия · события денег и потолка · развилка формата (JSONL против пофайловых/CRC-фрейминга) — решить дизайном · `status --json` отдельным каналом (ремонт, тот же flock) | бэкенд | скоро (промт бэкенду — по команде владельца, D39.107 п.3) | стройка по D39.106 + research/25 | research/23, D39.85, **D39.106** | +| 103 | **NDJSON-эмиттер прогонных событий со стабильным словарём** (машинный канал живого статуса для платформы, `research/23` §2): NDJSON-логи уже есть (`LOG_FORMAT=json`, авто-оси trace/book/chapter/stage/role — `obs/logging.go:15-54`), но сообщения прозой, version-хендшейка нет, а **событие потолка отсутствует вовсе** (деньги только в тексте ошибки `stagerun.go:489-513`); нужен словарь-enum + version-хендшейк первой строкой (образец terraform -json: минор = ignore-unknown, мажор = reject) + событие потолка; все границы — единичные call-sites в pipeline рядом с готовыми slog; человеческие логи уже на stderr — stdout-дисциплина соблюдена. **Форма ратифицирована D39.106 (research/25 §эмиттер):** `events.jsonl` каталога книги = outbox-проекция коммитов SQLite (та же транзакция, что чекпойнт) · fsync/seq/hello-версия · события денег и потолка · развилка формата (JSONL против пофайловых/CRC-фрейминга) — решить дизайном · `status --json` отдельным каналом (ремонт, тот же flock) | бэкенд | скоро — **ПРОМТ ВЫДАН** (`BACKEND_EMITTER_SESSION_PROMPT.md`, D39.128; мандат PD-196 дописан 14.08), запуск по слову владельца | стройка по D39.106 + research/25 | research/23, D39.85, **D39.106**, D39.128 | | 126 | **Потолок прогона УПРАВЛЯЕМЫЙ (владелец 07.08, D39.110); максимум шкалы = `Balance` КАК ЕСТЬ — поправка D39.115 п.2(а), «минус холды» = ошибка.** Форма: шкала в ГЛАВАХ (не доллары — D39.84 цел), ноль нельзя; потолок принадлежит ПРОГОНУ, приём аргументом построен (строка 145 закрыта D39.122: `--ceiling-usd`); фронт-форма — `run-options`/`CeilingBounds` (D39.115 п.4); пересчёт «главы→деньги» — платформа, ставка $0.03/глава (D39.123 п.2г; формула аргумента = committed + прирост, БЕЗ reserved — PD-158). Остаток строки: ручка на экране фронта (S4+). Археология дословно — `architecture/13-tech-debt-anchors.md` §Б-126 | платформа/фронт/бэкенд | скоро (форма решена, стройка — промтами) | дизайн-вход П-1 + правка спеки + строка 145 | ревью контракта 04.08, D39.99, **D39.110** | | 127 | **Устаревший DDL-коммент `glossary.source`** (`migrate.go:193`: «seed|ruby|auto», фактические пути записи — seed/ruby/mined, `auto` не пишет никто; фантом уже утёк во фронт-доки дважды) — поправить коммент | бэкенд | когда-нибудь (попутно любым паком store) | однострочная правка | ревью контракта 04.08, D39.99 | | 105 | **Роль `classifier` мис-вердиктится как эхо (`verdict=cjk_artifact` при `bad_lines=0`); ЛАТЕНТНО — `classify_types` выключен во всех шиппинг-конфигах.** Цена фикса, знать заранее: бамп `classifierVersion` → перекупка чекпойнтов классификатора (центы). Поля `rules=`/`VOICE` читать по знаменателям (13б). Разбор дословно — `architecture/13-tech-debt-anchors.md` §Б-105 | бэкенд | когда-нибудь (ближайшее касание банка/наблюдаемости; (б) — дешёвая часть, вердиктов не двигает) | малое касание + вердикт-двигающая половина (а) через СТОП-решение | D39.86 | diff --git a/docs/STACK.md b/docs/STACK.md index a0261526..d0d07f2b 100644 --- a/docs/STACK.md +++ b/docs/STACK.md @@ -4,7 +4,7 @@ | Роль | Модель (слаг) | thinking / effort | Носитель конфига | Статус | Квирки | |---|---|---|---|---|---| -| **draft** (translator) | `deepseek-v4-flash` | thinking ON, `reasoning:"low"` явно (D39.87/91 «вариант б») | `configs/pipeline-c1.yaml:36-60` | боевой ИНТЕРИМ (exp13; флип решает бейк-офф — эксп-22 ждёт лендинга) | quirks §0731 п.1 (дефолт-эффорт пробивает флор 8000), п.3а (не слать эффорт = ехать на `high`), п.4 (`low` пере-вооружает эхо), п.6 (эхо стохастично по вызову; ре-ген дешевле эскалации ×7.6). Thinking-OFF — НИКОГДА (эхо-мина, `echoMineViolation`) | +| **draft** (translator) | `deepseek-v4-flash` | thinking ON, `reasoning:"low"` явно (D39.87/91 «вариант б») | `configs/pipeline-c1.yaml:36-60` | боевой ИНТЕРИМ (exp13; бейк-офф эксп-22 заленден 10.08 — черновик менять не на что, но выводы заморожены до фазы Д, НЕ ратифицированы) | quirks §0731 п.1 (дефолт-эффорт пробивает флор 8000), п.3а (не слать эффорт = ехать на `high`), п.4 (`low` пере-вооружает эхо), п.6 (эхо стохастично по вызову; ре-ген дешевле эскалации ×7.6). Thinking-OFF — НИКОГДА (эхо-мина, `echoMineViolation`) | | **+ банкнота** (WHAT-канал драфта) | та же flash, промпт `translator-banknote.md` | как draft | ⚠ НЕ в shipping-c1 — ран-локальный конфиг книги: `~/books/gu-zhenren/coldrun-b/pipeline.yaml` (`gates.banknote` + `prompt_override`) | ⚠0731; включение в c1 = СТОП-решение владельца (строка 140: двигает RequestHash) | те же | | **терминолог** | `deepseek-v4-flash` | thinking ON, `gates.terminology.reasoning:"low"` (одна ручка на обе бэнк-роли) | ран-локальный `~/books/gu-zhenren/coldrun-b/reprobe/bank-low/pipeline.yaml:68-78`; схема — `internal/config/pipeline.go:298` (TerminologyGate); в shipping-c1 гейта НЕТ (opt-in OFF) | боевой по факту прогонов; носитель — конфиг книги | quirks §0731 п.3а: пустой `reasoning` = вендор-`high` → 4/5 `length` с пустым телом; экран `target_script: Cyrillic` обязателен при гейте ON | | **классификатор** (типы кандидатов) | flash (`classify_model` пуст ⇒ = model) | та же ручка | там же: `classify_types: true` + `classify_budget_usd` | проба/полигон; в shipping выключен ВЕЗДЕ | латентный мис-вердикт `cjk_artifact` — `13-tech-debt-anchors.md` §Б-105 | @@ -13,7 +13,7 @@ | **судья Ф2** | Gemini (нативный адаптер — Ф2, строка 33); в C2-скелете провизорно `glm-5` | Gemini: thinking mandatory | `models.yaml:95-108,240-255`; `pipeline-c2.yaml:33-44` (select; «DO NOT FLIP») | Ф2/полигон — в движке НЕ построен; C2 неисполняем | quirks: `thinking_budget:0` → HTTP 400; учёт `additive_total`; судья ЭРОТИКИ непригоден (PROHIBITED_CONTENT неконфигурируем, D22.6) → первичный судья 18+ = grok | | **канал B (18+)** | `mistral-large-2512` (переводчик-дефолт, D19.1) + `grok-4.3` (эскалация reasoning-ON + судья 18+) | mistral: не-reasoning; grok: OFF только явным `reasoning_effort:"none"` | `models.yaml:118-131,257-273` (accepts_labels, rate_limit) · `:63-87,221-238` · c1 `chains.adult:[grok-4.3]` | данные заведены; полный wiring — Ф2; `content_policy` пуст во всех shipping (сознательно) | quirks §Транспорт: mistral rate-limiter (~48% retry-fails → `max_concurrency:2`); grok: вложенная форма эффорта молча глотается; additive-биллинг (think-ON только за резервом D6.2) | | **эскалация (канал A)** | draft single-hop → `deepseek-v4-pro`; цепочка `[deepseek-v4-pro, glm-5.1, gemini-3.1-pro-preview]` | наследует политику мишени; апекс mandatory-thinking | `configs/pipeline-c1.yaml:118-135` | заведена, но ⚠ `budget_usd: 0` в shipping ⇒ НЕ исполняется (ран-локальные: 0.10 / 0.015) | слаг ИМЕННО `-preview` (без него 404); C2-цепочка `[kimi-k2.6]` = интерим-заглушка, НЕ контракт | -| **арбитр** | Sol (ChatGPT, внешний контур, руки владельца) · grok-агентские роли полигона | — | строка 150 бэклога + `eval/tenant_panel/sol.py`; кредиты xAI — лист владельца (PROGRESS строка 6) | полигон, ждёт владельца | Sol = LLM: «издательское качество» им не доказывается, человеческий контур — пилот Ф2.5 (D39.117 п.5б) | +| **арбитр** | Sol (ChatGPT, внешний контур, руки владельца) · grok-агентские роли полигона | — | строка 150 бэклога + `eval/tenant_panel/sol.py`; кредиты xAI — лист владельца (PROGRESS строка 6) | пакет (а) прогнан 09.08 — арбитраж НЕ состоялся (N=3 недомощен, шкала дрейфует ×2.6); пакет (б) заморожен до починки оснастки; возражение Sol по `tier` эксп-23 — на владельце | Sol = LLM: «издательское качество» им не доказывается, человеческий контур — пилот Ф2.5 (D39.117 п.5б) | ## Примечания - **⚠0731 (D39.61):** flash пере-обучен под тем же слагом; `/models` молчал. Развилка решена вариантом (б): явный `reasoning_effort:"low"` черновику + ручка эффорта бэнк-ролям (код `553f1a3`). Версию модели проверять ПОВЕДЕНИЕМ. diff --git a/docs/architecture/05-decisions-index.md b/docs/architecture/05-decisions-index.md index 8335024e..aaa1fd58 100644 --- a/docs/architecture/05-decisions-index.md +++ b/docs/architecture/05-decisions-index.md @@ -1,4 +1,4 @@ -# Реестр D-нот — карта актуальности v2 (D1–D39.126; строка 167) +# Реестр D-нот — карта актуальности v2 (D1–D39.130; строка 167) > Одна строка на КАЖДУЮ ноту журнала решений: № · дата · суть · статус · где тело · темы. Ведёт оркестратор при лендингах: новая нота = новая строка ТЕМ ЖЕ коммитом (полноту сторожит `docs/scripts/counts.py --check`). Суть и статус здесь — НАВИГАЦИЯ, не контракт: при конфликте побеждает ТЕЛО ноты (живой [`05-decisions-log.md`](05-decisions-log.md) → слайсы `../archive/architecture/05-decisions-*.md`). Несущие эрраты к фактам старых нот живут в шапке живого D-лога — их читать ОБЯЗАТЕЛЬНО, реестр их не дублирует. Темы (для грепа оси «какой закон по X»): деньги · шов · банк · промпт · судья · гейты · контракт · платформа · фронт · полигон · ToS · общность · процесс · нарезка · голос · инфра · модели. > Родословная: прозаическая карта D1–D39.28 (ревизии D31–D38.2) пересобрана в реестр докс-паком 167 (09.08.2026, №16): извлечение 6+6 агентов по worksheet `../archive/reports/DOC_AUDIT_INVENTORY_2026-08-09.md`, полнота сверена скриптом против заголовков всех шести файлов. «тело: жив» = живой D-лог; «слайс N» = `../archive/architecture/05-decisions-N.md`. @@ -167,11 +167,11 @@ | D39.112 | 07.08 | Верификация записей №15 независимым агентом: поправки к D39.109 (30 суток = SHOULD NIST, наш выбор строже; DoS входа ЕСТЬ — PD-80) и D39.110 (пересказ); восемь пробелов закрыты | частично: поправки к D39.109/110 несущие (продублированы в карте шапки); остальное — гигиена | жив | процесс | | D39.113 | 08.08 | Инцидент: агент панели откатил незакоммиченные правки двух параллельных сессий (git reset/checkout в реальном дереве); один файл восстановлен, шесть потеряны; норма изоляции панелей ужесточена | ЖИВОЕ: норма изоляции панелей (промт + deny); таблицу потерь читать через D39.117 п.7; Приложение А — строка 148 | жив | процесс инфра | | D39.114 | 08.08 | Фикс-пак платформы P3 принят и заленден: PD-79/80/83/84/85/91/95/100/106 закрыты, 8/8 посадок поймано, PD-80 и PD-91 пере-проверены исполнением; PD-104 оставлен открытым правильно | закрыт (нарратив приёмки) | жив | платформа | -| D39.115 | 08.08 | S3 «слой данных» принят: контракт 0.2.0 в каноне; потолок = run-options/CeilingBounds отдельным ресурсом; правило версий 0.x; три ошибки оркестратора поймала сессия (баланс-минус-холды) | ЖИВОЕ: CeilingBounds · правило версий 0.x · чтение чужой зоны для сверки — можно; контракт далее 0.2.1 (D39.123) | жив | фронт контракт деньги | +| D39.115 | 08.08 | S3 «слой данных» принят: контракт 0.2.0 в каноне; потолок = run-options/CeilingBounds отдельным ресурсом; правило версий 0.x; три ошибки оркестратора поймала сессия (баланс-минус-холды) | ЖИВОЕ: CeilingBounds · правило версий 0.x · чтение чужой зоны для сверки — можно; контракт далее 0.2.1 (D39.123) → 0.2.2 (D39.129) | жив | фронт контракт деньги | | D39.116 | 08.08 | Актуализация доков: 78 находок свипа по 107 живым докам; отработанные промты S3/P0 в архив с баннером-исходом; ошибка счёта counts.py исправлена; строки 146–148 заведены | закрыт (исполнен); строки 146–148 заведены | жив | процесс | | D39.117 | 08.08 | Эксп-21 принят: строка 65 закрыта (dspro/glm неразличимы — жилец = цена/конфиг), починка = пре-гейт перед редактором; опровергнут вывод D39.108; курс — эксп-22 «панель жильцов» + Sol-арбитраж | ЖИВОЕ: диспозиции 142/65/106/55; правило ничьей эксп-22 ратифицировано; строки 149–153 заведены | жив | полигон судья модели | | D39.118 | 08.08 | Фикс-пак банка (128+129+130-минимум) принят: семьи термов со-батчатся юнитами, bankdata-плоскость с BankDataVersion, сдвиг edit-волны bank-only, инверсия ранжирования семей; строки 154–159 | закрыт (нарратив приёмки); живое = ратификации (bankdata-плоскость · сдвиг edit-волны · лог эвиктнутых без миграции); 128/129 закрыты | жив | банк | -| D39.119 | 08.08 | Курс 08.08: эмиттер отложен; выданы два промта (бэкенд «блокеры контракта» · платформа «раннер»); S4 гейчен списком владельца (VS Code-вкладки); PD-105: дубль seq = норма, декодер идемпотентен | ЖИВОЕ: промты исполнены D39.122/D39.123; гейт S4 в силе до списка владельца | жив | процесс платформа фронт | +| D39.119 | 08.08 | Курс 08.08: эмиттер отложен; выданы два промта (бэкенд «блокеры контракта» · платформа «раннер»); S4 гейчен списком владельца (VS Code-вкладки); PD-105: дубль seq = норма, декодер идемпотентен | ЖИВОЕ: промты исполнены D39.122/D39.123; список владельца исполнен S3.5 (D39.127), гейт S4 ПАЛ D39.130 | жив | процесс платформа фронт | | D39.120 | 08.08 | Кросс-модельные контуры ревью: опровергатель другой моделью в панелях, независимый ревьюер тяжёлых ратификаций, предметные оси самопроверки в кодовых промтах; направление, не буква | ЖИВОЕ: норма-направление (носитель — промт оркестратора) | жив | процесс | | D39.121 | 09.08 | Записка-план после тяжёлого ревью (ID→статус→улика, движение по записке) + официальные практики Anthropic абсорбированы направлением; research/26 — дайджест 86 рекомендаций | ЖИВОЕ: норма-направление; носители — промт оркестратора + CLAUDE.md (компакция, запрет подгонки тестов) | жив | процесс | | D39.122 | 09.08 | Пак «блокеры контракта» принят: строки 99·100·101·125·145 закрыты; unit.id с тегом разреза, манифест tm-manifest-v2, --ceiling-usd = книжный потолок; research/27 принят фактурой (строки 160–162) | ЖИВОЕ: формы артефактов для потребителей; формула аргумента потолка поправлена D39.123 (PD-158); дизайн глав НЕ ратифицирован | жив | контракт нарезка деньги | @@ -179,7 +179,7 @@ | D39.124 | 09.08 | Закрытие сессии №15, передача №16: семь приёмок эры закрыты (D39.109–123); докс-диета — хроники в архив-слайсы, зонный журнал платформы 1856→630 строк, CURRENT-STATE пересобран | закрыт (исполнен); очередь №16 дополнена D39.125 п.4 (докс-пак 167 первой задачей) | жив | процесс | | D39.125 | 09.08 | Докс-диета по аудиту: D-лог слайсирован в 5 архив-слайсов (961→323 КБ), PROGRESS −42%, факты-против-кода исправлены (эррата D39.111); нормы формы доков; остаток аудита = строка 167 | ЖИВОЕ: правило чтения D-лога (карта+эрраты+живые тела+голова D39.106+, греп живой файл → слайсы) + нормы формы | жив | процесс | | D39.126 | 09.08 | Докс-пак 167 исполнен: реестр всех нот (этот файл) · counts --check полнота реестра + --lint якорей · разгрузка топ-10 строк бэклога · топикальные входы 15-money-path/16-events-emitter/STACK · К-статусы компаньона сведены | ЖИВОЕ | жив | процесс | -| D39.127 | 10.08 | Приёмка фронта S3.6 принята и залендена (57e6bd1): гейты пере-прогнаны исполнением, 12 находок ревью → промт S3.7; Ф-47 ратифицирован (sense обязателен, спека 0.2.2); строка 169 — экспорт банка | ЖИВОЕ: S3.7 выдан (запуск по слову владельца), S4 после его приёмки; канон sense — диффом при лендинге S3.7 | жив | фронт контракт | -| D39.128 | 10.08 | Полное пере-чтение корпуса по заказу владельца; выданы промты: бэкенд-эмиттер (103+135+165, PD-113) и платформа P5 (П-9/PD-72 + PD-140 + П-11/PD-114) | ЖИВОЕ: запуск обоих по слову владельца; развилка book.yaml при интейке гейчена ратификацией | жив | шов деньги платформа процесс | -| D39.129 | 10.08 | Приёмка фронта S3.7 принята и залендена (3e465bd): канон контракта 0.2.2, i18n-механизм построен (ПТ-36 🔶); арбитраж 8.1 — HIGH приёмки S3.6 снята как ложноположительная, урок «браузерный вердикт только живым прогоном» | ЖИВОЕ: находки приёмки → блок S4-промта; S4 после приёмки P5; В-9 (языки интерфейса) на владельце | жив | фронт контракт процесс | +| D39.127 | 10.08 | Приёмка фронта S3.6 принята и залендена (57e6bd1): гейты пере-прогнаны исполнением, 12 находок ревью → промт S3.7; Ф-47 ратифицирован (sense обязателен, спека 0.2.2); строка 169 — экспорт банка | ЖИВОЕ: S3.7 исполнен и принят (D39.129), канон sense внесён (0.2.2); S4 — промт по слову владельца (гейт пал D39.130) | жив | фронт контракт | +| D39.128 | 10.08 | Полное пере-чтение корпуса по заказу владельца; выданы промты: бэкенд-эмиттер (103+135+165, PD-113) и платформа P5 (П-9/PD-72 + PD-140 + П-11/PD-114) | ЖИВОЕ: P5 исполнен и принят (D39.130), развилка book.yaml решена там же (форма Б); эмиттер — промт жив (PD-196 дописан 14.08), запуск по слову владельца | жив | шов деньги платформа процесс | +| D39.129 | 10.08 | Приёмка фронта S3.7 принята и залендена (3e465bd): канон контракта 0.2.2, i18n-механизм построен (ПТ-36 🔶); арбитраж 8.1 — HIGH приёмки S3.6 снята как ложноположительная, урок «браузерный вердикт только живым прогоном» | ЖИВОЕ: находки приёмки → блок S4-промта; гейт S4 пал D39.130 (промт по слову владельца); В-9 (языки интерфейса) на владельце | жив | фронт контракт процесс | | D39.130 | 14.08 | Приёмка платформы P5 в три раунда (69d485a): интейк книг с сентинелом хранилища, стоп/резюм с намерением, Prometheus; ратификации Go-floor 1.26.6 + book.yaml формой Б; строка 170, дописка 165 (PD-196) | ЖИВОЕ: гейт S4 фронта пал — S4-промт по слову владельца (вход: POST /books + находки S3.7 + спека 0.2.3); стройка формы Б — следующим касанием зоны | жив | платформа деньги контракт шов | diff --git a/docs/architecture/05-decisions-log.md b/docs/architecture/05-decisions-log.md index c0bbe48e..9a017728 100644 --- a/docs/architecture/05-decisions-log.md +++ b/docs/architecture/05-decisions-log.md @@ -18,7 +18,7 @@ > (его HEAD — финальная версия); чьи модификации были в дереве — достоверно неизвестно. > ⚠ **Навигация (актуализация 04.08):** два supersede-указателя эры D39.9x: **D39.88/D39.84 п.8 (право самокоммита фронта/платформы) → отозвано, коммитит ТОЛЬКО оркестратор** (D39.98 п.3; тела переписаны на месте с санкцией владельца, pre-rewrite — git `2b166b7`) · **норма 30.07 «короткая приёмка» → амендирована владельцем 03.08: приёмка всегда адверсариальная** (носитель — промт оркестратора §Анти-паттерны + D39.101 п.1) — упоминания «короткой приёмки» в телах читать через эту пометку · **двухсекционная редакторская инъекция и смягчающая роль маркера ⟨проверить⟩ → доктрина инжекта D39.104**: банк на проводе = ЗАКОН для всех ролей независимо от статуса строки, право «перевести иначе» упразднено, блок редактора — ЕДИНЫЙ, маркер с провода снимается (статусы строк и подписная таблица не меняются; внесение в движок — строка 134 после пробы 18) — упоминания двухсекционки/смягчения в телах читать через это. -> ⚠ **РЕЕСТР ВСЕХ НОТ (карта актуальности v2) — [`05-decisions-index.md`](05-decisions-index.md):** одна строка на ноту (№ · дата · суть · статус жив/частично/superseded→кем · где тело), покрытие D1–D39.125 целиком; полноту сторожит `docs/scripts/counts.py --check`. Прозаические списки прежних ревизий («полностью superseded» · «частично амендировано» · «живое ядро» — покрывали только D1–D39.28) пересобраны туда ПОСТРОЧНО докс-паком 167 (09.08, оркестратор №16); тела нот не тронуты — они дословно здесь и в слайсах. Новые ноты аппендятся В ХВОСТ живого файла (**свежая голова — С ХВОСТА**); сводка головы и очередь — CURRENT-STATE в `../PROGRESS.md`. +> ⚠ **РЕЕСТР ВСЕХ НОТ (карта актуальности v2) — [`05-decisions-index.md`](05-decisions-index.md):** одна строка на ноту (№ · дата · суть · статус жив/частично/superseded→кем · где тело), покрытие ВСЕХ нот целиком (голова — по титулу реестра); полноту сторожит `docs/scripts/counts.py --check`. Прозаические списки прежних ревизий («полностью superseded» · «частично амендировано» · «живое ядро» — покрывали только D1–D39.28) пересобраны туда ПОСТРОЧНО докс-паком 167 (09.08, оркестратор №16); тела нот не тронуты — они дословно здесь и в слайсах. Новые ноты аппендятся В ХВОСТ живого файла (**свежая голова — С ХВОСТА**); сводка головы и очередь — CURRENT-STATE в `../PROGRESS.md`. > ⚠ **Форма эрраты впредь — ОДНА: навигационная пометка в этой шапке** (D39.125 п.3; правка тел задним числом — против D23.3). Прижизненные правки-на-месте остаются с маркерами по месту и новыми не множатся: D39.110 п.2(в) («⚠ ИСПРАВЛЕНО 08.08» → D39.115) · D39.112 п.2(а) (поправка к поправке тем же днём) · D39.98 п.3 (тела D39.84 п.8/D39.88 переписаны с санкцией владельца, pre-rewrite `2b166b7`). diff --git a/docs/architecture/09-target-architecture.md b/docs/architecture/09-target-architecture.md index 5a273092..b435d95e 100644 --- a/docs/architecture/09-target-architecture.md +++ b/docs/architecture/09-target-architecture.md @@ -7,7 +7,7 @@ > > Это карта «куда и почему», а не пошаговая спека. Спеки — в хендофф-промтах сессий; контракт — в D-логе. -> **⟶ СТАТУС СТРОЙКИ (освежён 09.08 оркестратором №16, пост-D39.125: шов движок↔платформа ратифицирован — транзиентный systemd-юнит на прогон + `events.jsonl`-outbox в каталоге книги, платформа НЕ родитель (D39.106); платформа достроена до раннера P4 (D39.109/114/123 — River-очередь, холд-до-спавна, реконсилятор; дефекты — `platform/docs/DEFECT_REGISTER.md`); фронт — слой данных S3, контракт 0.2.0→0.2.1 (D39.115/123); движок отдал блокеры контракта — `tm-manifest-v2`, `unit.id` с тегом разреза, пофазные счётчики на главу, `--ceiling-usd` (D39.122); слой 4 добит фикс-паком банка — семьи термов со-батчатся юнитами, bankdata-плоскость (D39.118). Ранее 04.08, пост-D39.105: слои 4/5 добраны паками банка/чекеров D39.69/78/82; репо на стандартах — `make battery`, tmvet/archguard, D39.96/97; контракт API v0 = `14-api-contract/` (D39.99), платформа = зона `platform/`, открыта D39.100. Баннер — не переписывание, тело ниже = замысел арх-ресета 13.07).** Карта «слой → статус → пак/D»: +> **⟶ СТАТУС СТРОЙКИ (освежён 14.08 оркестратором №16: платформа достроена до интейка книг P5 — `POST /books` с сентинелом хранилища, стоп/резюм с намерением, Prometheus, Go-floor 1.26.6 (D39.130); фронт — S3.5–S3.7 приняты (оболочка · слой данных · i18n), контракт **0.2.2** (D39.127/129); **гейт S4 фронта ПАЛ** — S4-промт по слову владельца; эмиттер шва — промт выдан (D39.128), сессия не запускалась. Ранее 09.08, пост-D39.125: шов движок↔платформа ратифицирован — транзиентный systemd-юнит на прогон + `events.jsonl`-outbox в каталоге книги, платформа НЕ родитель (D39.106); платформа достроена до раннера P4 (D39.109/114/123 — River-очередь, холд-до-спавна, реконсилятор; дефекты — `platform/docs/DEFECT_REGISTER.md`); фронт — слой данных S3, контракт 0.2.0→0.2.1 (D39.115/123); движок отдал блокеры контракта — `tm-manifest-v2`, `unit.id` с тегом разреза, пофазные счётчики на главу, `--ceiling-usd` (D39.122); слой 4 добит фикс-паком банка — семьи термов со-батчатся юнитами, bankdata-плоскость (D39.118). Ранее 04.08, пост-D39.105: слои 4/5 добраны паками банка/чекеров D39.69/78/82; репо на стандартах — `make battery`, tmvet/archguard, D39.96/97; контракт API v0 = `14-api-contract/` (D39.99), платформа = зона `platform/`, открыта D39.100. Баннер — не переписывание, тело ниже = замысел арх-ресета 13.07).** Карта «слой → статус → пак/D»: > | Слой | Статус | Пак / D | > |---|---|---| > | 1 Сегментация | ✅ ПОСТРОЕН: бюджет в выходных токенах снапшот-folded (`chunk.SegBudget`), edit-единицы декаплены; когезия/carryover — НЕ строится (D39.7/8: эффекты под floor 0.126; кнобы `STMDepth`/`OverlapTokens` УДАЛЕНЫ, WS2 §2а), граница `logical` — не рычаг (exp15), greedy остался | пак-11 (D39.13 WS2 · D39.17 волны · D39.18 c-lite) | diff --git a/docs/architecture/15-money-path.md b/docs/architecture/15-money-path.md index 52279ba0..c26120c1 100644 --- a/docs/architecture/15-money-path.md +++ b/docs/architecture/15-money-path.md @@ -4,7 +4,7 @@ ## 1. Канон одним абзацем -Деньги видимы с первого вызова: телеметрия, потолки, явное согласие на пере-оплату (CLAUDE.md, цель 5). Леджер без потолка запрещён — Р7: книга обязана нести хотя бы один из `book_usd`/`day_usd` (`backend/internal/config/book.go:250-251`, текст валидатора: «a ledger with no ceiling is forbidden, Р7»). Суммы на пользовательский экран НЕ выходят — запрет D39.84, подтверждён D39.100/К-8 («страница лимитов = СТАТУС, не суммы», D-лог `:201`) и держится в контракте (`14-api-contract/openapi.yaml:1152`: «No window, no `resets_at`, no sums»). Защита от перерасхода двойная и не зависит от событий: холд платформы делает кредит недоступным следующему прогону, а движок сам останавливается на потолке — «an overspend is impossible even while the platform is blind. The event stream is freshness only» (док-коммент `Hold`, `platform/internal/pgstore/credits.go:148-151`). +Деньги видимы с первого вызова: телеметрия, потолки, явное согласие на пере-оплату (CLAUDE.md, цель 5). Леджер без потолка запрещён — Р7: книга обязана нести хотя бы один из `book_usd`/`day_usd` (`backend/internal/config/book.go:250-251`, текст валидатора: «a ledger with no ceiling is forbidden, Р7»). Суммы на пользовательский экран НЕ выходят — запрет D39.84, подтверждён D39.100/К-8 («страница лимитов = СТАТУС, не суммы», D-лог `:196`) и держится в контракте (`14-api-contract/openapi.yaml:1152`: «No window, no `resets_at`, no sums»). Защита от перерасхода двойная и не зависит от событий: холд платформы делает кредит недоступным следующему прогону, а движок сам останавливается на потолке — «an overspend is impossible even while the platform is blind. The event stream is freshness only» (док-коммент `Hold`, `platform/internal/pgstore/credits.go:148-151`). ## 2. Деньги ДВИЖКА (зона `backend/`) diff --git a/docs/architecture/16-events-emitter.md b/docs/architecture/16-events-emitter.md index bcdb2843..033fb19d 100644 --- a/docs/architecture/16-events-emitter.md +++ b/docs/architecture/16-events-emitter.md @@ -6,19 +6,19 @@ ## 1. Что строим и зачем -**Что.** Строка 103 бэклога (`docs/PROGRESS.md:145`), дословно ядро ячейки: +**Что.** Строка 103 бэклога (`docs/PROGRESS.md:149`), дословно ядро ячейки: > «**NDJSON-эмиттер прогонных событий со стабильным словарём** (машинный канал живого статуса для платформы, `research/23` §2): NDJSON-логи уже есть (`LOG_FORMAT=json`, авто-оси trace/book/chapter/stage/role — `obs/logging.go:15-54`), но сообщения прозой, version-хендшейка нет, а **событие потолка отсутствует вовсе** (деньги только в тексте ошибки `stagerun.go:472-494`); нужен словарь-enum + version-хендшейк первой строкой (образец terraform -json: минор = ignore-unknown, мажор = reject) + событие потолка; все границы — единичные call-sites в pipeline рядом с готовыми slog; человеческие логи уже на stderr — stdout-дисциплина соблюдена. **Форма ратифицирована D39.106 (research/25 §эмиттер):** `events.jsonl` каталога книги = outbox-проекция коммитов SQLite (та же транзакция, что чекпойнт) · fsync/seq/hello-версия · события денег и потолка · развилка формата (JSONL против пофайловых/CRC-фрейминга) — решить дизайном · `status --json` отдельным каналом (ремонт, тот же flock)». -**Зачем (две ноги).** (а) *Свежесть статуса*: по слову владельца 08.08 «эмиттер нужен СВЕЖЕСТИ статуса и деньгам шва, не первым экранам — резерв на это время = периодический `status --json`-резюнк (построен в P1)» (D39.119 п.1, `05-decisions-log.md:395`). (б) *Деньги шва*: пока события нет, «экран покажет „ошибка“ там, где верно „остановлено: лимиты“» (PD-113, `DEFECT_REGISTER.md:124`), причём после PD-158 «PD-113 остаётся ЕДИНСТВЕННЫМ открытым major до эмиттера; … консервативный потолок останавливает ровно на исчерпании холда, и „деньги кончились“ неотличимо от „инфраструктура упала“» (D39.123 п.2(ж), `05-decisions-log.md:433`). +**Зачем (две ноги).** (а) *Свежесть статуса*: по слову владельца 08.08 «эмиттер нужен СВЕЖЕСТИ статуса и деньгам шва, не первым экранам — резерв на это время = периодический `status --json`-резюнк (построен в P1)» (D39.119 п.1, `05-decisions-log.md:390`). (б) *Деньги шва*: пока события нет, «экран покажет „ошибка“ там, где верно „остановлено: лимиты“» (PD-113, `DEFECT_REGISTER.md:18`), причём после PD-158 «PD-113 остаётся ЕДИНСТВЕННЫМ открытым major до эмиттера; … консервативный потолок останавливает ровно на исчерпании холда, и „деньги кончились“ неотличимо от „инфраструктура упала“» (D39.123 п.2(ж), `05-decisions-log.md:428`). -**Что уже есть со стороны движка.** NDJSON-инфраструктура логов: `obs.NewLogger` пишет slog в **stderr**, `LOG_FORMAT=json` даёт JSONHandler, UTC-время (`backend/internal/obs/logging.go:15-31`); оси trace_id/book/chapter/chunk/stage/role навешиваются из контекста автоматически (`logging.go:41-54`). Деньги при стопе по потолку существуют только в тексте ошибки: `" (committed=$%.6f reserved=$%.6f, denied estimate=$%.6f, ch%d/chunk%d/%s)"` и `"pipeline: book USD ceiling reached ($%g)%s — %s or stop: %w"` / `"pipeline: daily USD ceiling reached ($%g)%s: %w"` с сентинелом `errReserveCeiling` (`backend/internal/pipeline/stagerun.go:501-513`, сентинел — `escalation.go:49`). Trace id чеканится на каждый вызов в `cmd/tmctl/main.go:67-70` — это сегодняшний кандидат в `engine_run_id` (так и записано платформой, `platform/internal/ingest/events.go:75`). +**Что уже есть со стороны движка.** NDJSON-инфраструктура логов: `obs.NewLogger` пишет slog в **stderr**, `LOG_FORMAT=json` даёт JSONHandler, UTC-время (`backend/internal/obs/logging.go:15-31`); оси trace_id/book/chapter/chunk/stage/role навешиваются из контекста автоматически (`logging.go:41-54`). Деньги при стопе по потолку существуют только в тексте ошибки: `" (committed=$%.6f reserved=$%.6f, denied estimate=$%.6f, ch%d/chunk%d/%s)"` и `"pipeline: book USD ceiling reached ($%g)%s — %s or stop: %w"` / `"pipeline: daily USD ceiling reached ($%g)%s: %w"` с сентинелом `errReserveCeiling` (`backend/internal/pipeline/stagerun.go:489-513`, сентинел — `escalation.go:49`). Trace id чеканится на каждый вызов в `cmd/tmctl/main.go:67-70` — это сегодняшний кандидат в `engine_run_id` (так и записано платформой, `platform/internal/ingest/events.go:75`). -**Что эмиттер НЕ решает** (не тащить в пак): реконсилятор и свип — построены платформой, строки 138·139 закрыты (D39.123 п.3, `05-decisions-log.md:435`) · write-ahead intent / `uncertain`-эскроу / `closing` — отдельная строка 136 (`docs/PROGRESS.md:85`) · пиннинг версии бинаря на прогон — «исполняется и резюмом — PD-143/134 закрыты» (D39.123 п.3) · движковая оценка $/глава — строка 166 (`docs/PROGRESS.md:114`) · тейлер/декодер платформы — уже построены (пакет `platform/internal/ingest/`), эмиттер пишет ПОД их контракт. +**Что эмиттер НЕ решает** (не тащить в пак): реконсилятор и свип — построены платформой, строки 138·139 закрыты (D39.123 п.3, `05-decisions-log.md:430`) · write-ahead intent / `uncertain`-эскроу / `closing` — отдельная строка 136 (`docs/PROGRESS.md:85`) · пиннинг версии бинаря на прогон — «исполняется и резюмом — PD-143/134 закрыты» (D39.123 п.3) · движковая оценка $/глава — строка 166 (`docs/PROGRESS.md:114`) · тейлер/декодер платформы — уже построены (пакет `platform/internal/ingest/`), эмиттер пишет ПОД их контракт. ## 2. Ратифицированная форма (D39.106 · research/25) -Канон — D39.106 п.2 (`05-decisions-log.md:233`), дословно: +Канон — D39.106 п.2 (`05-decisions-log.md:228`), дословно: > «**2. Форма (заменяет ТРАНСПОРТ D39.85 §1; остальное D39.85 в силе):** движок = транзиентный systemd-юнит на прогон (`Restart=no`, SIGTERM); события = `events.jsonl` каталога книги как проекция коммитов SQLite движка (outbox, та же транзакция, что чекпойнт); платформа тейлит, курсор `(engine_run_id, seq)` коммитится с эффектом в одной Postgres-транзакции; `status --json` — ремонт по остановленному прогону. Формат NDJSON/hello/seq, деньги (холд+потолок = защита, события = свежесть, D39.84/D39.100) и запрет на живой SQLite — без изменений.» @@ -31,19 +31,19 @@ - **Сброс буфера на всех путях выхода**: «сброс буфера на всех путях выхода (`os.Exit` пропускает defer — теряются финальные события)» (`25:82`); то же PD-61(а) — см. §4. - **Живость**: «живость = растущий `seq`, не удерживаемый лок; политика обратного давления выбирается явно» (`25:83`). -**Отвергнутые альтернативы** (`25:33-44`; повторены в доккомменте зоны, «so that none of them comes back as a fresh idea» — `events.go:21-23`): платформа-родитель + пайп stdout/fd — **0 из 15** («время жизни движка — подмножество платформы: деплой/рестарт убивает или осиротляет прогон», `25:38`) · выделенный fd 3 — **0** (`25:43`) · stdout/journald как источник событий — **0** («journald молча роняет под всплеском и ротирует сам; людям — да, контракту — нет», `25:44`) · gRPC/HTTP поверх движка — 0 (`25:39`) · push в платформу — 2→0 (`25:40`) · брокер — 0 (`25:41`) · монолит — 0 из ~18 (`25:37`). Пайп-путь `supervisor.go` — ДЕВ-режим и только (D39.106 п.3 `05-decisions-log.md:235`; `events.go:23`). +**Отвергнутые альтернативы** (`25:33-44`; повторены в доккомменте зоны, «so that none of them comes back as a fresh idea» — `events.go:21-23`): платформа-родитель + пайп stdout/fd — **0 из 15** («время жизни движка — подмножество платформы: деплой/рестарт убивает или осиротляет прогон», `25:38`) · выделенный fd 3 — **0** (`25:43`) · stdout/journald как источник событий — **0** («journald молча роняет под всплеском и ротирует сам; людям — да, контракту — нет», `25:44`) · gRPC/HTTP поверх движка — 0 (`25:39`) · push в платформу — 2→0 (`25:40`) · брокер — 0 (`25:41`) · монолит — 0 из ~18 (`25:37`). Пайп-путь `supervisor.go` — ДЕВ-режим и только (D39.106 п.3 `05-decisions-log.md:230`; `events.go:23`). -**Словарь событий — ПРЕДЛОЖЕНИЕ платформы, записанное кодом**: «The vocabulary below is therefore the platform's PROPOSAL, written as code so the engine zone can answer it with a diff» (`events.go:5-6`). Состав (`events.go:37-147`): `StreamVersion = "1.0"` · типы `hello` / `progress` / `unit_done` / `bank_stop` / `ceiling` / `spend` / `finished` · конверт `{seq, type, time, data}` · `Hello{stream_version, engine_run_id, book_id, chunker_version}` · `Progress` — пофазные счётчики draft/edit + `eta_seconds` (семантика `done` = «разрешено волной», ok/flagged/skipped — D39.122 п.2(б), `05-decisions-log.md:421`) · `UnitDone{chapter, unit, wave, shipped, flagged, reason}` · `BankStop{terms_proposed}` (полная таблица — артефактом, не потоком: `events.go:117-118`) · `Ceiling{halted}` · `Spend{committed_micro_usd}` · `Finished{outcome: clean|flagged|bank_stop|failed}`. +**Словарь событий — ПРЕДЛОЖЕНИЕ платформы, записанное кодом**: «The vocabulary below is therefore the platform's PROPOSAL, written as code so the engine zone can answer it with a diff» (`events.go:5-6`). Состав (`events.go:37-147`): `StreamVersion = "1.0"` · типы `hello` / `progress` / `unit_done` / `bank_stop` / `ceiling` / `spend` / `finished` · конверт `{seq, type, time, data}` · `Hello{stream_version, engine_run_id, book_id, chunker_version}` · `Progress` — пофазные счётчики draft/edit + `eta_seconds` (семантика `done` = «разрешено волной», ok/flagged/skipped — D39.122 п.2(б), `05-decisions-log.md:416`) · `UnitDone{chapter, unit, wave, shipped, flagged, reason}` · `BankStop{terms_proposed}` (полная таблица — артефактом, не потоком: `events.go:117-118`) · `Ceiling{halted}` · `Spend{committed_micro_usd}` · `Finished{outcome: clean|flagged|bank_stop|failed}`. ## 3. Контракт декодера и дублей (PD-105 · D39.123 п.2(в)) -Ратификация — D39.119 п.3 (`05-decisions-log.md:399`), дословно: +Ратификация — D39.119 п.3 (`05-decisions-log.md:394`), дословно: > «доставка событий шва = at-least-once; ДУБЛЬ `seq` — норма повторного чтения, декодер обязан принимать идемпотентно без фатала; тот же `seq` с ДРУГИМ payload = карантин прогона (research/25)». -⚠ **Расхождение, разрешённое позже**: «карантин прогона» (D39.119 п.3 и `research/25:77-78` «тот же seq с другим payload = карантин прогона, не тихий no-op») уточнён D39.123 п.2(в) (`05-decisions-log.md:433`): «**PD-105-реализация: карантин ПРОЕКЦИИ (попытки), не прогона** — уточнение D39.119; деньги прогона сеттлятся ремонт-каналом». Побеждает D39.123 как более свежая нота. +⚠ **Расхождение, разрешённое позже**: «карантин прогона» (D39.119 п.3 и `research/25:77-78` «тот же seq с другим payload = карантин прогона, не тихий no-op») уточнён D39.123 п.2(в) (`05-decisions-log.md:428`): «**PD-105-реализация: карантин ПРОЕКЦИИ (попытки), не прогона** — уточнение D39.119; деньги прогона сеттлятся ремонт-каналом». Побеждает D39.123 как более свежая нота. -Фактическое поведение читателя (текущий текст PD-105, `platform/docs/DEFECT_REGISTER.md:116` — закрыт ратификацией и реализацией): +Фактическое поведение читателя (текущий текст PD-105, `platform/docs/DEFECT_REGISTER.md:192` — закрыт ратификацией и реализацией): > «Транспорт — тейл `events.jsonl` с курсором, поэтому повторное чтение строк НОРМА: `ingest.Tail` пропускает `seq <= last_seq` идемпотентно и не возвращает ошибку, а `pgstore.RunSink.Apply` пере-проверяет тот же high-water mark ВНУТРИ транзакции эффекта. Тот же `seq` с ДРУГИМ payload = `ErrPayloadConflict` → карантин ПОПЫТКИ, то есть её проекции: материализация останавливается, а жизненный цикл прогона продолжается — движок тратит зарезервированные деньги, и наша неспособность прочитать журнал не повод их выбросить (`pgstore.Quarantine` пишет только `run_attempts.quarantine_reason`, свежесть переходит на ре-синк). Сверка по sha256 строки (`run_attempts.last_line_sha256`). Пропасть (`seq > last+1`) осталась ошибкой — строки потеряны, читать дальше нечего. … Фатальный `ErrStreamGap` на дубле в `decoder.go` остаётся только на ДЕВ-пути пайпа, где передоставки нет». @@ -61,7 +61,7 @@ **Событие потолка — факт без цифр.** `Ceiling{halted}`: «It carries the FACT and nothing else: money never reaches the platform's wire or its INFO logs (D39.84), and the stop is resumable, so it is not a failure» (`events.go:123-127`). -**PD-113 (открытый major, закрывается этим паком)** — текущий текст `DEFECT_REGISTER.md:124`: +**PD-113 (открытый major, закрывается этим паком)** — текущий текст `DEFECT_REGISTER.md:18`: > «**Стоп по потолку сегодня НЕразличим от инфраструктурного отказа, и контракт при этом запрещает называть его `failed`.** Движок возвращает потолок ошибкой (`errReserveCeiling`, сверено в HEAD), а `exitCode` мапит всё нераспознанное в 1 — значит по коду выхода „деньги кончились“ и „упало“ это одно и то же число; события потолка не существует (строка 103). Платформа честно ставит `failed`, хотя `BookStatus` требует `paused` и „никогда не `failed`“, потому что стоп резюмируем. Единственный путь, которым платформа СЕГОДНЯ узнаёт о потолке, — событие потока, которого нет; ветка под него построена и запинена (`TestACeilingHaltPausesTheRunWithItsReason`, `TestWhatTheUnitDidBecomesTheProductStatus`, случай „a ceiling halt survives any exit“). Закрывается приходом эмиттера (строка 103); ⚠ до тех пор экран покажет „ошибка“ там, где верно „остановлено: лимиты“». @@ -71,11 +71,11 @@ Действующий exit-контракт движка, чтобы новый код не столкнулся с занятыми: 0 clean · 2 completed-with-flags (`*pipeline.CompletedWithFlags`) · 3 signature-stop банка (`*pipeline.WaveSignatureStop`) · 1 — infra failure и всё прочее (`backend/cmd/tmctl/main.go:30-52`). -**Семантика `--ceiling-usd`** (эмиттер-сессия трогает потолочную окрестность — знать обязана). D39.122 п.2(в) (`05-decisions-log.md:421`): +**Семантика `--ceiling-usd`** (эмиттер-сессия трогает потолочную окрестность — знать обязана). D39.122 п.2(в) (`05-decisions-log.md:416`): > «**`--ceiling-usd` = КНИЖНЫЙ потолок в силе, не бюджет прогона**: леджер сравнивает с накопленным committed+reserved книги; пересчёт „пользовательский прирост → абсолют“ — обязанность ПЛАТФОРМЫ, данные уже отдаются (`committed_usd`/`reserved_usd` в `status --json`); вторая денежная ось НЕ заводится». -Поправлено D39.123 п.2(б) (`05-decisions-log.md:433`) для стороны платформы: +Поправлено D39.123 п.2(б) (`05-decisions-log.md:428`) для стороны платформы: > «**ПОПРАВКА к D39.122(в)/пингу: формула аргумента потолка = `committed + прирост×ставка`, БЕЗ reserved (PD-158)** — `store.Open` движка зануляет утёкший reserved до первой судимой резервации, read-only `status` этого не делает ⇒ reserved из status всегда leftover». @@ -83,7 +83,7 @@ **PD-79 (закрыт; вход для денежной дисциплины шва)** — `DEFECT_REGISTER.md:90`: «**Строковый `"null"` читается как НОЛЬ денег.** … **закрыто:** литерал `null` судится ДО раскавычивания и оставляет значение нетронутым; кавычки снимает `encoding/json`, а не `strings.Trim` — слово `null`, пустая строка и экранированная цифра выходят тем, чем являются». Урок для эмиттера: денежные поля шва — целые micro-USD (`events.go:139-141`), без строковых форм и float. -**PD-60 (открыт; пере-постановка «что делает движок, когда журнал не пишется»)** — `DEFECT_REGISTER.md:71`: «⚠ **ПЕРЕ-ДИСПОЗИЦИЯ (эррата №15, 07.08): постановка строки устарела.** Она рассуждает про 64 КиБ пайпа, а ратифицированный транспорт (D39.106 п.2) — тейл `events.jsonl` с курсором: у файла обратного давления в этом смысле нет вовсе, зато появляются свои свойства (fsync-политика, ротация, отставание тейлера, поведение при заполненном диске). Строка живёт, но переформулируется вместе со строкой 103 — не „блокировать движок или ронять события“, а „что делает движок, когда журнал не пишется“». Политика выбирается ЯВНО, «молчаливой третьей нет» (там же); ср. `research/25:83`. +**PD-60 (открыт; пере-постановка «что делает движок, когда журнал не пишется»)** — `DEFECT_REGISTER.md:24`: «⚠ **ПЕРЕ-ДИСПОЗИЦИЯ (эррата №15, 07.08): постановка строки устарела.** Она рассуждает про 64 КиБ пайпа, а ратифицированный транспорт (D39.106 п.2) — тейл `events.jsonl` с курсором: у файла обратного давления в этом смысле нет вовсе, зато появляются свои свойства (fsync-политика, ротация, отставание тейлера, поведение при заполненном диске). Строка живёт, но переформулируется вместе со строкой 103 — не „блокировать движок или ронять события“, а „что делает движок, когда журнал не пишется“». Политика выбирается ЯВНО, «молчаливой третьей нет» (там же); ср. `research/25:83`. **PD-61 (открыт; два свойства ДО постройки)** — `DEFECT_REGISTER.md:72`: «**(а) Сброс буфера на выходе:** `bufio.Writer` вокруг потока плюс `os.Exit`/`log.Fatal` пропускает `defer` и теряет последние события — ровно те, что сообщают об окончании прогона. **(б) Хвост при падении платформы:** … ответ — НЕ сокет …, а журнал файлом: движок дописывает NDJSON в `/events.ndjson`, платформа тейлит его с чекпойнтом смещения в Postgres». Пункт (б) уже ОТВЕЧЕН ратифицированной формой (журнал файлом, D39.106); пункт (а) — живое требование к эмиттеру. ⚠ Имя `/events.ndjson` в PD-61 — до-ратификационное; канон — `events.jsonl` каталога книги (D39.106 п.2, `tail.go:17`). @@ -94,31 +94,31 @@ ## 5. Открытые развилки дизайна — отданы эмиттер-сессии 1. **Формат журнала** — главная развилка, «решить дизайном» (строка 103). `research/25:74-76` (GPT): «**формат — развилка строки 103 (GPT):** одиночный JSONL с ftruncate-ремонтом имеет гонку живого читателя и слеп к битой записи с валидным `\n`; альтернативы — пофайловые события (`events/.json`, temp+rename) либо CRC-фрейминг; побайтовая идентичность не требуется». ⚠ Учесть: тейлер и декодер платформы УЖЕ построены под одиночный `events.jsonl` (`tail.go:17`); выбор пофайловой/CRC-формы = согласованное изменение обеих сторон, пингом через оркестратора. -2. **Политика «журнал не пишется»** (PD-60): fsync-политика · ротация · отставание тейлера · заполненный диск; блокировать или деградировать — выбрать и записать явно, «обе позиции законны, молчаливой третьей нет» (`DEFECT_REGISTER.md:71`). Смежное: «диск ограничить (`ENOSPC` на ФС леджера ломает денежные инварианты…)» (`research/25:87-88`) — опс-слой, но поведение эмиттера при ENOSPC — его дизайн. -3. **fsync каталога** — NOTE без строки при приёмке D39.122: «NOTE без строк: … fsync каталога» (`05-decisions-log.md:423`); решить в дизайне записи (durability rename/append на ext4). +2. **Политика «журнал не пишется»** (PD-60): fsync-политика · ротация · отставание тейлера · заполненный диск; блокировать или деградировать — выбрать и записать явно, «обе позиции законны, молчаливой третьей нет» (`DEFECT_REGISTER.md:24`). Смежное: «диск ограничить (`ENOSPC` на ФС леджера ломает денежные инварианты…)» (`research/25:87-88`) — опс-слой, но поведение эмиттера при ENOSPC — его дизайн. +3. **fsync каталога** — NOTE без строки при приёмке D39.122: «NOTE без строк: … fsync каталога» (`05-decisions-log.md:418`); решить в дизайне записи (durability rename/append на ext4). 4. **Значение нового exit-кода** для потолка/graceful-stop (строка 165): 0/2/3 заняты (`main.go:30-52`) — выбрать и внести в shell-контракт. 5. **Словарь событий**: форма `events.go` — предложение платформы, «so the engine zone can answer it with a diff» (`events.go:5-6`); движок вправе ответить диффом (состав полей `progress`/`unit_done`, `eta_seconds`, `chunker_version` и т.д.), расхождения — пингом, не молча. ## 6. Чек-лист входного чтения эмиттер-сессии -Ратифицированный список — D39.123 п.4 (`05-decisions-log.md:437`): «промт эмиттера (103 + деньги шва; читать PD-95/105/79/99/107/60/61 + D39.106 + новые 165)»; продублирован в CURRENT-STATE (`docs/PROGRESS.md:5`). +Ратифицированный список — D39.123 п.4 (`05-decisions-log.md:432`): «промт эмиттера (103 + деньги шва; читать PD-95/105/79/99/107/60/61 + D39.106 + новые 165)»; продублирован в CURRENT-STATE (`docs/PROGRESS.md:5`). | # | Что | Где | Зачем | |---|---|---|---| | 1 | Этот док | `docs/architecture/16-events-emitter.md` | сборка всего ниже | -| 2 | D39.106 (форма шва) | `docs/architecture/05-decisions-log.md:229-235` | канон транспорта | -| 3 | D39.119 п.3 · D39.122 п.2(в) · D39.123 п.2(б,в), п.3 | там же `:399`, `:421`, `:433`, `:435` | at-least-once · семантика `--ceiling-usd` · формула PD-158 · карантин проекции | +| 2 | D39.106 (форма шва) | `docs/architecture/05-decisions-log.md:224-230` | канон транспорта | +| 3 | D39.119 п.3 · D39.122 п.2(в) · D39.123 п.2(б,в), п.3 | там же `:394`, `:416`, `:428`, `:430` | at-least-once · семантика `--ceiling-usd` · формула PD-158 · карантин проекции | | 4 | research/25 | `docs/research/25-seam-cold-review.md` §Форма (:16-31) · §эмиттер (:72-83) · отвергнутое (:33-44) | механизмы + чтобы отвергнутое не вернулось | -| 5 | PD-95 | `platform/docs/DEFECT_REGISTER.md:106` | история двух устаревших транспортных текстов зоны; что НЕ строить | -| 6 | PD-105 | там же `:116` | контракт дублей/пропасти/sha256 | -| 7 | PD-79 | `:90` | денежная дисциплина шва (null/строки) | -| 8 | PD-99 | `:110` | argv/деньги не в INFO | -| 9 | PD-107 | `:118` | гейт удаления аккаунта против холда | -| 10 | PD-60 · PD-61 | `:71-72` | «журнал не пишется» + сброс буфера на выходе | -| 11 | PD-113 | `:124` | major, который пак обязан закрыть | -| 12 | Строки 103 · 165 бэклога | `docs/PROGRESS.md:145`, `:113` | сам заказ + exit-коды | +| 5 | PD-95 | `platform/docs/DEFECT_REGISTER.md:180` | история двух устаревших транспортных текстов зоны; что НЕ строить | +| 6 | PD-105 | там же `:192` | контракт дублей/пропасти/sha256 | +| 7 | PD-79 | `:174` | денежная дисциплина шва (null/строки) | +| 8 | PD-99 | `:92` | argv/деньги не в INFO | +| 9 | PD-107 | `:56` | гейт удаления аккаунта против холда | +| 10 | PD-60 · PD-61 | `:24` · `:46` | «журнал не пишется» + сброс буфера на выходе | +| 11 | PD-113 | `:18` | major, который пак обязан закрыть | +| 12 | Строки 103 · 165 бэклога | `docs/PROGRESS.md:149`, `:113` | сам заказ + exit-коды | | 13 | Код читателя | `platform/internal/ingest/events.go` (словарь) · `decoder.go` · `tail.go` | писать ПОД существующий контракт чтения | -| 14 | Своя сторона | `backend/internal/obs/logging.go:15-54` · `backend/internal/pipeline/stagerun.go:494-513` · `backend/cmd/tmctl/main.go:30-52` | готовые call-sites, текст потолка, exit-контракт | +| 14 | Своя сторона | `backend/internal/obs/logging.go:15-54` · `backend/internal/pipeline/stagerun.go:489-513` · `backend/cmd/tmctl/main.go:30-52` | готовые call-sites, текст потолка, exit-контракт | ## 7. Оговорки сборки (снять при постройке) diff --git a/docs/glossary.md b/docs/glossary.md index 06e78607..c4ce96a7 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -8,7 +8,7 @@ - **Хендофф(-промт)** — передача роли новой сессии файлом-промтом; аддендумы к бегущей сессии доезжают только релеем владельца. - **Владелец** — человек; ратифицирует деньги, скоуп-сдвиги, продукт, 18+; связной между сессиями. - **Ф0–Ф3** — фазы: Ф0 скелет · Ф1 инфраструктура · Ф2 качество (судья/гейты) · Ф2.5 пилот · Ф3 продукт (веб-фронт, ридер-IDE). -- **S0–S7 / P0** — нумерация кодовых сессий зон: S-этапы фронта (D39.84) · P-этапы платформы (P0 — бутстрап, D39.100); не путать с фазами Ф0–Ф3. +- **S0–S7 / P0–P5** — нумерация кодовых сессий зон: S-этапы фронта (D39.84; S3.5–S3.7 приняты D39.127/129) · P-этапы платформы (P0 — бутстрап D39.100 … P5 — интейк книг, D39.130); не путать с фазами Ф0–Ф3. - **Зонный журнал / зонный бэклог** — `frontend/docs/frontend-PROGRESS.md` · `platform/docs/platform-PROGRESS.md` и BACKLOG зоны: прогресс/пинги фронта и платформы живут ТОЛЬКО там (D39.100); их строки единый бэклог не принимает (D39.84). - **Полигон** — eval-зона платных/бесплатных экспериментов (`eval/`; отчёты — `docs/experiments/`, статус эксп-а — его баннер/D-лог). diff --git a/docs/product-requirements.md b/docs/product-requirements.md index 2d7c7144..d330b930 100644 --- a/docs/product-requirements.md +++ b/docs/product-requirements.md @@ -52,7 +52,7 @@ | ID | Требование (источник) | Статус | Носитель / доказательство | |---|---|---|---| -| ПТ-20 | Ридер-IDE: VS Code-подобный фронт агентного перевода (V0-п.20/23) | ⭕ | research/16 принят (D29); строки 69–71; F3-brief — D29 п.3. Ф3 ОТКРЫТА 02.08 (D39.81): фронт-сессия живёт на моках (`frontend/`, S0–S2 + контракт исполнены); контракт API ратифицирован (D39.99, живой 0.2.1); платформа построена до раннера P4: вход/кредиты/квоты (P0–P3, D39.107/109/114) + River-очередь · транзиентные systemd-юниты · холд-до-спавна · реконсилятор (D39.123); фронт S3 — слой данных на 0.2.0 (D39.115); S4 гейчен «S3.5 фикс-паком оболочки» (D39.119 п.4) | +| ПТ-20 | Ридер-IDE: VS Code-подобный фронт агентного перевода (V0-п.20/23) | ⭕ | research/16 принят (D29); строки 69–71; F3-brief — D29 п.3. Ф3 ОТКРЫТА 02.08 (D39.81): фронт-сессия живёт на моках (`frontend/`, S0–S2 + контракт исполнены); контракт API ратифицирован (D39.99, живой **0.2.2** — D39.129); платформа построена до интейка книг P5: вход/кредиты/квоты (P0–P3) + раннер P4 (River-очередь · транзиентные systemd-юниты · холд-до-спавна · реконсилятор, D39.123) + `POST /books` со стоп/резюмом и Prometheus (D39.130); фронт — S3.5–S3.7 приняты (оболочка · слой данных · i18n, D39.127/129); **гейт S4 ПАЛ (D39.130)** — S4-промт по слову владельца | | ПТ-21 | Параллельное чтение двух текстов с выравниванием по смыслам (V0-п.21); выравнивание грубое, по единицам экспорта — принято владельцем 02.08, спаны внутри текста не строятся | 🔶 | механизм готов: `tmctl export --pairs` выравнивает пары побайтно по единицам редактуры (`internal/pipeline/export.go:89-93`); якорь = **edit-unit**, НЕ чанк (переформулировано D39.84 — финальный текст существует только на уровне юнита, ~1.9 юнита/главу, местами глава = один блок; читалка обязана это выдерживать); UI-читалка = Ф3 (этап S6) | | ПТ-22 | Настройки от человека: 18+, жанр и т.п. (V0-п.22) | 🔶 | `book.yaml` (labels/жанр) данными; UI = Ф3 | | ПТ-23 | Веб-ПЕРВЫЙ фронт; SEO/ранжирование Google — куки, страницы-сироты, актуальные алгоритмы (V5-п.2); продукт = **SaaS**, не локальное приложение (решение владельца 02.08, D39.81 — натив-прицел V0-п.26 СНЯТ этим решением, вернуть только новым словом владельца); SEO только под Google, Яндекс снят; рынок глобальный; десктоп = PWA первым шагом, Tauri по явным триггерам (решения владельца 02.08, D39.84) | ⭕ | строка 71 (Ф3-бриф); SEO вошёл в стек-дизайн ДО выбора (D39.84, требование исполнено): двухконтурный деплой — SPA `app.<домен>` целиком под noindex + статический публичный контур ≤3 кликов от главной (лечение страниц-сирот), `frontend/docs/STACK_DECISIONS.md` §4; SSR-вопрос закрыт этим решением |