textmachine/docs/PLATFORM_P12_SESSION_PROMPT.md

32 KiB
Raw Blame History

Промт: платформа, пак P12 «долги под ногами» — семь открытых major и висящие обязательства зоны

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

У зоны нет активной стройки, но регистр держит 7 открытых major — и почти все они про ДЕНЬГИ или про ЛОЖЬ экрана: запись о правке банка теряется навсегда при обрыве клиента (PD-425), экран показывает «готово» по чужому прогону, пока живой тратит деньги невидимо (PD-402), смена состава волн на живой книге продаёт уже переведённые главы повторно (PD-403/PD-404), полоса стоит на нуле всю жизнь прогона (PD-405), намертво заблокированная расплата невидима и не выводится ничем, кроме Stop пользователя (PD-424). Плюс обязательство, висящее с 27.08: обход --verify-bank так и не снят, хотя движковая половина порядка D39.158 давно залендена. Что решит твой результат: деньги перестают теряться молча, экран перестаёт врать, зона входит в живой прогон (очередь №20 п.23) без известных мин.

Чего пак НЕ решает: дверь выдачи createExport/getExport (пинг №20 в зонном журнале — она ждёт живого прогона) · PD-410 (единица продажи — ОТДЕЛЬНЫМ паком, слово оркестратора 28.08, тело решения — D39.165 §1) · эскроу П-18 · перф-строки PD-412/PD-413.

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

Пишешь только в platform/. Не коммитишь: дерево готовишь и передаёшь оркестратору. Канон git — в CLAUDE.md. ⚠ Одна операция выходит за код зоны и разрешена явно: tmctl migrate по СТЕНДОВЫМ книгам зоны свежесобранным бинарём (§3.7) — это операция над данными стенда, не правка backend/.

2. Карта чтения — ПЯТЬ позиций, дальше только по их ссылкам

  1. platform/docs/ENGINEERING_STANDARDS.md — целиком; DoD §3 — закон (каждый его пункт исполняется буквально, отступление = пинг).
  2. platform/docs/STACK_DECISIONS.md — разделы «Гейты батареи» (единственный носитель условий) · рецепт стенда · §35 (монотонность edit_wave — правило, которое этот пак пере-подписывает).
  3. platform/docs/DEFECT_REGISTER.md — шапка/легенда + ТЕЛА адресуемых строк: PD-425 402 403 404 405 424 418 411 369 420 431 432 427 203 367 422 213 423 380 44.
  4. platform/docs/platform-PROGRESS.md — пинг №20 (30.08) и ПИНГ №21 (27.08, D39.158) — носитель обязательства по обходу --verify-bank и СОСТАВА снятия (подавление флага при возобновлении + особый случай в спавне + персистентная колонка bank_released); вопросы sqlc-сессии.
  5. docs/architecture/05-decisions-log.md — ТОЛЬКО тело D39.165 (греп ^## D39.165), §2 «эпоха» — источник решения владельца для §3.2; остальной журнал не читать.

3. Работа

Порядок при нехватке ресурса (ранжирование оркестратора): first-class — §3.1 (деньги, теряемые молча) · §3.7 (обязательство, висящее с 27.08) · §3.3 (вход в живой прогон очереди №20); вторым эшелоном — §3.2 (вскроется конфликт с каноном — пинг, и пункт уезжает СЛЕДУЮЩИМ паком, не молчаливая отсрочка) · §3.6+§3.9 (дёшевы, тем же деревом); §3.4/§3.5/§3.8 — по остатку ресурса. Всё невзятое — диспозицией строкой в записке-плане §6; честная резка с доводом лучше молчаливой каши.

3.1 PD-425 — обрыв клиента теряет запись о правке банка навсегда (деньги, делай РОВНО так по классу)

Дверь коррекций пишет пост-verb факт (RecordBankMove) на контексте ЗАПРОСА (internal/httpapi/bank.go:149=ApplyBankCorrections): клиент закрыл вкладку до ответа — запись не легла, bank_moved_at NULL навсегда, второго писателя и свипа нет; дальше обычный прогон допускается без --resnapshot и умирает на снапшот-гарде движка ПОСЛЕ взятия холда. Средство «503, пере-шли документ» недостижимо — клиента уже нет. Класс лечения зона назвала сама и уже дважды применила: WithTimeout(WithoutCancel(ctx), …)platform/internal/httpapi/idempotency.go:151=WithoutCancel (settleCtx; комментарий :147-149 — дословно про обрыв клиента) и internal/books/books.go:205,215=writeCtx (тело — internal/books/parse.go:271-272=WithoutCancel). ⚠ Тело PD-425 в регистре несёт БИТЫЙ якорь pgstore/idempotency.go:150=Location (там чтение ключа, detach нет) — пере-нацель его той же правкой регистра (гигиена §3.9). Делай тем же классом; деталь (таймаут, что именно накрывается) — реши сам и аргументируй. Пины свои: посадка «контекст отменён между verb и записью» обязана красить дефект и зеленеть с фиксом.

3.2 PD-403/PD-404/PD-411/PD-405 — полоса и повторная продажа глав. РЕШЕНИЕ ВЛАДЕЛЬЦА ДАНО — исполняй, не пере-решай

Строки стоят «лечение за решением владельца» — решение дано 28.08, D39.165 §2, релей дословный: смена формы конвейера (добавили/убрали редактора) — СОБЫТИЕ КНИГИ, как пере-нарезка, и счёт легально пересчитывается при пересечении границы; канон уже открыл дверь («never moves backwards WITHIN one structure_version; cutting the book again recomputes both numbers» — docs/architecture/14-api-contract/openapi.yaml:1554-1558=never moves backwards; ⚠ якорь D39.165 1542-1545 дрейфанул — там сейчас RejectReason), нового исключения не изобретать. ⚠ Носитель границы эпохи нотой НЕ решён — реши сам и аргументируй в рамках: флаг монотонен (пин D39.153 §4б) · форму НЕ читать с последнего прогона · счёт пересчитывается только на СОБЫТИИ. Цена обеих дорог: пересчёт БЕЗ движения structure_version нарушает букву канона на направлении «вниз»; движение structure_version инвалидирует курсоры/идентификаторы пар/окна термов (openapi.yaml:1233-1236=moves when the book is cut). Если выбранная форма требует правки ФРАЗЫ канона (второе событие пересчёта рядом с пере-нарезкой) — это контрактный минор через ратификацию оркестратора: пинг ДО стройки, прецеденты миноров 0.7.0/0.8.0 есть. При этом:

  • Монотонность флага (D39.153 §4б) НЕ отменяется — пин стоит, правка пина под зелень запрещена (D39.121). Меняется другое: пожизненный счёт книги перестаёт выводиться из ЖИВОГО флага.
  • ⚠ Ложный док-комментарий recordWaveShapeinternal/pgstore/sink.go:402-409=Monotone in one direction (лгущий абзац :406-409; редакция D39.165 писала 405-408 — дрейф) — переписать/снести целиком вместе с правкой поведения, не механически диапазон строк.
  • Заново НЕ предлагать четыре отвергнутые формы: счёт всегда по редакторской волне · читать форму с последнего прогона · немонотонный флаг · «какая фаза считается» как вопрос клиенту.
  • §35 STACK_DECISIONS.md пере-подписать той же работой — это правка ЗАПИСАННОГО правила зоны, не только кода; прежняя формулировка остаётся в истории с датой и причиной.
  • PD-411 — мёртвые runs.draft_done/draft_total/edit_done/edit_total (два писателя, ноль читателей): запрет сноса был пер-паковым (P9); теперь снос миграцией — естественная часть этой же правки. Реши сам, этим ли паком; если нет — диспозиция строкой.
  • PD-405 — прогон над книгой без материализованного дерева читает 0/total всю жизнь. Зона назвала два лечения: отказ старта до дерева ИЛИ полоса из progress-событий. Выбери и аргументируй; ложный комментарий sink.go:219 снести.

3.3 PD-402, read-половина — экран не смеет показывать «готово» по чужому прогону (делай РОВНО так)

Write-гард уже закрыт (F12, ErrNotResumable, пин TestAnOlderRunCannotBeResumedOverANewerOne); осталась read-половина: lastRun берёт order by started_at desc — живой прогон обязан иметь приоритет над финишировавшим в карточке/полосе. ⚠ У lastRun ДЕСЯТЬ мест склейки на 30.08 (десятое — pgstore/runs.go:132=lastRun, добавлено 28.08 ПОСЛЕ счёта «девять» из PD-44; пере-сочти сам грепом паттерна склейки, не голым словом — голое ловит комментарии) и он в -зоне sqlc — правка судится СВОИМИ тестами по каждому месту, не «зеленью батареи».

3.4 PD-424 (+PD-418) — намертво заблокированная расплата обязана быть видимой и выводимой

Живой прогон с блокированной расплатой: reopen → вердикт deferredreturn nil + ClearRunDeferral, счётчик не растёт никогда, холд заморожен, не видит ни одна поверхность PD-385, run abandon не берёт. Приор зоны (опровергается аргументом): deferredestablished=false, блокированный расчёт = неудача владеющей фазы. PD-418 (settling живого прогона без ручки) — тот же узел: реши, закрывается ли он той же правкой, и подпиши диспозицию.

3.5 PD-369 (=П-21) + PD-420 — легитимный запрос не имеет права получать 500

Конкуренция на одном ключе идемпотентности: claimRounds=3, 8 гонщиков отбирают гонку трижды → 500. Зона назвала две формы: граница по ВРЕМЕНИ либо явный ErrKeyInFlight → контрактный ответ. Слово оркестратора: 500 на легитимном запросе недопустим; между двумя формами выбери сам и аргументируй (учти словарь кодов контракта — новый код = вопрос, маппинг существующих — нет). PD-420 — тот же узел (её диагноз НЕ установлен): порядок — СНАЧАЛА фикс PD-369 (форма ErrKeyInFlight зеленит тест по построению — он этот error уже принимает), ПОТОМ пере-замер серией (≥80 итераций + параллельные батареи); флейк пережил фикс — тогда изоляция/скип с диагнозом строкой в регистр; скип ДО фикса — снятие пина, не вариант (D39.121). Вердикты посадок — по ДЕЛЬТЕ и топичности (DoD §3), красная чистая копия не маскирует дельту.

3.6 PD-431 + PD-432 — честность носителей (делай РОВНО так)

  • PD-431: Touch (internal/pgstore/sessions.go:49=func (s *Store) Touch) выбрасывает RowsAffected — апдейт в ноль строк неотличим от успеха, скольжение окна бездействия не проверяет ни один живой тест. Слово оркестратора: поведение НЕ менять (ноль строк — законная гонка с отзывом); лечение — честность проверки: запинить скольжение окна СКВОЗНЫМ тестом через auth.Authenticator с живым *pgstore.Store (сегодня их не связывает ни один тест). Если по ходу увидишь, что и поведение требует слова, — пинг, не правка.
  • PD-432: рецепт гейтов батареи в STACK_DECISIONS.md не говорит, что движковый бинарь стенда надо ПЕРЕСОБИРАТЬ из текущего backend/ — допиши строку рецепта (свой док зоны; протухший tmctl даёт три красных теста «field … not found», читающиеся как дефект зоны). Той же док-правкой: команда-проверка четвёртого условия батареи (cut -d: -f3 /proc/self/cgroup/init.scope) УЖЕ стоит в «Гейтах батареи» и ОПРОВЕРГНУТА второй точкой PD-423 (ложный отрицательный: тест зелен 5/5 при /init.scope) — сними её или пере-подпиши как опровергнутую со ссылкой на PD-423; прежняя формулировка остаётся в истории с датой и причиной. Замену-кандидата (cgroup.subtree_control целевого среза) можно назвать только КАНДИДАТОМ — диагноз PD-423 не установлен, строке дай диспозицию, не закрытие.

3.7 Снятие обхода --verify-bank — довести порядок D39.158 до конца (делай РОВНО так)

Порядок односторонний и записан: движок первым (залендён 27.08) → tmctl migrate по КАЖДОЙ книге → только потом платформа снимает обход. Сделай: пересобери tmctl из ТЕКУЩЕГО backend/tmctl migrate по каждой стендовой книге зоны → сними обход в коде → живой пробой на стенде: стоп банка доезжает флажком движка, а не обходом.

Той же работой закрывается строка бэклога 240 (находка Д3 ревью P9, двое суток без носителя): оплаченный стоп подписи исчезает МОЛЧА — рестарт проходит границу банка насквозь, а гард LiftBankStop писан против движка ДО памяти v16 и этот путь не держит. Реши ОДНОЙ работой: снять гард вместе с обходом ЛИБО доказать живой пробой, что память bank_stop_presented (схема v16) делает его недостижимым; молчаливо оставить как есть — нельзя.

Состав снятия — по пингу №21, он ШИРЕ спавна: (а) особый случай в спавне — platform/internal/runs/spawn.go, греп BankReleased (⚠ номера строк здесь НЕ ставим: файл правит эта же сессия) — снять РОВНО; (б) писатель LiftBankStop (греп LiftBankStop по internal/runs/reconcile.go и internal/pgstore/runs.go — номера строк двигаются под твоей же правкой) и (в) колонка bank_released с читателями полосы (греп bank_released по internal/pgstore/readmodel.go — номера строк двигаются под твоей же правкой) — реши сам, этим ли паком: снос = НОВАЯ миграция (00016 не править) + пере-вывод сегмента полосы; (б)/(в) сцеплены — снять писателя, оставив колонку, значит заморозить bank_released=false и врать полосой (ось §5); не этим паком — диспозиция строкой, как у PD-411. ⚠ Снимаемое поведение ЗАПИНЕНО: TestAResumedRunIsSpawnedWithoutTheSigningStop (греп TestAResumedRunIsSpawnedWithoutTheSigningStop по platform/internal/runs/reconcile_test.go; его же комментарий — «Mutation caught: passing l.VerifyBank unconditionally», т.е. ровно заказанная правка). Пере-подпись этого пина заказана этим промтом — как в §3.8: заказанная смена контракта, не подгонка под зелень (D39.121); пере-подписанные пины перечисли поимённо. Той же работой уходят обоснования сброса флага из фикс-раунда 28.08 (строка F10, platform-PROGRESS.md:1467): комментарий spawn.go:159-169 («the owner's model») и док-коммент теста — оба описывают поведение, которое пинг №21 объявил лишним. Если найдёшь причину, по которой снимать рано, — пинг с уликой, не молчаливая отсрочка.

Стенд УЖЕ СТОИТ — второй по рецепту НЕ заводить: ~/.local/share/tmstand (стендовая книга одна — books/bk_WIUSGBQTIGWE4ZBY; бинари в bin/, tmctl~/.local/bin/tmctl); W=~/tmstand-work в рецепте — шаблон. Живой tmplatformd — демон ЗАКРЫТОЙ сессии оркестратора №19: убей по PID (⚠ не pkill -f — инцидент P11) и подними свой свежесобранный. Для живого пробоя $0-пары подними СВОЮ заглушку на 127.0.0.1:11434 (образец — platform/internal/runner/translate_resnapshot_live_test.go:41=Listen; ollama на хосте нет) и ⚠ гаси её на время make check: тест второго гейта при занятом порту скипается, а требование — скипов 0.

3.8 PD-367 — интейк не принимает манифест, который свой же материализатор отверг бы (решение оркестратора)

Сегодня {ChaptersTotal:120, пустой список} заводит книгу, по которой можно СТАРТОВАТЬ И ОПЛАТИТЬ прогон. Решено: пол самосогласованности — симметричный, интейк отказывает (закон шва: незнакомое/ несогласованное → не-деструктивно и громко). Это ПРАВКА ЗАПИНЕННОГО контракта интейка — расширение заказано этим промтом, правки пинов перечисли поимённо в отчёте (это не «подгонка под зелень», это заказанная смена контракта; сомнение — пинг). Батарея интейка ездит на документах без списка глав — фикстуры расширь, не обходи. Смежную PD-213 (незнакомая версия манифеста ведёт к УДАЛЕНИЮ файла) реши тем же классом «незнакомое → не-деструктивно» или подпиши диспозицию строкой.

3.9 Гигиена регистра (дёшево, тем же деревом)

Закрыть PD-427 (комментарий уже исправлен 29.08 — акт закрытия) и PD-203 («предложено закрыть» ещё P8-REVIEW; проверь предикат и закрой либо оспорь) · перенести PD-380 и PD-44 (обе fixed) из-под чужих заголовков «Открытые» · завести строку на НЕПОКРЫТУЮ гоночную ветку errIdentityRace (pgstore/identity.go:99-113=race — ретрай при on conflict … do nothing, гонка двух первых логинов одной новой identity; ни один тест её не касается, все тестовые вызовы последовательные) с диспозицией: запинить конкурентным тестом ЛИБО доказать недостижимость; снос — только с доказательством: ветка обслуживает ЛЕГИТИМНУЮ гонку логина, её снос = 500 на легитимном пути (класс §3.5) · пере-диспозиционировать PD-403 и PD-410: обе несут «лечение за решением владельца/оркестратора», хотя D39.165 §2/§1 дали направление ещё 28.08 — регистр отстаёт от D-лога, и следующий читатель понесёт владельцу уже отвеченное · PD-422 НЕ трогать (гейчена проводкой --max-units, гейт оркестратора) — просто не забудь её в грепе по своим путям.

3.10 Границы

  • backend/ не трогать (исключение — операция §3.7); дверь выдачи не строить; эскроу не строить; PD-410 не лечить (отдельный пак).
  • observe.go под sqlc не конвертировать, схему River в sqlc-конфиг не добавлять; склейки/read-модель — -зона sqlc; выпущенные миграции не править (append-only; новые — можно).
  • Новая зависимость = строка в STACK_DECISIONS.md с датой и «зачем», ратифицирует оркестратор; Redis/ORM/ OTel — записанные «нет».
  • Деньги: суммы не на провод/UI/INFO/метрики (D39.84); леджер append-only держит код.

4. Самопроверка ИСПОЛНЕНИЕМ (без неё работа не принята) — DoD §3 стандартов зоны, поимённо

  • make check целиком при ТРЁХ гейтах + условии хоста (носитель условий — STACK_DECISIONS.md «Гейты батареи»); скипы считать КОМАНДОЙ и называть вслух; зелень = полный список пакетов + 0 FAIL. ⚠ Статус четвёртого условия НЕ выводить из команды /proc/self/cgroup — она уже опровергнута второй точкой PD-423 (ложный отрицательный) и пере-подписывается в рецепте по §3.6; суди по самому тесту (TestARunIsBoundedByItsOwnCgroup зелен при 0 скипов); красный — сначала проверь среду (cgroup.subtree_control среза, рецепт в STACK_DECISIONS.md), потом ищи дефект.
  • Стенд: пересобрать ВСЕ ТРИ бинаря, включая tmctl из текущего backend/; демона убивать ПО PID (⚠ не pkill -f — инцидент P11); pipeline-zero для второго гейта; curl --noproxy '*'; правил миграцию — пересоздай базу.
  • Мутационные посадки — в КОПИИ дерева ВМЕСТЕ с каноном (cp -a --parents platform docs/architecture/14-api-contract <куда>/); вердикт по ДЕЛЬТЕ против чистой базы ТОЙ ЖЕ копии и по ТОПИЧНОСТИ упавшего теста, не по цвету. Каждое заявленное свойство несущего пути — запинено тестом, ловящим мутацию; в отчёте назови, какой тест что пинит.
  • Греп ОТКРЫТЫХ строк регистра по СВОИМ файлам ПОЛНЫМИ путями — каждое совпадение получает диспозицию; якорь, убитый твоим переездом, чинишь ты.
  • Находки — строками в регистр ТЕМ ЖЕ деревом; правки чужих до-паковых тестов — поимённо.
  • Тесты/голдены/гейты не подгонять под зелень (D39.121); несогласие — пинг.
  • Дифф ^func Test — исполнением; интервальная самоверификация субагентом в середине пака.
  • Разрешаю субагентов; модель задавай явно; трудный вопрос — старшей модели.
  • Адверсариальный проход по СВОЕЙ готовой работе перед сдачей. Направления: деньги, теряемые между verb и записью; экран, который врёт при гонке живого и финишировавшего; пересчёт счёта, продающий купленное; 500 на легитимном пути; зелёный тест, не проверяющий ничего (класс D39.171). Пока идёт проход — дерево не двигается: морозь или называй агенту коммит.

5. Оси ревью

Деньги (ни одна запись о деньгах не теряется молча; сверка леджера двумя путями) · честность экрана (полоса/карточка не врут ни при гонке, ни при смене формы) · контрактное поведение (интейк/идемпотентность/окно сессии отвечают то, что обещано, и это запинено). Вправе заменить ось с аргументом.

6. Записка-план и комплектность

До кода — записка-план в platform/docs/platform-PROGRESS.md: что берёшь, что не берёшь, чем докажешь; числа — свои, командами, не унаследованные из промта. Перед сдачей — механическая сверка состава против §3 таблицей: пункт → сделано/нет → чем доказано. Пропуск подписывается пропуском. Последний абзац отчёта оказался планом или обещанием? Сделай сейчас.

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

Конфликт промта с кодом/доками/регистром — пинг через владельца, не интерпретация. Есть право сказать «этого делать не надо» с аргументом (по любому пункту §3 — состав большой, честная резка с доводом лучше молчаливой каши).

⚠ Правки задания по ходу работы доезжают ТОЛЬКО релеем через владельца — отдельным его сообщением. Что не пришло релеем — не заказ. Полученную правку эхо-подтверди и вынеси отдельным пунктом отчёта.

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

Любое число и категорика — с командой получения; приёмка пере-ранит, клейм без пере-прогона = «со слов сессии». Утверждение без file:line/замера помечай словом «мнение».

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

ДО первой правки — ≤10 строк: скоуп / инварианты / чего не делаешь. Отправь первым действием по адресу оркестратора из /tmp/textmachine-channel (механизм — CLAUDE.md; впиши туда СВОЙ блок первым делом). Канала нет ⇒ НЕ искать: вопрос секцией в отчёт, работа продолжается.

10. Obstacle reporting

Обязательная секция: что НЕ удалось и что осталось непроверенным. Пустой не бывает. Три исхода: «подтверждено» / «опровергнуто» / «не проверено» — третье не сваливать во второе.

11. Журнал

Записка-план, итоги и вопросы — ЗОННЫЙ platform/docs/platform-PROGRESS.mddocs/PROGRESS.md платформа не пишет).