From 7dadc98ae45babee78d9df451db8f4481f22bd1f Mon Sep 17 00:00:00 2001 From: heaven Date: Fri, 28 Aug 2026 23:11:37 +0300 Subject: [PATCH] Rewrite both prompts on the refutation: a volume stop is completion rather than a halt, and the estimate proof no longer passes on unfixed code --- docs/BACKEND_MONEY_PACK_SESSION_PROMPT.md | 235 ++++++++++++++++++++++ docs/PLATFORM_P11_SESSION_PROMPT.md | 191 ++++++++++++++++++ docs/README.md | 4 +- 3 files changed, 428 insertions(+), 2 deletions(-) create mode 100644 docs/BACKEND_MONEY_PACK_SESSION_PROMPT.md create mode 100644 docs/PLATFORM_P11_SESSION_PROMPT.md diff --git a/docs/BACKEND_MONEY_PACK_SESSION_PROMPT.md b/docs/BACKEND_MONEY_PACK_SESSION_PROMPT.md new file mode 100644 index 00000000..1ea9ce92 --- /dev/null +++ b/docs/BACKEND_MONEY_PACK_SESSION_PROMPT.md @@ -0,0 +1,235 @@ +# Промт: бэкенд, пак «деньги» — продажа обретает настоящий стоп, а смета становится доступной до покупки + +> **Выдан оркестратором №19, 28.08.2026.** Основание — **D39.165** §1 (три продуктовых развилки сняты +> словом владельца) и строка бэклога **231**. Пак идёт ПАРАЛЛЕЛЬНО платформенному. +> ⚠ **ФАЙЛЫ вы не делите** — модули отдельные, платформа кода движка НЕ компилирует и его тестов НЕ +> запускает (проверено). **Но ШОВ общий и ведётся РУКАМИ в трёх точках:** таблица кодов выхода · +> argv из строковых литералов · аллоулист полей `status --json`. **Твой §3.1 трогает первые две** — +> форму ответа я решил за тебя (§3.1), а не оставил на согласование. + +## §0. Какая проблема и что решит твой результат + +**1. Ручка «купить N глав» ничего не ограничивает.** Платформа продаёт ГЛАВЫ, а движку передаёт +только денежный потолок: `--ceiling-usd` (`backend/cmd/tmctl/invocation.go:129`), и тот каппит +**КУМУЛЯТИВНУЮ** трату по книге (`backend/internal/store/ledger.go:67` — +`bookTotal+estimate > c.BookUSD`). **Про число глав движок не знает вовсе**, флага такого нет. + +**Измерено приёмкой 28.08 (леджеры реальных прогонов, $0):** настоящая цена главы — средняя +**$0.0115–0.0190**, максимум одной главы **$0.0375**; константа продажи платформы — **$0.03**. То +есть покупка «10 глав» отдаёт движку $0.30, а $0.30 на этом материале покупает **16–26 глав**. +Пользователь просит одно, получает другое, и полоса каппится на купленном. + +⚠ **И хвост цены порождает КАЧЕСТВО, а не объём** (наблюдение владельца, подтверждено данными): +вызов может отработать успешно и вернуть мусор — деньги списаны, юнит уезжает на ретрай, иногда на +эскалационный хоп к дорогой модели. В леджере это видно с именами причин (`empty`, `length`, +`cjk_artifact`, `sanitizer_defect`), и доля ретраев+эскалаций гуляет **1.5% → 23%** между прогонами. + +**2. Смету пере-прохода показать НЕЧЕМ — и это названная цена вчерашнего минора 0.7.0.** Движок уже +считает её (`projectRebill`, `backend/internal/pipeline/rebill.go:111`) и публикует в `status --json`. +Но `status` материализует банк из СОХРАНЁННОГО глоссария +(`backend/internal/pipeline/status.go:733-744`, `projectStoredMemory` — его собственный комментарий: +«A seed-FILE edit not yet re-run is NOT reflected here»), а `bank-apply` пишет только ФАЙЛЫ решений. +Свёртка происходит внутри СЛЕДУЮЩЕГО `translate`. **Итог: сразу после правки банка движок честно +отвечает «ничего не двигалось», и платформе нечего показать покупателю.** Носитель — строка **231**. + +**Что решит результат:** движок получает СПОСОБНОСТЬ остановиться по объёму, а пользователь получает +возможность увидеть, что затронет пере-проход, ДО оплаты. + +⛔ **ЧЕСТНАЯ ГРАНИЦА, которую первая редакция промта скрывала (нашёл опровергатель).** «Купил N глав — +получил N глав» этим паком НЕ становится правдой, потому что **число глав до движка не доезжает**: +`CeilingChapters` живёт на платформе (`platform/internal/runs/runs.go:232`) до самого спавна, а +`runner.TranslateArgs` собирает argv литералами и канала для него не имеет. **Проводка — платформенная +половина, и она в этом паке НЕ заказана.** Ты строишь механизм; труба к нему — отдельный заказ, и я +его завожу строкой. Не считай пак провалившимся оттого, что после него обещание §0 ещё не выполнено. + +## §1. Зона записи и git + +**Твоя зона — `backend/`.** Итоги и находки — своя секция журнала `docs/PROGRESS.md` («Бэкенд»). + +- **Ты НЕ коммитишь.** Лендит оркестратор после адверсариальной приёмки. +- ⚠ **`platform/` НЕ ТРОГАТЬ.** Там параллельно работает платформенный пак. Нужна правка на той + стороне — это ПИНГ, а не правка. +- ⚠ **`docs/` — не твоя зона**, кроме своей секции журнала. ⚠ Перед записью в неё **перечитай файл**: + журнал правят две сессии, и 28.08 оркестратор уже унёс чужую секцию своим коммитом из-за общего + окна записи. +- ⚠ **Стендовый `tmctl` собирай из ЗАФИКСИРОВАННОЙ копии дерева, а не из рабочего**, если он тебе + понадобится: рабочее дерево грязное твоими же правками, и бинарь из него мерит непонятно что. +- В дереве незакоммиченная работа полигона (20 позиций) — не касаться. + +## §2. Карта чтения — ≤5 позиций, ЗАКОН + +1. **`backend/cmd/tmctl/main.go:252-262`** — три денежных флага и почему они ОРТОГОНАЛЬНЫ; там же + предупреждение «`--ceiling-usd` — НЕ бюджет прогона» · **`invocation.go:120-210`** (парсинг и + валидация флагов). +2. **`backend/internal/store/ledger.go:30-80`** — где потолок реально судит трату (`Reserve`). +3. **`backend/internal/pipeline/rebill.go`** — `RebillProjection`, `projectRebill` (`:111`), порог + согласия и его текст отказа (`:318-324`). +4. **`backend/internal/pipeline/status.go:733-744`** — `projectStoredMemory`; **читать ВНИМАТЕЛЬНО: + это и есть слепое окно из §0.2**. +5. **`docs/architecture/05-decisions-log.md`, тело D39.165** (греп `^## D39.165`) — основание пака; + **и эррата 28.08-к в шапке того же файла** — там названа моя ошибка про смету, не повтори её. + +## §3. Состав пака + +### §3.1. Потолок ОБЪЁМА рядом с денежным — ЗАКАЗ; форма свободна + +**Заказано:** движок умеет остановиться по объёму работы, а не только по деньгам, и **говорит, по +какому потолку встал**. + +**Ратифицировано D39.165 §1б и обсуждению не подлежит:** потолок живёт в ДВИЖКЕ. Резать волну на +стороне платформы нельзя — она волной не владеет и пер-юнитной цены заранее не знает. + +**Свободен и обязан обосновать — В ЧЁМ мерить. ⚠ Кандидатов ТРИ, а не два (поправка опровергателя):** +(а) **выходной юнит** — `ManifestUnit`, та самая гранулярность, которую движок отгружает, и она же +платформенный `chapters.units_total` с интейка; (б) **чанк**; (в) **`chunk×stage` — БИЛЛИНГОВАЯ +единица движка**, ровно та, в которой считает смета (`rebill.go:322`: «%d chunk×stage unit(s)»). +⚠ **Ловушка ровно здесь:** режущий волну естественно считает то, за что ПЛАТЯТ, то есть (в), а +платформа продаёт (а) — и купивший десять глав получит их долю. **Дефект пака воспроизведётся слоем +ниже, в той же форме.** Выбор объясни и назови, как он ложится на платформенную единицу продажи. + +⚠ **И ещё одно, чего первая редакция не спрашивала: как против объёмного потолка считаются РЕПИНЫ и +РЕТРАИ.** Пере-проход, пере-привязывающий пятьсот юнитов за $0 (`rebill.go:315-320`), сожжёт объёмный +потолок, не потратив цента. Ответь на это явно. + +⛔ **ФОРМА ОТВЕТА ЧЕРЕЗ ШОВ РЕШЕНА МНОЙ, и это НЕ предмет твоего выбора — потому что выбор здесь +ломает деньги в обе стороны (нашёл опровергатель).** Словарь кодов выхода объявлен ЗАМОРОЖЕННЫМ самим +движком (`backend/cmd/tmctl/main.go:125-127`: «both bands are frozen seams and a fresh code would be a +word added to a ratified dictionary»), а платформа незнакомый код читает как ОТКАЗ +(`platform/internal/ingest/exit.go:168-169`, `default: OutcomeFailed`). Отсюда: +- переиспользуешь код денежного потолка → платформа объявит прогон ПРИОСТАНОВЛЕННЫМ и возобновит его + за уже купленный объём — дефект, ради которого пак заведён, воспроизведётся слоем ниже; +- заведёшь новый код → пользователь, получивший РОВНО купленное, увидит «ошибка сервиса». + +**РЕШЕНИЕ: остановка по объёму — это НЕ остановка, а ЗАВЕРШЕНИЕ.** По деньгам прогон встал ПОСРЕДИ +работы, там честно «приостановлен» и возобновление. По объёму он сделал ровно то, что куплено, — это +УСПЕХ, код **0**, замороженный словарь не трогается вовсе, платформа читает штатное «готово». +Различение, которого требует пункт ниже, живёт тогда не в КОДЕ ВЫХОДА, а в отчёте/логе. Если найдёшь, +что это ломает что-то, чего я не вижу, — **пинг, и я пере-решаю**: на этой развилке уже стоял выбор, +ломающий деньги в обе стороны. + +⚠ **Две грабли, забранные у внешних систем — исполнить обе:** +- **остановка обязана НАЗЫВАТЬ свой потолок.** У OpenHands (`max_budget_per_task` + `max_iterations`) + агент упирается в лимит итераций МОЛЧА — известная жалоба. У нас «встал по деньгам» и «встал по + объёму» — разные ответы пользователю и разные ремеди; +- **проверять ПЕРЕД началом единицы работы, а не после.** У LiteLLM пост-фактум-проверка токенного + потолка всегда пробивает его на один вызов. Денежный потолок у нас проверяется в `Reserve` до + вызова — объёмный обязан вести себя так же. + +⚠ **Не сломай ортогональность.** `--ceiling-usd` — кумулятивный КНИЖНЫЙ кап, не бюджет прогона +(`main.go:256-260`). Новый потолок — про работу ЭТОГО прогона. Смешаешь семантику — сломаешь +платформенный расчёт холдов, который на кумулятивности и стоит. + +### §3.2. Смета БЕЗ покупки — ЗАКАЗ; форма свободна + +**Заказано:** платформа может узнать «сколько юнитов затронет пере-проход», НЕ запуская `translate` и +ничего не покупая. + +**Что знать** (проверено мной, пере-проверь): смета уже считается (`projectRebill`) и уже публикуется +в `status --json` полями `rebill_units`/`rebill_usd`. Мешает ровно одно — **тайминг свёртки**: +`status` читает СОХРАНЁННЫЙ глоссарий, а решения лежат в ФАЙЛАХ до следующего `translate`. + +**Форма свободна.** Очевидные кандидаты, оба со своей ценой: +- **флаг у `status`** («сверни решения в память для расчёта и не пиши») — дёшево, но `status` + ратифицирован как ЧИСТО ЧИТАЮЩИЙ ремонтный глагол, и свёртка внутри него это свойство ломает; +- **новый $0-глагол** — честнее по разделению, но новая поверхность CLI и новый документ. +⚠ **Родня, которую надо знать: `resnapshot --dry-run`** — строка **124(в)**, поименована в законе шва +как будущая дверь. Она просит ТУ ЖЕ способность «оценить, ничего не покупая». **Если твоя форма +закрывает обе — скажи это прямо, это удешевляет проект.** + +⛔ **Границы, обе жёсткие, но сформулированы ТОЧНО (первая редакция обе переоценила — нашёл +опровергатель):** +- **$0 — абсолютно:** ни одного провайдерского вызова. +- **Read-only — с ОДНОЙ названной оговоркой:** «ни одной записи в стор» абсолютом быть НЕ МОЖЕТ — + первое касание проекта создаёт и мигрирует базу движка по построению (`backend/internal/pipeline/runner.go:193-197`; + ратифицировано D39.122, у `status` тот же побочный эффект). Требование верное: **никаких записей + СВЕРХ этого first-touch**, и ни одной записи в банк/глоссарий/чекпойнты. +- **Ключей НЕ требует.** ⚠ Якорь первой редакции (`dotenv.go:53-55`) я ВЫДУМАЛ — там середина + докблока про другое. Настоящий носитель: `backend/cmd/tmctl/invocation.go:152-155` (текст отказа, + перечисляющий читающие глаголы) и пин `backend/cmd/tmctl/keysfile_test.go`. + +⚠ **ТРЕТИЙ КАНДИДАТ, ДЕШЕВЛЕ ОБОИХ МОИХ — его нашёл опровергатель, и я его не видел.** У `bank-apply` +УЖЕ ЕСТЬ режим проекции (`invocation.go:126`: «print the projection of the decisions and write +NOTHING»), он берёт тот же арбитр-флок, ничего не пишет и печатает JSON-отчёт. **И у него уже на +руках ровно недостающее состояние**: `readBookState` поднимает bank + seed + delta + rejects ДО +свёртки. Не хватает только statuses и manifest для `projectRebill`. Рассмотри этот путь ПЕРВЫМ: он не +трогает «`status` — чисто читающий» вовсе. + +⛔ **ЛОВУШКА, КОТОРАЯ УБЬЁТ ВЕСЬ СМЫСЛ, если её не увидеть.** Свернуть решения В СТОР ты не сможешь +(`store.go:117-128`, `OpenReadOnly` ставит `PRAGMA query_only=1`), значит фолд будет В ПАМЯТИ. Но +канонический фолд идёт ЧЕРЕЗ стор: `seeding.go` пишет банк, читает его обратно `ORDER BY src, sense, +…` и материализует. Порядок НЕ безразличен — `membank/memory.go:610-617` сортирует стабильно «в +порядке замороженных entries», а дальше токенный бюджет РЕЖЕТ хвост. **Материализуешь «будущий банк» +в порядке добавления — получишь другой набор строк глоссария, другие отрендеренные байты, другой +content-hash: бесплатная смета назовёт одно число, а платный прогон выставит другое.** Это ровно тот +дефект, который пак продаёт как решённый. Докажи тождество, а не предположи его. + +⚠ **И мина формы:** оба поля сметы объявлены `omitempty` (`status.go:208-209`). D39.166 п.2 уже +заплатил за это однажды: «$0-цена мурует дверь — юниты по нулевой цене приходят БЕЗ цены». Если +переиспользуешь форму, «ноль юнитов» и «не считалось» на проводе станут неотличимы. +⚠ **Факт из строки 231, который тебе полезен:** поля `rebill_units`/`rebill_usd` СНЯТЫ с аллоулиста +шва до появления потребителя — вернутся вместе с твоим глаголом. + +### §3.3. Чего в паке НЕТ — пропуски подписаны + +- **Калибровка константы $0.03 — НЕ твоя и НЕ сейчас.** Она платформенная и гейчена строкой **202** + (живой прогон текущего стека). Ты даёшь МЕХАНИЗМ, цену считает не движок. +- **Цена от объёма исходника** (D39.165 §1а) — платформенная половина, носитель `chapters.units_total`. +- **Строки 228 / 230 / 141-остаток / 131** — соседи, не заказ. Увидишь — назови строкой, не чини. + +## §4. Самопроверка ИСПОЛНЕНИЕМ — «перечитал сам» её не удовлетворяет + +1. **Батарея зоны** под `-race`, линтер 0 issues; числа — с командами. +2. **Потолок объёма доказывается ПОСТ-ФИКСНЫМ инвариантом:** прогон с потолком в N единиц + останавливается на N, отвечает признаком «встал по ОБЪЁМУ» (отличимым от денежного), и + останавливается ПЕРЕД началом N+1, а не после. +3. ⛔ **Смета доказывается $0 — и РЕПРО ПЕРВОЙ РЕДАКЦИИ БЫЛО ВЫРОЖДЕННЫМ, я повторил ошибку, о + которой сам же написал эрратy 28.08-и.** Состояние «`translate` не запускался» негодно: у такой + книги строк `chunk_status` нет вовсе, и `projectRebill` отдаёт ПУСТО и до фикса, и после + (`rebill.go:132-134` пропускает строки без снапшота). **Верное состояние: прогон СОСТОЯЛСЯ** + (строки `chunk_status` есть, снапшоты записаны) → **ПОТОМ применена правка банка** → и твой + механизм отдаёт НЕнулевой счёт затронутых юнитов, тогда как сегодняшний `status` на том же + состоянии отвечает нулём. Разница «сегодня ноль / после фикса N» и есть деливерабл. + При этом леджер не двинулся ни на цент, а в стор не ушло ничего сверх first-touch. +4. **Свои посадки мутаций:** минимум по одной на пункт; вердикт — по ДЕЛЬТЕ против чистой базовой + линии и по ТОПИЧНОСТИ упавшего теста, не по цвету батареи. +5. ⛔ **ШИРОКИЙ АДВЕРСАРИАЛЬНЫЙ ПРОХОД ПО СВОЕЙ ГОТОВОЙ РАБОТЕ — ЗАКАЗ, не право** (норма + `CLAUDE.md`, вписана 28.08). Несколько линз, мандат «найди, где я неправ», каждая находка — с + траекторией и `file:line`. **Основание — замер:** пак, где сессия прошлась так по себе, дал шесть + настоящих дефектов, и ЧЕТЫРЕ из них внёс сам пак; другой пак, где прохода не было, сдался с + неработающей починкой внутри и был бы залендан. **Дефекты, которые внёс сам пак, называй первыми.** + ⚠ **Бюджет тяжёлой модели — ОДИН агент либо одна подсессия воркфлоу, на самую тяжёлую линзу**; + остальным — модели попроще. Модель задавай КАЖДОМУ агенту явно и запрещай им порождать своих. + +## §5. Оси ревью — 1–3, вправе заменить с аргументом + +1. **Ось денег:** может ли новый потолок дать перерасход или, наоборот, отказать законной работе; + не сломана ли кумулятивная семантика денежного капа. +2. **Ось «пара, которой в репо нет»:** ветвления по паре/книге в Go быть не должно. +3. **Ось детерминизма:** трогаешь сборку запроса или снапшот — не перекупается ли прогон. + +## §6. Записка-план, комплектность + +**До правок** — записка-план в своей секции журнала. **В конце** — таблица комплектности против §3: +пункт → что сделано → каким ИСПОЛНЕНИЕМ подтверждено. Слово вместо команды = пункт НЕ сделан. + +## §7. Эхо-протокол старта + +ДО работы — ≤10 строк: **скоуп · инварианты · не-делать**. Первое действие — вписать свой блок в файл +канала (§10), сразу второе — послать мне эхо. + +## §8. Obstacle — обязательная секция + +**«Что НЕ удалось и что НЕ проверено»** отдельной секцией, не россыпью. + +## §9. Канал вопросов и твоё право отказаться + +Конфликт промта с кодом или доками — **пинг, не интерпретация в свою пользу**. +⚠ **У тебя есть право сказать «этого делать не надо» — с аргументом.** За последние сутки исполнители +опровергли ЧЕТЫРЕ моих заказа и все четыре раза были правы; два я пере-проверил своей посадкой и +отозвал. Отказ с разбором дороже послушного исполнения. +⚠ **Тесты и гейты не подгонять под зелень** (D39.121). + +## §10. Как со мной связаться + +**Адрес — в файле `/tmp/textmachine-channel`.** Впиши свой блок первым делом, чужие не трогай. +⚠ **Канала нет ⇒ НЕ искать:** вопрос секцией в отчёт, работа продолжается. diff --git a/docs/PLATFORM_P11_SESSION_PROMPT.md b/docs/PLATFORM_P11_SESSION_PROMPT.md new file mode 100644 index 00000000..9f9e80e5 --- /dev/null +++ b/docs/PLATFORM_P11_SESSION_PROMPT.md @@ -0,0 +1,191 @@ +# Промт: платформа, пак P11 — отзыв сессии перестаёт быть словом, застрявшие деньги перестают быть невидимыми + +> **Выдан оркестратором №19, 28.08.2026.** Пак идёт ПАРАЛЛЕЛЬНО бэкендовому. +> ⚠ **ФАЙЛЫ вы не делите** (модули отдельные, платформа кода движка не компилирует — проверено), +> **но ШОВ общий и ведётся руками:** таблица кодов выхода · argv литералами · аллоулист `status --json`. +> Бэкендовый пак трогает первые две. Увидишь расхождение — ПИНГ, батарея его не поймает по построению. +> Источник состава — читающий пак **P8-REVIEW** (D39.159): 24 строки регистра, открытых **23**. +> **Этот пак берёт СЕМЬ**, и почему именно их — §3.5. + +## §0. Какая проблема и что решит твой результат + +**1. «Выйти везде» не выключает уже открытый канал — `PD-379`, единственный открытый `major` +уязвимости.** Аутентификация происходит РОВНО ОДИН РАЗ, на входе в `guard`; дальше `streamEvents` +уходит в `pump`, и цикл до конца соединения строку сессии не смотрит НИ РАЗУ. Значит `logout`, +`logout-all`, `tmplatformctl revoke` и оба потолка сессии (idle и абсолютный) открытый +`GET /v0/books/{bookId}/events` не прекращают. + +⚠ **Это пере-проверено ТРИЖДЫ независимо** (финдер · рефутер в отдельной копии · координатор пака): +`revoke --user` отчитался «revoked 4 sessions», новый запрос той же кукой дал `401`, **а тот же поток +через 9 секунд ПОСЛЕ отзыва отдал настоящий кадр данных**. На демоне с пятисекундным idle и +десятисекундным абсолютным потолком поток жил ещё сорок секунд. + +⚠ **Бьёт по ОБЪЯВЛЕННОЙ норме, а не по вкусу:** ASVS 5.0 7.4.1 — требование УРОВНЯ 1 при объявленном +зоной L2. И `STACK_DECISIONS` §13 отказывается от лимита одновременных сессий **именно в обмен на +мгновенный отзыв** — то есть цена уже заплачена, а товар не получен. + +**2. Застрявшие деньги невидимы ТАМ, КУДА ПОСЫЛАЕТ ЛОГ — `PD-385`, второй `major`.** +⚠ **Абсолюта «невидим вообще» тут НЕТ** — он опровергнут рефутером прошлого пака, и первая редакция +этого промта его по ошибке повторяла: холд ВИДЕН через `tmplatformctl balance --user`, гейдж +старейшего открытого холда растёт, `tmplatformctl books` пишет «WHY NOT: unsettled hold». **Слепы +ТРИ поверхности ПОРОГА, и терминальной ручки нет.** Живая проба на состоянии, выращенном штатными путями: `runs --stalled` отвечает «no run is failing to reconcile», +`runs` — «no run is live», `run abandon` — «is not a live run», гейдж 0 — **при этом в базе +`settled_at` NULL, пять неудач реконсиляции и открытая резервация на 90 000 микро-USD.** + +**Что решит результат:** отзыв сессии станет действием, а не словом; а деньги, застрявшие в расчёте, +станут видны тому, кого лог за ними и посылает. + +## §1. Зона записи и git + +**Твоя зона — `platform/`.** Итоги, находки, вопросы — зонный журнал `platform/docs/platform-PROGRESS.md`. + +- **Ты НЕ коммитишь.** Лендит оркестратор после адверсариальной приёмки. +- ⚠ **`backend/` НЕ ТРОГАТЬ.** Там параллельно работает бэкенд-пак «деньги». Нужна правка там — ПИНГ. +- ⚠ **`docs/` — не твоя зона.** Нужна правка канона контракта — опиши ПРЕДЛОЖЕНИЕМ в своём журнале, + правлю я: канон и константа версии обязаны сойтись в ОДНОМ коммите, а коммичу я. +- ⚠ **Стендовый `tmctl` собирай из ЗАФИКСИРОВАННОЙ копии** `backend/`, если он понадобится: рабочее + дерево сейчас правит параллельная сессия, и бинарь из него мерит непонятно что. Без него живые + тесты просто уходят в SKIP — это нормально и батарея остаётся зелёной. +- В дереве незакоммиченная работа полигона (20 позиций) — не касаться. + +## §2. Карта чтения — ≤5 позиций, ЗАКОН + +1. **`platform/docs/DEFECT_REGISTER.md`**, строки `PD-379` · `PD-385` · `PD-384` · `PD-391` · + `PD-394` · `PD-397` — **тела читать целиком**, там траектории и живые пробы предыдущего пака. +2. **`platform/internal/httpapi/stream.go`** целиком + `guard`/`Require` в `auth` — предмет `PD-379`. +3. **`platform/internal/runs/reconcile.go`** — `settlePhase`, `deferItem`, `StalledAfter`; и + **`platform/internal/pgstore/runs.go`** — `StalledRuns` (`:406`) и `AbandonRun` (`:452`). + ⚠ `AbandonRun` живёт в `pgstore`, а не в `internal/runs` — первая редакция приписала его не туда. +4. **`platform/docs/STACK_DECISIONS.md` §13** — там объявлен размен «нет лимита сессий В ОБМЕН на + мгновенный отзыв», и §-норма уровня ASVS. +5. **`docs/architecture/05-decisions-log.md`, тело D39.159** (греп `^## D39.159`) — акт приёмки + читающего пака, откуда взялись эти строки. + +## §3. Состав пака — ШЕСТЬ строк, две группы + +### §3.1. `PD-379` — отзыв обязан гасить открытый поток. ЗАКАЗ, форма свободна + +**Заказано:** после `logout` / `logout-all` / `revoke`, а равно по истечении **АБСОЛЮТНОГО** потолка +сессии, уже открытый поток событий прекращается. +⛔ **Idle-потолок из заказа ИСКЛЮЧЁН, и это поправка (нашёл опровергатель):** окно бездействия +скользит только на ЗАПРОСЕ (`auth/middleware.go:63-66`), а SSE — ОДИН запрос на всю жизнь соединения. +Значит поток по определению никогда не трогает свою сессию, и гашение по idle убивало бы поток под +АКТИВНЫМ пользователем — это регресс, а не починка. + +**Свободен и обязан обосновать — ГДЕ проверять.** ⚠ **И я зря пугал ценой:** `pump` уже зовёт +`ReadStream` на КАЖДОЙ итерации (`stream.go:169`; комментарий `:29-33` сам считает «два +индексированных запроса в секунду на соединение»), так что проверка сессии кладётся в тот же тик и +лишнего запроса НЕ создаёт. **Значит «окно» заводить не обязательно** — первая редакция гнала тебя к +нему страхом, которого нет. Если окно всё же остаётся — назови его ЧИСЛОМ. + +⛔ **Сигнала «тебя выгнали» в протоколе НЕТ, и это придётся решать.** Заголовок ответа уходит ДО +`pump` (`stream.go:84-85`), поэтому кодом ответа уже не скажешь; терминальных событий ровно два — +`end` («книга закончена») и `resync_required` («пере-синхронизируйся»), и оба скажут клиенту неправду. +**Новое имя события — правка КАНОНА, которую §1 тебе запрещает.** Поэтому: форму назови +ПРЕДЛОЖЕНИЕМ в журнале, я впишу в канон и подниму версию; в коде реализуй так, чтобы имя менялось +одной строкой. ⚠ И не сломай догон: `hello` несёт позицию, гашение обязано быть отличимо от обрыва сети. + +### §3.2. `PD-385` — застрявший расчёт обязан быть виден. ЗАКАЗ + +**Заказано:** прогон с недоведённым расчётом виден операторской поверхности, на которую его посылает +лог-строка, и с ним можно что-то сделать. + +⚠ **Рефутер предыдущего пака ОПРОВЕРГ заголовочный абсолют «невидим» — тело строки это несёт.** +Прочти тело целиком и не чини то, что уже видно: заказ про КОНКРЕТНЫЙ слепой угол, а не про «сделать +всё видимым». + +### §3.3. Денежная группа — четыре строки, все про ОДНО + +`PD-384` (расчёт, упавший ДЁШЕВО, не считается нигде) · `PD-391` (`run abandon` не возвращает холд +«на ближайшем свипе») · `PD-394` (гард отрицательного расхода в `Settle` не запинен) · `PD-397` (два +самых сильных денежных инварианта объявлены, но не запинены). + +**Заказано:** каждая закрыта либо ПИНОМ, либо строкой с причиной, почему не закрывается. +⚠ **Три из четырёх — про ПИНЫ, а не про код.** Это не «мелочь для галочки»: `PD-397` прямо говорит, +что сильнейшие денежные инварианты держатся на слове. Пин, посаженный мутацией, и есть предмет. + +### §3.4. Свободная форма и право пере-формулировать + +Тела строк писаны неделю назад читающим паком. **Дерево с тех пор двигалось трижды** (D39.162, +D39.166 и фикс-раунды). Если строка описывает состояние, которого уже нет, — **это находка, скажи +её, а не чини по букве.** Сегодня такое случалось: строка регистра держалась на основании, снесённом +чужим паком. + +### §3.5. Чего в паке НЕТ — пропуски ПОДПИСАНЫ + +⚠ **Счёт первой редакции был неверен (поправка опровергателя): строк пака 24, закрыта только +`PD-398`, значит открытых ДВАДЦАТЬ ТРИ.** Беру СЕМЬ. +- **Взято:** обе `major` (уязвимость и невидимые деньги) плюс денежная группа, которая с `PD-385` + составляет ОДИН предмет — «деньги, застрявшие или не посчитанные». +- ⚠ **`PD-376` ДОБАВЛЕНА** — первая редакция не назвала её НИ ВО ВЗЯТЫХ, НИ В ПРОПУСКАХ, а это + нарушение нормы «пропуски подписаны», и на самом дешёвом пункте: строка ДЕНЕЖНАЯ (`PD-159` стоит + `fixed`, но её пин доказывает свойство СЛАБЕЕ, чем читается — мутация проходит батарею), а готовый + пин уже написан ФАЙЛОМ в `platform/docs/p8-review/axis1-money/`. Возьми и проверь посадкой, что он + ловит именно ту мутацию. +- **НЕ взято и почему:** группа телеметрии (`PD-389`, `PD-390`, `PD-392`, `PD-393`) — отдельный + предмет, ей нужен свой пак и своя ось ревью · группа сессий и кук (`PD-380`…`PD-383`) — родня + `PD-379`, но **сознательно оставлена**: сначала закрыть уязвимость, потом чистить её окрестность, + иначе пак распухнет вокруг самого срочного · `PD-375`, `PD-377`, `PD-378`, `PD-386`…`PD-388`, + `PD-395`, `PD-396` — россыпь `minor`/`info`, идёт следующим паком. ⚠ `PD-398` первая редакция + включила в этот список ОШИБОЧНО — она уже `fixed` (приёмка 27.08). +- ⚠ **Увидишь по дороге, что невзятая строка чинится ОДНОЙ строкой внутри твоего же диффа — бери и + скажи.** Запрет тут не ради чистоты, а ради размера. + +## §4. Самопроверка ИСПОЛНЕНИЕМ — «перечитал сам» её не удовлетворяет + +1. **Батарея зоны** под `-race` С ЖИВЫМ Postgres, линтер 0 issues; числа — с командами. + ⚠ **`TM_PLATFORM_TEST_DSN` ставить ОБЯЗАТЕЛЬНО:** без него значительная часть батареи уходит в + SKIP, а зелень рапортуется всё равно. **Число пропусков посчитай КОМАНДОЙ** и приведи с DSN и без. +2. ⛔ **`PD-379` доказывается ЖИВЬЁМ и ДВУМЯ РАЗДЕЛЬНЫМИ сценариями — первая редакция склеивала их в + один, и склейка делала регресс зелёным** (нашёл опровергатель): реализация «таймер до абсолютного + потолка» гасит поток по потолку, сценарий зелен, а ОТЗЫВ не починен. + **(а) ДЛИННЫЕ потолки + `revoke`** → доказывает отзыв. **(б) короткие потолки БЕЗ отзыва** → + доказывает потолок. ⚠ Юнит на + «функция проверки вызвана» — вырожденный: сегодня она вызвана один раз на входе, и это ровно + дефект. +3. **`PD-385` доказывается СОСТОЯНИЕМ, выращенным штатными путями** (интейк → HTTP-старт → отказ + спавна → `abandon`), как его и нашли, а не подложенной строкой в базе. +4. **Свои посадки мутаций:** минимум по одной на пункт; вердикт — по ДЕЛЬТЕ и ТОПИЧНОСТИ упавшего + теста, не по цвету батареи. +5. ⛔ **ШИРОКИЙ АДВЕРСАРИАЛЬНЫЙ ПРОХОД ПО СВОЕЙ ГОТОВОЙ РАБОТЕ — ЗАКАЗ, не право** (норма + `CLAUDE.md`, вписана 28.08). Несколько линз, мандат «найди, где я неправ», каждая находка — с + траекторией и `file:line`. **Основание — замер: твой же пак P10 прошёл такой проход и нашёл, что + починка, объявленная сделанной, НЕ работала.** Без прохода он был бы залендан. **Дефекты, которые + внёс сам пак, называй первыми.** + ⚠ **Бюджет тяжёлой модели — ОДИН агент либо одна подсессия воркфлоу, на самую тяжёлую линзу.** + Модель задавай КАЖДОМУ агенту ЯВНО и запрещай им порождать своих: 28.08 неявно заданная модель и + незапрещённый веер стоили оркестратору убитого захода. + +## §5. Оси ревью — 1–3, вправе заменить с аргументом + +1. **Ось «что видит атакующий»** — не оператор и не тест: тот, у кого отозвали доступ. +2. **Ось денег:** может ли починка `PD-385`/`PD-391` дважды вернуть один холд или вернуть чужой. +3. **Ось «поток под нагрузкой»:** пере-проверка сессии на каждом кадре — это запрос к стору на каждый + тик; не превращается ли гашение в новую стоимость. + +## §6. Записка-план, комплектность + +**До правок** — записка-план в зонном журнале. **В конце** — таблица комплектности против §3: строка → +что сделано → каким ИСПОЛНЕНИЕМ подтверждено. Слово вместо команды = пункт НЕ сделан. + +## §7. Эхо-протокол старта + +ДО работы — ≤10 строк: **скоуп · инварианты · не-делать**. Первое действие — вписать свой блок в файл +канала (§10), сразу второе — послать мне эхо. + +## §8. Obstacle — обязательная секция + +**«Что НЕ удалось и что НЕ проверено»** отдельной секцией, не россыпью. + +## §9. Канал вопросов и твоё право отказаться + +Конфликт промта с кодом или доками — **пинг, не интерпретация в свою пользу**. +⚠ **У тебя есть право сказать «этого делать не надо» — с аргументом.** За последние сутки исполнители +опровергли ЧЕТЫРЕ моих заказа и все четыре раза были правы. Отказ с разбором дороже послушного +исполнения. +⚠ **Тесты и гейты не подгонять под зелень** (D39.121). + +## §10. Как со мной связаться + +**Адрес — в файле `/tmp/textmachine-channel`.** Впиши свой блок первым делом, чужие не трогай. +⚠ **Канала нет ⇒ НЕ искать:** вопрос секцией в отчёт, работа продолжается. diff --git a/docs/README.md b/docs/README.md index 07fff206..b6371780 100644 --- a/docs/README.md +++ b/docs/README.md @@ -22,8 +22,8 @@ | Роль | Активный промт | Статус | |---|---|---| | Оркестратор | [ORCHESTRATOR_SESSION_PROMPT.md](ORCHESTRATOR_SESSION_PROMPT.md) | роль и нормы; счётчик роли — CURRENT-STATE | - | Бэкенд | активного НЕТ | пак «тихая порча» ОТРАБОТАН, ПРИНЯТ и ЗАЛЕНДЖЕН 28.08 (**D39.164**): инъекция банка больше не теряется на провайдере с одним системным слотом, дыра выдачи видна читателю В ТЕКСТЕ, повтор принятого документа сходится. Промт — в `archive/prompts/`. ⚠ Заказ §3.2 был ПЕРЕ-ФОРМУЛИРОВАН находкой исполнителя (маркер существовал и врал), а подсказка промта про место правки ОТКЛОНЕНА им с грунтом — оба решения ратифицированы. Свободные строки зоны: **228** (алиас возвращает отклонённую поверхность), **230** (размен сходимости), **141**-остаток, **131**. Четыре промта входной двери шва — в `archive/prompts/` (D39.158) | - | Платформа | активного НЕТ | пак **P10** ОТРАБОТАН, ПРИНЯТ и ЗАЛЕНДЖЕН 28.08 (**D39.166**) вместе с минором **0.7.0**: мина под правкой банка обезврежена, пере-проход можно КУПИТЬ. Промт — в `archive/prompts/`. ⚠ **Первая сдача пака была НЕВЕРНОЙ**, и это нашёл ШИРОКИЙ самопроход сессии (заказан владельцем 28.08, канон дополнен `40a649c`): три фатальные находки, включая «мина, объявленная обезвреженной, стоит». Две ошибки оркестратора вынесены эрратой 28.08-к. Следующая работа зоны — кодовый пак по 23 открытым строкам P8-REVIEW либо эпоха смены формы конвейера (`PD-403`/`PD-404`, D39.165 §2) | + | Бэкенд | [BACKEND_MONEY_PACK_SESSION_PROMPT.md](BACKEND_MONEY_PACK_SESSION_PROMPT.md) | **НАПИСАН, ждёт запуска владельцем.** Пак «деньги»: потолок ОБЪЁМА в движке рядом с денежным (D39.165 §1б) + $0-глагол сметы «оценить, ничего не покупая» (строка **231**). Оба рубежа пройдены: механический + опровергатель, **9 находок применены**, включая три фатальные — форма ответа через шов (словарь кодов ЗАМОРОЖЕН; решено: стоп по объёму = ЗАВЕРШЕНИЕ, код 0), выдуманный мной якорь, и вырожденное репро, повторявшее эррату 28.08-и. ⚠ Честная граница вписана в §0: проводка числа глав до движка паком НЕ заказана | + | Платформа | [PLATFORM_P11_SESSION_PROMPT.md](PLATFORM_P11_SESSION_PROMPT.md) | **НАПИСАН, ждёт запуска владельцем.** Пак **P11** по строкам читающего ревью: единственная открытая уязвимость `PD-379` (отзыв сессии не гасит открытый поток — проверено трижды независимо) + `PD-385` (застрявшие деньги невидимы там, куда посылает лог) + денежная группа. Семь строк из 23 открытых, шестнадцать пропусков подписаны поимённо. Оба рубежа пройдены, **8 находок применены** | | Полигон | [POLYGON_EXP2223_REDO_SESSION_PROMPT.md](POLYGON_EXP2223_REDO_SESSION_PROMPT.md) (отложенный — [POLYGON_PACKAGE4_SESSION_PROMPT.md](POLYGON_PACKAGE4_SESSION_PROMPT.md), строка 85) | фаза Д ИДЁТ; ⚠ живой носитель курса — в `eval/dovodka/`, какой именно называет зона (⚠ [POLYGON_PHASE_D_HANDOFF.md](POLYGON_PHASE_D_HANDOFF.md) — перекрытый снимок, читать не как курс) | | Фронт | активного НЕТ | **ЗОНА ЗАМОРОЖЕНА** (D39.136 п.2 + D39.147: разморозка отдельным словом владельца, не привязана к P7); перечень первого касания — в зонном журнале | | Контракт | активного НЕТ | минор **0.7.0** ПРИНЯТ и заленджен 28.08 (**D39.166**): пере-проход продаётся членом `RunRequest.re_pass`, полоса такого прогона объявлена «одной неделимой единицей работы», фраза «finished work is not bought twice» ограничена. До него в тот же день — **0.6.0** (D39.162/D39.163: сквозная полоса, `Progress.stage` вторым исключением границы) и **0.5.0** (D39.161, дверь правок банка). ⚠ Названная цена 0.7.0: смету «затронуто N юнитов» ДО покупки провод НЕ несёт — строка **231**. Хвост компаньона — строка **203** |