8.7 KiB
Промт бэкенд-сессии: дофикс паритета анализаторов + живая проба провода (строки 121-п.0 · 117; хвост пака стандартов)
✅ ИСПОЛНЕН И ПРИНЯТ (D39.97, 04.08): шесть дыр закрыто (3 промта + 3 сверх, вкл. блокер type-param), 9/9 мутаций, проба PASS 3/3 с прямым клеймом
reasoning_contentна проводе, $0.0053 из $0.50. Заленден в составе пака стандартов. Отчёт:../reports/ARCHGUARD_DOFIX_2026-08-03.md. Инструкции отсюда не исполнять.
Мандат: приёмка пака стандартов D39.96 (03.08): пак принят по качеству кода, но пасс-2 приёмки нашёл регрессию egress-паритета против снесённого байт-гарда — снос гардов в текущем виде нарушает условие исходного промта «только после доказанного паритета». Владелец выбрал дофикс ДО лендинга. Твой предшественник сделал качественный пак — ты закрываешь три конкретные дыры, найденные посадками приёмки, и добиваешь единственный неисполненный пункт (живую пробу провода).
Онбординг: CLAUDE.md → docs/README.md → CURRENT-STATE в docs/PROGRESS.md → D39.96 в 05-decisions-log.md (вся фактура приёмки там) → отчёт archive/reports/REPO_STANDARDS_2026-08-03.md (ревью-шапка = сводка находок). Код-факты бери из кода — file:line ниже это отправные точки, код первичен.
§0. Скоуп и правила
- Зона записи:
backend/ТОЛЬКО. НЕ коммитить — лендит оркестратор..envНЕ ЧИТАТЬ (для этапа 2 сорсить шеллом — ключи в контекст/отчёт не тащить). - Деньги: этап 1 = $0. Этап 2 = живая проба, потолок $0.50 (санкция D39.92 п.2), каждый цент в отчёт.
- Эхо-протокол: первый деливерабл — ≤10 строк «что понял: скоуп / инварианты / не-делать» ДО работы.
- Канал вопросов: непонятно / конфликт промта с кодом или доками → пинг оркестратору через владельца, НЕ интерпретация.
- Дерево содержит незакоммиченный пак стандартов — это ТВОЯ база, поверх неё и работаешь. Чужого в дереве быть не должно, но
git statusперед началом сверь.
Этап 1 ($0): три дыры анализаторов — фикс + посадки
Все три доказаны исполнением при приёмке (посадки exit=0 там, где обязан быть флаг). Форма фикса — «реши сам»; приоры ниже опровергаются аргументом.
A. egressseam пропускает пакетную функцию llm.Complete(...). archguard.go:240-242: у qualified identifier (функция пакета, не метод) pass.TypesInfo.Selections[sel] = nil → анализатор молча выходит. Пакет internal/llm исключён целиком, так что хелпер func Complete(...) в llm + вызов откуда угодно = второй egress, невидимый ничем. Приор фикса: fallback на pass.TypesInfo.Uses[sel.Sel] → *types.Func с Pkg() = llm.
B. egressseam пропускает интерфейс, прячущий llm-типы ВНУТРИ композита. touchesPkg (archguard.go:76-92) разворачивает один уровень указателя и не смотрит внутрь элементов: Complete(ctx context.Context, reqs []llm.LLMRequest) ([]*llm.LLMResponse, error) проходит молча. Приор: рекурсия по Slice/Map/Chan/Array/Signature (+указатель уже есть).
C. requestseam ловит только литералы. runRequestSeam обходит один узел *ast.CompositeLit (archguard.go:197) против четырёх у stage-сеама (:140-165): var r pipeline.Request + пополевое присваивание и new(pipeline.Request) из чужого пакета проходят молча (дыра общая со старым гардом — не регрессия, но и не задокументирована). Приор: симметрия ValueSpec/CallExpr со stage-сеамом.
D. Честные комменты. «that is what cannot be hidden» (archguard.go:250-253) и клейм фикстуры (testdata/.../egresssites/egresssites.go:33) фальсифицированы посадками — переписать по фактическому охвату. Если что-то из A–C решишь осознанно НЕ ловить — это легитимно, но пропуск ОБЯЗАН быть назван в doc-комменте пакета и негативной фикстурой (молчащий пропуск = как раз то, что приёмка вскрыла).
E. Посадки. Каждая закрытая форма — кейс analysistest в testdata (формы из A/B/C выше) + негативные контроли (легитимный вызов через шов; Complete чужого пакета с не-llm сигнатурой; var в exempt-местах). Плюс мутационная самопроверка: сломай каждый фикс — соответствующий кейс обязан упасть.
F. Батарея. make battery EXIT=0; четыре поведенческих теста pipeline (BankProbe/ReasoningIsPart/RepairStage/InternalCallDecidesEveryStageField) живы.
Этап 2: живая проба провода (строка 117 — гейт платных прогонов)
⚠ ГЕЙТ: слово владельца по бампу @latest (D39.96 п.6-iii) — спроси ДО этапа 2, если он не передал с промтом.
- Confirm @latest → проба на текущем дереве.
- Deny → сначала минимальный пере-бамп (приор, доказан ревьюером исходного пака; опровергается замером):
go get golang.org/x/tools@v0.45.0(тянет x/net v0.54.0, x/text НЕ двигается) + откатmodernc.org/sqliteна v1.53.0 + откат x/text-пинов (norm.go:69→ v0.38.0, зеркалаenclosure_test.goиmemory_f1_test.go) + голден обязан пройти БЕЗ пере-захвата (вернётся к HEAD-версии). Затем проба.
Команда (ключи грузит шелл; вывод фильтруй от ключей):
cd backend && set -a && . ./.env && set +a && TM_LIVE=1 go test -tags live -run TestLiveAdapterConformance -v ./internal/pipeline/
Кроет deepseek/zai/kimi (grok закомментирован — clean-prod гигиена, НЕ включать). Сверять против docs/experiments/00-provider-quirks.md: finish=stop · reasoning_content непустой где ожидается · нет новых отказов/фреймингов. Контекст риска: после бампа x/net у клиента новый SETTINGS_MAX_FRAME_SIZE=16384 (семантически инертен, но меняет h2-фингерпринт для WAF). Любое расхождение = СТОП-пинг с сырьём, откатов без слова владельца не делать.
Отчёт
docs/archive/reports/ARCHGUARD_DOFIX_<дата>.md, компактный: эхо-шапка · дифф этапа 1 с таблицей «форма × ловится» · итог мутационной самопроверки · результат пробы по провайдерам (finish/usage/цена; тел с ключами НЕ вставлять) · найдено-не-починено. Каждое число — с командой. СТОП — приёмка оркестратора.