textmachine/docs/archive/prompts/PLATFORM_INTAKE_TRUTH_SESSION_PROMPT.md

44 KiB
Raw Blame History

ОТРАБОТАН И ПРИНЯТ 08.09 — акт D39.229, лендинг ddcbf0c (26 путей, $0). Инструкции ниже НЕ исполняются: пак закрыт. Исход: синхронный вход разреза получил потолок, граница хвоста выведена из кода, рантбук назвал молчание маршрута, шапка зонного журнала и три ряда регистра приведены к правде. Пункт §4.6 закрыт ПО ПОСТРОЕНИЮ (причины уже едут перечислимыми; неисполнена клиентская половина, фронт заморожен). Остаток потолка — строка 364. Адверсариальный проход дал 8 находок, 6 из них дефекты этого же пака на зелёной батарее; норма про НАПРАВЛЕНИЕ самопроверки заландена c3039be.

Пак платформы: «РАЗРЕЗ ПРИЁМА ДО ГОТОВНОСТИ И ПРАВДА О СЕБЕ»

1. Какая проблема и что решит твой результат

Синхронный разрез книги на приёме заландён с формулировкой «ПОСТРОЕН, НО НЕ ГОТОВ»: из одиннадцати major прошлого пака девять легли в этот один механизм, каждая починка открывала новую площадь, и зона прекратила его чинить по правилу остановки. Десять пунктов остались, все проверены живыми сегодня, ни один не починен молча — их и надо забрать.

Острее всего не аккуратность, а доступность хоста, и точная формулировка тут важнее лозунга. parseClaimed — ОДНО тело, порождающее процесс движка, и у него ДВА входа (platform/internal/books/parse.go, докстринг: «the body of a parse, shared by the queue worker and the intake»). Вход ЧЕРЕЗ ОЧЕРЕДЬ ограничен: River жив, parseWorker зарегистрирован, MaxWorkers берётся из конфига с дефолтом 4. Вход СИНХРОННЫЙ, из HTTP-обработчика приёма, не ограничен ничем — именно его разрез и завёл, перестав ставить задание (пункт 8 списка остановки: «разрез потерял единственный ограничитель параллелизма»). ⇒ N одновременных загрузок = N процессов на одной VM без потолка, при том что рядом стоит РАБОТАЮЩИЙ потолок для второго входа.

Второе: платформа неверно рассказывает о себе самой, и с этого рассказа онбордится следующая сессия зоны. Шапка зонного журнала называет последним заландённым паком «форму заказа» с каноном 0.12.0 и держит «деньги и правду» как незакоммиченный пак в дереве — а тот заландён fda0679, коммитов в platform/ после него 0, канон сегодня 0.13.0. Три ряда регистра стоят open, будучи заландёнными, и проект отчитывается владельцу «major 3» при фактически одном.

Что покупает твой результат. (1) Приём перестаёт быть местом, где один пользователь может положить хост. (2) Оператор и прокси знают, сколько маршрут молчит. (3) Следующая сессия зоны начинает с правды, а не с картины недельной давности.

2. Зона и git

Зона записи — platform/ плюс свой зонный журнал platform/docs/platform-PROGRESS.md (решение владельца: платформа пишет ТОЛЬКО туда, в docs/PROGRESS.md не пишет). Чужие зоны (backend/, frontend/, eval/, books/) не трогаешь ни строкой. docs/ — зона оркестратора, правки туда просишь пингом. Ты НЕ коммитишь: дерево готовишь и передаёшь оркестратору (канон — CLAUDE.md §«Git-координация мультисессий»). Никаких git add -A, reset --hard, переписывания истории. .env не читать никогда.

3. Карта чтения — ЗАКОН, дальше только по её ссылкам

Обязательное пре-чтение сверх карты, для КАЖДОГО платформенного пака: platform/docs/ENGINEERING_STANDARDS.md — норматив зоны, §3 DoD — закон, отступление от любого его пункта = пинг, а не решение сессии. Оттуда же берётся форма твоей самопроверки (§5 ниже её не переписывает, а указывает на неё) и правило копии под мутации: копия несёт КАНОН (cp -a --parents platform docs/architecture/14-api-contract <куда>/), иначе гейт версии контракта постоянно красный и МАСКИРУЕТ дельту — мутация выходит «выжившей» и даёт ложную находку. Направление зоны — platform/docs/PLATFORM_DIRECTION.md (ратифицировано).

  1. docs/BACKLOG.md — строка 332, твой основной заказ. Греп ^| 332 |. Копии десяти пунктов в строке НЕТ — она указывает на носитель: список живёт в твоём зонном журнале, греп СРАБОТАЛО ПРАВИЛО ОСТАНОВКИ. Открой его и сверяйся с ним, а не с §4 этого промта: §4 берёт СЕМЬ из десяти, три вынесены в §4.8 с доводами. Расхождение списка с промтом — пинг.
  2. platform/docs/DEFECT_REGISTER.md — открытые ряды. ⚠ Числа брать прибором: python3 docs/scripts/counts.py (он читает колонки С КОНЦА — наивный разбор слева даёт ложное «open»).
  3. platform/docs/platform-PROGRESS.md — свой журнал. ⚠ Его ШАПКА протухла (см. §4.5) — читай её как предмет работы, а не как факт.
  4. docs/architecture/14-api-contract/ — канон API: openapi.yaml + README.md. Версию брать ФАЙЛОМ (grep '^ version:' openapi.yaml), не из доков.
  5. platform/deploy/README.md — рантбук выката: то, что читает человек, поднимающий систему.

Ратифицированное, нужное по существу, вложено сюда и похода в журнал решений НЕ требует:

  • title и detail проблемы НИКОГДА не показываются пользователю — канон, openapi.yaml: «written for a DEVELOPER and a log, and a client MUST NOT show either to a user». Фразу человеку рисует КЛИЕНТ по code. Инструмент серверной фразы — localized, и его не несёт 0 строк кода при 197 .go.
  • D39.176 п.1 — продуктовых КВОТ и фри-тир-лимитов нет и не проектируется. Из гигиены интейка законны только инженерные вещи: ретеншен, свип сирот, потолок диска.
  • D39.216 — где форма не тянет, её переписывают; «дешевле подпереть» доводом не является.
  • D39.183 — запрет править тесты «чтобы прошло» про МОТИВ; правка от заказанной смены поведения — обслуживание, но объявляется в отчёте.
  • D39.208 п.5 — норму купила ТВОЯ ЖЕ зона, и она прямо про §4.4. Три круга ревью нашли девять вещей при ЗЕЛЁНОЙ батарее на всех девяти, потому что фикстуры зоны делали два РАЗНЫХ числа ОДНИМ. Фикстура, в которой две различные величины совпадают, делает весь их класс расхождений невидимым, и никакой батареей это не ловится. Лечение — не тест, а ФИКСТУРА, где величины РАЗЛИЧНЫ.
  • Правило, купленное движковой зоной дважды подряд: пин на УСЛОВНОЕ сообщение обязан иметь фикстуру, где оно ОБЯЗАНО прозвучать. Тест, утверждающий только молчание, вакуумен ровно там, где сообщение ложно.

4. Состав и разметка свободы

4.1 Ограничитель параллелизма на пути порождения процессов — делай РОВНО так по составу, форму реши сам

Сегодня синхронный вход не ограничен ничем (замер в §1). Заказ: потолок одновременных разборов, за которым запрос либо ждёт (см. приор ниже), либо получает честный отказ. ⚠ Где ставить и почему это единственная граница. Вызывающих у порождения ТРИ: интейк (без потолка), воркеры River (MaxWorkers 4), свип (последовательный). Ставить надо на ОБЩЕЙ точке порождения (Engine.Manifest / s.manifest), а не в маршруте, иначе два других входа останутся мимо. И довод к тому, чтобы дефолт был скромным: разбор идёт голым exec.CommandContext (internal/runner/engine.go, readEngine) — без systemd-run, без cgroup, без MemoryMax, в отличие от ПРОГОНОВ, которые обёрнуты. ⇒ твой потолок — единственная граница по памяти, какая у приёма есть. Форму (семафор · очередь с ёмкостью · лимит на уровне HTTP) выбираешь ты и аргументируешь; но потолок обязан быть конфигурируемым и наблюдаемым — оператор должен видеть, что упёрлись, а не догадываться по латентности. ⚠ Отказ при упоре — это code для клиента, НЕ detail (см. §4.6).

Этот пункт и §4.2 связаны, и связь видна только из кода — не чини один, тихо ломая другой. Если потолок реализован ОЖИДАНИЕМ, время молчания маршрута после последнего байта растёт на время ожидания, и граница §4.2 перестаёт быть границей, а число в рантбуке §4.3 становится ложным. ⇒ либо ожидание ОГРАНИЧЕНО и его потолок входит в вывод §4.2 слагаемым, либо при упоре отказ немедленный. Третьего («подождём сколько получится») в паке нет: неограниченное ожидание — это та же недоступность, только выглядящая как работа.

ПРИОР ЗАКАЗЧИКА, опровергается аргументом или замером — но опровергать придётся ЯВНО. Я написала выше «потолок ожидания входит слагаемым в §4.2» и, проверив код, снимаю это: ожидание внутри уже стоящего бюджета не добавляет к UploadSettle НИЧЕГО. cutNow держит разрез под context.WithTimeout(context.WithoutCancel(ctx), CutBudget) (books/books.go), и parseClaimed → manifest идёт под ним. Простоял в очереди семафора дольше бюджета ⇒ errNotConclusive201 parsing, книгу доделывает очередь (MaxWorkers 4) — ровно та штатная деградация, ради которой CutBudget и существует. И тогда же снимается требование «потолок конфигурируем»: CutBudget сделан КОНСТАНТОЙ намеренно — «a knob here would let an operator push the tail of an upload past the window in which its key can still be replayed» (books/parse.go, над CutBudget; гейт — config/config.go, сравнение in.UploadDeadline+books.UploadSettle с min(UploadGrace, ClaimStale)). ⇒ конфигурируемым обязан быть ПОТОЛОК ПАРАЛЛЕЛИЗМА (число), а не время ожидания.И если ты всё же выбираешь немедленный отказ — минор НЕ нужен, проверено: service_unavailable уже стоит в закрытом словаре канона, cause.code открыт, Retry-After каноном предусмотрен. Не выбирай ожидание из страха перед контрактом.

4.2 Бюджет приёма выводится ИЗ кода, а не ставится рукой — делай РОВНО так

platform/internal/books/parse.goUploadSettle объявлен как «худший случай всего, что загрузка ещё делает после прихода тела», и собран формулой CutBudget + 4*writeBudget. Пере-счёт по коду даёт другое число: шесть шагов, каждый на своём WithoutCancel, ни один не вложен. Значение не пинит ничто: UploadSettle встречается в тестах 3 раза в 2 файлах, и два из трёх сравнивают константу с самой собой (config/effective_test.go), третий — строка в имени подтеста. Заказ — СВОЙСТВО «РОВНО так», ФОРМА твоя, и обе формы названы с ценой. Свойство: хвост после последнего байта ≤ UploadSettle при ЛЮБОМ числе шагов, и это проверяемо.

  • Форма A (перечень): пере-перечислить шаги и их бюджеты. ⚠ Это ровно та форма, что подвела ТРИЖДЫ, и D39.216 называет её заплатой; выбрав её, объясни, чем твой четвёртый перечень надёжнее трёх прежних.
  • Форма Б (структурная): ОДИН отсоединённый контекст хвоста с дедлайном UploadSettle, все шаги берут min(шаг, остаток), WithoutCancel на пути ровно один. Тогда добавленный шаг границу не двигает ПО ПОСТРОЕНИЮ. ⚠ И от выбора зависит §5.3: «добавь шаг — пин обязан покраснеть» осмысленно при форме A; при форме Б пин обязан утверждать САМО свойство (хвост укладывается в дедлайн), потому что шаг его не двигает. ⚠ Границу выводили трижды и трижды неверно, каждый раз по новой причине (носитель — PD-464 и твой журнал, не нота), поэтому «поднять руками» здесь запрещено мандатом чистоты D39.216.

4.3 Рантбук не знает, что маршрут молчит после последнего байта — делай РОВНО так

platform/deploy/README.md про таймаут ОТВЕТА прокси не говорит ничего (греп по теме — 0 хитов). Единственное указание про прокси — размер тела и таймаут ЧТЕНИЯ запроса. Прокси с дефолтным таймаутом ответа вернёт человеку ошибку на книге, которая на самом деле принята. Заказ: рантбук называет величину молчания числом, выведенным в §4.2, и требование к прокси; и это единственная правка рантбука в паке — остальное про выкат не трогай.

4.4 Три места приёма, где сбой неотличим от нормы — состав РОВНО так, лечение реши сам

  • platform/internal/books/books.goClaimParse в cutNow не различает гонку и сбой БД и молчит; книга остаётся parsing без задания до свипа (окно — claimGrace).
  • platform/internal/pgstore/books.go — не запинена ВЕТКА RowsAffected()==0 ⇒ задание НЕ ставить в ReleaseParseClaim. ⚠ Уточняю улику, чтобы ты не сняла пункт как ложный: сама функция ИСПОЛНЯЕТСЯ (failfast_test.go, TestACutWithNoVerdictGivesTheClaimBackAndEnqueuesTheJob), по имени в тестах её 0 хитов при 110 тестовых файлах — но предмет не «функция не вызвана», а «ветка не различена». Предъявление — мутация: переверни условие, тест обязан покраснеть по ТЕКСТУ про задание.
  • Свип StuckIntake — третий претендент на ту же строку, и он считает от coalesce(parse_started_at, added_at), где added_at штампуется ДО прихода тела. ⚠ Все три — про то, что «застряло» и «сломалось» выглядят одинаково. Лечение твоё; предъявление — исполнением, и на каждое условное сообщение нужна фикстура, где оно ОБЯЗАНО прозвучать.

4.5 Правда о собственном состоянии — делай РОВНО так, это $0 и это предусловие всего остального

  • Шапка твоего журнала лжёт о том, где вы находитесь: называет последним заландённым паком «форму заказа» с каноном 0.12.0 и держит «деньги и правду» как незакоммиченный пак в дереве. Замер: пак заландён fda0679, коммитов в platform/ после него 0, канон 0.13.0 (файл-носитель). Приведи к правде — с этой шапки онбордится следующая сессия зоны.
  • Три ряда регистра несут диспозицию «статус флипает лендинг», лендинг состоялся, а статус у всех трёх так и стоит open. Замер: grep -c 'статус флипает лендинг' platform/docs/DEFECT_REGISTER.md3 (PD-424, PD-441, PD-438), у каждого колонка статуса open, при 465 рядах в файле. И маркер ВЕРЕН только на двух из трёх — не исполняй его механически. PD-441 двухзонный: его ячейка сама говорит «платформенная половина закрыта… движковая половина названа поимённо и ушла строкой бэклога» (строка 331 единого трекера, чужая зона) ⇒ ряд остаётся open, а неверен его собственный маркер. Переведи PD-424 и PD-438; у PD-441 почини МАРКЕР, а не статус. ⚠ Во всех трёх ячейках диспозиция называет пак «в дереве» — он заландён (fda0679), и эта фраза протухла тем же движением. Правя ячейку, снимай и её. И ЭТО СДЕЛАЕТ ГЕЙТ ЧИСЕЛ КРАСНЫМ — так и должно быть, это НЕ твоя поломка. docs/PROGRESS.md держит под гардом counts.py --check литералы «открытых рядов регистра платформы — 112 (major 3)», и после твоего флипа они станут 110 и major 1. docs/PROGRESS.mdНЕ твоя зона (CLAUDE.md: платформа «в docs/PROGRESS.md не пишет»), и лезть туда НЕЛЬЗЯ даже ради зелени. ⇒ правильное поведение: назови новые числа в отчёте явно («после флипа: open 110, major 1») и скажи, что гард красный ОЖИДАЕМО. Литерал двигаю я тем же актом, что и лендинг. ⚠ И это единственное место пака, где красный гейт на выходе — норма; во всех остальных красное есть находка.
  • Три ряда несут незаэкранированный | — гигиена, и НЕ пинг. В КОЛОНКАХ, как их печатает сам прибор (n-2, шапка регистра — 7): PD-375 → 9, PD-422 → 11, PD-197 → 8 при норме 7; рядов с НЕДОСТАЧЕЙ — 0, всего рядов 465. ⚠ Сырой split даёт на два больше (пустые края) — если считаешь сама, считай тем же прибором, иначе решишь, что пак ошибся. Заэкранируй \| в своей зоне. ⚠ И не заводи по этому поводу находку о гейте: она была бы неверна, я проверила. Счёт ячеек ловить избыток НЕ МОЖЕТ по построению — | внутри содержательной ячейки легален и намеренен, — а опасный случай (черта, съехавшая в одну из трёх ПОСЛЕДНИХ колонок, где молча сдвигаются статус и вес) гейт уже судит СЛОВАРЁМ хвоста, tail_vocab() со своим селф-тестом. Все три нынешних ряда доброкачественны: лишнее легло до хвоста, статус и вес читаются верно.

4.6 «Честная причина человеку» — делай РОВНО так, и начни с проверки, не построено ли это уже

Пункт 10 списка остановки: «отказ уходит наружу только машинным кодом (Detail не заполняется) ⇒ честная причина человеку НЕ доезжает». ⚠ Формулировка пункта вводит в заблуждение, и я это заявляю как заказчик: лечение НЕ в заполнении Detail.

Что запрещено: канон дословно — title и detail «are written for a DEVELOPER and a log, and a client MUST NOT show either to a user». Единственное исключение — localized, и его не несёт 0 строк кода (замер по platform/**.go). Значит Detail не заполняется ПРАВИЛЬНО, и это не дефект.

Что уже построено — проверь ПЕРВЫМ делом, прежде чем строить. Словарь errors[] по словам самого канона ОТКРЫТ, и обе причины отказа разреза уже едут наружу перечислимыми: httpapi/problem.goItemNoBook = "no_book" и ItemNoChapterStructure = "no_chapter_structure", ставятся в httpapi/v0.go на /file. То есть машина причину уже называет.

Инструмент расширения — НЕ корневой code. Канон: корневой code «stable, closed for this version», а cause.code — «its vocabulary is NOT closed and grows without a minor bump». Компаньон контракта прямо называет это механизмом расширяемости. ⇒ новый КОРНЕВОЙ код = ломающее изменение и минор (мой акт, пинг мне); новая частная причина в cause.code или новый член errors[] — аддитивно и минора НЕ требует. Это твой путь по умолчанию.

И скорее всего пункт закрыт ПО ПОСТРОЕНИЮ — начни с попытки это опровергнуть, а не с работы. Таблица «код → русская фраза» у клиента уже есть (14-api-contract/README.md, и фронт её рисует), обе причины перечислены, словарь открыт. Неисполнена только КЛИЕНТСКАЯ половина, а фронт ЗАМОРОЖЕН — то есть это не твоя работа и не работа этого пака. Заказ, отсюда: (а) проверь и объяви: закрыт по построению — или назови причину отказа приёма, которой сегодня НЕТ в errors[]/cause; (б) нашлась такая — добери её ОТКРЫТЫМ словарём (errors[].code / cause.code), это аддитивно; (в) нашлась причина, не выразимая кодом в принципе, — вот это пинг мне (там localized и минор), с примерами, а не с тезисом. ⚠ Граница зоны: РИСУЕТ фразу клиент. Твоё дело — чтобы у него было по чему её нарисовать.

4.7 Живой гейт — делай РОВНО так: проверь причину исполнением, прежде чем её повторять

Твой журнал объясняет, почему разрез не предъявлен настоящим tmctl: гейт требует $0-пайплайна рядом с backend/prompts/, то есть записи в чужую зону ИЛИ полной копии дерева. ⚠ Зона про копию ЗНАЛА и её не сделала — я не утверждаю, что довод выдуман, я утверждаю, что он не проверен исполнением. А 35 строками ниже в том же журнале лежит рецепт снапшота через git archive <commit> backend/configs backend/prompts, то есть путь без записи в чужую зону. Итог: новый механизм в платном пути ни разу не встречался с живым движком, а единственная причина этого — непроверенное предположение. Заказ: проверь рецепт исполнением. Работает — предъяви разрез настоящим движком; не работает — назови ЧЕМ именно, и это пинг мне, а не строка «не получилось».

4.8 Чего в паке НЕТне делай, и это ОБЪЯВЛЕННЫЕ сужения

  • Квоты интейка и фри-тир-лимиты — сняты словом владельца (D39.176 п.1). Из гигиены законны только ретеншен, свип каталогов-сирот и потолок диска — и они НЕ в этом паке.
  • Пятая причина отказа (строка 340) — ждёт слова владельца, рекомендация оркестратора уже записана.
  • Читатель секции предложений банка (строка 224) — ждёт КЛЮЧА у движковой стороны: у строки предложения нет ни id, ни полного кортежа, а дверь правок требует одного из двух. Строить раньше ключа = адресовать правку по угаданному ключу.
  • deleteBook — предмет вырос: каскад по строкам есть, по файлам нет; без ретеншена решается вполсилы.
  • Зеркало контракта фронта — зона заморожена, отставание ратифицировано.
  • Строка 342 (восстановление из бэкапа на масштабе) — предмет РАЗНЫЙ: это авария и большие данные, а пак про приём. Не бери; и не считай её пропуском — она названа здесь.
  • ТРИ ПУНКТА ИЗ ДЕСЯТИ, взятые сознательно и названные поимённо (иначе они выпадут молча, а §1 обещает все десять):
    • п. 2 — комментарий в cutNow («the queue job is already enqueued») противоречит починке, ради которой функцию правили: на этом пути задание ставит сам ReleaseParseClaim. БЕРЁШЬ, если правишь cutNow по §4.4 — правка механизма обязана снять ложное утверждение о нём тем же движением (D39.216 п.3б); отдельной работой не заводи.
    • п. 4 — параметр enqueue у StartParsing в бою мёртв (движок настроен всегда), а его doc описывает его штатным путём; решение «кто ставит задание» размазано по двум местам на одном предикате. БЕРЁШЬ вместе с §4.1: ты всё равно трогаешь вопрос «кто ставит задание», и развязка этого предиката — часть ответа. Форма — твоя.
    • п. 6 — «ВСЕГДА» в дельте контракта есть гарантия по ТАЙМИНГУ, не по построению (свип материализатора теоретически успевает между FinishParse и ReadBook). НЕ берёшь: текст контракта — зона оркестратора, и лечение тут либо структурная гарантия, либо оговорка в каноне. Твоё действие — пинг мне с тем, какую из двух ты считаешь верной, и почему.
  • Миграции — ни один пункт пака их не требует ПО ЗАМЫСЛУ. ⚠ Известное исключение: у StuckIntake (§4.4) прямое лечение просится колонкой «тело пришло / StartParsing отработал», которой в таблице нет (замер: body_received — 0 хитов при 34 миграциях). ⇒ упрёшься в это — пинг, а не самовольная миграция и не полумера молча; назови, какую полумеру видишь и что она недодаёт.

5. Мандат самопроверки ИСПОЛНЕНИЕМ — «перечитал сам» не считается

  1. Каждая новая гарантия предъявляется ИСПОЛНЕНИЕМ, а условное сообщение — фикстурой, где оно ОБЯЗАНО прозвучать, И фикстурой, где обязано молчать. Тест, утверждающий только молчание, вакуумен.
  2. Ограничитель параллелизма (§4.1) предъявляется НАГРУЗКОЙ, а не чтением: N одновременных приёмов при потолке M дают ровно M одновременных процессов, остальные ждут или получают названный отказ.
  3. Бюджет (§4.2) предъявляется МУТАЦИЕЙ: добавь шаг в путь — пин обязан покраснеть.
  4. Субагенты РАЗРЕШЕНЫ ЯВНО — и на охват, и на адверсариальный проход по ГОТОВОЙ работе. Направление: (1) фикстуры, где «застряло» и «сломалось» совпали; (2) числа, взятые из соседнего файла — за прошлые сутки это стоило проекту четырёх неверных чисел; (3) утверждения о чужой зоне, сделанные по памяти.
  5. Проверяемый артефакт — таблица «находка → что сделано → ЧЕМ ПРЕДЪЯВЛЕНО» плюс, для каждого класса, столбец «закрыт в N носителях из M», где M посчитан командой.
  6. BASELINE НА ВХОДЕ сними САМ первой командой и сверь с моим: гейт чисел python3 docs/scripts/counts.py --check обязан говорить «Литералы сходятся»; батарея — make check по DoD §3 п.1. Число скипов и их условия бери ТОЛЬКО из platform/docs/STACK_DECISIONS.md §«Гейты батареи» — это единственный носитель, и он заведён потому, что число жило в трёх файлах, они разошлись, и сессия, ЧЕСТНО исполнившая этот пункт по устаревшей копии, объявила приёмку выполненной при красном тесте. Невыполненное на хосте условие НАЗЫВАЙ вместе с числом скипов. Красное на входе — находка и пинг, а не твоя работа. И сам этот носитель уже протух — почини его ПЕРВЫМ движением, он твой: там стоит «19 пакетов», а go list ./... даёт 20, и эррата 06.09-е двадцать уже установила. Сессия, честно исполнившая этот пункт, получит расхождение первой же командой и потратит круг на выяснение, чья это ошибка.

6. Оси ревью — характер «Код», плюс шов и деньги (ось вправе заменить с аргументом)

Тест утверждает не то, что думает (D39.171): часы как способ синхронизации там, где предмет не время, и ассерт по подстроке в общем буфере. Обе формы дают и ложное красное, и тихо-зелёное — оно дороже. Вторая ось: шов — инвентарь ВСЕХ каналов другой стороны чтением ЧУЖОГО кода, не по памяти. Третья: деньги — любое число из сырого носителя, а не из агрегата. Четвёртая, и она про §4.1 прямо: сверка с индустриальным первоисточником ПРЕЖДЕ велосипеда. Форму ограничителя ты выбираешь сама — значит x/sync/semaphore, errgroup.SetLimit, netutil.LimitListener и уже стоящий рядом MaxWorkers очереди обязаны быть РАССМОТРЕНЫ и отвергнуты с доводом, а не пропущены. Самописный счётчик там, где есть stdlib или устоявшаяся библиотека, — находка приёмки, а не решение.

7. Записка-план ДО работы

До первой правки — короткая записка в журнал: что берёшь, в каком порядке, что считаешь рискованным. После работы — сверка комплектности против §4 МЕХАНИЧЕСКИ (таблицей), не перечитыванием.

8. Заявление = команда

Каждое число и категорика — с командой, которой получены. Отрицательный замер печатается ВМЕСТЕ с контрольной величиной («0 хитов при 197 go-файлах»). Сверх этого:

  • перед отчётом сверь каждый клейм с результатом инструмента ЭТОЙ сессии, а не с памятью и не с этим промтом: адреса §4 сняты 08.09 и могли уехать;
  • последний абзац отчёта оказался планом или обещанием? сделай это СЕЙЧАС;
  • править тест/гейт, чтобы он прошёл, — НЕДОПУСТИМО; исключение — правка от заказанной смены поведения, и она объявляется отдельным пунктом;
  • сессия длинная — поставь себе интервальную самоверификацию субагентом против ЯВНЫХ критериев §13.

9. Эхо-протокол старта

ДО работы — ≤10 строк СВОИМИ словами: скоуп · инварианты · что НЕ делаешь. Дословный пересказ промта подтверждает канал, но не понимание, и ошибку промта повторяет вместе с ним. Эхо — оркестратору по адресу из прямого канала (§12); канала нет — эхо первой секцией журнала, работа продолжается.

10. Что НЕ удалось — обязательная секция отчёта

Что не вышло, что не проверено, где сомневаешься. «Не проверено» и «опровергнуто» — РАЗНЫЕ исходы.

11. Канал вопросов и право сказать «этого делать не надо»

Конфликт промта с кодом или доками — пинг, а не интерпретация: за прошлые сутки в промтах и трекере нашли шесть ложных утверждений, три из них авторства оркестратора. Считаешь пункт ненужным — скажи с доводом. Решение владельца требуется, если работа упрётся в деньги, скоуп или продукт.

12. Прямой канал

Механизм — CLAUDE.md §«Связь между сессиями». Впиши СВОЙ блок в /tmp/textmachine-channel первым делом, чужие блоки не трогай. ⚠ Адрес из файла не доказывает, что сессия жива: сверься с ListAgents. Нужной роли нет или имя не отвечает ⇒ канала нет, и это НОРМАЛЬНЫЙ случай: НЕ опрашивай сессии подряд — вопрос секцией в журнал, работа продолжается.

13. Критерий завершённости — по нему тебя примут

Работу доводишь до конца САМ; приёмка идёт последней и вторым кругом твоей самопроверки не служит. Готово — это когда:

  • у КАЖДОГО пункта §4 есть исход: сделано · не делаю с доводом · пинг;
  • круги СОШЛИСЬ: последний проход не дал НОВЫХ находок, прежние закрыты таблицей «находка → что сделано → ЧЕМ ПРЕДЪЯВЛЕНО»;
  • каждый класс закрыт со ЗНАМЕНАТЕЛЕМ «N из M», и M посчитан командой;
  • ограничитель §4.1 предъявлен НАГРУЗКОЙ, бюджет §4.2 — мутацией;
  • числа сняты ПОСЛЕ последней правки, а не вспомнены;
  • всё живое — в ДЕРЕВЕ, а не в письме;
  • сказано явно: «работа завершена, править не планирую». Без этой фразы пак считается идущим.

Деньги

Пак $0. Платных вызовов провайдерам ноль: разбор книги — $0-глагол движка, живой гейт гоняет его же. Если тебе кажется, что задача требует платного прогона, — это стоп и пинг, а не вызов.

Отчёт

Зонный журнал platform/docs/platform-PROGRESS.md: исход по каждому пункту §4 · таблица «находка → что сделано → чем предъявлено» · столбец «закрыт в N из M» · пере-снятая шапка журнала · пинги (форма гейта рядов — оркестратору; PD-441 — движку; всё, что упёрлось в контракт) · §10 «что не удалось» · вопросы оркестратору.