Remove the spent sqlc prompt from the active directory: the archived copy landed but the original stayed, the same miss as with the two prompts before it

This commit is contained in:
heaven 2026-08-29 22:45:59 +03:00
parent 63fcee5749
commit 24b1a94ad0

View file

@ -1,184 +0,0 @@
# Промт: платформа, пак `sqlc` — конверсия свободного от склейки блока `pgstore`
## 0. Что это за работа и почему она отдельной сессией
Платформа собирает SQL строками в Go. Класс дефектов, который это порождает, зона ловила дважды
рантайм-падениями. Владелец 20.08 решил взять **`sqlc`** — генератор типизированных методов из
`.sql`-файлов (**D39.153 п.6а**, «я вообще за»), а 22.08 уточнил: **отдельной сессией, не внутри
содержательного пака** (D39.154), потому что правок много и мешать их с другой работой нельзя.
Ты — эта сессия. Носитель работы — `platform/BACKLOG.md` строка **П-19**.
⚠ **И сразу главное, чего промт не скрывает: бо́льшую часть ценности sqlc зона уже получила другим
механизмом.** Гейт `pgstore.TestEverySQLStatementParsesAgainstTheMigratedSchema`
(`internal/pgstore/sqlgate_test.go:36`) планирует ЖИВЫМ Postgres каждый собранный запрос пакета против
мигрированной схемы — то есть закрывает класс «нет такой колонки» для ВСЕХ операторов, включая те, куда
sqlc не дойдёт никогда, и где случились оба реальных падения зоны. По разбору **D39.155 п.9** остаётся
узкий остаток: **арность `$n` и цели `Scan`**.
**Что решит твой результат:** снимет остаток, которого гейт не берёт, и уберёт ручную сборку там, где
она не нужна. **Чего не решит:** склейки, read-модель и денежные транзакции остаются рукописными.
## 1. Зона записи и git
Пишешь только в `platform/`. **Не коммитишь**: дерево готовишь и передаёшь оркестратору, он лендит.
Канон git — `CLAUDE.md`, здесь не дублируется. Чужие незакоммиченные файлы не трогать.
## 2. Карта чтения — ПЯТЬ позиций, дальше только по их ссылкам
1. `platform/docs/PLATFORM_DIRECTION.md` §3 — **сначала верхний слой-баннер 22.08**: по `sqlc` действует
НЕ то решение, что записано ниже в разделе; отказ пака P7 там — история, а не действующая норма.
2. `platform/BACKLOG.md` строки **П-19** (эта работа) и **П-21** (см. §3.5 — флейк в твоей же зоне).
3. `platform/docs/ENGINEERING_STANDARDS.md` — норматив зоны; отступление от любого пункта = пинг.
4. `platform/internal/pgstore/sqlgate_test.go` — гейт, который уже съел бо́льшую часть ценности, и его
экстрактор. **Прочти ДО решения, что строишь** (§3.4 — там ловушка, решаемая до первой строки).
5. `platform/docs/STACK_DECISIONS.md` §«Гейты батареи» — **единственный носитель** числа условий батареи.
## 3. Работа
### 3.0 ⛔ ПЕРВЫМ ДЕЙСТВИЕМ — СИНХРОНИЗАЦИЯ С КОДОМ (делай РОВНО так, слово владельца)
Все числа ниже — мои на 29.08, и часть из них уже расходилась с носителями. **Пере-считай сам, до
первой правки**, и назови расхождения в отчёте: расхождение — факт, а не твоя ошибка. Заодно сверь, что
`git status` чист и в дереве нет чужой незакоммиченной работы.
### 3.1 Затем — ОТВЕТ, а не код (реши сам, аргументируй)
**Вопрос: что `sqlc` даёт СВЕРХ существующего гейта?** Ответь ЧИСЛАМИ до первой строки конфигурации:
сколько запросов набора не проверяется сегодня ничем, какие классы ошибок это ловит, что из этого не
ловится дешевле.
⚠ **Число «два запроса, не исполняемых ничем» взято из D39.155 п.9, НЕ проверено мной и, вероятно,
занижено.** Мой опровергатель нашёл статически минимум четыре функции набора без единой ссылки из
тестов пакета: `OpenReservations` (`credits.go:142`), `ReleaseUnspawned` (`credits.go:324`),
`DeleteOldLoginEvents` (`identity.go:73`), `UserByIdentity` (`identity.go:121`) — их вызовы живут под
`cmd/`, где тесты есть, но достигают ли они этих путей, никто не проверял. **Метод определения выбираешь
сам** (покрытие живым прогоном / инструментальный анализ), но метод назови: это самое дорогое число
пака, и на нём висит развилка «строить или нет».
- Ответ «существенно больше остатка» — строй, покажи расчёт.
- **Ответ «почти ничего» — СКАЖИ ЭТО и остановись.** Законный исход (см. §7), а не провал: владелец
сказал «БЕРЁМ», зная довод про гейт, но твоих чисел на сегодняшнем дереве он не видел.
### 3.2 Граница набора — числа уехали, носители расходятся (делай РОВНО так: считай сам)
П-19 называет **41 запрос**. Моя пере-проверка 29.08 даёт **42**: `credits.go` 15 · `identity.go` 13 ·
`idempotency.go` 7 · **`sessions.go` 6** (было 5; пак P11 добавил `StillLive`, лендинг `e548e5a`) ·
`observe.go` 1. Операторов в пакете вне тестов — около **168**, то есть набор это примерно **четверть
пакета**, а не шестая часть. ⚠ Сам гейт в комментарии (`sqlgate_test.go:21-23`) даёт третью оценку доли
склеенного — **носители расходятся, выбери и назови свой метод счёта, а не наследуй чужой**.
⚠ **Граница описана оптимистичнее, чем есть (D39.155 п.9), и это твой главный риск:**
- **набор НЕ замкнут по транзакции**: **8 запросов** идут из транзакций неконвертируемого кода — все в
`credits.go` (`lockBalance`, `holdTx`, `appendLedger`, `closeReservation`, `lockBook`), достижимы из
`runs.go`, `books.go`, `readmodel.go`, `sink.go`. Генерённый метод, вызванный внутри чужой транзакции,
обязан её ПРИНИМАТЬ, а не открывать свою.
- ⚠ **Поправка к самой ноте, проверенная мной:** её фраза про «занижено вдвое» неверна. Денежных
запросов в чужой транзакции — **11 из 15** в `credits.go`, и это точно; **20** — это ВСЕ
транзакционные запросы набора (11 денежных + 5 `identity` + 4 `idempotency`). Не ищи девять
несуществующих денежных запросов и не расширяй денежную границу на `identity`/`idempotency`.
### 3.3 Стройка (форму выбираешь сам, ограничения жёсткие)
- **Инструмент пинится ТОЧНОЙ версией**, как `golangci-lint` в `platform/Makefile:21` с гейтом версии
на `:55`. Версию бери ЖИВОЙ проверкой у вендора, не из памяти и не из этого промта. `sqlc` в тулчейне
сейчас нет — установка твоя.
- **Гейт актуальности генерации — В БАТАРЕЕ (делай РОВНО так).** Не просто цель `Makefile`: цель,
которую `make check` не зовёт, гейтом не является, а П-19 заказывает именно гейт «сгенерённое
актуально». Прогон на чистом дереве не меняет ни байта.
- **Строка в `STACK_DECISIONS.md`** — обязательный деливерабл зоны для любой новой зависимости
(`ENGINEERING_STANDARDS.md:12-14`): дата релиза и «зачем». **Ратифицирует оркестратор** — пришли её
вместе с деревом, не считай сделанной сама.
- **Денежные типы требуют `overrides`**: micro-USD целочисленный, и генерённый слой не имеет права
превратить его в float ни на одном шаге (класс PD-15).
- ⛔ **Не двигать:** склейки, фрагменты-константы, read-модель (`readmodel.go` — страница, её ревизия,
курсор, водяной знак и агрегаты в ОДНОЙ транзакции).
- ⚠ **Шов, который надо решить явно:** `lockBook` живёт в конвертируемом `credits.go:481`, но зовётся из
`readmodel.go:262` и `books.go:374` — то есть стоит ровно на границе ⛔-зоны и набора. Конвертировать
или оставить — **реши и аргументируй**, молча не бери ни то ни другое.
### 3.4 ⛔ РАЗВИЛКА, КОТОРУЮ РЕШАЮТ ДО ПЕРВОЙ СТРОКИ КОНФИГУРАЦИИ
**Куда генерировать: в сам `pgstore` или в под-пакет (дефолт `sqlc`)?** У экстрактора гейта жёсткий
пол — `if len(stmts) < 140` (`sqlgate_test.go:41`), и глобит он `*.go` только в СВОЁМ каталоге. Уведи
42 оператора в под-пакет — счёт упадёт ниже пола, и **гейт покраснеет по собственному полу**. ⚠ Подвинуть
пол ради зелени НЕЛЬЗЯ: это подгонка гейта, запрещённая каноном. Значит либо генерируешь в тот же
каталог, либо расширяешь ОХВАТ экстрактора (не пол) так, чтобы генерённые операторы продолжали
проверяться живой схемой. Реши, аргументируй, и покажи прогоном, что гейт видит их после конверсии.
**Второй носитель схемы.** sqlc нужен вход-схема, а у зоны она уже имеет носителя с гейтом целостности:
`internal/pgstore/migrations/` + манифест `migrations.sha256` (`migrations_test.go`). Собственная копия
схемы в конфиге заведёт второй носитель факта, которого манифест не видит, — класс «один носитель на
факт». **Реши и аргументируй**, как этого избежать.
### 3.5 ⚠ Красное, которое НЕ твоё (знай заранее)
В `idempotency_test.go:265` живёт `TestAClaimThatLostARaceToAReleaseIsRetriedAndNotAnError` — известный
флейк, `PD-369` / `BACKLOG.md` **П-21**, замерено 12 падения на ~80 прогонов, разгоняется `-race`.
Файл `idempotency.go` — в твоём наборе. **Увидишь красное — сперва пере-прогони серийно, и не приписывай
его конверсии.** ⛔ И не «чини» его ради зелени: править или удалять тест, чтобы он прошёл, недопустимо
(D39.121); несогласие с тестом — пинг, а не правка.
## 4. Самопроверка ИСПОЛНЕНИЕМ (без неё работа не принята)
Мандат — не «перечитал», а прогон с числами:
- **Батарея зоны с полным набором гейтов**, `-race` обязателен. ⚠ Условий у батареи больше, чем помнит
большинство доков, и часть требует РУЧНОЙ сборки стенда (движковый бинарь + $0-пайплайн, которого в
репо нет; плюс условие про `user@<uid>.service`, под WSL не выполняющееся). Рецепт — в карте чтения
поз. 5. **Заложи на это время отдельно** и назови в отчёте, какие условия у тебя выполнены, а какие нет.
- **Поведенческая эквивалентность:** каждый конвертированный запрос доказывается тем, что его тест
проходит ДО и ПОСЛЕ. Дифф генерённого кода — не доказательство.
- **Дифф `^func Test` — ИСПОЛНЕНИЕМ, не памятью:** покажи командой, что ни один тест не исчез и не
переименовался при переписывании слоя.
- **СОБСТВЕННЫЕ мутационные посадки**, не список из промта: сломай арность `$n`, подмени цель `Scan`,
поменяй тип денежной колонки — каждая обязана падать АДРЕСНО. Посадка, которую никто не ловит, ценнее
трёх пойманных: неси её в отчёт.
- **Разрешаю субагентов** (иначе дефолт харнесса тихо запретит). Модель задавай ЯВНО и знай, сколько их
работает. Трудный вопрос — старшей модели.
- **Интервальная самоверификация** (D39.121): пак длинный, поэтому в середине работы — проход субагента
по СВОЕЙ готовой части против явных критериев, не в конце.
- ⚠ **Адверсариальный проход по своей готовой работе перед сдачей — ОБЯЗАТЕЛЕН, изменения потенциально
опасные (слово владельца).** Направление, что уязвимо здесь: генерённый метод, открывающий свою
транзакцию внутри чужой; денежный тип, потерявший целочисленность на границе; запрос, выпавший из-под
гейта; **тихо-зелёный тест** — проходящий, ничего не проверив (D39.171). Глубину и веер выбираешь сам.
- **Доказательная база — в РЕПОЗИТОРИЙ** (логи посадок, числа прогонов идут в зонный журнал), а не в
`/tmp`: что должно пережить рестарт, живёт в дереве.
## 5. Оси ревью
**Деньги** (целочисленность micro-USD сквозь генерацию, транзакционные границы) · **шов с гейтом** (ни
один запрос не выпал из `sqlgate_test.go`) · **воспроизводимость генерации**. Вправе заменить ось с
аргументом.
## 6. Записка-план и комплектность
До стройки — короткая **записка-план** в зонный журнал: что берёшь, что не берёшь, чем докажешь.
Перед сдачей — **механическая сверка состава против §3**, таблицей: пункт → сделано/нет → чем доказано.
Пропуск подписывается пропуском. **Последний абзац отчёта оказался планом или обещанием? Сделай сейчас.**
## 7. Канал вопросов и право отказаться
Конфликт промта с кодом или доками — **пинг через владельца, не интерпретация**. Есть право сказать
«этого делать не надо» с аргументом; по §3.1 это ожидаемый исход, а не поражение.
## 8. Заявление = команда
Любое число и любая категорика в отчёте — **с командой, которой получены**. Приёмка пере-ранит: клейм
без пере-прогона записывается как «со слов сессии». «Проверено» без исполнения в этой зоне уже дважды
оказывалось ложным.
## 9. Эхо-протокол старта
ДО первой правки — ≤10 строк: **скоуп / инварианты / чего не делаешь**. Отправь первым действием по
адресу оркестратора из `/tmp/textmachine-channel` (механизм — `CLAUDE.md` §«Связь между сессиями»; впиши
туда СВОЙ блок первым делом). Эхо служит и проверкой канала. **Канала нет ⇒ НЕ искать**: вопрос секцией
в отчёт, работа продолжается.
## 10. Obstacle reporting
Обязательная секция отчёта: **что НЕ удалось и что осталось непроверенным**. Пустой не бывает. Три
исхода: «подтверждено» / «опровергнуто» / **«не проверено»** — третье не сваливать во второе.
## 11. Зонный журнал
Итоги, пинги и вопросы — `platform/docs/platform-PROGRESS.md`. В `docs/PROGRESS.md` платформа не пишет.