12 KiB
Промт бэкенд-сессии: индустриальные стандарты репозитория — линтер · CI · бамп зависимостей · гарды-в-analyzer (строки 107 · 112 · Д7)
✅ ИСПОЛНЕН, ПРИНЯТ (D39.96 двумя пассами) И ЗАЛЕНДЕН (D39.97, 04.08; семь pathspec-коммитов
e8d4ac0…0e64efe). Строки 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.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-замер, НИЧЕГО не чинить): объём находок стандартного набора
golangci-lintПИНОВАННОЙ версией (бинарь вне репо, версию в отчёт) — дефолтный набор +staticcheck, errcheck, unused, ineffassign, misspell, nolintlintв report-only на./backend/....- Отчёт ЧИСЛАМИ: находки по правилам × по пакетам × 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/net0.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(), hoistedRequest+ алиас-литерал + слайс — посадки приёмки 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 · снесённое/оставленное · найдено-не-починено с носителями · «заявление = команда» на каждое число. СТОП — приёмка оркестратора.