diff --git a/docs/BACKLOG.md b/docs/BACKLOG.md index 6a6011d9..20aac3ff 100644 --- a/docs/BACKLOG.md +++ b/docs/BACKLOG.md @@ -3,7 +3,7 @@ > **Единственный трекер проекта.** Здесь живут строки, на которые доки, промты и D-ноты ссылаются словами «строка N» / «строка бэклога N»: **ID строки стабилен навсегда**, не перенумеровывается и не переиспользуется (D39.80). Правки — только через оркестратора; каждая петля обязана иметь диспозицию: решено / отложено-с-записью / отклонено. > ⚠ **Это НЕ бэклог зоны `docs/`, а бэклог ПРОЕКТА.** У зон свои, с другими неймспейсами ID, и единый их строк не принимает (D39.84): платформа — [../platform/BACKLOG.md](../platform/BACKLOG.md) (`П-N`) и её регистр дефектов `platform/docs/DEFECT_REGISTER.md` (`PD-N`); фронт — [../frontend/docs/BACKLOG.md](../frontend/docs/BACKLOG.md) (`Ф-N`). > ⚠ **Состояние проекта — не здесь.** Очередь, курс, CURRENT-STATE, состояние паков и живая хроника — шапка [PROGRESS.md](PROGRESS.md). Здесь только долг и его диспозиции. -> - **СЧЁТ ОЧЕРЕДИ на 10.09 (скриптом по таблице — `python3 docs/scripts/counts.py`; обновлять при каждом лендинге):** всего **270** строк · зона бэкенд **131** строго / **178** широко (⚠ колонки счётчик читает С КОНЦА — испр. D39.116) · **блокеров очереди 0** (236 закрыта D39.175; **371** — актом D39.233, **360** — актом D39.232, обе 10.09), платные прогоны разблокированы · «скоро» **125** (перечень — грепом по таблице, рукописный список снят D39.126) · гейт-строка эксп-22: 153 (плюс 150 — руки владельца; ⚠ 55 из гейтов СНЯТА — D39.198 п.5); строка 5 — остаток гейчен ре-пробой 74, носитель события теперь строка 188 (аудит D39.140); остальное «когда-нибудь». ⚠ Счёт — НИЖНЯЯ граница долга, не потолок (разбор — легенда таблицы ниже). +> - **СЧЁТ ОЧЕРЕДИ на 10.09 (скриптом по таблице — `python3 docs/scripts/counts.py`; обновлять при каждом лендинге):** всего **271** строк · зона бэкенд **132** строго / **179** широко (⚠ колонки счётчик читает С КОНЦА — испр. D39.116) · **блокеров очереди 0** (236 закрыта D39.175; **371** — актом D39.233, **360** — актом D39.232, обе 10.09), платные прогоны разблокированы · «скоро» **125** (перечень — грепом по таблице, рукописный список снят D39.126) · гейт-строка эксп-22: 153 (плюс 150 — руки владельца; ⚠ 55 из гейтов СНЯТА — D39.198 п.5); строка 5 — остаток гейчен ре-пробой 74, носитель события теперь строка 188 (аудит D39.140); остальное «когда-нибудь». ⚠ Счёт — НИЖНЯЯ граница долга, не потолок (разбор — легенда таблицы ниже). > - ⚠ **Переезд 06.09 (D39.218):** таблица вынесена из `PROGRESS.md` ДОСЛОВНО и ни один ID не сдвинут — **с единственным исключением: две ячейки (строки 220 и 306) тронуты РОВНО в номере якоря `docs/scripts/counts.py:566`→`:569` и `:592`→`:595`**, потому что цель сдвинул этот же коммит; текст ячеек не менялся, длины равны. В `PROGRESS.md` на прежнем месте оставлен заголовок-указатель, поэтому ссылки «секция „Бэклог“» доезжают в один хоп. ## Бэклог (ЕДИНЫЙ, собран 26.07, актуализация 04.08 D39.99/D39.101; правки — только через оркестратора) @@ -306,3 +306,4 @@ | 382 | ⛔ **ПОМЕТКА «ЭТО ОЦЕНКА» — УСЛОВИЕ СЛОВА ВЛАДЕЛЬЦА (`D39.230` п.1) — ПО ШВУ НЕ ЕДЕТ И ПОТРЕБИТЕЛЯ НЕ ИМЕЕТ.** Владелец разрешил списывать с читателя по ОЦЕНКЕ при условии, что пометка стоит. В движке она есть: `backend/internal/pipeline/status.go:321` — `estimated_rows` / `estimated_usd` в `status --json`. Дальше она обрывается. Замер 10.09 с контролем: в кадрах событий шва (`backend/internal/runevents/runevents.go`) слова `estimated` **0 хитов** (контроль: `committed` в том же файле — **6**; денежный кадр несёт один `committed_micro_usd`, `runevents.go:244`); в `platform/internal` вне тестов — **2 хита, оба КОММЕНТАРИИ**, причём `pgstore/credits.go:235` прямо просит эту величину: «publish the count and sum of estimated-price rows beside committed_usd, which is what would let this side say "at most Y"» (контроль: `committed_micro` — 1 хит; go-файлов вне тестов прибор прочёл **81**). ⇒ условие исполнено на ОДНОМ канале из двух, и читателя, ради которого пометка ставилась, у неё нет: платформа не может сказать пользователю «не больше Y». ⚠ Пара к строке **381**: и то и другое — признак, который обязан ехать в кадре `finished`/`spend`, а не только в `status --json` | бэкенд | скоро | платформа ЧИТАЕТ счёт и сумму оценочных строк из потока и может назвать пользователю верхнюю границу списания | акт `D39.233` п.7, замер оркестратора 10.09 по разбору чистого Fable 5 | | 383 | **ПОТОЛОК ОЖИДАНИЯ ЖИВЁТ КОНСТАНТОЙ В ОДНОЙ ЗОНЕ, А ВЫВОДИТСЯ ИЗ КОНФИГА ДРУГОЙ — ФОРМА, КОТОРАЯ ТУХНЕТ МОЛЧА.** Платформенный грейс остановки обязан покрывать законное ожидание движка. Сегодня это число платформа ВЫВОДИТ из движкового каталога и кладёт себе константой (пак «две остановки», `D39.236` п.6): любая правка `backend/configs/models.yaml` — новый провайдер, поднятый `edit_ceiling_out`, изменённый `tok_s_floor` — делает константу ниже правды, и никто об этом не узнает: превышение грейса даёт SIGKILL, а SIGKILL не оставляет ни пометки `cancelled`, ни сеттла оценки. ⛔ **И ловушка уже названа числом, а не гипотезой (замер платформенной сессии 10.09):** `attempt_max_s` инертен у ПЯТИ провайдеров из восьми, и у беcключевых `DeadlineFor` сверху не ограничена вовсе — она растёт с бюджетом линейно. Беcключевой `zai` перерастает сегодняшний максимум 1240 с (deepseek) при бюджете ≥ **43 400** токенов, то есть при `edit_ceiling_out` ≈ **9 900** против сегодняшних **8 000**. ⇒ запас по конфигу — меньше четверти. **Нетухнущая форма, которую надо построить:** движок ПЕЧАТАЕТ свой потолок ожидания сам (он и так умеет считать его `DeadlineFor` — функция экспортирована ровно для вопроса о конфигурации), платформа читает его НА БУТЕ и отказывается стартовать с грейсом ниже. ⚠ В паке «две остановки» этого НЕТ ни в одной половине — там принята сегодняшняя форма (пин на арифметику + строка реестра + комментарий с адресом), и она честно названа тухнущей | бэкенд | скоро | грейс платформы не может молча оказаться ниже законного ожидания движка: число выводится ИЗ ДВИЖКА в рантайме, а расхождение ловится на буте, а не SIGKILL-ом | эхо-протокол платформенной сессии по паку «две остановки», 10.09 (`D39.237` п.5) | | 384 | **ЛЕНДИНГА НЕТ — А ПРОДУКТ ПО СЛОВУ ВЛАДЕЛЬЦА СОСТОИТ ИЗ ДВУХ ПОВЕРХНОСТЕЙ.** 10.09 владелец назвал модель: «фронт — это скорее IDE для переводов; к нему нужна обёртка в виде ЛЕНДИНГА; модель такая же, как у любого ИИ-продукта — лендинг с продуктом, и IDE отдельно, с аккаунтами, оплатой и всем таким» (`D39.239` п.1). Сегодня в репозитории есть только вторая поверхность, и та наполовину: `frontend/` — две маршрутные точки и витрина компонентов (About · AddBook · Bank), зона ЗАМОРОЖЕНА словом владельца с 15.08 и разморозка — отдельным его словом. Лендинга нет ни кодом, ни требованием в `docs/product-requirements.md`, ни строкой до этой. ⚠ **Практическое следствие, из-за которого строка заведена СЕЙЧАС, а не когда дойдут руки:** когда владелец скажет размораживать фронт, надо будет знать, ЧТО размораживают — витрина относится к IDE, и склейка её с лендингом в один поток была бы ошибкой архитектуры, а не темпа | фронт | когда-нибудь | у продукта названы обе поверхности: что делает лендинг, что IDE, где проходит граница входа и оплаты — и это записано требованием, а не устной моделью | слово владельца 10.09, `D39.239` п.1 | +| 385 | ⛔ **У ДВИЖКА НЕТ ЕДИНОГО МЕСТА, ОТВЕЧАЮЩЕГО НА ВОПРОС «МОЖНО ЛИ ЕЩЁ ПОКУПАТЬ» — их ЧЕТЫРЕ, и каждая новая причина остановки протягивается руками через все.** Замер 10.09 (вопрос владельца «почему остановка задела 18 файлов — нет ли архитектурного косяка»): причин перестать тратить деньги сегодня ТРИ, и каждая живёт своим набором носителей — денежный потолок `CeilingHalt` в **6** файлах (`internal/pipeline/{events,escalation,stagerun,waverun,reservegate}.go` + `cmd/tmctl/main.go`), объёмный грант `VolumeStop` в **4** (`internal/pipeline/{volume,bookrun,waverun}.go` + `cmd/tmctl/main.go`), остановка человеком — в **7**. **Пересечение несущее:** `waverun.go` и `cmd/tmctl/main.go` несут ВСЕ ТРИ, `stagerun.go` и `events.go` — две из трёх. Причина в том, что решение «тратить или нет» принимается в ЧЕТЫРЁХ независимых точках, каждая в своём словаре: фидер волны («выдать индекс?»), денежный гейт («впустить резервацию?»), петля ретраев («начинать попытку N+1?»), попартийный приём банка («брать ещё партию?»). ⚠ **Это НЕДО-абстракция, а не оверхед:** лишнего не построено, не хватает ОДНОЙ сущности — распорядителя допуска к трате, — и за её отсутствие платит каждая новая причина, протягиваясь четырежды. Денежный потолок заплатил ту же цену раньше, чем остановка вообще появилась. ⛔ **Чинить СЕЙЧАС не надо и это часть диспозиции:** введение единого распорядителя трогает ровно те пути, где живут деньги, ради выгоды, которая проявится только на ЧЕТВЁРТОЙ причине; риск больше пользы. Делать, когда эта область откроется по другому поводу или когда причина появится четвёртая | бэкенд | когда-нибудь | у вопроса «можно ли ещё покупать» ОДИН распорядитель, а причины (потолок · грант · остановка · будущие) — его входы, а не независимые протяжки; новая причина стоит одной реализации, а не четырёх | замер оркестратора 10.09 по вопросу владельца об инвазивности пака «две остановки» |