40 KiB
Пак бэкенда: «ДВИЖОК УЖЕ ЗНАЕТ — ДОВЕЗИ ДО ЧИТАТЕЛЯ»
1. Какая проблема и что решит твой результат
Движок вычисляет правду и пишет её себе в лог, а тот, кто по этой правде принимает решение — владелец на экране подписи банка и оператор, читающий траты, — смотрит в другое место. Это один класс, а не три случая, и он сегодня стоит дороже всего остального в очереди.
- Полнота банка.
internal/pipeline/terminologist.go:99-103считаетConsolidated·Declined·Unanswered·BatchesDropped·ClassifyBatchesDropped;:582предупреждает — «this bank is PARTIALLY consolidated — a budget cut a pass». ВLog. А носитель, который читает платформа и с которого строится экран подписи, —internal/pipeline/bankexport.go(BankExport:bank_version,book_id,total,signed,as_of,run_id,terms,proposed) — полей полноты не несёт вовсе. Наблюдение платформы за живым потоком 04.09 (H10/H11, строка 199): консолидировано 38, не спрошено ни разу 47, срезано бюджетом 5. Владелец подписал бы такой банк как полный. - Деньги.
internal/pipeline/waverun.go:218складывает в итог волны толькоCostUSDрендер-паса;ClassifyCostUSD(terminologist.go:145) вTOTAL (this run)не попадает. А разложение «за что заплачено» относит классификатор вsuperseded, потому что обе банк-роли адресуются ОДНИМ именем стадии и делят позицию{глава, чанк, стадия}. Замер прогона 08.09 по строкам леджера: терминологическая фаза стоила $0.013608 — классификатор$0.009013плюс два рендер-батча$0.002775и$0.001820; в итог волны входит только рендерная половина, а разложение печатает$0.004595 (2)— ровно два последних. Оператор читает о своих деньгах два числа, не сходящиеся с сырым леджером — ровно тогда, когда решает, продолжать ли платить.
Что покупает твой результат. (1) Владелец видит на подписи, что банк неполон, ДО того как подписал. (2) Числа отчёта сходятся с леджером. (3) Ни один байт снапшота, хеша запроса, ключа манифеста и версии встроенных данных не двигается — пак $0 и ничего не перекупает.
2. Зона и git
Зона записи — backend/ плюс свой подзаголовок в секции «Бэкенд» docs/PROGRESS.md. Чужие зоны
(platform/, frontend/, eval/, books/) не трогаешь ни строкой; docs/ кроме своей секции — тоже.
Ты НЕ коммитишь: дерево готовишь и передаёшь оркестратору (канон — CLAUDE.md
§«Git-координация мультисессий»). Никаких git add -A, reset --hard, переписывания истории.
⚠ Заведи подзаголовок #### Пак «движок уже знает» внутри секции «Бэкенд» и пиши только под ним: файл
коммичу я, и чужой текст уедет под моим сообщением. .env не читать никогда.
3. Карта чтения — ЗАКОН, дальше только по её ссылкам
docs/BACKLOG.md— строки 253 (обе половины) · 357 · 358 · 355 · 312. Греп^| 253 |. Строка — носитель заказа; расхождение строки с этим промтом — пинг, не интерпретация.docs/architecture/18-bank-ontology.md— нормативная страница банковых проекций: три правила дисциплины проекции и два класса дефектов. Ты добавляешь поля в проекцию банка ⇒ читаешь ДО работы. ⚠ Там же эррата 07.09 про класс A, заведённый сознательно.docs/architecture/15-money-path.md— денежный путь: что чем считается и где леджер есть нижняя граница.docs/architecture/12-go-style-notes.md— норматив формы («least mechanism», размер не критерий сплита, интерфейс объявляет потребитель, код английский).backend/cmd/tmmutate/main.go— шапка целиком (контракт мутационного инструмента) плюсbackend/Makefile, целиbatteryиmutations.
Ратифицированное, нужное по существу, вложено сюда и похода в журнал решений НЕ требует:
D39.226— акт предыдущего пака этой зоны: что уже построено (узкий фильтр банка, пометкаNOT ASKEDв текстовом сайдкаре, каталог мутаций 259/48).D39.225п.10 — ⛔ правило остановки, применённое к секции предложений сайдкара: четвёртый круг по ней НЕ открывается (строка 353 — гейт «появится читатель»).D39.104п.1 — банк на проводе есть ЗАКОН для всех ролей независимо от статуса строки. Отсюда цена неполного банка: владелец подписывает то, что станет законом для всей книги.D39.183— запрет править тесты «чтобы прошло» про МОТИВ; правка от ЗАКАЗАННОЙ смены поведения — обслуживание, но объявляется в отчёте.D39.208п.5 — фикстура, где две различные величины совпали, делает весь их класс невидимым.D39.216— где нынешняя форма не выдерживает заказ, её РАЗВЯЗЫВАЮТ или переписывают, а не обкладывают заплатой; «дешевле подпереть» само по себе доводом НЕ является. Отступление законно, но объявляется с ценой: почему заплата дешевле развязки и что именно она откладывает. ⚠ Второй носитель одного знания не заводится: если правка требует держать две копии в согласии — развязка назрела. Это прямо про §4.1, где форму полей выбираешь ты.- ⛔ Правило, купленное дважды подряд: пин на УСЛОВНОЕ сообщение обязан иметь фикстуру, где оно ОБЯЗАНО прозвучать. Тест, утверждающий только молчание, вакуумен ровно там, где сообщение ложно.
4. Состав и разметка свободы
4.1 Полнота банка доезжает до того, кто подписывает — состав РОВНО так, форма полей — реши сам
Три поверхности подписи, и правда есть только в логе:
- машинный сайдкар
BankExport(internal/pipeline/bankexport.go) — полей полноты нет; его читает платформа, и с него строится экран; - текстовый сайдкар стоп-таблицы (
internal/pipeline/mining.go) — несёт пометкуNOT ASKED(…)(1 хит), и это единственное место, где она есть; - экран стопа на stdout (
cmd/tmctl/render.go,renderSignatureStop) — про пропущенного кандидата не знает: хитовNOT ASKEDтам 0, при том что тот же рендерер УМЕЕТ печатать пер-строчные пометки (контроль —invented).
Заказ: довези до ОБОИХ читателей то, что движок уже посчитал. Что именно нести — Consolidated,
Declined, Unanswered, BatchesDropped, ClassifyBatchesDropped — и в какой форме (плоские поля,
вложенный объект, одно суммарное «полон/неполон» плюс детали) решаешь ты; аргументируй в отчёте.
⛔ Что не обсуждается: (а) поля берутся из УЖЕ вычисленного — ПРОИЗВОДНАЯ от посчитанного (например
бит «полон») законна и приветствуется, запрещён ПЕРЕСЧЁТ полноты вторым механизмом;
(б) версию формата сайдкара (tm-bank-v1) НЕ бампать — платформа разбирает аллоулистом и новое поле
игнорирует, это ПИНГ ей, а не поломка; (в) на stdout-экране оператор узнаёт о пропущенных кандидатах. ⛔ Но НЕ обязательно пер-строчной
пометкой, и вот почему — это ловушка вырожденной фикстуры. cmd/tmctl/render.go: bankStopStdoutCap = 20, строки сортируются reviewRank, а у не-спрошенной строки Dst пуст ⇒ ранг 1000 ⇒ она уходит
ПОСЛЕДНЕЙ и при ≥20 строках проваливается под кап. Фикстура на ≤20 строк будет зелёной, а на боевом банке
оператор не увидит ничего. ⇒ задано СВОЙСТВО (оператор со стдаута узнаёт, сколько кандидатов не
спрашивали и почему), форму выбираешь ты — сводная строка над таблицей или пер-строчная пометка плюс
работа с капом; и фикстура обязана быть ШИРЕ капа;
(г) секцию предложений сайдкара не трогать — по ней применено правило остановки (D39.225 п.10, строка 353).
⛔ «ОБА ЧИТАТЕЛЯ» = машинный сайдкар и stdout-экран. Текстовый сайдкар стоп-таблицы уже несёт NOT ASKED и счётчиков полноты от тебя НЕ требует — трогать его в этом пункте не надо.
⛔⛔ ПОСЧИТАННОЕ ДВИЖКОМ САМО НЕТОЧНО — не довози его буквально, иначе построишь ложную тревогу. Три факта, которые смешивать нельзя:
BatchesDropped(рендер-пас срезан) — вот это и есть неполный БАНК: термины не консолидированы.ClassifyBatchesDropped(классификатор срезан) — банк ПОЛОН, не уточнены ТИПЫ. Другой факт.Unanswered— по собственному тексту предупреждения «counts them together with terms the role saw and did not answer», то есть СЛИВАЕТ «не предложено бюджетом» и «предложено, роль не ответила». ⛔ И предупреждениеterminologist.goкричит «PARTIALLY consolidated» приBatchesDropped > 0 **||** ClassifyBatchesDropped > 0. На прогоне 08.09 былоbatches_dropped=0,classify_batches_dropped=1,consolidated=29,unanswered=0— то есть рендер-пас ЦЕЛ, а движок всё равно говорит «неполон». ⇒ вывод «полон/неполон» изdropped > 0даёт ЛОЖНУЮ ТРЕВОГУ ровно на этом прогоне — то, что пункт запрещает абзацем ниже. Полнота БАНКА выводится из рендер-паса; срез классификатора несётся ОТДЕЛЬНО.
⛔⛔ ГЛАВНАЯ ЛОВУШКА ЭТОГО ПУНКТА, и наивная проекция в неё падает. exportBank зовётся из ПЯТИ мест
(bookrun.go:180 run-start/seeded · bookrun.go:258 run-finished · mining.go:249 auto-continue ·
mining.go:269 signature-stop · status.go:1125 redrive/re-seeded), а r.lastTerminology заполняется
РОВНО в одном (mining.go:170). Плюс mining.go:66: майнинг не сконфигурирован ⇒ терминология не
запускается вовсе. ⇒ на четырёх границах из пяти счётчики нулевые, и «consolidated=0 unanswered=0»
прочтётся как «неполноты нет» там, где её просто НЕ МЕРИЛИ. Это класс D39.202 — прибор, отвечающий на
свой вопрос, — и ровно он куплен строкой 312 из §4.3 («toc_unresolved = 0, потому что целей НОЛЬ»).
Заказ: «не мерено» и «полно» обязаны быть РАЗЛИЧИМЫ на выходе; форма различения твоя. ⚠ Самый простой
путь — граница: поля осмысленны там, где пас ШЁЛ (signature-stop, run-finished), и на run-start/seeded
их быть не должно вовсе (omitempty), иначе «неполон» повиснет на проекции следующего прогона.
⚠ Предъявление — не «поле добавлено», а «читатель видит»: нужны ТРИ фикстуры, и третья — та, которую легче всего забыть: (1) банк неполон ⇒ артефакт и экран это НЕСУТ; (2) банк полон ⇒ молчат, ложной тревоги нет; (3) терминология не работала вовсе (граница run-start или майнинг не сконфигурирован) ⇒ выход говорит «не мерено», а НЕ «полно».
⚠ КЛАСС A ЗАВОДИТСЯ СОЗНАТЕЛЬНО, и это надо ОБЪЯВИТЬ. 18-bank-ontology.md требует у проекции
НАЗВАННОГО читателя. У новых полей его сегодня нет: Consolidated/Unanswered/BatchesDropped дают
0 хитов в platform/internal/ при 183 go-файлах (контроль: слово bank знают 65 из них). Читатель
появится на платформенной стороне и заказан ПИНГОМ. ⇒ назови класс A в отчёте прямо, как это сделал
предыдущий пак зоны (D39.225 п.4), а не оставляй читателя подразумеваемым.
4.2 Два числа о деньгах, не сходящиеся с леджером — делай РОВНО так
- (а) Итог волны занижен.
internal/pipeline/waverun.go:218—res.TotalUSD += r.lastTerminology.CostUSD, аCostUSDпо собственному докстрингу — «what THIS run's RENDER phase paid»; классификаторская стоимость лежит отдельным полемClassifyCostUSD(terminologist.go:145, заполняется на:406) и вTOTAL (this run)не попадает вовсе. Замер прогона 08.09 по строкам леджера: терминологическая фаза стоила$0.013608= классификатор$0.009013+ рендер-батчи$0.002775и$0.001820; в итог входит только рендерная сумма$0.004595, то есть две трети денег фазы до итога не доезжают. ⇒ ВКЛЮЧИТЬ. ⚠ Я рассматривала второй вариант («объявить в строке, что классификатор считается отдельно») и снимаю его: он оставляетTOTALМЕНЬШЕ леджера, а этого пак запрещает ниже и требует §13. Вариант один. ⚠ Числа выше — из отчёта зоны о том прогоне (docs/PROGRESS.md, секция «Бэкенд»), СЫРОГО леджера того прогона в дереве НЕТ (замер:.dbновее 07.09 — 0 при 163 в дереве) ⇒ предъявляй на СВОЕЙ фикстуре, а эти числа бери как описание симптома, не как мишень для воспроизведения. - (б) Разложение относит классификатор в «купил ничего». Обе банк-роли адресуются одним синтетическим
именем стадии (
terminologist.go:65terminologyStageName, проставляется обоим), а разложение ключуетсяpos{Chapter, ChunkIdx, Stage}без роли (internal/pipeline/paidtail.go), и более ранний из двух батчей с одинаковой позицией уезжает вSupersededUSD. Улика живого прогона — три строки леджера (0 0 terminology classifier·0 0 terminology terminologist·0 1 terminology terminologist) при печатном «the book's TERMINOLOGY … (2)», где два — последние. ⇒ развести позиции банк-ролей в ключе разложения. Роли различимы уже сегодня (roleTerminologist/roleClassifier), и колонкаroleв БД ЕСТЬ (store/migrate.go) — миграция не нужна. ⛔⛔ ПРАВИТСЯ ЧИТАТЕЛЬ, НЕ ПИСАТЕЛЬ, и это денежная граница, а не вкус. Соблазн дать классификатору СВОЁ имя стадии есть, и он покупает перепокупку: чекпойнты адресуютсяEnsureJob(bookID, 0, terminologyStageName, snapID), новое имя стадии = новый джоб = старые чекпойнты не матчатся = на резюме классификатор оплачивается заново. ⇒ имя стадии НЕ переименовывать; роль доезжает до разложения отдельным полем. ⛔ Но на ВХОДЕ разложения роли нет:store.CheckpointUsageполяRoleне несёт, и запрос её не выбирает (internal/store/ledger.go, тип и егоSELECT). ⇒ правкаinternal/store/ledger.goРАЗРЕШЕНА и входит в заказ — это не выход за скоуп. ⛔ И она делает ЛОЖНЫМ комментарий, стоящий в самом предмете:paidtail.goпро идентификацию класса по стадии — «equivalent to readingcheckpoints.roleand needing no store change». Правя механизм, снимай и это утверждение: держать два носителя одного знания в согласии — ровно то, что запрещаетD39.216п.3(б). ⛔ ТЕСТ, КОТОРЫЙ ОБЯЗАН ОСТАТЬСЯ ЗЕЛЁНЫМ И НЕ ПОДЛЕЖИТ ПРАВКЕ:TestAReboughtGlossaryBatchIsStillALoss(paidtail_test.go) держит ДВА вызова в ОДНОЙ позиции и требует, чтобы ранний уехал вsuperseded. Это ДРУГОЙ случай — перепокупка ОДНОЙ роли при росте черновикового множества (строка 233), и она остаётся потерей. Твоя правка разводит РАЗНЫЕ роли, а не амнистирует перепокупку одной. Покраснел он — ты сломала класс, а не починила свой. ⚠ И существующие фикстурыpaidtail_test.go— ровно вырожденный классD39.208п.5: коллизионного случая (две РАЗНЫЕ роли в одной позиции) в них нет ни одного, поэтому батарея на этом дефекте зелёная. Фикстуру, где роли РАЗЛИЧНЫ, заводишь ты. ⛔ Обе половины предъявляются СВЕРКОЙ С ЛЕДЖЕРОМ, а не чтением кода: тест берёт числа отчёта и числа леджера на одной фикстуре и утверждает их отношение. ⚠ Отношение назови точно, это два разных утверждения: для (а) — РАВЕНСТВО (итог обязан сойтись с суммой строк), для (б) — что классификаторская строка попала в свой класс, а не вsuperseded. «Леджер есть нижняя граница» — про мир, а не про этот тест: там, где движок не записал вызов, равенства нет и быть не может, и это отдельный класс (PD-441, строка 331), в пак НЕ входящий.
⛔ ГРАНИЦА ЭТОГО ПУНКТА, и она снята чтением ОБЕИХ сторон шва — не выводи её заново и не расширяй.
Это правка ОТЧЁТА, а не денег: платформа биллит НЕ TotalUSD, а committed_usd — сумму по таблице
spend (platform/internal/runs/reconcile.go докстринг attemptSpend), а классификатор ходит тем же
учтённым путём, что и все стадии (runBankAttempt → runAttempt, terminologist.go:783-796), и его
деньги в spend УЖЕ лежат. ⇒ ни один счёт пользователя не двигается, согласия владельца пункт не требует.
Если тебе кажется, что нужно тронуть ЛЕДЖЕР, — это стоп и пинг: там будет двойной счёт, а не починка.
⚠ СОСЕДНЯЯ МИНА — не в этом пункте, но в шаге от него, и я называю её ГРАНИЦЕЙ, а не заказом. Твоя
правка waverun.go порога согласия НЕ касается: база порога — projectBookUSD в
internal/pipeline/rebill.go, другая сумма. ⛔ Но если работа поведёт тебя в ПРОЕКЦИЮ (ProjectedBookUSD,
status, добавка контура к bookUSD) — там порог СОГЛАСИЯ на пере-оплату считается БЕЗ банкового контура
НАМЕРЕННО («THE CONSENT THRESHOLD IS COMPUTED WITHOUT THE CONTOUR, and the two numbers part company HERE»),
и первая версия той правки сложила контур ДО взятия порога и тихо ОСЛАБИЛА денежный гейт; поймала
приёмка. ⇒ пошла в проекцию — это стоп и пинг, а не «заодно».
4.3 Третий член того же класса — реши сам, бери если по пути
Строка 312, остаток Д-3: движок предупреждает о нечитаемом оглавлении в свой Log.Warn, а платформа
читает events.jsonl — то есть та же форма «знает один, смотрит другой». Проверь сам, тот ли это класс;
если да и если дёшево — закрой тем же движением. Если дорого или предмет другой — скажи в отчёте, оставлю
строкой.
4.4 Чего в паке НЕТ — не делай, и это ОБЪЯВЛЕННЫЕ сужения
- Секция предложений сайдкара банка — по ней применено правило остановки (
D39.225п.10), гейт возврата назван строкой 353: появление первого ЧИТАТЕЛЯ секции. Четвёртый круг не открывается. - Платформенные половины строк 253 и 224 — чужая зона. Твоё действие — ПИНГ в отчёте, не правка.
- Всё, что двигает снапшот, хеш запроса, ключ манифеста или версию встроенных данных. В этом паке заказанных смен поведения ДВЕ, и обе — в путях отчётности и артефактов: §4.1 и §4.2.
- ⛔ СТРОКА 360 — ТАЙМАУТ ЧТЕНИЯ, МАСКИРУЮЩИЙСЯ ПОД НЕЧИТАЕМОЕ ТЕЛО. НЕ БЕРЁШЬ, и я называю это прямо,
потому что она ДОРОЖЕ всего, что в этом паке. Замер полигона: 23.8–34.5 % цены редакторской руки;
ошибка чтения выбрасывается в
_, обрезок биллится по оценке и РЕТРАИТСЯ. Почему не здесь: (1) это другой класс — не «движок знает, а читатель не видит», а «движок не знает, что оборвал сам»; (2) её денежная половина требует слова владельца (платит ли пользователь за вызов, который оборвали МЫ) и сцеплена со строкой 331, где тот же предмет закрыт ПРОТИВОПОЛОЖНО — нулём вместо оценки. Идёт отдельным паком. ⚠ Наткнёшься на неё по пути — не чини, отдай наблюдением в отчёт: молчаливая починка здесь смешает два денежных класса в одном лендинге. - Строки 261 · 262 · 331 — члены того же класса «вызов оборвали мы»; уезжают вместе с 360.
- Переписывание
Runner, дроблениеinternal/pipeline— запрещеныD39.224§7. ⚠ «Новый детектор границ» там же — не запрет, а УСЛОВИЕ; к твоим задачам не относится, но силу пункта не путай. - Платные вызовы — ноль, см. §Деньги.
5. Мандат самопроверки ИСПОЛНЕНИЕМ — «перечитал сам» не считается
- Каждая новая гарантия предъявляется МУТАЦИЕЙ, и краснота читается ПО ТЕКСТУ падения: говорит ли он про сломанное тобой. Правый вердикт по неправой причине — дыра, а не поимка.
- Мутации — ТОЛЬКО на копии дерева, и рецепт копии УЖЕ СТОИТ в цели
mutations(backend/Makefile) — своего однострочника не пиши, он станет вторым носителем и разойдётся. Гонишь батарейное подмножество —make mutations. Гонишь одиночную посадку-id, то есть копию делаешь руками, — повтори цель ДОСЛОВНО: распаковка в подкаталог$tmp/backend(а не в корень времянки), исключения--exclude='./.env*'и--exclude=./bin, и два трапа:EXITубирает, аINT TERMубирает И ВЫХОДИТ (exit 130) — иначе прерванный прогон продолжает жить. Рабочее дерево не правится никогда, в том числе «на секунду». - Мутируй и СВОИ новые фикстуры. ⛔ И особая осторожность здесь: у тебя ДВА условных сообщения (неполный банк · пропущенный кандидат). Пин на каждое обязан иметь фикстуру, где оно ОБЯЗАНО прозвучать, и вторую, где оно обязано молчать. Предыдущий пак этой зоны выпустил ТРИ ложных операторских предупреждения подряд, и все три были зелёными именно потому, что утверждалось только молчание.
- Новые записи — в каталог
cmd/tmmutate/mutations.json. Ключи СТРОЧНЫЕ:id,package,why,edits, плюс необязательныйbattery. ⚠package— пакет ПИНА, а не пакет правки: инструмент гоняет один пакет. ⚠batteryставится не всем: сегодня это 48 записей из 259 — гейтовое подмножество; какие из твоих туда входят, решаешь ты и говоришь почему. - BASELINE НА ВХОДЕ (снят оркестратором 08.09):
make battery→ 19ok· 0FAIL· 4 «no test files» · 4 скипа поимённо;make mutations→ 48 записей · 0 unexpected ·anchors swept: 0 of 259. Красное на входе — находка и пинг, а не твоя работа. - Субагенты РАЗРЕШЕНЫ ЯВНО — и на охват, и на адверсариальный проход по ГОТОВОЙ работе. Направление, что здесь уязвимее всего: (1) вторая половина утверждений про условные сообщения; (2) сверка отчёта с леджером — легко заявить и трудно доказать; (3) фикстуры, где «полон» и «неполон» случайно совпали.
- Проверяемый артефакт — таблица мутаций в отчёте:
мутация → где посажена → красный тест → ТЕКСТ падения, и отдельной строкой выжившие, если такие есть.
6. Оси ревью — характер «Код», плюс деньги (ось вправе заменить с аргументом)
Тест утверждает не то, что думает (D39.171): часы как способ синхронизации там, где предмет не время, и
ассерт по подстроке в буфере, куда пишет кто-то ещё. Обе формы дают и ложное красное, и тихо-зелёное —
оно дороже: зелёное, не проверившее ничего, не перечитывает никто. Третья ось твоя: деньги — любое число
выводится из СЫРОГО леджера, и леджер есть нижняя граница, а не оценка.
7. Записка-план ДО работы
До первой правки — короткая записка в отчёт: что берёшь, в каком порядке, что считаешь рискованным. После работы — сверка комплектности против §4 МЕХАНИЧЕСКИ (таблицей), не перечитыванием.
8. Заявление = команда
Каждое число и категорика отчёта — с командой, которой получены. Отрицательный замер печатается ВМЕСТЕ с контрольной величиной, доказывающей, что вопрос задан существующему предмету. Сверх этого, про код:
- перед отчётом сверь каждый клейм с результатом инструмента ЭТОЙ сессии, а не с памятью и не с этим промтом: адреса §4 сняты 08.09 и могли уехать;
- дифф
^func Test— исполнением, ИМЕНАМИ черезcomm, а не разностью счётчиков; - последний абзац отчёта оказался планом или обещанием? сделай это СЕЙЧАС;
- ⛔ править или удалять тест/голден/гейт, чтобы он прошёл, — НЕДОПУСТИМО; исключение — правка от заказанной смены поведения (§4.1, §4.2), и она объявляется отдельным пунктом;
- сессия длинная — поставь себе интервальную самоверификацию субагентом против ЯВНЫХ критериев §13.
9. Эхо-протокол старта
ДО работы — ≤10 строк СВОИМИ словами: скоуп · инварианты, которые не имеешь права сломать · что НЕ делаешь. Дословный пересказ промта подтверждает канал, но не понимание, и ошибку промта повторяет вместе с ним. Отправь эхо оркестратору по адресу из прямого канала (§12); канала нет — эхо идёт первой секцией отчёта, и работа продолжается.
10. Что НЕ удалось — обязательная секция отчёта
Что не вышло, что не проверено, где сомневаешься. Пустая секция при непустой работе — сама по себе находка; «не проверено» и «опровергнуто» — РАЗНЫЕ исходы.
11. Канал вопросов и право сказать «этого делать не надо»
Конфликт промта с кодом или доками — пинг, а не интерпретация: промт мог устареть, и в этом проекте это случается — за прошлые сутки в промтах и трекере нашли шесть ложных утверждений, три из них авторства оркестратора. Считаешь пункт ненужным — скажи с доводом; такие возражения ценнее послушного исполнения.
12. Прямой канал
Механизм — CLAUDE.md §«Связь между сессиями». Впиши СВОЙ блок в /tmp/textmachine-channel первым делом,
чужие блоки не трогай. ⚠ Адрес из файла не доказывает, что сессия жива: сверься с ListAgents. Нужной роли
нет или имя не отвечает ⇒ канала нет, и это НОРМА: не опрашивай сессии подряд — вопрос секцией в отчёт.
13. Критерий завершённости — по нему тебя примут
Работу доводишь до конца САМ; приёмка идёт последней и вторым кругом твоей самопроверки не служит. Готово — это когда:
- у КАЖДОГО пункта §4 есть исход: сделано · не делаю с доводом · пинг;
- круги СОШЛИСЬ: последний проход не дал НОВЫХ находок, прежние закрыты таблицей «находка → что сделано → ЧЕМ ПРЕДЪЯВЛЕНО»;
- каждый класс закрыт с ЗНАМЕНАТЕЛЕМ: «закрыт в N носителях из M», и M посчитан командой, а не на глаз;
- таблица мутаций полная, выжившие названы;
- числа отчёта сверены с СЫРЫМ леджером, а не с логом;
- числа сняты ПОСЛЕ последней правки, а не вспомнены;
- всё живое — в ДЕРЕВЕ, а не в письме;
- сказано явно: «работа завершена, править не планирую». Без этой фразы пак считается идущим.
Деньги
Пак $0. Платных вызовов ноль: всё, что нужно предъявить, предъявляется на ФЕЙК-провайдере и на
собственных фикстурах. ⚠ Сырого леджера прогона 08.09 в дереве НЕТ (замер: файлов .db новее 07.09 —
0 при 163 в дереве, свежайший от 02.09) — числа этого прогона живут только описанием в отчёте зоны, и
воспроизводить их не надо. Если тебе кажется, что задача требует платного прогона, — это стоп и пинг, а не
вызов.
Отчёт
Секция «Бэкенд» в docs/PROGRESS.md, подзаголовок #### Пак «движок уже знает»: исход по каждому
пункту §4 · таблица мутаций · таблица «находка → что сделано → чем предъявлено» · столбец «закрыт в N из M» ·
сверка отчёта с леджером числами · пинги в чужие зоны (платформенные половины 253 и 224) · §10 «что не
удалось» · вопросы оркестратору.