# Промт бэкенд-сессии: ПАК-12 «транспорт-гигиена» (по research/21) **Статус: ВЫДАН 23.07.2026, оркестратор №7. ГЕЙТ ОТКРЫТ 23.07 (D39.20): платный путь пере-прогона завершён, чтение принято — можно стартовать на чистом дереве.** Координация: возможен параллельный пак-13 «выпускной QA» — зоны файлов почти не пересекаются (пак-12 = `internal/llm/` + тесты; пак-13 = чекеры/санитайзер/банк), но при одновременном запуске — согласовать через оркестратора, кто первый лендится. ## Рамка Источник скоупа — `docs/research/21-llm-transport-survey.md` (читать ревью-шапку: там эрратум и поправки применимости). Вердикт обзора ратифицирован: **транспорт НЕ рефакторим** — наш дизайн (Capability-как-данные, единый retryLoop, fail-loud) правильнее SDK-паттернов для детерминизм-критичной системы. Пак — ТОЛЬКО точечные добавки ниже. Любой соблазн «заодно переделать» — стоп и пинг оркестратору. **Жёсткий инвариант пака: ноль wire-байтов.** Ни одно изменение не трогает тело запроса → snapshot не двигается, `--resnapshot` НЕ требуется, golden байт-идентичен (новые пины — отдельными тестами). Это критерий приёмки №1. ## Онбординг `CLAUDE.md` → `docs/README.md` → CURRENT-STATE `PROGRESS.md` → `research/21` (целиком) → `00-provider-quirks.md` → `backend/internal/llm/` + `internal/pipeline/{ratelimit,quality,cheapgates}.go` + `configs/models.yaml`. ## Скоуп (10 пунктов, каждый ~10–60 строк + тест) 1. **Валидация-тест `models.yaml`** (research/21 §1.12/goose `declarative.rs:396-467`): go-тест — каждый `api_key_env` объявлен у провайдера моделей; reasoning-режим ∈ известного enum; `min_max_tokens` разумен; каждая модель ссылается на объявленного провайдера; цены >0 там, где обязаны. Падает на дрейфе каталога ДО платного прогона. 2. **Quota-429 → terminal** (§1.4): узкий body-маркер (`insufficient_quota`/`quota_exceeded`) + HTTP 402 → терминальная ошибка (не 3 ретрая под USD-резервацией). Тест: обычный 429 остаётся retryable. 3. **`parseRetryAfter`: дробные секунды + `Retry-After-Ms`** (§1.13, `httpllm.go:426`): float-парс + ms-header first. Под существующим 5-мин капом. 4. **HTTP/2 keepalive на общем клиенте** (§1.5, `httpllm.go:161-174`): http2.Transport ReadIdleTimeout/PingTimeout (~15s/5s по образу grok-build). **Гейт внутри пака:** дым-проверка, что фронты наших провайдеров не рвут h2-PING (без платных вызовов — TLS/HEAD-пробы); рвут → h1 для того провайдера, отметить в отчёте. 5. **Пропорциональный джиттер** (§1.18а, `httpllm.go:144`): `rand.Intn(250)ms` → ±25% от backoff. Де-синк N-∥ волн. 6. **xAI reasoning identity-гард** (§1.9, `provider_openai.go:101-102`): additive-фолд только при `total == prompt+completion+reasoning`; иначе считать subset и логировать WARN (кандидат в квирк-реестр). Кап латентного 30–44% overcount. 7. **CostSource-маркер** (§1.10): на settle-estimate строках (`stagerun.go:469-473`) — флаг `estimated` в request_log/report (аддитивное поле read-модели, экспорт-контракт №8 не ломать). Estimated-токены display-only, `CostUSD` НЕ трогают. Оценщик — fertility research/20 (1.20·cjk+0.39·other), НЕ char/4 (CJK-мина). 8. **Drift-guard-тесты** (§1.18б): (а) пин полной status→retryable-мапы; (б) finish-классификатор перевести на префикс/substring-матч (композит `content_filter: PROHIBITED_CONTENT` должен классифицироваться) + пин-тест. Незнакомый finish остаётся fail-loud (НЕ litellm-стиль «unknown→stop»). 9. **Кап billed-decode-ре-биллов** (§1.18в): BilledDecodeError ретраится ≤1 раза (не полный MaxAttempts) — платный 2xx-мусор не жжёт бюджет штормом. 10. **Сегмент-луп-гард, observability-only** (§ арх-чтение/crush `loop_detection.go`): нормализованная SHA-сигнатура перевода-сегмента, повтор >N подряд → style-флаг класса наблюдаемости (КАК стиль-гейты: не диспозиция, не wire). Дополняет echoMineViolation по дегенеративной петле (research/15). ## Вендор-сверка (внутри сессии, БЕЗ реализации при неподтверждении) По правилу 10.07 два кандидата реализуются ТОЛЬКО при подтверждении в офиц. доке: **(а)** GLM finish-словарь `sensitive`/`network_error` — сверить с docs.z.ai (reference finish_reason); подтвердится → добавить в классификатор (`sensitive`→content_filter; `network_error` — НЕ маппить в stop, оставить fail-loud) + строка-кандидат в отчёт для 00-provider-quirks; **(б)** kimi reasoning-модели: temperature omit vs force:1 — сверить platform.kimi.ai; подтвердится → capability-твик. Не подтвердится — в отчёт «не подтверждено, не реализовано». ## НЕ делать (явные не-цели) Рефакторинг транспорта/option-паттерн · стриминг/StreamingLLMClient · assistant-prefill continuation (#17, HIGH-риск детерминизма) · native-Gemini судья (Ф2) · GLM cache_control-маркировка (двигает wire → решение владельца отдельно) · GLM context-overflow гард (ждёт вендор-сверки + estimator-инфры) · дата-фикация каталога провайдеров · `prompt_cache_key` (наши провайдеры не чтут). ## Приёмка (ревью ИСПОЛНЕНИЕМ, мандат 12.07) `go build/vet/test ./... -race` зелёные · **golden байт-идентичен** (пак wire-нейтрален; сдвиг golden = провал инварианта — стоп, пинг) · новые тесты: №1 валидация, №2 quota-терминал, №3 ms-парс, №6 identity, №8 drift-пины, №9 кап, №10 луп-гард на синтетике · самопроверка: свой код + прогон всех пинов + адверсариальный селф-ревью (author≠reviewer, минимум 3 линзы: детерминизм/деньги/конкурентность). Отчёт — `docs/archive/reports/TRANSPORT_PACK12_REPORT_<дата>.md` (НЕ в backend/), с file:line по каждому пункту. Сессия НЕ коммитит — лендит оркестратор.