diff --git a/docs/BACKEND_CONSENT_SESSION_PROMPT.md b/docs/BACKEND_CONSENT_SESSION_PROMPT.md new file mode 100644 index 00000000..2ec1e708 --- /dev/null +++ b/docs/BACKEND_CONSENT_SESSION_PROMPT.md @@ -0,0 +1,91 @@ +# Промт сессии: БЭКЕНД — «число согласия на пути второй покупки» + +> **Роль:** бэкенд. **Зона записи:** `backend/`. **Не коммитишь** — дерево готовишь и передаёшь на +> лендинг оркестратору. Чужие зоны читаешь, не правишь. Норматив стиля — `docs/architecture/12-go-style-notes.md`. + +## Какая проблема и что изменит твой результат + +Продукт продаёт главы **частями**. Покупатель берёт кусок, потом ещё кусок — и на этом пути число, +которым движок спрашивает согласия на оплату, **врёт в трёх местах**, а один юнит может быть оплачен +дважды. После пака покупатель, берущий книгу частями, видит число, которое не занижает при смене +модели стадии, признаётся, какая его часть — старые деньги, и не платит второй раз за юнит, который +уже двигал. + +## Карта чтения — пять позиций, дальше только по их ссылкам + +1. Шапка-таблица `docs/architecture/09-target-architecture.md` — что построено. +2. `backend/README.md` · `docs/architecture/03-implementation-notes.md` (через баннер). +3. `docs/architecture/15-money-path.md` — денежный путь целиком, включая §2 «согласие на пере-оплату». +4. Строка **197** единого бэклога (`docs/PROGRESS.md`) — фикс-лист ФЧ-1…ФЧ-8, и строка **232**. +5. Нота **D39.150** — тело ратификации ФЧ-5 (греп `^## D39.150`). + +## Состав — четыре пункта, в этом порядке + +**1. ФЧ-5 — ось МОДЕЛИ в числе согласия. Ратифицирован 17.08 (D39.150 п.1) и НЕ построен.** +Ратифицировано дословно: прайсить по модели, которую стадия резолвит **сейчас**; при незнании +округлять **вверх**; оговорка в тексте согласия. Нота помечает это обязательным **до первого +пере-прогона со сменой модели стадии**. Сегодня первый же такой пере-прогон занижает число согласия +молча — ровно тот вред, ради которого чинилась строка 181. +⚠ **Проверь исходное состояние САМ** и не бери с моих слов: оркестратор утверждал, что «шапка +`rebill.go` заявляет обратное ратифицированному», и **это не подтвердилось** — в шапке речь про +`$0 model`. Формулируй по коду, который увидишь. + +**2. Строка 232, ВТОРАЯ половина.** Первая (читающий метод `store.AnnouncedOnceKeys()`) исполнена +31.08. Живой остаток: **юнит, прерванный МЕЖДУ волнами, тратит слот объёмного гранта повторно** — +покупатель платит за N глав и получает меньше. Разбор — `backend/docs/MONEY_HONESTY_REPORT.md` §4.5. +⚠ **Оговорка веса, проверь её:** платформа сегодня продаёт денежным потолком (`--ceiling-usd`), а +`--max-units` не передаёт вовсе — то есть вред пока не доезжает до пользователя через платформу. +Это меняет приоритет, но не отменяет дефект. + +**3. ФЧ-4 — раскрытие «часть суммы — старые деньги» не доезжает до `status --json`:** +`HistoricalRows` теряется на границе. Покупатель не может отличить новую трату от уже оплаченной. + +**4. ФЧ-1 — посадки на гарантии, чьи мутации ПЕРЕЖИВАЮТ зелёную батарею.** +⚠ **Ограничь тремя**, поимённо: D39.149 п.5 называет три HIGH. Не превращай в бесконечный список — +это последний пункт, и он берётся, если осталось время. + +## Границы — что НАМЕРЕННО не берём + +- **Строка 160 «структура глав, Этап 0»** — хотя слово владельца 15.08 ставит её ближайшим паком и её + блокер закрыт 30.08. Причина техническая: строка требует бампа **формы манифеста**, а параллельно + идёт платформенный пак, и незнакомая форма манифеста отправляет КАЖДУЮ новую книгу в `rejected`. + Берётся отдельно, со стоп-миром. +- **Читающая сторона банка** (строки 221 · 224 · 226 · 228 · 230) — крупнейшая продуктовая дыра зоны, + но её гейт не техника, а **слово владельца**. Вопрос вынесен ему отдельно. +- **Следующий платный замер** — не в этом паке: у его оси «эффорт off против low» не разрешено + предусловие (см. ниже), и до решения владельца он не заказывается. + +## ⚠ ПОРЯДОК ДЕПЛОЯ — почему пак безопасен параллельно платформе + +Зоны независимы по коду, но **не по деплою**: форма манифеста требует «платформа первой», схема +хранилища v16 — «движок первым». **Пак НЕ меняет форму манифеста, схему хранилища и версию +контракта.** Понадобилось — **стоп и пинг**, не «сделаю аккуратно». + +## Свобода и её разметка + +«Делай РОВНО так» — порядок пунктов · границы выше · запрет на три вещи из порядка деплоя · +ограничение ФЧ-1 тремя посадками. **Решаешь сам и аргументируешь**: форма хранения и проводки +модели в числе согласия, форма раскрытия исторических строк, состав посадок. + +## Мандат самопроверки — исполнением + +`make battery` — не отчёт, а предусловие. Обязательны: **дифф `^func Test` исполнением, не памятью** · +**собственные адверсариальные посадки ВНЕ списка выше** · **отдельный проход по СВОЕЙ ГОТОВОЙ работе** +свежим контекстом. Субагенты разрешены явно; модель задавай ИМЕНЕМ. +⚠ **Править или удалять тест ради зелени — недопустимо.** Правка, вызванная сменой поведения, которая +заказана этим промтом, — обслуживание, и она **объявляется в отчёте**: что изменилось в поведении, +какой тест это описывал, куда уехала гарантия. +⚠ Перед отчётом **сверь каждый клейм с результатом инструмента ЭТОЙ сессии**. Последний абзац — +план или обещание? Сделай сейчас. + +## Отчёт + +Записка-план ДО работы (эхо: скоуп · инварианты · не-делать) в секцию «Бэкенд» `docs/PROGRESS.md`. +Итог — туда же, каждое число **с командой получения**. Обязательная секция **«Что НЕ удалось и что +НЕ проверено»**. Конфликт промта с кодом — **пинг через владельца, не интерпретация**. + +## Прямой канал + +Механизм — `CLAUDE.md`, секция «Связь между сессиями». Свой блок в `/tmp/textmachine-channel` — +первым делом. ⚠ Адрес из файла **не доказательство, что сессия жива**: сверяйся с `ListAgents`. +Нужной роли нет ⇒ **канала нет, это НОРМАЛЬНЫЙ случай**, вопрос секцией в отчёт. diff --git a/docs/PLATFORM_P13_SESSION_PROMPT.md b/docs/PLATFORM_P13_SESSION_PROMPT.md new file mode 100644 index 00000000..bd08968e --- /dev/null +++ b/docs/PLATFORM_P13_SESSION_PROMPT.md @@ -0,0 +1,109 @@ +# Промт сессии: ПЛАТФОРМА, пак P13 — «шов возврата оплаченного прогона» + +> **Роль:** платформа. **Зона записи:** `platform/`. **Не коммитишь** — дерево готовишь и передаёшь +> на лендинг оркестратору (канон — `CLAUDE.md`, таблица ролей). Чужие зоны читаешь, не правишь. +> **Обязателен к ссылке:** `platform/docs/ENGINEERING_STANDARDS.md`; отступление от него — пинг, не +> самовольство. Направление зоны — `platform/docs/PLATFORM_DIRECTION.md`. + +## Какая проблема и что изменит твой результат + +Оплаченный прогон сегодня может подорожать, зависнуть или замереть на экране — **без вины +пользователя и без единого сигнала оператору**. Четыре независимых пути ведут к одному и тому же: +человек заплатил, а получил либо не то, либо ничего, и вывести его из этого состояния нечем, кроме +psql. После пака оплаченный прогон возвращается на **те деньги, за которые был продан**, оператор +перестаёт начислять кредиты дважды, а чужой процесс перестаёт замораживать чужую проекцию. + +## ⚠ ПРЕДУСЛОВИЕ, НЕ ПУНКТ РАБОТЫ — прочти прежде всего + +**Экспортируй `TM_PLATFORM_TEST_DSN` до первой команды.** Замер 02.09 на этом хосте: +`go test ./... -count=1` в `platform/` без DSN даёт **661 тест: PASS 342, SKIP 319, FAIL 0, exit 0**, +все 18 пакетов «ok». В `pgstore` тёмно 167 из 177, в `runs` — 110 из 135, и среди пропущенных — +**105 тестов денежного пути реконсилятора**. + +⚠ `make check` про это ЧЕСТЕН — печатает «did NOT run (set TM_PLATFORM_TEST_DSN…)» и имена скипов. +Молчит именно голый `go test ./...`. + +**Цена, которую ты обязан не повторить:** в регистре **восемь рядов** заведены с формулировкой +«мутация пережила ПОЛНУЮ батарею», **четыре из них открыты** (`PD-433`, `PD-386`, `PD-389`, `PD-388`), +и ни один не называет DSN. На хосте без базы такой вердикт не значит ничего. +⇒ **Каждая посадка мутации в твоём отчёте обязана нести строку «гонялось при DSN = да».** Иначе пак +проверит себя ровно тем способом, каким заводились ряды, которые он чинит. + +## Состав пака — четыре правки и один гейт + +**1. ГЛАВНОЕ — денежный бюджет прогона ЧИТАТЬ, а не пере-выводить из ставки.** +`internal/runs/reconcile.go`, греп `s.Pricing.Ceiling(l.CeilingChapters)` в `reopen`: бюджет берётся +из ставки СЕГОДНЯШНЕГО деплоя. Вызывающих двое — свиповый `restart` и **контрактный `Resume`**, то +есть путь дёргает пользователь. Смена `TM_PLATFORM_USD_PER_CHAPTER` между покупкой и продолжением +молча пере-оценивает уже оплаченный прогон в обе стороны; при удвоении ставки на тонком счёте он +становится невозобновляемым. Носитель — `PD-168` (стоит `minor`, вес занижен). +**Задача:** сумма, на которую пользователь согласился, хранится при покупке и читается при +перезапуске. Форму решаешь сам и аргументируешь. + +**2. `PD-89` — печатать ключ идемпотентности НА ПУТИ ОШИБКИ.** `write()` чеканит `id = newKey()`, +зовёт денежную операцию и на ошибке возвращает `err`, **не напечатав ключ**. Неоднозначный обрыв на +коммите → оператор повторяет без `--key` → **второе начисление**. Комментарий тремя строками ниже +описывает ровно эту ловушку, но только для пути чтения баланса. Лечение — одна строка; посадка +обязательна. + +**3. `PD-426` + `PD-214` — решать «ЧЕЙ handshake» ПРЕЖДЕ, чем его валидировать.** +`internal/ingest/tail.go`, функция `apply`: четыре отказа (декод, `checkVersion`, пустой +`EngineRunID`, `Seq != 1`) стоят ВЫШЕ ветки «another attempt's stream begins here». Чужой ЗАКОННЫЙ +hello карантинит проекцию **оплаченного живого прогона**, снятия карантина в дереве нет, операторской +ручки нет. Гейдж `tm_platform_quarantined_attempts` это видит и молчит о том, что делать. +**Задача:** перестановка решения о принадлежности выше валидации + ручка снятия карантина. + +**4. МЕЛКОЕ, закрывающее урок пака: гейт батареи печатает ВСЕ условия хоста, а не первое.** +Сегодня `platform/Makefile` подсказывает роль первого недостающего условия и молчит про остальные. + +**5. ГЕЙТ ПРОТИВ КЛАССА, а не против ряда** (заказ оркестратора №22, замер 02.09): колонка +серьёзности регистра разъехалась с сутью — **21 открытый ряд** несёт два и более слова тревоги +(деньги · холд · «молча» · блокирует · невидим · 500 · паника) при `minor`/`info`. Добавь в гейт +зоны печать таких рядов. Без него следующая разведка снова доложит «major всего два». + +## Границы — что НАМЕРЕННО не берём + +- **`PD-412`/`PD-413` (LATERAL в полосном агрегате).** Находки настоящие и замеренные (1.359 мс → 0.307 мс + на книге 2283 глав), но это переписывание запроса в горячем read-модельном пути, а арифметика полосы + в этом паке не трогается. Контенция, а не корректность денег. +- **`PD-162` (клин на удалённом каталоге).** Настоящий и денежный, но его терминальность — это эскроу + (П-18), а половину эскроу рядом с проектируемым целым зона уже отказывалась строить (диспозиция P7). +- **Дверь выдачи** — отдельный пак: он требует минора канона и сводит на себя все точки столкновения. + +## ⚠ ПОРЯДОК ДЕПЛОЯ — почему пак безопасен параллельно бэкенду + +Зоны независимы по коду (разные модули, импортов нет, `go.work` в корне отсутствует), но **НЕ по +деплою**, и сцеплений ДВА с противоположным порядком: форма манифеста ⇒ «сначала платформа, потом +движок» (незнакомая форма → `parser_unavailable`, интейк массово отклоняет); схема хранилища v16 и +обход ⇒ «движок первым → `tmctl migrate` → потом платформа» (D39.158 п.6). +**Поэтому:** пак НЕ меняет форму манифеста, схему хранилища и версию контракта. Понадобилось — +**стоп и пинг**, не «сделаю аккуратно». + +## Свобода и её разметка + +«Делай РОВНО так» — предусловие DSN · строка «DSN = да» у каждой посадки · границы выше · запрет на +три вещи из порядка деплоя. Всё остальное — **решаешь сам и аргументируешь**: форма хранения бюджета, +форма ручки снятия карантина, состав посадок, порядок работ внутри пака. + +## Мандат самопроверки — исполнением, не перечитыванием + +Батарея зелёная — это НЕ отчёт. Обязательны: **живая проба каждого из четырёх путей** под DSN · +**собственные адверсариальные посадки ВНЕ списка выше** · и **отдельный проход по СВОЕЙ ГОТОВОЙ +работе** свежим контекстом. Субагенты разрешены явно; модель задавай ИМЕНЕМ и знай, сколько их +работает. ⚠ Класс, купленный этой сменой: веер по исходным уликам находит втрое меньше, чем веер, +читающий готовый результат. + +## Отчёт + +Записка-план ДО работы (эхо-протокол: скоуп · инварианты · не-делать) в `platform/docs/platform-PROGRESS.md`. +Итог — туда же. Каждое число и каждая категорика — **с командой получения**: приёмка пере-ранит. +Обязательная секция **«Что НЕ удалось и что НЕ проверено»** — «не проверено» ≠ «опровергнуто». +Конфликт промта с кодом — **пинг через владельца, не интерпретация**; право сказать «этого делать не +надо» с аргументом у тебя есть. + +## Прямой канал + +Механизм — `CLAUDE.md`, секция «Связь между сессиями». Впиши свой блок в `/tmp/textmachine-channel` +первым делом; адрес роли бери оттуда, но **сверяйся с `ListAgents`: адрес из файла не доказательство, +что сессия жива**. Нужной роли нет ⇒ **канала нет, и это НОРМАЛЬНЫЙ случай — не опрашивай сессии +подряд**, вопрос секцией в отчёт. diff --git a/docs/README.md b/docs/README.md index 1fba89a4..c8eefcd1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -22,8 +22,8 @@ | Роль | Активный промт | Статус | |---|---|---| | Оркестратор | [ORCHESTRATOR_SESSION_PROMPT.md](ORCHESTRATOR_SESSION_PROMPT.md) | роль и нормы; счётчик роли — CURRENT-STATE | - | Бэкенд | активного НЕТ | последний пак — «деньги и честность выдачи», принят и заленджен 31.08 (**D39.182**; закон раскрытия — **D39.181**). Открыто: различение уровней теста (вопрос владельцу) · §2.2 против `snapshotdiff` · строка **246** (чинит платформа) | - | Платформа | активного НЕТ | последний пак — P12 «долги под ногами», принят и заленджен 31.08 (**D39.180**) вместе с контрактным минором. Открытое зоны — её регистр дефектов (`platform/docs/DEFECT_REGISTER.md`, счёт — `counts.py --check`) | + | Бэкенд | [BACKEND_CONSENT_SESSION_PROMPT.md](BACKEND_CONSENT_SESSION_PROMPT.md) | последний пак — «деньги и честность выдачи», принят и заленджен 31.08 (**D39.182**; закон раскрытия — **D39.181**). Открыто: различение уровней теста (вопрос владельцу) · §2.2 против `snapshotdiff` · строка **246** (чинит платформа) | + | Платформа | [PLATFORM_P13_SESSION_PROMPT.md](PLATFORM_P13_SESSION_PROMPT.md) | последний пак — P12 «долги под ногами», принят и заленджен 31.08 (**D39.180**) вместе с контрактным минором. Открытое зоны — её регистр дефектов (`platform/docs/DEFECT_REGISTER.md`, счёт — `counts.py --check`) | | Полигон | [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); перечень первого касания — в зонном журнале | | Контракт | активного НЕТ | канон — `architecture/14-api-contract/`; ⚠ версию брать ФАЙЛОМ (`grep '^ version:' openapi.yaml`), не отсюда: миноры ратифицируются D-нотами и их содержание грепается по реестру нот. |