diff --git a/docs/PROGRESS.md b/docs/PROGRESS.md index 1fed5b58..4bd4b51c 100644 --- a/docs/PROGRESS.md +++ b/docs/PROGRESS.md @@ -1,12 +1,12 @@ # Журнал прогресса -> **⟶ ТЕКУЩЕЕ СОСТОЯНИЕ** (на 2026-08-07, голова D39.109; хендофф №14→№15 — D39.107). ⚠ **Оркестраторов сейчас ДВА, зоны разведены явно (решение владельца 07.08):** №15 — приёмка ПЛАТФОРМЫ (исполнена, D39.109) · №16 — приёмка ПОЛИГОНА (эксп-21, ждёт результатов; его пинг лежит в секции «Полигон» незакоммиченным). Одновременно не запускаются; 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**: 37 открыто, из них **1 major** (PD-80: вход выключается ~3 rps, и 429 колбэка добивает начатые входы). **Живой уязвимости нет.** ⚠ **ЭРРАТА 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). **Открытый вопрос владельцу по потолку:** платформа объявила себя владельцем `book.yaml` и намерена поднимать `ceilings.book_usd` правкой файла, а флага/ENV на прогон у движка НЕТ (проверено: `tmctl` таких флагов не имеет) — форма передачи потолка требует решения, см. ниже · **приёмка экспов 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 (промт готов, `6ac26f3`) · вахта deepseek-v4-pro — пере-проба маппинга вшита в Ф1 эксп-21 · мини-проба флора 44 — одобрена, промт не выдан. **Открыто на владельце:** запуск эксп-21 (потолки + готовность слепого чтения ~50 пар) · передача платформы · Приложение А `14-api-contract` (незакоммичено) · запуск S3 · 116 (порог подан) · мини-проба 44 · подпись денежного шага 46 · лист В-3+К-6 · вопрос платформы (авто-резюме `paused`). +> **⟶ ТЕКУЩЕЕ СОСТОЯНИЕ** (на 2026-08-07, голова D39.110; хендофф №14→№15 — D39.107). ⚠ **Оркестраторов сейчас ДВА, зоны разведены явно (решение владельца 07.08):** №15 — приёмка ПЛАТФОРМЫ (исполнена, D39.109) · №16 — приёмка ПОЛИГОНА (эксп-21, ждёт результатов; его пинг лежит в секции «Полигон» незакоммиченным). Одновременно не запускаются; 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**: 37 открыто, из них **1 major** (PD-80: вход выключается ~3 rps, и 429 колбэка добивает начатые входы). **Живой уязвимости нет.** ⚠ **ЭРРАТА 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). **Потолок прогона РЕШЁН владельцем 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 (промт готов, `6ac26f3`) · вахта deepseek-v4-pro — пере-проба маппинга вшита в Ф1 эксп-21 · мини-проба флора 44 — одобрена, промт не выдан. **Открыто на владельце:** запуск эксп-21 (потолки + готовность слепого чтения ~50 пар) · передача платформы · Приложение А `14-api-contract` (незакоммичено) · запуск S3 · 116 (порог подан) · мини-проба 44 · подпись денежного шага 46 · лист В-3+К-6 · вопрос платформы (авто-резюме `paused`). > - **Сделано (сводно; детали — 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, сюда НЕ дублируются. > - **Горизонт (D39.62/67, освежён D39.95):** ре-проба flash ИСПОЛНЕНА и строка 74 закрыта (D39.86/91; порог 6/6 → пере-ратификация выборочным, строка 116; проба Q2 ИСПОЛНЕНА — research/24, D39.102: семейства не окупаются, остаток = рецензент спорных кластеров при ре-пробе 74; эмиссия Q7 — по слову) → **ДОБОР ИДЕАЛА** (первым прогоном: оси голоса 24 · авто-режим · итерация №2 редакторов 65 · цена 16 · веса K1–K12 13а · вне-претрейн чекпоинт 55) → ВТОРАЯ ПАРА живьём (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) · проба провода исполнена и 117 закрыта (D39.97), конфиги 112 залендены — платные прогоны разблокированы. > - **Стек:** draft deepseek-v4-flash thinking-ON (банкнота: ⚠ канал в shipping-c1 НЕ включён — жив ран-локальным конфигом книги, строка 140) **⚠0731** → терминолог (та же модель, батчи, экран `target_script`) → editor deepseek-v4-pro БИЛИНГВ ИНТЕРИМ (⚠ exp20/D39.108: второй проход на dspro отрицателен по слепому суду — судьба роли = эксп-21; ⚠ вендор АНОНСИРОВАЛ смену маппинга эффорта pro «early August 2026» — вахта в реестре 108; glm-5 резерв) → судья gemini (Ф2, полигон); канал B Mistral+grok; ~$0.85/ранобэ (D30.4) — 112 залендена (D39.97), пере-калибровка цены при следующем платном прогоне. -> - **ЕДИНЫЙ БЭКЛОГ — секция «Бэклог» ниже** (одна таблица, единственный трекер; каждая петля обязана иметь диспозицию: решено / отложено-с-записью / отклонено; ведёт оркестратор). **СЧЁТ ОЧЕРЕДИ на 06.08 (D39.108, скриптом по таблице; обновлять при каждом лендинге):** всего **119** строк · зона бэкенд **61** строго (ячейка ровно «бэкенд») / **78** широко (ячейка содержит «бэкенд») · **блокеров очереди 0**, платные прогоны разблокированы · «скоро» **30** (2·4·18·46·49·55·99·100·101·103·108·109·113·114·116·118·119·120·121·125·128·129·130·134·**135·136·138·139·140·143**) · гейт-строки эксп-21: 65·106·142; строка 5 — остаток гейчен ре-пробой 74 (D39.102 п.2); остальное «когда-нибудь». ⚠ **Счёт — НИЖНЯЯ граница долга, а не потолок:** трекер содержит только замеченное, и 02.08 дважды за $0 свежие глаза вытащили из кода дефекты, которых в нём не было (релей фронта → строки 99/100/102; приёмочное ревью → третий шов `repair.go:384` в 104 и честность `quality.go:436` в 105). Лента ✅ выше — про ЗАКРЫТЫЕ паки, читать её как «долга нет» неверно (разбор — вопрос владельца 02.08, D39.89). +> - **ЕДИНЫЙ БЭКЛОГ — секция «Бэклог» ниже** (одна таблица, единственный трекер; каждая петля обязана иметь диспозицию: решено / отложено-с-записью / отклонено; ведёт оркестратор). **СЧЁТ ОЧЕРЕДИ на 07.08 (D39.110, скриптом по таблице; обновлять при каждом лендинге):** всего **120** строк · зона бэкенд **62** строго (ячейка ровно «бэкенд») / **79** широко (ячейка содержит «бэкенд») · **блокеров очереди 0**, платные прогоны разблокированы · «скоро» **32** (2·4·18·46·49·55·99·100·101·103·108·109·113·114·116·118·119·120·121·125·**126**·128·129·130·134·**135·136·138·139·140·143·145**) · гейт-строки эксп-21: 65·106·142; строка 5 — остаток гейчен ре-пробой 74 (D39.102 п.2); остальное «когда-нибудь». ⚠ **Счёт — НИЖНЯЯ граница долга, а не потолок:** трекер содержит только замеченное, и 02.08 дважды за $0 свежие глаза вытащили из кода дефекты, которых в нём не было (релей фронта → строки 99/100/102; приёмочное ревью → третий шов `repair.go:384` в 104 и честность `quality.go:436` в 105). Лента ✅ выше — про ЗАКРЫТЫЕ паки, читать её как «долга нет» неверно (разбор — вопрос владельца 02.08, D39.89). > - Архивы хроники: `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)**. Записи ниже — живой хвост (№11+, эра D39.91+). ## Бэклог (ЕДИНЫЙ, собран 26.07, актуализация 04.08 D39.99/D39.101; правки — только через оркестратора) @@ -92,6 +92,7 @@ | 142 | **Механизм «гейты флагают → точечная починка по флагу» как прод-путь**: exp20 §3.3 — $0.0002/дефект, 12/12 (при ИДЕАЛЬНОЙ детекции); механизм конкурентов (research/22:179), у нас петля пака-16 за `enabled:false` (строка 13); детекторы «выдуманное слово»/«инверсия» прототипируются эксп-21 Ф0 | владелец → бэкенд | гейт: эксп-21 | решение владельца по итогам эксп-21 | D39.108 | | 143 | **Абсорбция норматива судейства в `09-pilot-protocol.md`**: разброс инструмента ДО замера · объявленный порог различимости · MQM-lite/error-span первичен, pairwise только для стиля · декой обязателен · запрет судьи семейства жильца арма | полигон/оркестратор | скоро ($0) | правка дока | D39.108, exp20 §7 | | 144 | **Вахта: grok `reasoning_tokens` ВНЕ `completion_tokens`** — формула цены харнессов может недосчитывать (до $0.0325 на exp20); вендор-сверка биллинга xAI при следующем прогоне с grok | полигон | когда-нибудь (следующий xAI-прогон) | вендор-чек | D39.108 (приёмка) | +| 145 | **Движок обязан принимать потолок НА ПРОГОН, а не только из `book.yaml`** — сегодня флага/ENV нет вовсе (проверено: `tmctl` таких флагов не имеет, значение приходит только через `Ceilings.BookUSD`, `stagerun.go:480,505`). Пока так, платформа для управляемого потолка (строка 126) вынуждена ПРАВИТЬ конфиг книги — то есть пользовательское число становится постоянной записью в данных движка, что смешивает зоны против D39.81/D39.85. Форма: аргумент прогона (флаг или ENV), потолок остаётся состоянием ПРОГОНА. Смежное: `Ceilings` в `BriefHash` не входит (`book.go:280-297`) ⇒ ни снапшот, ни ре-билл не двигаются — цена правки нулевая | бэкенд | скоро (денежным промтом, со строками 135–139) | малое касание CLI + проводка | D39.110, приёмка платформы D39.109 | | 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) | @@ -127,7 +128,7 @@ | 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** | | 125 | **Артефакт экспорта БАНКА** (полный банк тремя статусами — канал чтения `/bank` контракта 14): строка 101 это таблица ПОДПИСИ (кап 20 stdout, `cmd/tmctl/render.go:98`), не экспорт; сам банк в приватном SQLite, платформе закрыт (D39.85) — нужен экспорт-артефакт движка на границе стадии/стопе | бэкенд | скоро (БЛОКЕР контракта API, D39.99) | дизайн + малое касание export | ревью контракта 04.08, D39.99 | -| 126 | **Механизм поднятия потолка для resume после ceiling-стопа**: движок продолжает «once the ceiling is raised» (`stagerun.go:488-489`), канала поднятия в контракте нет и в MVP-UI быть не может (деньги, D39.84) — платформенный механизм/политика; продуктовое слово стопа — К-8 у владельца | платформа/бэкенд | когда-нибудь (до подключения фронта к живым прогонам) | дизайн-вход П-1 | ревью контракта 04.08, D39.99 | +| 126 | **Потолок прогона — УПРАВЛЯЕМЫЙ, решение владельца 07.08: настройка в интерфейсе фронта, шкала от минимума (ноль выбрать НЕЛЬЗЯ, подсвечен серым) до максимума баланса аккаунта.** Форма снимает конфликт с Р7 бесплатно: максимум = баланс ⇒ движок всегда получает положительное число и состояния «выключено» не существует, валидатор `book.go:250` не правится. **Три следствия, ратифицированы формой (D39.110):** (а) **единица — НЕ доллары**, а главы (или % баланса): тогда минимум объясняет себя сам («одна глава»), а D39.84 цел — читатель не видит структуру расходов; доллары на пользовательском экране = осознанный амендмент D39.84, не побочный эффект виджета; (б) это потолок ПРОГОНА ⇒ в `book.yaml` он не пишется, движку нужен приём потолка на прогон — строка 145; (в) **максимум шкалы = баланс МИНУС открытые холды**, иначе ползунок в упоре запирает весь баланс на одну книгу и вторую начать нельзя (холд берётся ДО спавна; `ReadAccount` уже возвращает `Balance` и `Reserved` раздельно). Прежнее тело строки (механизм поднятия потолка для resume после ceiling-стопа: движок продолжает «once the ceiling is raised», `stagerun.go:488-489`) — половина этой же работы. Продуктовое слово стопа — К-8 у владельца | платформа/фронт/бэкенд | скоро (форма решена, стройка — промтами) | дизайн-вход П-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` мис-вердиктится как эхо + честность двух новых строк наблюдаемости (D39.86).** (а) `classifyOutput` даёт поблажку `SourceEchoExpected` только `roleTerminologist` (`chunkrun.go:37`), а ответ классификатора по формату состоит из исходных ханьских термов ⇒ доля исходного письма 0.20–0.29 > порога 0.15 на каждом батче: живой артефакт пробы 6/6 несёт `verdict=cjk_artifact` при `bad_lines=0`. Ущерб узкий — `runBankRoleBatches` кладёт `run.texts[i] = att.text` без проверки диспозиции (`terminologist.go:603`), посчитанные эхо-ставки (`quality.go:313-321`) берутся из `chunk_status`, куда бэнк-путь не пишет ⇒ портятся только строки `tmctl report`/лога; **латентно** (`classify_types` выключен во всех шиппинг-конфигах). ⚠ Цена дисциплинированного фикса, которую надо знать заранее: бамп `classifierVersion` (литерал, сам не двигается) меняет payload снапшота → snapshot id → `RequestHash` ⇒ промах ВСЕХ чекпойнтов книги, то есть `--resnapshot` + пере-покупка. (б) тем же касанием — честность поверхностей: строка `VOICE` берёт `rules=` из конфига ВРЕМЕНИ ОТЧЁТА (`quality.go:436`), поэтому включение `gates.voice` после прогона печатает «измерено, чисто» для неизмеренной книги (воспроизведено); и она печатается при выключенном гейте, если `SpoilerLeaks>0` (дизъюнкция — поведение верное, формулировка отчёта/коммента неверна); знаменатель `BANKNOTE` = `len(states)` включая призрачные строки `retrieval_state`, тогда как соседний агрегатор их фильтрует (`quality.go:259-260`) ⇒ после пере-чанковки покрытие занижается | бэкенд | когда-нибудь (ближайшее касание банка/наблюдаемости; (б) — дешёвая часть, вердиктов не двигает) | малое касание + вердикт-двигающая половина (а) через СТОП-решение | D39.86 | | 106 | **Слой 3 НЕ достроен: контракт редактора = full-regen, а целевой — узкие мандаты + ДИФФЫ.** `09-target-architecture.md:121-126` дословно: «research/07 предписывает узкие мандаты + диффы, а не полную перегенерацию — сейчас ровно наоборот (4 мандата, full-regen), что и породило хвост инверсий»; целевой контракт — редактор правит anchored search/replace-спанами с детерминированным Go-apply (ограниченный blast-radius, дешевле, аудируемо, структурно omission-safe). Пак-16 построил петлю РЕМОНТА (починка флагнутого спана постфактум), а не diff-контракт роли ⇒ это разные вещи. **Строки не было ни одной** — дыра учёта, найденная сверкой 02.08 (грепы `diff`/`мандат`/`span` по бэклогу = 0). Смежное: арм Q4b «diff-fidelity+style редактор» (`exp15:108`) не прогонялся НИ РАЗУ, хотя трек B объявлен завершённым. **ЭМПИРИКА ПОЛУЧЕНА (D39.108, экспы 19/20):** дифф-контракт механически исправен (комплаенс 0.966 на боевой единице, аппликатор 15/15), но по замороженному гейту Q4b диффы ОТЛОЖЕНЫ (fidelity-trap 11/12; дороже full-regen на dspro×ru ×2.5–2.9 при невскрытой причине; D21.4/D21.10 закрыты явно). Дальше — эксп-21 (топология) → решение владельца | владелец → бэкенд | гейт: эксп-21 | решение владельца по бейк-оффу эксп-21 | 09 §Слой 3, D39.90, **D39.108** | diff --git a/docs/architecture/05-decisions-log.md b/docs/architecture/05-decisions-log.md index 7b50178f..c7343292 100644 --- a/docs/architecture/05-decisions-log.md +++ b/docs/architecture/05-decisions-log.md @@ -1,4 +1,4 @@ -# Журнал решений оркестратора — контракт D1–D39.109 (развязки 04.07 · пакеты 09–10.07 · приёмка/качество-первым/пивот/эмпирика 11–12.07 · арх-ресет+стройка пере-прогонного стека 13–19.07) +# Журнал решений оркестратора — контракт D1–D39.110 (развязки 04.07 · пакеты 09–10.07 · приёмка/качество-первым/пивот/эмпирика 11–12.07 · арх-ресет+стройка пере-прогонного стека 13–19.07) > **⟶ КАРТА АКТУАЛЬНОСТИ (ревизия D31, продлена до D38.2 [12.07]; исторические записи ниже НЕ переписываются — дисциплина D23.3).** Читая контракт целиком, держи под рукой, что чем перекрыто: > ⚠ **Навигация (актуализация 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) — упоминания двухсекционки/смягчения в телах читать через это. @@ -1551,3 +1551,15 @@ API-529-долг закрыт: 8-осевой refute-by-default воркфлоу **7. Долг лендинга, названный вслух:** PROGRESS CURRENT-STATE **не обновлён** — файл занят живым полигоном (его пинг по эксп-21 лежит незакоммиченным, коммит `d472599` его же). Тот же случай, что D39.107 п.3: обновляет тот, кто лендит полигон. `docs/README.md` обновлён этим же коммитом (норма D39.80), промт P0 платформы получил баннер-исход. **D39.109-эррата (07.08, по вопросу владельца — процессом НЕ поймано).** Приёмка №15 при лендинге пропустила, что **D39.106 п.3 снял пайп-транспорт**: «PD-59 superseded; пайп-путь `supervisor.go` P1 = дев-режим; ответ PD-13 переезжает на cgroup юнита прогона». Зонный журнал платформы при этом длинно доказывает обратное («канал остаётся stdout», SIGPIPE-аргумент), и я принял эту секцию как живое решение — классический анти-паттерн «связность вместо истинности»: аргументация убедительна, а голова D-лога её уже перекрыла. Ошибка ушла в мою же строку PD-95, которая ссылалась на снятый PD-59 как на действующий. **Исправлено:** секция журнала помечена SUPERSEDED с дословным перечислением ратифицированной формы (`research/25` §Форма: транзиентный systemd-юнит на прогон · платформа НЕ родитель · `events.jsonl` в каталоге книги как outbox-проекция коммитов SQLite · тейл платформой с курсором `(engine_run_id, seq)` в одной транзакции с эффектом; отвергнуты с нулём голосов: родитель+пайп 0/15, выделенный fd 3 — 0, stdout/journald как источник — 0) · PD-95 переписан на верное основание и поднят в вес (его прочтёт эмиттер-сессия как задание) · **PD-92 понижен до info** (дефект дев-пути: в проде родителя нет, `cmd.StdoutPipe()` не существует) · **PD-105 повышен** (при тейле журнала повторное чтение строк после краша читателя — НОРМА, значит норматив зоны «at-least-once, дубль не ошибка» буквально верен, а фатальный отказ декодера ему противоречит) · **PD-60 пере-диспозиционирован** (постановка про 64 КиБ пайпа устарела; переформулируется вместе со строкой 103 как «что делает движок, когда журнал не пишется»). Вердикт лендинга не меняется: код принят как дев-путь, которым его и объявил D39.107 п.3, — меняются ДОКИ зоны и вес трёх строк. **Носители работы существовали и до эрраты:** строка 103 несёт эмиттер уже в форме D39.106, строки 138/139 — реконсилятор и пиннинг версии, строка 126 — механизм поднятия потолка. **Урок в норму:** при лендинге зоны каждый вывод зонного дока, спорящий с транспортом или швом, грепается по D-логу на supersede ДО ратификации — «решение, живущее только в зонном доке при противоречащем каноне, — дефект синхронизации» (норма D39.99 п.4) действует и в обратную сторону: канон мог снять зонный вывод, а не только наоборот. + +## D39.110 — ПОТОЛОК ПРОГОНА УПРАВЛЯЕМЫЙ: решение владельца 07.08 ратифицировано формой; фри-тир — предложение оркестратора на confirm; строка 145 заведена (07.08). ✅ + +**1. Решение владельца 07.08 (дословно по смыслу):** потолок управляется двумя вещами — «выключить потолок» и «выставить вручную с фронта»; форма — шкала в интерфейсе от минимума (ноль выбрать НЕЛЬЗЯ, подсвечен серым) до максимума баланса аккаунта, конкретный виджет на выбор исполнителя. **Ратифицировано формой, и форма сама снимает конфликт с Р7:** максимум = баланс ⇒ движок всегда получает положительное число, состояния «потолка нет» не существует, валидатор `book.go:250-251` («a ledger with no ceiling is forbidden, Р7») не правится и Р7 не амендируется. Носитель — пере-поставленная строка **126**. + +**2. Три следствия, без которых форма неполна (добор оркестратора, каждое проверено кодом).** **(а) Единица шкалы — НЕ доллары, а главы (либо % баланса).** Тогда минимум объясняет себя сам («одна глава», ниже прогон бессмыслен — владелец сам отметил, что непонятно, какое минимальное число ставить), а **D39.84 остаётся цел**: читатель не видит структуру наших расходов, платформа сама переводит главы в доллары по оценке движка. Доллары на ПОЛЬЗОВАТЕЛЬСКОМ экране = осознанный амендмент D39.84, и это отдельное решение владельца, а не побочный эффект виджета (П-5 показывает процент ровно по этой причине). **(б) Это потолок ПРОГОНА, значит он не пишется в `book.yaml`.** Дизайн платформы объявлял её владельцем `book.yaml` и намеревался поднимать `ceilings.book_usd` правкой файла — тогда пользовательское число становится постоянной записью в данных движка, что смешивает зоны против D39.81/D39.85. В коде этого НЕТ (проверено: платформа только ставит `cmd.Dir`), значит форма выбирается бесплатно ⇒ **НОВАЯ строка 145**: движок принимает потолок аргументом прогона; сегодня ни флага, ни ENV не существует (`tmctl` таких флагов не имеет, значение идёт только через `Ceilings.BookUSD`, `stagerun.go:480,505`). Цена нулевая: `Ceilings` в `BriefHash` не входит (`book.go:280-297`) — ни снапшот, ни ре-билл не двигаются. **(в) Максимум шкалы = баланс МИНУС открытые холды.** Платформа берёт холд на сумму потолка ДО спавна, поэтому ползунок в упоре запирает весь баланс на одну книгу и вторую начать нельзя; `ReadAccount` уже отдаёт `Balance` и `Reserved` раздельно, данных хватает. + +**3. Фри-тир — вопрос владельца («а как это обычно делается в бэкендах?»), ответ и ПРЕДЛОЖЕНИЕ, а не ратификация.** Разделяется на две половины, и стандартный ответ есть только у одной. **Где живёт начисление:** учебник — промо-кредит пишется строкой леджера в ТОЙ ЖЕ транзакции, что создание аккаунта, идемпотентно по `(аккаунт, source, source_id)`; код зоны это уже делает верно (`upsertIdentityTx`), менять нечего. **Стреляет ли само:** норма — «автоматически, но с ЯКОРЕМ, который стоит абьюзеру денег» (карта на файле — AWS/GCP; телефон — OpenAI добавил его к своим $5 после фарминга; инвайт), плюс бюджет кампании отдельной суммой и алерт при упоре. `email_verified` от Google якорем НЕ является — аккаунты бесплатны и создаются пачками, признак доказывает существование ящика, а не отдельного человека. У нас нет ни одного из трёх, а деньги — предоплаченные ключи владельца. **Предложение: на бете дефолт в НОЛЬ и начисление руками** (платёжного инструмента нет ⇒ между скриптом и ключами нет ничего; бета-тестеров столько, что одна команда в шелле на человека не работа); при появлении платежей дефолт возвращается к $5 ВМЕСТЕ с суточным агрегатным потолком — якорь и потолок приезжают по одному поводу. Ждёт слова владельца; носитель — PD-104. + +**4. Расхождение док↔код, чинится независимо от п.3:** реестр при закрытии PD-30 утверждает «аккаунт создаётся с нулём, начисление руками из админки», а код создаёт аккаунт С $5 (`config.go:73` дефолт `5 * 1_000_000` → `main.go:99` → `login.go:285`). Один из двух текстов лжёт прямо сейчас; строка PD-104 переписана и несёт оба факта. + +**5. Счёт очереди пере-считан скриптом (норма D39.101):** всего **120** строк · зона бэкенд **62** строго / **79** широко · «скоро» **32** (добавлены 126 и 145). diff --git a/platform/docs/DEFECT_REGISTER.md b/platform/docs/DEFECT_REGISTER.md index 49a30dec..486abf44 100644 --- a/platform/docs/DEFECT_REGISTER.md +++ b/platform/docs/DEFECT_REGISTER.md @@ -111,7 +111,7 @@ | PD-101 | bug | minor | `internal/login/login.go:507` | `login_events.ip_prefix` берётся из `r.RemoteAddr`, а в задуманном деплое перед сервисом стоит edge-прокси ⇒ префикс всегда сеть прокси. Журнал входов заведён как ответ на «откуда примерно я входил» — в шипуемой форме он систематически отвечает неверно. `X-Forwarded-For`/`Forwarded` нигде не читаются и доверенного прокси в конфиге нет (это правильный дефолт: доверять заголовку без edge нельзя) — значит решение про edge и про этот столбец принимается вместе | open | приёмка P2 (панель) | | PD-102 | doc | minor | `internal/httpapi/serve.go:36-38` | Доккоммент `DefaultTimeouts` утверждает, что «an upload extends its own deadline as it makes progress» — это НЕВЕРНО: `ReadTimeout` в `net/http` (Go 1.26.5, `server.go:990` `wholeReqDeadline = t0.Add(ReadTimeout)`) выставляется один раз и по мере прихода байтов не продлевается. Комментарий несущий: он объясняет, почему `Read` короткий, и на нём будущая ручка загрузки книги (23 МБ по контракту) построит неверное ожидание — ей понадобится собственный дедлайн через `ResponseController`, а не «прогресс продлевает» | open | приёмка P2 (панель, сверено с исходником Go) | | PD-103 | hardening | minor | `internal/auth/middleware.go:43,66` | У обращений к БД на аутентифицированном пути (`Lookup`/`Touch`) нет собственного дедлайна — только голый `r.Context()`, а `WriteTimeout` у сервера отсутствует по проекту (SSE) и `TimeoutHandler` в цепочке нет. Зависший Postgres паркует хендлеры и ждущих в пуле, пока клиент сам не уйдёт. `readyz` свой таймаут получил (PD-14) — горячий путь нет | open | приёмка P2 (панель) | -| PD-104 | hardening | minor | `internal/login/login.go:285-288` | **Фри-тир печатается НЕАУТЕНТИФИЦИРОВАННЫМ потоком без агрегатного потолка:** $5 за каждую новую пару `(provider, subject)` с подтверждённой почтой, единственный ограничитель — тот же лимитер входа. Агрегатного лимита грантов, счётчика аномалий и алерта нет нигде. PD-30 закрыл половину («только подтверждённой личности»); вторая половина — суточный потолок и наблюдаемость — вопрос владельцу (вынесен приёмкой) | open | приёмка P2 (панель) | +| PD-104 | bug | **minor, но с расхождением док↔код** | `internal/login/login.go:285-288`, `internal/config/config.go:73` | **Фри-тир начисляется АВТОМАТИЧЕСКИ, а реестр обещает обратное.** Код: дефолт `SignupGrantMicroUSD: 5 * 1_000_000` (`config.go:73`) проведён в демона (`main.go:99`) и логин отдаёт его в стор на каждой новой подтверждённой паре `(provider, subject)` — то есть аккаунт создаётся С $5. Строка PD-30 при закрытии утверждает «аккаунт создаётся с нулём, начисление руками из админки» — **один из двух текстов лжёт**. Ограничитель у автоматического начисления один — лимитер входа; агрегатного потолка суммы грантов, счётчика и алерта нет нигде (грепнуто). Деньги при этом предоплаченные ключи владельца. ⚠ **Индустриальная норма:** автоматический промо-грант нормален, но только с ЯКОРЕМ, который стоит абьюзеру денег (карта на файле — AWS/GCP; телефон — OpenAI добавил его к своим $5 после фарминга; инвайт), плюс бюджет кампании отдельной суммой и алерт. `email_verified` от Google якорем НЕ является: аккаунты бесплатны и делаются пачками. **Предложение оркестратора №15 (ждёт confirm владельца):** на бете дефолт в НОЛЬ и начисление руками — платёжного инструмента нет, значит между скриптом и ключами нет ничего; при появлении платежей дефолт возвращается к $5 ВМЕСТЕ с суточным агрегатным потолком (якорь и потолок приезжают по одному поводу). Расхождение док↔код чинить независимо от ответа | open | приёмка P2 (панель; расхождение и норма — оркестратор №15, 07.08) | | PD-105 | standards | minor | `internal/ingest/decoder.go:96` | **Декодер и норматив зоны расходятся на дубле `seq`:** декодер объявляет его фатальным `ErrStreamGap`, а `ENGINEERING_STANDARDS §2` ратифицирует «at-least-once — норма, дубль — не ошибка». После фикса PD-12 цена выросла: сбой ингеста ОСТАНАВЛИВАЕТ прогон, поэтому одна задублированная строка убивает платный прогон, хотя ратифицированный путь ремонта — `status --json`. Внутри одного пайпа передоставки нет, так что отказ декодера защитим; непропорциональна РЕАКЦИЯ. Разрешать ратификацией вместе с промтом эмиттера (строка 103), не молча. ⚠ **Пере-диспозиция (эррата №15): вес ПОВЫШЕН до major-для-эмиттера** — при ратифицированном транспорте (тейл `events.jsonl` с курсором, D39.106) повторное чтение строк после краша читателя — НОРМА, а не аномалия пайпа, поэтому норматив «at-least-once, дубль не ошибка» буквально верен, и фатальный отказ декодера прямо ему противоречит | open | приёмка P2 (панель) | | PD-106 | standards | minor | `cmd/tmplatformctl/` | **Админ-CLI — единственный писатель денег в дереве — не имеет ни одного теста.** В том числе не покрыто правило, которое он сам называет несущим («после коммита команда не может отчитаться провалом», фикс PD-75), и разбор флагов, и формат вывода. Батарея зоны его не видит вовсе (`[no test files]`) | open | приёмка P2 (панель) | | PD-107 | hardening | info | `internal/pgstore/migrations/00007_credits.sql:85`, `00002_readmodel.sql:13` | **Удаление аккаунта обходит защиту PD-25:** составной FK `reservations → books(id, owner_id) on delete restrict` блокирует `DeleteBook`, но `users` каскадит в `reservations` НАПРЯМУЮ, поэтому `delete from users` уносит и ОТКРЫТУЮ резервацию. Замерено приёмкой: аккаунт с открытым холдом удаляется. Учётной дыры нет — леджер и кэш баланса каскадятся тем же удалением, — но прогон, идущий против этого холда, останется без того, кто его закроет. Кода удаления аккаунта в дереве нет вовсе (грепнуто) ⇒ строка = гейт перед появлением такой операции (и перед ASVS 7.4.2 в полной форме). ⚠ Заодно ОПРОВЕРГНУТА обратная версия этой находки от панели («удаление падает на композитном FK даже при закрытых резервациях») — мой прогон: удаляется и с закрытой резервацией, и без неё | open | приёмка P2 (замер оркестратора №15; версия панели опровергнута) |