# Промт бэкенд-сессии: индустриальные стандарты репозитория — линтер · CI · бамп зависимостей · гарды-в-analyzer (строки 107 · 112 · Д7) **Мандат:** решение владельца 02.08 (D39.92): «делаем по стандартам индустрии: CI, линтер, бамп x/net и всех библиотек; осторожный, затем полный подход; спилить самописные AST-тест-гарды в пользу штатной формы». Ограничение владельца, равное по силе самому мандату: **стандарты не должны мешать разрабатывать, тормозить и приводить модели к хакам.** **Онбординг:** CLAUDE.md → `docs/README.md` → CURRENT-STATE в `docs/PROGRESS.md` → голова D39.91–92 в `05-decisions-log.md` → `backend/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` не читать. - Деньги: этапы 0–C и 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 · снесённое/оставленное · найдено-не-починено с носителями · «заявление = команда» на каждое число. **СТОП — приёмка оркестратора.**