textmachine/docs/archive/prompts/BACKEND_REPO_STANDARDS_SESSION_PROMPT.md

12 KiB
Raw Blame History

Промт бэкенд-сессии: индустриальные стандарты репозитория — линтер · CI · бамп зависимостей · гарды-в-analyzer (строки 107 · 112 · Д7)

ИСПОЛНЕН, ПРИНЯТ (D39.96 двумя пассами) И ЗАЛЕНДЕН (D39.97, 04.08; семь pathspec-коммитов e8d4ac00e64efe). Строки 107/112/117 закрыты. Регрессия egress-паритета, найденная приёмкой, закрыта дофикс-паком (BACKEND_ARCHGUARD_DOFIX_SESSION_PROMPT.md рядом); живая проба провода исполнена там же (PASS 3/3). Отчёты: ../reports/REPO_STANDARDS_2026-08-03.md · ../reports/ARCHGUARD_DOFIX_2026-08-03.md. ⚠ Эрратум промта: адрес pipeline-c2.yaml:39 был ошибкой трекера (judge на glm-5, не черновик) — флипов ровно 5. Инструкции отсюда не исполнять.

Мандат: решение владельца 02.08 (D39.92): «делаем по стандартам индустрии: CI, линтер, бамп x/net и всех библиотек; осторожный, затем полный подход; спилить самописные AST-тест-гарды в пользу штатной формы». Ограничение владельца, равное по силе самому мандату: стандарты не должны мешать разрабатывать, тормозить и приводить модели к хакам.

Онбординг: CLAUDE.md → docs/README.md → CURRENT-STATE в docs/PROGRESS.md → голова D39.9192 в 05-decisions-log.mdbackend/README.md + 12-go-style-notes.md. Контекст предмета: отчёт archive/reports/EFFORT_HANDLE_2026-08-02.md §1.3(2), §5.5, Д7; D39.90 п.7; строка 107 трекера.

§0. Скоуп, деньги, стоп-правила

  • Зона записи: backend/ ТОЛЬКО. НЕ коммитить — лендит оркестратор. git add/commit не запускать вовсе; .env не читать.
  • Деньги: этапы 0C и E — $0. Этап D (бамп зависимостей) включает живую мини-пробу провода: потолок $0.50, каждый цент в леджер, тела предъявить.
  • Анти-хак-правило (владелец): запрещено «зеленить» линтер обходами — переименованиями без смысла, пустыми обёртками, дроблением функций ради метрики, гашением через рефактор-мусор. Спорное правило линтера → ВЫКЛЮЧИТЬ правило в конфиге с одной строкой причины — это честнее, чем хак в коде. Голый //nolint без причины запрещён (включить nolintlint).
  • СТОП-пинги оркестратору: этап A даёт >1000 находок → пинг с числами ДО любых правок · этап B требует правок >30 файлов разом → пинг с планом · этап D меняет поведение провода (красный квирк-тест, флейк пробы, новый заголовок/фрейминг) → СТОП, откат бампа, пинг. Молча продавливать нельзя ни одно из трёх.
  • Мандат самопроверки (CLAUDE.md 12.07): ревью ИСПОЛНЕНИЕМ своего кода и конфигов; адверсариальные посадки для этапа E обязательны; спорное — author≠reviewer.

Этап 0 (15 минут, независим от остального): строка 112 — санкционированная правка пяти шиппинг-конфигов

stages[draft].reasoning: "off""low" в: configs/pipeline-c1.yaml:49 · pipeline-c2.yaml:26,39 · pipeline-arm-mistral.yaml:30 · pipeline-arm-glm.yaml:34 · pipeline-arm-deepseek-pro.yaml:34. Санкция владельца 02.08 (D39.92); перекупка снапшотов старых книг принята, новые книги $0.

  • НЕ ТРОГАТЬ reasoning: "off" на РЕДАКТОРСКИХ/финальных стадиях (c1:77 · c2:51 · arm-glm:43 · arm-deepseek-pro:43) — они осознанные (D39.91 Д11: на glm это живой thinking-off от таймаутов ×3, на dspro — no-op-страховка эхо-мины).
  • У arm-mistral черновик — проверь МОДЕЛЬ стадии прежде чем править: ключ имеет смысл только там, где стадия резолвится в reasoning-модель; no-op на не-reasoning модели можно оставить "off" с комментарием, но реши ЯВНО и запиши.
  • После правки: tmctl status --config на каждом из пяти + полная батарея. В отчёт: дифф построчно, что не тронуто и почему.

Этап A ($0-замер, НИЧЕГО не чинить): объём находок стандартного набора

  1. golangci-lint ПИНОВАННОЙ версией (бинарь вне репо, версию в отчёт) — дефолтный набор + staticcheck, errcheck, unused, ineffassign, misspell, nolintlint в report-only на ./backend/....
  2. Отчёт ЧИСЛАМИ: находки по правилам × по пакетам × prod/test раздельно. Ни одной правки на этом этапе — это замер, санкционированный владельцем как первый шаг (D39.90 п.7).

Этап B (состав и режим — предложение, решение с оркестратором)

  • Предложить .golangci.yml: каждое правило ВКЛ/ВЫКЛ с обоснованием ЧИСЛОМ из этапа A (не вкусом). База: go vet уже чист — зафиксировать.
  • Режим внедрения: baseline «только новый/правленый код» (--new-from-rev) против big-bang по правилам с малым хвостом (например, всё с ≤20 находками — big-bang, остальное — baseline). Предложить, НЕ исполнять до ответа на СТОП-пинг, если хвост большой.
  • exhaustruct НЕ включать глобально (16 находок, 15 в тестах — замерено §5.5); точечно на config.Stage/pipeline.Request рассмотреть — это ровно класс исходного бага.

Этап C (CI + Makefile: одна команда для всех)

  • Makefile (или make.go): цели build · vet · lint · test · battery — где battery = ровно текущая ручная батарея (build && vet && vet -tags live && gofmt -l && test -race -count=1 + голден/парити/labels/K6 по env-флагам). Сессии перестают собирать её руками.
  • CI-воркфлоу: проверь git remote -v; если удалёнки/раннера нет — файл workflow подготовить (go build/vet/lint/test), обязательной точкой входа до его оживления становится make battery. Пины версий тулчейна и линтера в конфиге, не latest.
  • Прекоммит: у фронта уже стоит самоустанавливающийся гейт (7832be7, frontend/scripts/githooks/) — НЕ ломать и НЕ дублировать; если расширяешь на backend-пути, только согласованной правкой через оркестратора (это смежная зона).

Этап D (бамп зависимостей — осторожно: x/net это наш транспорт)

  • Бамп прямых зависимостей go.mod (включая x/net 0.26 → текущий, x/tools под этап E). Go toolchain — только если требуется, отдельной строкой в отчёте.
  • x/net/http2 — транспорт ко ВСЕМ провайдерам. После бампа обязательны: полная батарея · голден (PASS без пере-захвата — вердикты не двигаются) · живая мини-проба провода на КАЖДЫЙ провайдер из models.yaml (1 короткий вызов; потолок $0.50 суммарно; сверить: тела, ключи запроса, reasoning_content, finish_reason, отсутствие новых заголовков/фреймингов против 00-provider-quirks.md). Любое расхождение = СТОП-пинг, откат.

Этап E (гарды → analyzer; снос тест-гардов ТОЛЬКО после доказанного паритета)

Предмет: synthetic_stage_seam_test.go (два AST-гарда + пол числа файлов) и давний байтовый TestProviderEgressSeamIsSingle (Д7) → ОДИН обход на x/tools/go/analysis с types.Info (алиасы/дот-импорты закрываются по построению), запуск через go vet -vettool= из make battery/CI.

  • Инварианты — предмет контракта, не форма: (i) config.Stage строится вне лоадера только швом InternalCall.Stage(); (ii) pipeline.Request собирается только в attemptRequest; (iii) egress-инвариант старого гарда — перенести его словарь исключений осознанно, не копипастой; (iv) рефлексионный TestInternalCallDecidesEveryStageFieldНЕ трогать, он не про обход дерева и в analyzer не нуждается.
  • Паритет посадками: все 12 известных обходов (5 байтовых + алиас + []config.Stage{{…}} из отчёта §1.3; var-форма, new(), hoisted Request + алиас-литерал + слайс — посадки приёмки D39.91) воспроизвести как тест-кейсы АНАЛИЗАТОРА (analysistest). Analyzer обязан ловить все 12 + иметь эквивалент пола «я реально видел файлы».
  • Известная слепая зона go/packages: старый гард ходил и по eval/ ВНЕ Go-модуля (исторически там жил четвёртый сайт дефекта). Реши явно: гонять analyzer и на eval-модуле, или закрыть этот класс иначе — и запиши решение.
  • Снос _test.go-гардов — ПОСЛЕДНИМ коммитом пака, только при 12/12 у analyzer. До того оба механизма живут параллельно.

Отчёт

docs/archive/reports/REPO_STANDARDS_<дата>.md: эхо-шапка · числа этапа A · состав+режим B с обоснованиями · что даёт make battery · дифф бампа и предъявление живой пробы D · паритет-таблица 12 посадок E · снесённое/оставленное · найдено-не-починено с носителями · «заявление = команда» на каждое число. СТОП — приёмка оркестратора.