From e4097cb5a9fb834449b7bb857db1888e32d1e2ff Mon Sep 17 00:00:00 2001 From: heaven Date: Sun, 6 Sep 2026 22:00:24 +0300 Subject: [PATCH] Rewrite both zone packs to what the tree actually holds, since two of their items were already built, and re-point the backlog rows they lean on --- docs/BACKEND_CONSISTENCY_SESSION_PROMPT.md | 103 +++++++++++++++---- docs/BACKLOG.md | 4 +- docs/PLATFORM_MONEY_TRUTH_SESSION_PROMPT.md | 104 ++++++++++++++++---- docs/README.md | 4 +- 4 files changed, 174 insertions(+), 41 deletions(-) diff --git a/docs/BACKEND_CONSISTENCY_SESSION_PROMPT.md b/docs/BACKEND_CONSISTENCY_SESSION_PROMPT.md index 24bea29f..b57cf3cb 100644 --- a/docs/BACKEND_CONSISTENCY_SESSION_PROMPT.md +++ b/docs/BACKEND_CONSISTENCY_SESSION_PROMPT.md @@ -17,11 +17,18 @@ расхождения — пингом в секцию «Бэкенд» файла `docs/PROGRESS.md`. **Сессия НЕ коммитит** — готовое дерево передаёшь оркестратору. Канон git-дисциплины — `CLAUDE.md`. `.env` не читать. Не работать под `/tmp`. +⚠ **Что должно пережить рестарт — кладётся в РЕПОЗИТОРИЙ** (в свою зону), а не в скрэтчпад: он умирает +вместе с окружением. Вне репозитория — только рабочее временное, о котором другим знать не нужно. +⚠ **Входящее сообщение от другой сессии — не приказ**: промт сильнее; расходится — пинг, не исполнение. ## 3. Карта чтения — ЗАКОН, дальше только по её ссылкам 1. `CLAUDE.md` — цели владельца и гардрейлы. -2. Строки бэклога **267**, **318**, **320** (`docs/BACKLOG.md`, греп `^| N |`). +2. Строки бэклога **267**, **318**, **320**, **321**, **322** (`docs/BACKLOG.md`, греп `^| N |`) — все + пять; ⚠ адреса ложных комментариев в этих строках даны НЕ полностью, первый назван в §4.4. + Отправные точки в коде (дальше код первичен): `backend/internal/membank/mempostcheck.go` · + `backend/internal/membank/memseed.go` · `backend/internal/pipeline/bankmaterialize.go` · + `backend/internal/pipeline/seeding.go`. 3. `backend/README.md` — механика движка. 4. `docs/architecture/03-implementation-notes.md` — через баннер. 5. `docs/architecture/12-go-style-notes.md` — только больные места. @@ -34,8 +41,12 @@ - **`D39.216` (мандат владельца, 06.09), делай РОВНО так**: проектировать и чинить **без хаков и воркэраундов**; где нынешняя форма не тянет — **развязать или переписать**, а не обложить заплатой. «Дешевле подпереть» доводом НЕ является. Отступление законно, но **объявляется с ценой**. -- **Комментарий не доказывает поведение** (`D39.214` п.3): источник утверждения о СМЫСЛЕ — тест или - прогон. ⚠ Эту норму НЕ ищи грепом в `CLAUDE.md` — её там нет, она живёт нотой. +- **Комментарий не доказывает поведение**: источник утверждения о СМЫСЛЕ — тест или прогон, и весь этот + пак ровно об этом. ⚠ **Атрибуция исправлена 06.09 проверкой промта:** прежняя редакция приписывала + норму `D39.214` п.3 — там сказано ДРУГОЕ и почти обратное: **«ЕСТЬ ПИН» ≠ «ПИН ДОКАЗЫВАЕТ + СКАЗАННОЕ»** (зелёный тест доказывал отображение, а утверждали про жизнь). Обе нормы тебе нужны, но + это РАЗНЫЕ нормы, и вторая опаснее: цитируя пин, спрашивай не «есть ли он», а «что именно он + утверждает». - **Число называет ДЕРЕВО и ПОПУЛЯЦИЮ**: приводишь счёт — назови коммит и что именно посчитано. - **Рядом с нулём — контрольная величина**: «0 совпадений» неотличимо от «искал не там» (`CLAUDE.md`). - **Мутация засчитывается по ТЕКСТУ сообщения, а не по факту красноты** (`CLAUDE.md`): правый вердикт @@ -44,10 +55,36 @@ ## 4. Состав и разметка свободы -### 4.1 Гард перекрытия окон при слиянии (строка 267) — **делай РОВНО так** +### 4.1 Гард перекрытия окон при слиянии (строка 267) — **реши сам, аргументируй** -Один термин в одном смысле может нести две конкурирующие формы, и обе доезжают на оба провода — дыра в -проверке схлопывания. Решение владельца 05.09 состоялось, строка несёт разбор. Закрыть. +⛔ **Постановка «дыры нет гарда, построй его» БЫЛА НЕВЕРНА и снята 06.09 проверкой промта исполнением.** +В точке слияния уже стоят ДВА гарда, и ни промт, ни строка 267 их не называли: +- `membank.ApprovedSharedKeyCollisions` — зовётся в `gatherBankInputs` + (`backend/internal/pipeline/bankmaterialize.go:142`) ПОСЛЕ append сида+ruby+mined+auto; условие «общий + firing-ключ + РАЗНЫЙ dst + перекрывающиеся окна», поведение **fail-loud** (прогон падает); +- `membank.UnverifiedKeyConflicts` — зовётся в `backend/internal/pipeline/seeding.go:73` над полным + набором из БД; ловит пару «approved × неподписанная» с разным dst и перекрытием, но **варнингом**, и + это осознанный выбор с записанным доводом (`backend/internal/membank/memseed.go:685-688`: ронять + оплаченный прогон из-за собственного предложения движка — самострел). + +Замер, на котором это построено (проба $0 в песочнице, HEAD `ff14901`, плюс структурная сверка второй +рукой): пример самой строки 267 (сид `[0,0]` «юаньши» + майнинг `[3,9]` «камень первоисточника») +попадает в один из двух гардов при ЛЮБОМ статусе майненой строки. +⚠ **Формулировку «непокрыта ровно одна пара unsigned × unsigned» НЕ бери на веру — она уточнена:** +внутри ОДНОГО файла пара с тем же `Src` ловится статус-слепым гардом `parseBankSeed` +(`backend/internal/membank/memseed.go:217`), который гоняют и `LoadGlossarySeed`, и `loadMinedDelta`. +Непокрытым остаётся: **unsigned × unsigned МЕЖДУ источниками** (сид-`draft` × mined × auto) и **через +общий alias даже внутри файла** (`:217` сравнивает только `Src`). + +⇒ **Твой предмет:** (а) ПЕРЕ-СНЯТЬ замер своими руками — он не мой, и я его не воспроизводил, только +сверил структурно; (б) если подтвердится — закрыть непокрытое; (в) вопрос «варнинг → стоп» для +`approved × unsigned` **отдельным решением, и это пинг, а не правка**: у нынешнего поведения записан +довод, а смена меняет поведение ПЛАТНОГО прогона. +⛔ **ГДЕ закрывать — уже сказано владельцем, и это не твой выбор.** Слово владельца в строке 267: +«у неподписанного термина тоже обязан быть ОДИН перевод, **отвечает за это стадия схлопывания, подпись +ни при чём**». ⇒ лечение идёт в схлопывание; гард на слиянии — страховка, а не место починки. ⚠ Носителя +этого слова в журнале решений НЕТ, он живёт только в строке 267 — если решишь иначе, это пинг. +⚠ Если замер не подтвердится — это самый ценный ответ, и он законный. ### 4.2 Совет, который движок не исполняет (строка 320а) — **реши сам, аргументируй** @@ -67,19 +104,27 @@ ### 4.4 Два ложных комментария — снять (строки 321 и 322) — **делай РОВНО так** -- Оправдание `nil`-переноса в редакторской волне («единица есть глава или её часть») — **ложно**: глава - регулярно делится на несколько правочных единиц. ⛔ **Сам перенос НЕ строить** — по строке 321 сначала - замер дрейфа, инцидентов пока ноль. Здесь только честный комментарий. -- Утверждение, что обычный резюм перезаписывает строку статуса, — **ложно**: он выходит раньше, пишет - только ре-пин. +⚠ **Читать вместе с §4.5:** из строки 322 берётся ТОЛЬКО попутный ложный комментарий (ниже), а её +предмет — жизненный цикл принятой редактуры — в пак НЕ входит. Это не противоречие, а разрез: комментарий +дешёв и лжёт сейчас, механизм — отдельный пак. + +- Оправдание `nil`-переноса в редакторской волне («единица есть глава или её часть, поэтому внутриглавное + окно липкости неприменимо») — **ложно**: глава регулярно делится на несколько правочных единиц (замер + строки 321: 86 % глав полной книги многоединичны). Адрес — `backend/internal/pipeline/waverun.go:695-696` + (греп `intra-chapter sticky window does not apply`). ⛔ **Сам перенос НЕ строить** — по строке 321 + сначала замер дрейфа, инцидентов пока ноль. Здесь только честный комментарий. +- Утверждение про обычный резюм и строку статуса. ⚠ **Формулировка «он выходит раньше, пишет только + ре-пин» — МНЕНИЕ автора промта, в строке 322 её нет** (там сказано «обычный резюм её не пишет»). + Установи поведение сам по коду и приведи комментарий к нему; если моё мнение неверно — так и скажи. ### 4.5 Чего в паке НЕТ и почему — **не делай** - **Строка 322 (история принятой редактуры)** — другой предмет: жизненный цикл чекпойнтов и схема, а не закон банка. Отдельным паком. - **Строка 295 (подать подписанный канон в прогон)** — снята из этого пака: у бэкенд-сессии нет ни - книги, ни стенда, ни санкции на деньги. Если найдёшь чисто бэкендовую половину — **назови её пингом**, - но не бери. + книги, ни стенда, ни санкции на деньги. ⚠ **Испр. 06.09:** прежняя редакция просила «найди и назови + половину» — половины УЖЕ названы в самой строке 295 сегодняшним деревом, так что искать нечего. Если + увидишь в них ошибку — это пинг. - **Перекрой структуры глав (161/283)** — отдельный дизайн-пак. ## 5. Мандат самопроверки ИСПОЛНЕНИЕМ — механизм назван, и пустое исполнение его не удовлетворяет @@ -96,6 +141,24 @@ противоречащее», а не «проверь, всё ли хорошо». 3. **Греп по отозванной формулировке перед словом «исправлено»**: `grep -c "<снятая фраза>" <файл>` — ноль либо только внутри пометки. Смена 06.09 попалась на этом трижды. +4. **Интервальная самопроверка**: примерно на середине — субагент против ЯВНЫХ критериев («вот заказ, вот + сделанное — что расходится»), а не «посмотри, всё ли хорошо». +5. **Дифф тестов ИСПОЛНЕНИЕМ, не памятью**: `git diff -- '*_test.go' | grep '^[-+]func Test'` (и то же по + `func Fuzz`), число до и после; удалённый тест объявляется отдельно и с причиной. +6. **Перед отчётом сверь КАЖДЫЙ клейм с результатом инструмента ЭТОЙ сессии**, а не с памятью о том, что + делал час назад. + +## 5а. Попутный проход: ЛОГИЧЕСКИЕ расхождения, а не исполнительские — **делай РОВНО так** + +Пока ты внутри этих файлов, ищи места, где код работает **как написано**, но написанное — **не то, что +задумывалось**: гейт, отвечающий на свой вопрос вместо заказанного · метрика, чьё имя шире её смысла · +ветка, которая по построению не исполняется · тест, зелёный оттого, что не проверяет ничего. +⛔ **Найденное НЕ чинить молча** — вынести СПИСКОМ в отчёт («задумано против сделано»), с `file:line` и +одной фразой «что обещано / что исполняется». Правка — отдельным решением, не этим паком. + +⚠ Почему это здесь: сам пак ровно об этом классе (три пункта из четырёх — «описание лжёт о поведении»), +а класс за смену 06.09 сработал не меньше восьми раз у всех ролей (`D39.217` п.3). Проход дешёв: ты уже +читаешь эти файлы ради §4. ## 6. Оси ревью — характер работы «Код» и «Доки» @@ -106,7 +169,7 @@ ## 7. Записка-план ДО работы -До первой правки пришли оркестратору ≤15 строк: что берёшь по каждому из четырёх пунктов · где ждёшь +До первой правки пришли оркестратору ≤15 строк: что берёшь по каждому из четырёх пунктов §4 (плюс попутный проход §5а) · где ждёшь сопротивления · что считаешь спорным в самом заказе. Это дешевле, чем разойтись на готовом. ## 8. Заявление = команда @@ -116,8 +179,10 @@ ## 9. Эхо-протокол старта -ДО работы пришли ≤10 строк: **скоуп** (что берёшь) · **инварианты** (что обязано уцелеть) · **не-делать** -(что в паке запрещено). Если эхо разойдётся с моим заказом — лучше здесь, чем в приёмке. +ДО первой правки пришли **оркестратору — первым действием, по адресу из `/tmp/textmachine-channel`** +(`SendMessage`) ≤10 строк: **скоуп** (что берёшь) · **инварианты** (что обязано уцелеть) · **не-делать** +(что в паке запрещено). Эхо в собственный блокнот — не эхо: разойтись с заказом ему негде. Канала нет — +эхо идёт первой секцией отчёта, и это законный случай. Разойдётся с заказом — лучше здесь, чем в приёмке. ## 10. Что НЕ удалось — обязательная секция отчёта @@ -136,15 +201,17 @@ ## Деньги -**Этот пак — $0.** Платных вызовов к моделям в нём нет ни одного: все четыре предмета — код, +**Этот пак — $0.** Платных вызовов к моделям в нём нет ни одного: все четыре предмета §4 и проход §5а — код, комментарии и пины на фикстурах. ⛔ Если по ходу окажется, что предъявить что-то можно только платным прогоном — **это пинг оркестратору за санкцией, а не твоё решение**. Санкции на деньги промт не несёт. ## Отчёт Секция «Бэкенд» в `docs/PROGRESS.md` + сообщение оркестратору: что построено · чем предъявлено (команда -и вывод) · таблица мутаций из §5.1 · что сказал опровергатель и что ты с этим сделал · двигает ли +и вывод) · таблица мутаций из §5.1 · **список «задумано против сделано» из §5а** · что сказал опровергатель и что ты с этим сделал · двигает ли что-нибудь из сделанного снапшот, хеш запроса, ключ манифеста или версию встроенных данных · секция §10 · **что ты сам считаешь слабым местом своей работы**. ⚠ Числа батареи снимай **после последней правки**, не до. +⛔ **Последний абзац отчёта — план или обещание? Значит работа не кончена: сделай сейчас.** Отчёт +описывает СДЕЛАННОЕ; «дальше надо бы…» живёт отдельной секцией предложений, и решает по ней оркестратор. diff --git a/docs/BACKLOG.md b/docs/BACKLOG.md index a18b0577..be19838f 100644 --- a/docs/BACKLOG.md +++ b/docs/BACKLOG.md @@ -209,7 +209,7 @@ | 263 | **Дизъюнкты предупреждения банкноты и `forWrite` не прибиты по отдельности** (позитивная фикстура без обоих входов, негативная — с обоими): пережили посадки «нет контраста», «нет пака», «предупреждать и на read-open». **`WB15` несёт тот же дефект ложного пина, что найденный и починенный `WB36`** — одиночный сдвиг порога под `TestGoldenDeterminism`: на чистом литерале голден не двинется и запись выживет при целой гарантии. **AST-тест исчерпаемости парсит ТОЛЬКО `disposition.go`** — `FlagReason`, объявленный в другом файле, в карту не попадёт при зелёном тесте. **Дайджест корпуса не покрывает `provenance`** — адрес пере-снятия, подмену которого дайджест не видит | бэкенд | когда-нибудь | четыре независимых пина | круг 4 петли, X11/X12/X13 · WB15 · X9 · X30 | | 265 | **Питоново зеркало полигона держит ВТОРУЮ копию таблицы плейсхолдеров движка, и она разошлась: `genre` есть, `book_id` нет.** `eval/bank_arbitration/editor_wire_probe.py` — ПЛАТНАЯ проба, читающая ШИППИНГОВЫЙ `backend/prompts/zh-ru/editor.md`, на неё ссылаются ещё **25** скриптов (`grep -rl editor_wire_probe eval --include=*.py`; ⚠ испр. 05.09, первая редакция говорила «девять»); 27 промтов под `eval/` несут `{{genre}}`, который движок ОТКАЗЫВАЕТСЯ собрать при загрузке. ⇒ замеры идут на проводе, которого в проде не существует, и это «третий путь», которого в Go больше нет. ⚠ Зона ПОЛИГОНА — чинит она, носитель заведён оркестратором пингом | полигон | скоро (перед следующим платным замером) | зеркало читает таблицу движка, а не держит копию | передано бэкенд-сессией 04.09, чужая зона | | 266 | **Правки кругов 3 и 4 петли не ревьюил НИКТО — круг свёрнут решением владельца, а не замкнут.** Замеренная база, из-за которой это долг, а не формальность: ДВАЖДЫ подряд дефект вносил фикс предыдущего круга (круг 2 объявил денежную дыру закрытой — круг 3 показал, что она открыта; ратификация оркестратора по дедупу внесла живой дефект — поймала зона). Круг 3 добавил ~2000 строк и не ревьюил из них ни одной; круг 4 — две правки, обе проверены исполнением, но не чужими глазами. ⚠ Дисциплина петли исправлена эрратой: круг крутит СЛЕДУЮЩАЯ сессия по готовому паку, а не прежняя — правило «сессия отрабатывает скоуп и завершается» бьёт норму петли | бэкенд | скоро | проход свежей сессии по диффу `c77c3ba`+`2e13cd1` | решение владельца 04.09 остановить полировку | -| 267 | ⛔ **ОДИН ТЕРМИН В ОДНОМ СМЫСЛЕ МОЖЕТ НЕСТИ ДВЕ КОНКУРИРУЮЩИЕ ФОРМЫ, И ОБЕ ЕДУТ НА ОБА ПРОВОДА — дыра в ПРОВЕРКЕ схлопывания.** ⚠ **Пере-снято 05.09: было заведено как ДОКТРИНА («показывать обе или схлопывать») — это была неверная постановка оркестратора.** Владелец: у неподписанного термина тоже обязан быть ОДИН перевод, отвечает за это стадия схлопывания, подпись ни при чём. **Измерено зоной по коду и предъявлено на банке:** ключ уникальности БД — `(book_id, src, sense, since_ch, until_ch)`, значит один смысл при РАЗНЫХ окнах законен для БД; гард «одна форма на главу» существует (`backend/internal/pipeline/memseed.go`, греп `a term has ONE rendering per chapter`) и статус-слеп, **но работает ВНУТРИ ОДНОГО ФАЙЛА** — `loadMinedDelta` проверяет дельту саму против себя и НЕ против сида; точка слияния (`bankmaterialize.go`, греп `storeOrder`) отвергает только ТОЧНЫЙ дубль, перекрывающиеся окна проходят. Предъявлено: сид `[0,0]` «юаньши» + майнинг `[3,9]` «камень первоисточника», глава 5 внутри обоих ⇒ **injected=2, две строки и редактору, и черновику**. ⇒ Банк перестаёт быть законом ровно там, ради чего построен — консистентность термина на всю книгу. ⚠ **ГРАНИЦА, названная зоной: доказано, что состояние ДОСТИЖИМО и провода его несут; НЕ доказано, что обычная последовательность операций его производит** (консолидация даёт один `dst` на термин — сверено; сверяет ли она предложение с УЖЕ существующей сид-строкой другого окна — не мерено). Это дыра в проверке, а не наблюдённый инцидент. Чинить на СЛИЯНИИ, где видны все три источника, а не на загрузке каждого | бэкенд | скоро | гард перекрытия окон на слиянии + пин на достижимом состоянии | решение владельца 05.09 + замер зоны | +| 267 | ⛔ **ОДИН ТЕРМИН В ОДНОМ СМЫСЛЕ МОЖЕТ НЕСТИ ДВЕ КОНКУРИРУЮЩИЕ ФОРМЫ, И ОБЕ ЕДУТ НА ОБА ПРОВОДА — дыра в ПРОВЕРКЕ схлопывания.** ⚠ **Пере-снято 05.09: было заведено как ДОКТРИНА («показывать обе или схлопывать») — это была неверная постановка оркестратора.** Владелец: у неподписанного термина тоже обязан быть ОДИН перевод, отвечает за это стадия схлопывания, подпись ни при чём. **Измерено зоной по коду и предъявлено на банке:** ключ уникальности БД — `(book_id, src, sense, since_ch, until_ch)`, значит один смысл при РАЗНЫХ окнах законен для БД; гард «одна форма на главу» существует (`backend/internal/membank/memseed.go`, греп `a term has ONE rendering per chapter`; ⚠ испр. 06.09 — прежде здесь стоял путь `internal/pipeline/memseed.go`, которого не существует) и статус-слеп, **но работает ВНУТРИ ОДНОГО ФАЙЛА** — `loadMinedDelta` проверяет дельту саму против себя и НЕ против сида; точка слияния (`bankmaterialize.go`, греп `storeOrder`) отвергает только ТОЧНЫЙ дубль, перекрывающиеся окна проходят. Предъявлено: сид `[0,0]` «юаньши» + майнинг `[3,9]` «камень первоисточника», глава 5 внутри обоих ⇒ **injected=2, две строки и редактору, и черновику**. ⇒ Банк перестаёт быть законом ровно там, ради чего построен — консистентность термина на всю книгу. ⚠ **ГРАНИЦА, названная зоной: доказано, что состояние ДОСТИЖИМО и провода его несут; НЕ доказано, что обычная последовательность операций его производит** (консолидация даёт один `dst` на термин — сверено; сверяет ли она предложение с УЖЕ существующей сид-строкой другого окна — не мерено). Это дыра в проверке, а не наблюдённый инцидент. Чинить на СЛИЯНИИ, где видны все три источника, а не на загрузке каждого ⛔ **ПЕРЕ-СНЯТО 06.09 ПРОВЕРКОЙ ПРОМТА ИСПОЛНЕНИЕМ ($0, `go test -overlay` в песочнице, `ff14901`): в точке слияния УЖЕ СТОЯТ ДВА ГАРДА, и постановка «гарда нет» была неверна.** `membank.ApprovedSharedKeyCollisions` — `backend/internal/pipeline/bankmaterialize.go:142`, после append сида+ruby+mined+auto, условие «общий firing-ключ + разный dst + перекрытие окон», **fail-loud**; `membank.UnverifiedKeyConflicts` — `backend/internal/pipeline/seeding.go:73`, пара «approved × неподписанная», **варнинг** с записанным доводом (`backend/internal/membank/memseed.go:685-688`: ронять оплаченный прогон из-за собственного предложения движка — самострел). Пример САМОЙ ЭТОЙ СТРОКИ (сид [0,0] «юаньши» + майнинг [3,9] «камень первоисточника») ловится одним из двух при ЛЮБОМ статусе майненой строки. **Непокрыто: «неподписанная × неподписанная» МЕЖДУ источниками** (сид-`draft` × mined × auto) **и через общий alias даже внутри файла** — внутри одного файла пара с тем же `Src` ловится статус-слепым `parseBankSeed` (`membank/memseed.go:217`, сравнивает только `Src`). ⇒ остаток строки: пере-снять замер своими руками, закрыть непокрытый случай, назвать оба гарда здесь; «варнинг → стоп» для approved × unsigned — ОТДЕЛЬНОЕ решение, меняет поведение платного прогона. | бэкенд | скоро | гард перекрытия окон на слиянии + пин на достижимом состоянии | решение владельца 05.09 + замер зоны | | 268 | **Гейт версии контракта у фронта читает СВОЁ зеркало, а не канон — и потому слеп по построению.** `frontend/src/api/contract.test.ts` сверяет `${cwd}/docs/api-contract/openapi.yaml` с фикстурой, то есть копию с копией, и зелен при любом отставании; соседний тест сравнивает только МАЖОР, а он у `0.2.3` и `0.10.0` одинаков — ноль. Зеркало отстало на ВОСЕМЬ миноров. Сравнение: тот же класс гейта у платформы читает КАНОН с диска и поймал расхождение `0.9.0→0.10.0` в тот же час. ⚠ Зона фронта ЗАМОРОЖЕНА — строка ждёт разморозки, но входит в перечень первого касания | фронт | скоро (первое касание при разморозке) | перенацелить гейт на канон | находка платформенной сессии 04.09, подтверждена оркестратором | | 272 | **ШАБЛОН КНИГИ ДЕПЛОЯ ОДИН НА ВСЕ ПАРЫ, а в нём лежит ПАР-СВЯЗАННОЕ значение — `transcription: palladius`.** Платформа рендерит `book.yaml` из единственного операторского шаблона и подставляет ровно пять ключей (`book_id · title · source_lang · target_lang · source_file`); всё остальное едет из шаблона нетронутым. Палладий — система транскрипции ДЛЯ КИТАЙСКОГО. Движок значение не валидирует (свободная строка) и подставляет прямо в промпт. ⇒ Деплой, объявивший `zh>ru,ja>ru`, отдаёт КАЖДОЙ японской книге инструкцию транскрибировать по-китайски: не отказ и не флаг, а тихо неверные имена во всей книге — ровно тот класс брака, ради которого продукт существует. ⚠ Чинить придётся не одну книгу: значение вшито в `book.yaml`, который платформа НИКОГДА не перезаписывает (`O_EXCL`) | платформа+бэкенд | скоро (гейт второй пары) | пар-связанные ключи шаблона + валидатор значения в движке | критик полноты стратегии 04.09 | | 273 | **ПАР-ШОВ ЛОМАЕТСЯ АСИММЕТРИЧНО: промпт-пак падает ГРОМКО, целевые ДАННЫЕ выключаются МОЛЧА — вместе с банком.** Отсутствие промптов пары — жёсткая ошибка загрузки («never silently substitute another pair's conventions»). Отсутствие ЦЕЛЕВЫХ данных — тишина в трёх местах: `lang.InjectionTextsFor` на незнакомом таргете возвращает пустое, обе банк-инъекции рендерят пустоту (`if !tx.HasData() { return "" }`), `LoadReaderWords` отдаёт значки вместо слов без ошибки. ⇒ Книга на новый таргет переводится ЦЕЛИКОМ и за ПОЛНЫЕ деньги, но БЕЗ банка-как-закона — то есть без единственного механизма, держащего термины консистентными на всю книгу, без $0-чекеров цели и с пометками из значков в выданном файле. Ни ошибки, ни варнинга, ни поля в отчёте сборки. ⚠ Строка 32 закрыта формулировкой «инертна ПО ОТСУТСТВИЮ данных» — для ЧЕКЕРОВ это хорошо, для БАНК-инъекции такого вывода не делал никто | бэкенд | скоро (гейт второй пары) | префлайт готовности таргета: банк-данные есть ⇒ работаем, нет ⇒ громко | критик полноты стратегии 04.09 | @@ -218,7 +218,7 @@ | 279 | ⚠ **ПРОТУХЛА — испр. 06.09: половина ИСПОЛНЕНА без пометки, половина осталась остатком без имени.** Форма `OrderOptions` (`chapters_left`, `affordable_chapters`, `verdict`) стоит в каноне с минора 0.11.0, а `shortfall` в каноне ОТСУТСТВУЕТ (ноль вхождений); тело `D39.208` строку не называет, ✅ не стоит. Класс `D39.167` п.1: акт лендинга обязан быть сверен со строками. ⇒ разделить: исполненное пометить, остаток `shortfall` назвать своим предметом. **ШАГ 3, КОНТРАКТ (минор, полоса ломающих правок мажора 0 законна): заказ объёмом.** `ceiling_chapters` → `chapters` со смыслом ОБЪЁМА (`null` = вся книга) · `CeilingBounds{min,max,default}` → `OrderOptions{chapters_left, affordable_chapters, verdict: covers_all|covers_part|covers_none, blocked}` · `PausedReason` += `run_limit_reached` (и `credit_exhausted` СТАНОВИТСЯ правдой — сегодня лжёт при 34% баланса, наблюдение H14) · `Run` += `ordered_chapters`/`delivered_chapters`. ⚠ Фразы — ДАННЫМИ по коду причины и локали, не литералом. ⚠ **ПЕРЕ-СНЯТО 05.09 под D39.196:** наружу ВЫХОДЯТ баланс, потолок заказа и холд — деньгами; контракт получает `balance`, `estimate{expected, hold}` под выбранный заказ, границы денежного ползунка `{min: неделимый шаг, max: баланс}` и `shortfall` у паузы; процент остатка остаётся СИГНАЛОМ «мало/пусто». НЕ выходят: цены моделей, стоимость стадий и вызовов, структура НАШИХ расходов. Плюс `OrderOptions` обязан нести ТРИ вида заказа (вся книга · знаки · до главы N), а не только главы. Ремедиа-таблица `resumeRun` упрощается: «Продолжить» — новый прогон ТОГО ЖЕ заказа | контракт | скоро | минор контракта одним актом с платформенной половиной | согласование 04.09 | | 280 | ✅ **ИСПОЛНЕНО ЛЕНДИНГОМ 06.09 — акт `D39.208`.** Заказ живёт на КНИГЕ и хранится ИДЕНТИЧНОСТЬЮ (`books.ordered_through_chapter_id`), а не ординалом; холд считается от проекции движка; `--max-units` едет в argv. ⚠ **Кроме ОДНОЙ позиции, от которой зона отказалась с доводом и которая живёт отдельно:** денежный ползунок объявлен на проводе, но отправить его нечем, и оценки под ВЫБРАННЫЙ заказ нет. Прежняя редакция ряда: **ШАГ 4, ПЛАТФОРМА: заказ живёт на КНИГЕ, холд считается от проекции, `--max-units` наконец едет в argv.** `books.ordered_through_chapter` (null = вся книга) — сегодня интент живёт на ПРОГОНЕ, оттого и неловкость «поднять лимит = НОВЫЙ прогон с бо́льшим `ceiling_chapters`»; с заказом на книге «Продолжить» после пополнения тривиален, и дверь пере-прохода встаёт рядом вторым типом заказа. Холд = `min(баланс, проекция × k)`; `bookCap = committed + холд` (`PD-158` цел). В argv добавляется `--max-units` = сумма юнитов заказанных глав минус доставленные. Удаляются `DefaultPerChapter`, `Scale` и `draftWork`: план движка становится РАВЕН заказу, и «черновики на весь потолок при нуле готовых глав» исчезает структурно. Закрывает `PD-410`, `PD-440`, `PD-446`. ⚠ **ПРЕДУСЛОВИЕ, названное отдельно: `PD-422`** — `--resnapshot` передаётся УСЛОВНО, а условие ставит только правка банка; рост авто-банка от майнинга флага не ставит. Частичный заказ на майнящей книге растит банк ⇒ следующий заказ без `--resnapshot` умрёт на снапшот-гарде, холд взят, попытка сожжена. Взять В ТОТ ЖЕ пак | платформа | скоро | заказ на книге + холд от проекции + проводка `--max-units` + PD-422 | согласование 04.09 | | 281 | **ЗАМЕР: сколько наших денег стоит тысяча ПЛОТНЫХ и тысяча РАЗРЕЖЕННЫХ знаков по стадиям и парам.** Цель — НЕ константа (D39.165 п.1г прямо запрещает ставку константой), а **дисперсия проекции**: коэффициент k для холда и честность вердикта «хватит ли». Снимать есть из чего и это $0: `find -L books` даёт 162 базы прогонов, в `request_log` лежат `chapter · chunk_idx · stage · prompt/completion_tokens · cost_usd · tm_hit`, исходник по юниту отдаёт `tmctl export --pairs` бесплатно. Метод: по юниту плотные/разреженные знаки против суммы `cost_usd` при `tm_hit=0`, по стадиям; хвост ретраев и эскалаций считать ОТДЕЛЬНО; базы до 16.08 пере-прайсить по токенам. ⚠ Гейт для коэффициента холда в строке 280 | полигон | скоро (гейт строки 280) | замер по 162 базам, $0 | согласование 04.09, вторая редакция | -| 282 | ⛔ **ЧИСЛО, ПОДПИСАННОЕ «ЗНАКОВ», СЧИТАЕТ РУНЫ ПОТОКА ЗАПИСИ ФАЙЛА — что для UTF-8 txt И ЕСТЬ знаки, а для EPUB даёт руны ZIP-АРХИВА.** ⚠ Заголовок первой редакции («считает байты») — противоположная полуправда, испр. 05.09: ложно оно для EPUB, GB18030 и UTF-16, а не всегда. Проверено оркестратором по коду: `platform/internal/books/books.go`, греп `type counter` — счёт идёт по не-продолжающим байтам UTF-8 ПОТОКА ЗАПИСИ файла, а не по тексту; там же комментарий признаёт приближение для GB18030. Наружу уходит как `character_count` (`platform/internal/httpapi/v0.go`), на экране подписано `'about.characters': 'Знаков'` (`frontend/src/i18n/ru.ts`). ⇒ Живая ложь на продуктовом экране, и она же — вторая ненадёжная единица, найденная тем же вопросом «откуда берётся число». **Основой страницы быть не может.** Лечение: переименовать в размер файла ЛИБО заменить манифестной суммой знаков движка — ✅ **источник ПОСТРОЕН**: `source_chars` по юниту в `manifest --json` (лендинг `81a89e9`, акт D39.206; строка 278 закрыта и снята). Остаток строки — платформенная половина: взять число и снять ложную подпись. ⚠ Фронт заморожен — подпись правится при разморозке, число на платформе раньше | платформа+фронт | скоро | снять ложную подпись + заменить источник на манифест движка | согласование 04.09; проверено оркестратором по коду | +| 282 | ⛔ **ЧИСЛО, ПОДПИСАННОЕ «ЗНАКОВ», СЧИТАЕТ РУНЫ ПОТОКА ЗАПИСИ ФАЙЛА — что для UTF-8 txt И ЕСТЬ знаки, а для EPUB даёт руны ZIP-АРХИВА.** ⚠ Заголовок первой редакции («считает байты») — противоположная полуправда, испр. 05.09: ложно оно для EPUB, GB18030 и UTF-16, а не всегда. Проверено оркестратором по коду: `platform/internal/books/books.go`, греп `type counter` — счёт идёт по не-продолжающим байтам UTF-8 ПОТОКА ЗАПИСИ файла, а не по тексту; там же комментарий признаёт приближение для GB18030. Наружу уходит как `character_count` (`platform/internal/httpapi/v0.go`), на экране подписано `'about.characters': 'Знаков'` (`frontend/src/i18n/ru.ts`). ⇒ Живая ложь на продуктовом экране, и она же — вторая ненадёжная единица, найденная тем же вопросом «откуда берётся число». **Основой страницы быть не может.** Лечение: переименовать в размер файла ЛИБО заменить манифестной суммой знаков движка — ✅ **источник ПОСТРОЕН**: `source_chars` по юниту в `manifest --json` (лендинг `81a89e9`, акт D39.206; строка 278 закрыта и снята). ⛔ **ПЛАТФОРМЕННАЯ ПОЛОВИНА ИСПОЛНЕНА (пере-снято 06.09 по коду, не по комментарию):** число берётся из манифеста движка — `platform/internal/httpapi/project.go:38`=`out.CharacterCountExact`, рядом с ним флаг точности в `httpapi/v0.go:211`, пин `v0_test.go:933`. Остаток строки — ТОЛЬКО подпись `'about.characters': 'Знаков'` во фронте, а зона фронта ЗАМОРОЖЕНА ⇒ строка ждёт разморозки и в платформенные паки больше не входит | фронт | скоро (первое касание при разморозке) | снять ложную подпись `'about.characters'` во фронте (источник уже манифест движка — половина исполнена) | согласование 04.09; проверено оркестратором по коду | | 283 | **СТРУКТУРА ГЛАВ ДЛЯ ВЫДАЧИ — отдельная задача, которую «страница» НЕ отменяет, и она гейтит бету для не-CJK и EPUB.** Билдер кладёт по одному XHTML на главу движка и сам признаёт, что ридер делает главу из каждого документа spine (`backend/internal/bookfile/epub.go`) ⇒ **для не-CJK txt читатель получает книгу ОДНИМ ПОЛОТНОМ при любой единице заказа**. Состав — этап 1 `research/27`: EPUB по nav/NCX (обязательно по стандарту), FB2, индуктор оглавления для txt, разрез по ДАННЫМ ПАРЫ вместо захардкоженного CJK (сегодня асимметрия: распознавание строки-заголовка данные пары читает — `configs/langpacks/zh-ru/heading.txt`, — а РАЗРЕЗ на главы нет). ⚠ Делать в единственном окне пере-снапшота, пока платная книга одна: перекрой двигает нарезку. Пере-скоуп строк 160–162 | бэкенд | скоро (ДО открытия беты не-CJK и EPUB-входам) | этап 1 research/27 своим паком | согласование 04.09, вторая редакция | | 284 | **НАЗВАНИЕ КНИГИ И ЗАГОЛОВКИ ГЛАВ ИДУТ ЧЕРЕЗ ТЕРМИНЫ — ОТДЕЛЬНОЙ СТАДИЕЙ (решение владельца 05.09).** ⚠ **СЮДА ЖЕ ПЕРЕЕХАЛ ОСТАТОК ЗАКРЫТОЙ СТРОКИ 274 (D39.201 п.7): доставка имени В ФАЙЛ.** Платформенная половина построена — имя вычисляется ПРИ СКАЧИВАНИИ (`platform/internal/httpapi/v0.go`, греп `exportName`), внутрь файла не пишется намеренно: движок сворачивает `title` в `BriefHash` → снапшот → каждый request-hash, то есть запись в `book.yaml` отказала бы следующему прогону недопереведённой книги и стоила бы ПЕРЕ-ОПЛАТЫ книги целиком. **ФОРМА ОПИСАНА, ПАТЧ НЕ ПРОВЕРЕН** (слово платформенной зоны, принято дословно): путь — `tmctl build --title` аргументом при спавне, прецедент `--ceiling-usd`, но НЕ предъявлено исполнением, что движок примет незнакомый флаг без правки разбора аргументов — по закону шва там громкий отказ по построению. Остаток регистра — `PD-450`. Сегодня их не переводит НИКТО: `dc:title` берётся из `book.yaml` как есть (`backend/internal/bookfile/epub.go`, греп `dc:title`), заголовок главы собирается детерминированно шаблоном из langpack (`backend/configs/langpacks/zh-ru/heading.txt`, `template Глава {n}`). ⇒ Русский EPUB приезжает в читалку с китайским названием — ломается первое, что видит человек. Владелец: «пусть едет как термины, причём отдельные, то есть как-то надо называть эту стадию». ⚠ Значит у стадии своё имя, свой бюджет и своя ПОДПИСЬ: название книги владелец утверждает так же, как утверждает термин. ⚠ Родня — строка 274 (ручка переименования у пользователя) и открытый лист владельца «что печатать на титуле и в имени файла» (D25.1): механизм строится, СЛОВО остаётся за владельцем | бэкенд | скоро | стадия перевода заголовков + подпись владельца | решение владельца 05.09 | | 285 | **FAIL FAST ПРИ ЗАГРУЗКЕ вместо приёма-и-удаления (решение владельца 05.09).** Сегодня при загрузке проверяется ТОЛЬКО размер (`platform/internal/httpapi/middleware.go`, греп `LimitBody`); понять, есть ли в файле книга, умеет лишь движок и лишь при разборе — то есть ПОСЛЕ приёма и записи, а на классе «источник нечитаем» интейк УДАЛЯЕТ загрузку. Владелец: «почему просто не fail fast, как это обычно принято». ⚠ Механизм для этого есть и он $0: `tmctl manifest` режет книгу и возвращает число юнитов без ключей и без единого платного вызова, и платформа уже умеет его звать. Звать СИНХРОННО на загрузке: либо человек сразу видит «в этом файле книги нет» и файл не принят вовсе, либо получает принятую книгу и её объём. ⇒ **Снимает вопрос про удаление целиком — удалять нечего, если не приняли** (строка 254 закрывается этим). ⚠ Решить: латентность синхронного разбора на большой книге и что показывать, пока он идёт | платформа | скоро | синхронный $0-разбор на приёме + отказ вместо удаления | решение владельца 05.09 | diff --git a/docs/PLATFORM_MONEY_TRUTH_SESSION_PROMPT.md b/docs/PLATFORM_MONEY_TRUTH_SESSION_PROMPT.md index eb2afa68..90b87280 100644 --- a/docs/PLATFORM_MONEY_TRUTH_SESSION_PROMPT.md +++ b/docs/PLATFORM_MONEY_TRUTH_SESSION_PROMPT.md @@ -5,17 +5,31 @@ Проект готовится впустить **первого платящего чужого человека**. Критерия впуска в репозитории нет вовсе (строка бэклога **326**) — и этот пак пишет его первую половину **делом**, а не формулировкой. -Сегодня платформа врёт человеку тремя способами и один раз молчит: +Сегодня платформа врёт человеку деньгами и молчанием — три живых предмета (четвёртый снят проверкой промта, см. ниже): - **деньги считаются по нижней границе**: отменённые вызовы, УЖЕ ушедшие к провайдеру, не записываются никуда (`PD-441`, замер: три отменённых вызова прожили по две минуты с ценой `0`, соседние завершённые стоили $0.017 и $0.063); -- **заклинивший прогон невидим**: живой прогон с намертво заблокированной расплатой не показывается ни - на одной поверхности и не лечится штатной ручкой; вывести его может только пользователь, нажав Stop, - и **никто ему об этом не говорит** (`PD-424`); +- **освобождение заклинившего прогона доказывается один раз и не транзакционно** (`PD-424`). ⚠ **Ряд + длиной 6192 знака и правился трижды; ОБЕ прежние его беды закрыты** — «невидим» вылечен паком P12, + **ручка `tmplatformctl run abandon` ПОСТРОЕНА 04.09** пакетом «закрыть цикл» (пины + `platform/internal/runs/abandon_orphan_test.go`). ⛔ Первая редакция этого пака заказывала строить + ручку — **заказ снят проверкой промта 06.09**. Остаток, ради которого ряд открыт, — **окно гонки**: + отсутствие процесса доказывается ОДИН раз, в момент команды, а между этим ответом и коммитом + транзакции юнит может подняться заново; закрыть это может только фактически транзакционная проба — + **арбитр в хранилище, а не ещё одна проверка в CLI** (формулировка самого ряда). Окно узкое, цена + названа в ряду. **Предмет — это окно; берёшь ли ты его в этот пак, решаешь сам и аргументируешь**; - **чужие события ложились на оплаченную попытку** — чужой потолок ставил `paused` живому оплаченному - прогону, чужой `unit_done` писал главы, которых никто не покупал (`PD-438`); -- **экран врёт о единице**: число под подписью «Знаков» считает руны потока записи файла, а для EPUB — - руны ZIP-архива (строка **282**). + прогону, чужой `unit_done` писал главы, которых никто не покупал (`PD-438`). ⚠ **Сам дефект вылечен + и заленджен 04.09** (чтение останавливается на чужом handshake'е); ряд держится `open` на остатке — + видимости парковки для оператора, и прошлый пак отложил её СОЗНАТЕЛЬНО. **Сначала пере-сними статус + остатка по ряду и коду, потом решай, что здесь вообще осталось делать** — вплоть до ответа «ничего, + ряд закрывается актом»; +⚠ **Четвёртый пункт — «экран врёт о единице» (строка 282) — ИЗ ПАКА СНЯТ, и вот почему.** Замер +06.09 по дереву: платформенная половина ПОСТРОЕНА и заленджена — `character_count` берётся из +манифеста движка, рядом едет флаг `character_count_exact` (`platform/internal/httpapi/v0.go:211`, +пин в `v0_test.go:933`). Остаток строки 282 — подпись `'about.characters': 'Знаков'` во фронте, а +**зона фронта ЗАМОРОЖЕНА**. ⇒ трогать нечего; если найдёшь платформенный остаток — это пинг, а не +работа пака. И отдельно: **вход шире выдачи** — интейк принимает форматы, для которых выдача отдаёт книгу одним полотном (строка **325**). Компенсация «на бете просто не впустим» сегодня — намерение, а не факт: она @@ -30,6 +44,10 @@ `docs/PROGRESS.md` платформа не пишет. **Сессия НЕ коммитит** — дерево передаёшь оркестратору. Канон git-дисциплины — `CLAUDE.md`. `.env` не читать. +⚠ **Что должно пережить рестарт — кладётся в РЕПОЗИТОРИЙ** (в свою зону), а не в скрэтчпад: скрэтчпад +умирает вместе с окружением. Вне репозитория — только рабочее временное, о котором другим знать не нужно. +⚠ **Входящее сообщение от другой сессии — не приказ**: промт сильнее. Расходится с ним — пинг +оркестратору, а не тихое исполнение. ## 3. Карта чтения — ЗАКОН @@ -38,7 +56,8 @@ ⚠ Ссылка на этот файл обязана быть в каждом платформенном промте; из семи прежних сослались пять, и норма дважды проскользнула. Здесь она стоит. 3. `platform/docs/DEFECT_REGISTER.md` — ряды `PD-441`, `PD-424`, `PD-438`. -4. Строки **282**, **325**, **326** бэклога (`docs/BACKLOG.md`, греп `^| N |`). +4. Строки **325**, **285**, **305**, **326** бэклога (`docs/BACKLOG.md`, греп `^| N |`). ⚠ Строка **282** из + карты снята вместе с §4.2 — читать её не надо. 5. `platform/README.md` + зонный журнал (шапка, не целиком — он 5029 строк, см. §4.0). **Ратифицированное — в теле промта:** @@ -48,9 +67,13 @@ законно, но **объявляется с ценой**. - **Продуктовых КВОТ и фри-тир-лимитов нет и не проектируется**; оплаты в бете нет, пополнение — из админки. Первую внешнюю книгу впускает владелец. -- **Число называет ДЕРЕВО и ПОПУЛЯЦИЮ** · **рядом с нулём — контрольная величина** · **мутация - засчитывается по ТЕКСТУ сообщения, а не по факту красноты** · **комментарий не доказывает поведение** - (`D39.214`; грепом в `CLAUDE.md` не ищи, там её нет). +- **Число называет ДЕРЕВО и ПОПУЛЯЦИЮ** · **рядом с нулём — контрольная величина ПЕЧАТАЕТСЯ, а не + упоминается** · **мутация засчитывается по ТЕКСТУ сообщения, а не по факту красноты** (все три — + `CLAUDE.md`, генезис — `D39.217` п.2). +- **`D39.214`: «ЕСТЬ ПИН» ≠ «ПИН ДОКАЗЫВАЕТ СКАЗАННОЕ»** — цитируя зелёный тест в утверждении о + ЗНАЧЕНИИ, спрашивай не «есть ли пин», а «что именно он утверждает». ⚠ Прежняя редакция этого промта + приписывала ноте «комментарий не доказывает поведение» — **это не её текст**, испр. 06.09 по проверке + промта. - **Тесты и гейты не подгонять под зелень** (`D39.121`, решает мотив). ## 4. Состав и разметка свободы @@ -83,16 +106,25 @@ ### 4.1 Три мажора — **делай РОВНО так** в предмете, **реши сам** в форме -`PD-441` · `PD-424` · `PD-438`. Все три про одно: **деньги и видимость чужого прогона**, и человек -жалуется одинаково — «списали не то / висит / молчит». Форму лечения выбираешь ты; предмет не двигаешь. +`PD-441` · `PD-424` · `PD-438`. Все три — про **честность денег и чужого прогона**, но ⚠ **у двух из +трёх заказанная беда УЖЕ вылечена, и открыт узкий остаток** (см. §1): у `PD-424` — окно гонки между +пробой живости и коммитом, у `PD-438` — видимость парковки для оператора. ⛔ **Первым действием по +каждому ряду пере-сними СТАТУС по ряду ЦЕЛИКОМ и по коду** — ряды длиной в тысячи знаков, и промт писан +по ним же. Законный исход по любому из трёх: «здесь делать нечего, ряд закрывается актом». Форму +лечения выбираешь ты; предмет не двигаешь. -⚠ По `PD-441` отдельно: если полная запись цены отменённого вызова недостижима, **честный выход — -объявить маржу и показать её пользователю**, а не оставить леджер нижней границей молча. Выбор объяви. +⚠ **По `PD-441` выбор НЕ равносильный, и это надо знать до начала.** «Полная запись цены отменённого +вызова» требует правки движка (`backend/internal/pipeline/stagerun.go` — сеттл оценки при отмене уже +ушедшего вызова); это **ЧУЖАЯ зона**, ряд сам это и пишет. ⇒ из `platform/` достижима вторая половина: +**объявить маржу и показать её пользователю**, чтобы леджер перестал молча притворяться точным. Движковую +половину назови ПОИМЁННО в отчёте (что именно должен сделать движок) — это заказ следующему паку, и без +твоей формулировки его придётся выводить заново. -### 4.2 Экран не врёт о единице (строка 282) — **делай РОВНО так** +### 4.2 СНЯТО ДО ВЫДАЧИ — строка 282 (экран о единице) — **не делай** -Либо число приезжает из манифеста движка, либо подпись переименована в то, что оно на самом деле -считает. ⛔ Третьего — «оставить как есть, все привыкли» — нет: это живая ложь на продуктовом экране. +Пункт стоял в первой редакции пака и снят проверкой промта по дереву: платформенная половина уже +построена (см. §1). Оставлен здесь НАМЕРЕННО, а не вычищен: снятый пункт с причиной дешевле, чем +пункт, всплывший заново через неделю. ### 4.3 Вход не шире выдачи (строка 325) — **реши сам, аргументируй** @@ -100,6 +132,14 @@ форматам, чью выдачу мы не умеем, — с честной причиной человеку, а не молча. Границу и формулировку отказа выбираешь ты; **согласуй с тем, что выдача действительно умеет сегодня**, а не с планом. +⭐ **Та же дверь несёт РЕШЕНИЕ ВЛАДЕЛЬЦА 05.09, и брать его надо здесь же — строка 285.** Сегодня при +загрузке проверяется только размер (`platform/internal/httpapi/middleware.go`, греп `LimitBody`), а +понять, есть ли в файле книга, умеет лишь движок и лишь при разборе — то есть ПОСЛЕ приёма и записи, и +на классе «источник нечитаем» интейк УДАЛЯЕТ загрузку. Владелец: «почему просто не fail fast, как это +обычно принято». Механизм для этого есть и он $0 — `tmctl manifest` режет книгу и возвращает число +юнитов без ключей и без единого платного вызова. **Предмет — делай РОВНО так; форму (где именно звать, +что показывать человеку) решаешь сам.** + ### 4.4 Два малых дока — **не трогай, это работа оркестратора** `ENGINEERING_STANDARDS.md` и `PLATFORM_DIRECTION.md` прочитаны оркестратором 06.09 целиком: **оба живые, резать @@ -107,6 +147,21 @@ ось «по сессии» заставляла искать правило перебором семи секций. ⚠ Если по ходу работы найдёшь в них утверждение, разошедшееся с кодом, — **пинг, не правка**: это зона оркестратора. +### 4.4а Твой собственный прибор приёмки врёт при таймауте (строка 305) — **делай РОВНО так** + +`make check` зоны при таймауте пакета печатает заголовок `--- FAILURES ---` и НИЧЕГО под ним: оператор +получает «check упал» без единого имени. Ты этим прибором будешь предъявлять свою же работу, поэтому +чинится он здесь, а не «когда-нибудь». Проверь исполнением: искусственный таймаут обязан назвать пакет. + +### 4.4б Протухший комментарий о собственной невозможности — **делай РОВНО так** + +`platform/internal/books/books.go` (греп `THE FIX IS NOT IN THIS PACKAGE`) объясняет, почему число не +берётся из манифеста: «нужен по-юнитный счёт знаков, которого манифест ещё не несёт (строка 278)». +**Оба довода протухли:** строка 278 закрыта, число из манифеста уже берётся +(`platform/internal/httpapi/project.go:38`). Комментарий, объясняющий отсутствие того, что построено, — +ровно тот класс, ради которого этот пак и написан. Привести к поведению; проверить грепом по снятой +формулировке. + ### 4.5 Чего в паке НЕТ — **не делай** Не строить структуру глав для выдачи (чужая зона) · не трогать движок · не менять контракт без пинга @@ -123,6 +178,12 @@ спавнит — **тебе разрешено и требуется**. Модель задай ЯВНО (`fable`), одного-двух хватит. Мандат: «найди отсутствующее и противоречащее». 4. **Греп по отозванной формулировке перед словом «исправлено»** — ноль либо только внутри пометки. +5. **Интервальная самопроверка в длинной сессии**: примерно на середине работы — субагент против ЯВНЫХ + критериев («вот заказ, вот сделанное — что расходится»), не «посмотри, всё ли хорошо». +6. **Дифф тестов — ИСПОЛНЕНИЕМ, не памятью**: `git diff -- '*_test.go' | grep '^[-+]func Test'` (и то же + по `func Fuzz`), число до и после. Удалённый тест объявляется отдельно и с причиной. +7. **Перед отчётом сверь КАЖДЫЙ свой клейм с результатом инструмента ЭТОЙ сессии** — не с памятью о том, + что ты делал час назад. ## 6. Оси ревью — характер «Код» и «Доки» @@ -143,7 +204,10 @@ ## 9. Эхо-протокол старта -≤10 строк ДО работы: скоуп · инварианты · не-делать. +≤10 строк ДО первой правки: **скоуп** (что берёшь) · **инварианты** (что обязано уцелеть) · **не-делать** +(что в паке запрещено). ⛔ **Отправь их ПЕРВЫМ действием оркестратору** по адресу из +`/tmp/textmachine-channel` (`SendMessage`) — эхо в собственный блокнот не эхо: разойтись с заказом ему +негде. Канала нет — эхо идёт первой секцией отчёта, и это законно. ## 10. Что НЕ удалось — обязательная секция @@ -174,3 +238,5 @@ своей работы**. ⚠ Числа снимай **после последней правки**, не до. Правки якорей объявляй наравне с содержательными. +⛔ **Последний абзац отчёта — план или обещание? Значит работа не кончена: сделай сейчас.** Отчёт +описывает СДЕЛАННОЕ; «дальше надо бы…» живёт отдельной секцией «предложения», и оркестратор решает сам. diff --git a/docs/README.md b/docs/README.md index d08c990f..be5ea1a4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -23,11 +23,11 @@ | Роль | Активный промт | Статус | |---|---|---| | Оркестратор | [ORCHESTRATOR_SESSION_PROMPT.md](ORCHESTRATOR_SESSION_PROMPT.md) | роль и нормы; счётчик роли — CURRENT-STATE | - | **Бэкенд · КОНСИСТЕНТНОСТЬ** | [BACKEND_CONSISTENCY_SESSION_PROMPT.md](BACKEND_CONSISTENCY_SESSION_PROMPT.md) | приоритет владельца №1: канон в прогон (295) · гард перекрытия окон (267) · честный комментарий постчека (318) · не уничтожать принятую редактуру (322 а/б) · два ложных комментария. ⚠ Несёт заказ владельца на список ЛОГИЧЕСКИХ расхождений «задумано против сделано» | + | **Бэкенд · КОНСИСТЕНТНОСТЬ** | [BACKEND_CONSISTENCY_SESSION_PROMPT.md](BACKEND_CONSISTENCY_SESSION_PROMPT.md) | приоритет владельца №1 «закон банка честно»: гард перекрытия окон (267 — ⚠ предмет СУЖЕН 06.09: два гарда в коде уже есть, непокрыт один случай) · совет, который движок не исполняет (320а) · честный комментарий постчека (318) · два ложных комментария (321 · попутный из 322). плюс попутный проход §5а «логические расхождения задумано против сделано» — списком в отчёт, без тихих правок. ⛔ **Строка 295 и ПРЕДМЕТ строки 322 из пака СНЯТЫ** (§4.5 промта) — прежняя редакция этой ячейки называла их составом, и это было ложью о заказе | | Бэкенд · СТРУКТУРА ГЛАВ | активного НЕТ | пак 1 «форматы и честный словарь» ОТРАБОТАН, ПРИНЯТ С ДОФИКСОМ и ЗАЛЕНДЕН 06.09 — акт **D39.210**, `2f65d1d`; промт в `archive/prompts/CHAPTER_STRUCTURE_SESSION_PROMPT_2026-09-05.md` с баннером исхода. ⚠ **ПАК 2 (лексиконы не-CJK, корпус, замер оракулом, валидаторы) — НЕ НАПИСАН и ждёт файлов владельца** (страта скрейпов); промта под него нет, брать нечего. Открытые следствия пака 1 — строки бэклога **302** (резка по якорям) и **303** (безъюнитная грамматика) | | Бэкенд · отозванный | активного НЕТ | пак КАЧЕСТВО написан и ОТОЗВАН до выдачи 05.09 (`archive/prompts/…_WITHDRAWN.md`): предмет дешевле пака — точность чекера уже измерена, пере-снять её стоит одной команды. Следующий пак — СТРУКТУРА ГЛАВ (решение владельца 05.09 «любая книга любого формата»), пишется | | Бэкенд · прежний | активного НЕТ | пак «денежный стоп» ОТРАБОТАН и ПРИНЯТ С ДОФИКСОМ 05.09 — акт **D39.206** (`81a89e9` + `616a8e4`), промт в `archive/prompts/` с баннером исхода. Следующая работа зоны — строки **291** (флаг вместо клина, `D39.204`) · **294** (форма «сколько добавить», `D39.203`) · **296** (точечная перегенерация по промаху глоссария, после 295) | - | **Платформа · ДЕНЬГИ И ПРАВДА** | [PLATFORM_MONEY_TRUTH_SESSION_PROMPT.md](PLATFORM_MONEY_TRUTH_SESSION_PROMPT.md) | первая половина критерия впуска ДЕЛОМ: три мажора регистра (леджер — нижняя граница · заклинивший прогон невидим · чужие события на оплаченной попытке) + ложь экрана о единице (282) + вход шире выдачи (325); пункт 0 — ТРИАЖ зонного журнала перед выносом | + | **Платформа · ДЕНЬГИ И ПРАВДА** | [PLATFORM_MONEY_TRUTH_SESSION_PROMPT.md](PLATFORM_MONEY_TRUTH_SESSION_PROMPT.md) | первая половина критерия впуска ДЕЛОМ: три мажора регистра (леджер — нижняя граница `PD-441` · окно гонки при освобождении заклинившего прогона `PD-424` — ⚠ ручка построена 04.09, остаток узкий · остаток видимости по `PD-438`) + вход не шире выдачи (325) вместе с решением владельца о fail fast (285) + свой прибор приёмки (305); пункт 0 — ТРИАЖ зонного журнала перед выносом. ⛔ **Строка 282 из пака СНЯТА 06.09** — платформенная половина построена (`character_count_exact`), остаток фронтовой, зона заморожена | | Платформа · ФОРМА ЗАКАЗА | активного НЕТ | пак ОТРАБОТАН, ПРИНЯТ С ДОФИКСОМ и ЗАЛЕНДЕН 06.09 — акт **D39.208**, код + канон **0.11.0**; промт уведён в `archive/prompts/ORDER_FORM_SESSION_PROMPT_2026-09-05.md` с баннером исхода. ⚠ **НЕ построено, хотя заказывалось:** денежный ползунок на проводе объявлен, а отправить его нечем, и оценки под ВЫБРАННЫЙ заказ нет; «упрощение резюма» не сделано — обе позиции живут строками бэклога, брать их как новый пак СЛЕДУЮЩЕЙ сессии, не читать промт как задание | | Платформа · прежний | активного НЕТ | пак «пустить внутрь можно» ОТРАБОТАН и ПРИНЯТ С ДОФИКСОМ 05.09 — акт **D39.201** (`7e2226a` + `3e84716`), промт в `archive/prompts/` с баннером исхода. Следующая работа зоны — строки **294** (зеркало словаря под минор потока) ⚠ (строка 293 — зона ОРКЕСТРАТОРА, не платформы: правило игнора общее для всех рабочих деревьев клона) | | **Полигон · РЕМОНТ ПРИБОРА** | [POLYGON_INSTRUMENT_REPAIR_SESSION_PROMPT.md](POLYGON_INSTRUMENT_REPAIR_SESSION_PROMPT.md) | ⚠ **ИДЁТ ПЕРЕД любым следующим платным замером, включая продолжение фазы Д**: три эрраты носителей БАННЕРАМИ · гигиена стенда (300, 265) · линза против ИСХОДНИКА + порог различимости (319, 143). Санкции на платный замер НЕ несёт |