textmachine/docs/archive/prompts/PLATFORM_P9_SESSION_PROMPT_2026-08-27.md

26 KiB
Raw Permalink Blame History

Промт: платформа, пак P9 — смонтировать дверь правок банка, довести прогресс и расшить живой прогон

Выдан оркестратором №19, 27.08.2026. Это пункт (2в) очереди, ратифицированной D39.156, и последний в связке шва. Два предыдущих отработаны: движковый пак — D39.158 (d1eb8a9), контрактный минор 0.5.0 — D39.161. Твой пак закрывает связку и впервые делает возможным живой прогон книги насквозь (строка 202, не гонялся НИ РАЗУ).

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

Сегодня цепь «пользователь поправил термин → перевод пере-собрался с этой правкой» разорвана на твоей стороне. Движок принимать правки умеет с 27.08: есть $0-глагол tmctl bank-apply. Канон объявил дверь POST /books/{bookId}/bank/corrections СЕГОДНЯ же, минором 0.5.0 (D39.161). Платформа не делает ни того, ни другого: двери нет, глагол не вызывается, ключи движку не передаются.

Следствия, каждое с носителем:

  • Правку положить некуда — строка 199, движковая половина построена, платформенный конец открыт.
  • Живой прогон невозможен — строка 211: движок на SaaS не получает провайдерских ключей. ⚠ Движковая половина этого блокера ПОСТРОЕНА (--keys-file), платформа его не передаёт: греп по зоне даёт НОЛЬ. То есть блокер снят наполовину и вторая половина — твоя.
  • Полоса прогресса обнуляется на снятии стопа — требование владельца от 20.08, строка 200.
  • Канон объявляет два поля, которых деплой больше не должен слатьPD-399.
  • Деплой знает чужую конвенцию пути — строка 213.

Что решит результат. После пака: пользователь правит термин через API, правка доезжает до движка, прогон возобновляется и пере-собирает банк с ней; полоса не врёт; и книгу наконец можно прогнать насквозь по-настоящему.

§1. Зона записи и git

Твоя зона — platform/. Отчёт и находки — зонный журнал platform/docs/platform-PROGRESS.md, новые дефекты — строками в platform/docs/DEFECT_REGISTER.md тем же деревом.

  • Ты НЕ коммитишь. Лендит оркестратор после адверсариальной приёмки. Канон — CLAUDE.md.
  • docs/ (корень), backend/, frontend/, eval/не трогать ничем. Если увидишь, что правка нужна там, — это пинг, а не правка.
  • В дереве живёт незакоммиченная работа зоны полигона (20 позиций). Чужого не касаться.
  • Мутации — только в КОПИИ дерева, и копия несёт КАНОН: cp -a --parents platform docs/architecture/14-api-contract <куда>/. Голая cp -a platform даёт постоянный красный gates.TestTheAnnouncedContractVersionIsTheOneTheCanonRatified и вердикты лгут — норма зоны ENGINEERING_STANDARDS §3 п.3.

§2. Карта чтения — ≤5 позиций, ЗАКОН

  1. docs/architecture/14-api-contract/openapi.yaml, блок /books/{bookId}/bank/corrections (:478) и схемы BankCorrection* — это ТВОЙ заказ дословно: описание двери там уже написано, тебе его исполнять, а не сочинять. Плюс Capabilities (:1297 — флаг bank_corrections_enabled).
  2. docs/architecture/14-api-contract/README.md §2.19 — вывод двери из словаря глагола с провенансом file:line и тремя названными обязательствами монтажа (они адресованы тебе).
  3. Словарь и коды глагола — в КОДЕ движка, он первичен: backend/internal/membank/decisions.go (тип Decision, строки 51117) · backend/internal/pipeline/bankdecisions.go (отчёт, SignatureState :88-118, кап :647) · backend/cmd/tmctl/main.go:69-75 (полоса отказов 1019) и :95 (код 3 — стоп).
  4. platform/docs/platform-PROGRESS.md — свой журнал: последняя запись приёмки P8-REVIEW и ПИНГ №21 (он про твою дверь).
  5. docs/architecture/18-bank-ontology.md (69 строк, ратифицирована D39.158) — роли носителей и дисциплина проекции. Короткая и объясняет, ПОЧЕМУ дверь устроена так.

⚠ Ратифицированное, что бьёт всё, вложено в §3.0 — грепать журнал решений не требуется.

§3. Состав пака

§3.0. Ратифицированное, из чего исходишь

  • D39.144: подписывается ВЕСЬ банк ОДНИМ «ОК». Пер-термно существует не подпись, а ПРАВКА.
  • D39.158: стоп банка — ФЛАЖОК, движок чтит его сам; «ОК» = возобновление.
  • D39.156 п.6: платформа НЕ пере-реализует движковый закон у себя. Считает движок — ты отдаёшь.
  • D39.161: канон 0.5.0; дверь объявлена, признак «не построено» машиночитаем.
  • D39.160: сквозная полоса прогресса едет ЗДЕСЬ, а не в контрактном миноре.

§3.1. Смонтировать дверь — контракт делай РОВНО так, свободна только внутренняя реализация

Маршрут, схемы, коды и тексты уже написаны в каноне — исполняй их, не переизобретай. Раскладка отказов оттуда: 409 bank_corrections_refused (всё-или-ничего; отказанные — в refusals[] конверта Problem) · 409 run_in_flight · 503 bank_corrections_incomplete («слать ТОТ ЖЕ документ», ретрай сходится) · 413 (1 МиБ) · 404, когда дверь не смонтирована.

Отображение кодов движка на HTTP — РАЗМЕЧЕНО ПОПОЛАМ, не путай половины. Заказано каноном, делай ровно так (не «твой аргумент» — это уже решено и опубликовано): 14 → 409 bank_corrections_refused · 15 → 503 bank_corrections_incomplete · 12 → 409 run_in_flight · тело > 1 МиБ → 413. Свободен и обязан обосновать: чем едут 13 (схема проекта не та — операторская ошибка деплоя, не пользовательская) и 10 / 11 / 19. Приор, опровергаемый аргументом: ни один из них не должен становиться неразличимым 500 — пользователь обязан отличать «пере-реши» от «повтори то же» от «позови оператора».

Capabilities.bank_corrections_enabled обязателен: false ⇒ дверь не смонтирована ⇒ 404. Условное монтирование в зоне уже есть — platform/internal/httpapi/v0.go:75+, поле mounts:.

§3.2. Форма вызова: СИНХРОННО, и вот почему — но проверь на себе

Ратифицированный состав (2в) говорит «воркер решений → глагол перед возобновлением». Он писался, когда двери в контракте НЕ БЫЛО. Проверено мной 27.08 исполнением:

  • движок на банковом стопе ВЫХОДИТ (cmd/tmctl/main.go:95, код 3), процесса не остаётся;
  • флок проекта — не-блокирующий эксклюзивный на процесс (backend/internal/store/store.go:187), ядро отпускает его на выходе процесса;
  • значит на стопе флок свободен, и синхронный вызов bank-apply из обработчика законен;
  • кап в 5000 решений поставлен движком ровно из соображения «вызов должен влезать в таймаут вызывающего» (bankdecisions.go:647) — то есть синхронность в нём уже учтена.

Заказ: строй синхронно — принял документ, вызвал глагол, вернул его отчёт как квитанцию.

Один остаток, и это НЕ воркер, а одна строчка сериализации. Гонка: resume спавнит прогон, ПОКА дверь обслуживает вызов по той же книге. Она доброкачественная по построению — translate упрётся в занятый флок и откажет классом 12, — но холостая попытка стоит денег и шума, поэтому дешевле её не плодить: пер-книжная сериализация «не спавнить resume, пока по этой книге живёт вызов corrections» — мьютекс в обработчике, не очередь и не воркер. Зеркальная половина уже дана самой дверью: corrections пришёл при живом прогоне → мгновенный класс 12 → твой 409 run_in_flight.

Взаимоисключение живого прогона и решения — не наша выдумка, а п.2 закона входной двери шва, и оно запинено цепным тестом движка (backend/internal/pipeline/bankchain_test.go:62-64): «a live run and a decision are mutually exclusive by design… the operator decides between runs». Твой обработчик обязан жить в том же ~60-секундном классе бюджета, который зона даёт вызовам движка. ⚠ Если найдёшь, что синхронность не держится (свой замер, не рассуждение) — это ПИНГ, и я снимаю пункт «воркер» эрратой к D39.156. Молча воркер не строить и молча не выкидывать.

§3.3. Передать движку ключи — делай РОВНО так

Строка 211, вторая половина. Движок принимает --keys-file <абсолютный путь> (backend/cmd/tmctl/dotenv.go:46,63, пин cmd/tmctl/keysfile_test.go). Раннер строит argv в одном месте — platform/internal/runner/runner.go:146 (startArgv, «built in one place so a test can read it»). Путь берётся из конфигурации деплоя, в окружение юнита ключи не кладутся. ⚠ Это половина БЛОКЕРА живого прогона: без неё строка 202 не двигается.

§3.4. Полоса прогресса — реши САМ, но причину знай

Строка 200, требование владельца: ОДНА доля на всю работу прогона, считает СЕРВЕР (иначе клиент снова начнёт знать про фазы), плюс подпись «что делается сейчас».

Причина обнуления найдена мной и она конкретна: platform/internal/pgstore/readmodel.gosegmentUnits (:400) переключается с units_draft_done на завершённые юниты в момент, когда банк released, а runProgress (:446) меряет от базовой линии прогона и каппится его покупкой. То есть полоса меряет СНАЧАЛА черновую волну, ПОТОМ редакторскую — отсюда «100%, затем ноль».

Не сноси то, что стоит по делу. Комментарий :437-445 объясняет, почему бар прогона базируется и каппится: решения переживают прогоны, возобновлённый прогон пере-ходит готовые главы за $0 и не должен их двигать. Рядом уже есть chaptersDone (:403) — КНИЖНАЯ доля, другой вопрос. Твоя задача — монотонная доля на всю работу прогона через обе волны; форма твоя, обоснуй.

§3.5. Снять два поля с провода — делай РОВНО так

PD-399. Канон 0.5.0 больше НЕ объявляет pending_decisions и complete, а pgstore/readmodel.go:330 их кладёт. ⚠ Их присутствие ЗАПИНЕНОinternal/httpapi/reading_test.go:113 — значит это правка с пином, а не вычёркивание.

§3.6. Снять дубль конвенции пути — делай РОВНО так

Строка 213: platform/internal/runner/artifacts.go:65+ (projectDB) парсит book.yaml нестрогим декодером ради двух ключей и при пустом project_db САМА вычисляет путь по движковой конвенции. Платформа не должна знать конвенцию чужой зоны.

§3.7. Чего в паке НЕТ — и пропуски ПОДПИСАНЫ

Читающая сторона банка (решённость · история · улика предложения — строки 221, 224, 226) — отдельный ДВИЖКОВЫЙ пак, разобран консилиумом 27.08 и заказа пока не имеет. Не бери, даже если покажется, что экрану это нужно: писатель там движок, не ты.

Пропуски, которые я подписываю сознательно (норма требует сверять состав против всех листов владельца и подписывать пропуск, а не умалчивать):

  • sqlcНЕ в этом паке. Слово владельца 20.08 «я вообще за» стоит в твоём журнале, и решение 22.08 — отдельной сессией: работа механическая (41 запрос в пяти файлах), и мешать её с содержательной запрещено прямо. Не бери попутно.
  • Строка 198 (апгрейд движка безвозвратно стирает замечания и счётчики книги) — НЕ в этом паке, хотя она твоей зоны и помечена «до первого реального пользователя». Причина: она о композиции двух половин и требует движковой стороны, а этот пак обязан остаться про шов и живой прогон. Она пойдёт следующим заказом — не считай пропуск забывчивостью.
  • Открытые строки регистра PD-375PD-398 (пак P8-REVIEW) — НЕ в этом паке целиком; из них сюда взята одна PD-399, потому что её породил вчерашний минор. Остальные — отдельный кодовый пак.

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

Обязательная норма зоны: каждый деливерабл проверен исполнением, не чтением. Названный механизм:

  1. Батарея с ТРЕМЯ гейтами (TM_PLATFORM_TEST_DSN · пара _ENGINE_BIN + _BOOK_TEMPLATE · достижимый пользовательский менеджер systemd). Ожидание — EXIT=0, линтер 0 issues, скипов 0. ⚠ Скипы логом не доказываются: секция «did NOT run» печатается только при найденном --- SKIP; счёт снимай отдельно go test ./... -count=1 -v с грепом.
  2. Дверь — ЖИВОЙ пробой против НАСТОЯЩЕГО движка, а не мока: подними стенд (рецепт — STACK_DECISIONS.md §«Стенд разработчика»), доведи книгу до банкового стопа, пошли в дверь preview, потом настоящую правку, потом resume — и покажи, что следующий прогон её ВИДИТ. Это и есть доказательство, что цепь срослась. Артефакт: лог пробы в отчёте.
  3. Свои посадки мутаций по норме §3 п.3: минимум по одной на дверь, на ключи и на прогресс; вердикт — по ДЕЛЬТЕ против чистой базовой линии ТОЙ ЖЕ копии и по ТОПИЧНОСТИ упавшего теста, не по цвету батареи.

Субагенты РАЗРЕШЕНЫ явно (харнесс по умолчанию их не берёт): опровергатель на раскладку кодов §3.1 и на форму прогресса §3.4 — ЗАКАЗ, не право; его находки в отчёт, включая отвергнутые с причиной. ⚠ Веер соразмеряй заранее: 24 агента. Панель на полтора десятка на этой машине убивает сама себя.

§5. Оси ревью — 13, вправе заменить с аргументом

  1. Ось «деньги» — обязательная норма зоны: сверить леджер ДВУМЯ путями на нетривиальном состоянии. Твой пак трогает возобновление, а это денежный путь.
  2. Ось «дверь против словаря глагола» — каждое поле и каждый код с ответом, откуда он в движковом коде. Поле без ответа — либо изобретение, либо находка.
  3. Ось «что увидит пользователь, когда сломается» — 409 против 503 против 500: различает ли клиент «пере-реши» от «пошли то же самое ещё раз».

§6. Записка-план, комплектность, «заявление = команда»

До правок заведи запись в зонном журнале с планом. В конце — таблица комплектности против §3: пункт → что сделано → каким ИСПОЛНЕНИЕМ подтверждено. Пункт со словом вместо команды в третьей колонке считается НЕ сделанным. Любое число отчёта — с командой, которой оно получено.

§7. Эхо-протокол старта — и он же проверка канала

ДО работы — ≤10 строк: скоуп · инварианты · не-делать. Расхождение эха с промтом — первый вопрос.

Эхо ПОШЛИ МНЕ первым действием, а не пиши в пустоту: SendMessage на имя из §10 (в конце промта). Это двойная проверка — я вижу твоё понимание скоупа ДО того, как ты начал, а ты убеждаешься, что канал живой, пока чинить его дёшево.

§8. Obstacle — обязательная секция

«Что НЕ удалось и что НЕ проверено» отдельной секцией. Названный пробел дёшев; необъявленная ошибка автора — находка, которой нет.

§9. Канал вопросов и твоё право отказаться

Конфликт промта с кодом или доками — пинг оркестратору через владельца, не интерпретация в свою пользу и не обход.

У тебя есть право сказать «этого делать не надо» — с аргументом. Промт писал не тот, кто живёт в этом коде. Если пункт заказа окажется неверным, вредным или уже исполненным, скажи это и не делай — назвав, чем именно он неверен. Отказ с разбором стоит дороже послушного исполнения плохого пункта, и сегодня это уже случилось дважды: пункт «воркер решений» я снял эрратой, потому что исполнитель показал изменившуюся посылку; и мой промт контрактного минора содержал две неверных посылки, которые нашла его сессия и принесла пингом.

Аддендумы по ходу доезжают ТОЛЬКО релеем через владельца. Что не пришло релеем — не заказ.

Тесты и гейты не подгонять под зелень: несогласие с гейтом — вопрос, не правка.

§10. Как со мной связаться — прямой канал

Впиши себя в /tmp/textmachine-channel первым делом — дописать свой блок в конец, чужие не трогать; ключи и правила в шапке самого файла. Тогда тебя найдут, а не будут искать.

Мой адрес — там же, не здесь. Прочитай его — там имя моей сессии и чем писать (SendMessage). Имя в промте я НЕ пишу нарочно: оно протухает, а протухший адрес в документе выглядит живым и стоит сессии дня.

Пиши, не копи. Поводы, по которым молчать хуже: нашёл глупость или ошибку в этом промте (сегодня их находили в КАЖДОМ моём промте — в одном девять, две из них убили бы работу) · пункт заказа оказался уже исполненным или вредным · упёрся в развилку, которую я не назвал · нужен факт из чужой зоны, которую тебе не читать.

КАНАЛА НЕТНЕ ИСКАТЬ. Файла нет или имя не отвечает — значит оркестратора сейчас нет, и это НОРМАЛЬНЫЙ случай, а не авария (файл лежит в /tmp именно затем, чтобы умирать вместе с адресом). Тогда:

  1. НЕ опрашивай сессии подряд в поисках меня — это шум, который ничего не находит;
  2. положи вопрос секцией «вопросы оркестратору» в свой отчёт и продолжай работу;
  3. владелец прочитает отчёт и пере-передаст — он единственный вечный канал.