Land research/21 LLM-transport survey with review header: citations spot-verified, one status-code erratum, arm-quirks downgraded to latent for the single-shot wire; adoption deferred post-rerun

This commit is contained in:
Claude (backend session) 2026-07-23 22:40:24 +03:00
parent 1e4418b503
commit 82013130ac
4 changed files with 235 additions and 2 deletions

View file

@ -9,6 +9,10 @@
> - **Ждём от владельца:** тачпойнты exp16 (карта подписи/пол · мини-голд алиасов · precision@30, `books/gu-zhenren/exp16/`, ~3040 мин — для сид-дельты к пере-прогону) · развилки плана §10 (W1.5-UX · DC5-стих-политика · Edit-ceiling · и др.) · реплика ja→ru (тест общности §B5) · **ре-чек прайса DeepSeek у катовера слагов 24.07** (до него платных deepseek-прогонов нет) · чтение пере-прогона (после R1+resnapshot) · старые висящие: планка запуска (лучше-фана/гибрид/издательский) · билингв-якорь пилота (D25.9-Q1) · контаминация пилот-корпуса (D27.4) · publishable/waiver (D25.1) · FN-bound L3 (D25.4) · юр-пакет · провенанс 12-*-доков.
> - Архивы хроники: `archive/PROGRESS-2026-07-04-10.md` (D31) · `archive/PROGRESS-2026-07-10-13.md` (D39.6-гигиена). Записи ниже — живая эра D39.
## Оркестратор №7 — research/21 (обзор LLM-транспорта) ПРИНЯТ и залендён, 23.07
Ресёрч-сессия сдала обзор (57 агентов; самопроверка исполнением поймала плейсхолдер-заглушки синтеза Q1/Q3 — пере-выведены из survey-сырья, 8/8 несущих цитат CONFIRMED; ещё один датапоинт мандата 12.07). **Приёмка исполнением:** 7/7 цитат о нашем коде + 5/5 из клонов сверены байт-в-байт; 1 эрратум (Mistral 400↔422 — класс верен); **поправка применимости моя:** wire single-shot `system+system+user` (`render.go:223-227`) → «арм-квирки» (Mistral extra_forbidden, deepseek multi-turn) ЛАТЕНТНЫ для текущего пере-прогона, GLM-overflow — future-proofing; идущий прогон НЕ трогаем. **Вердикт обзора:** наш транспорт опережает/вровень со всеми 11 (retryLoop, 5-мин кап Retry-After, fail-loud, served-model биллинг, min_max_tokens-флор, double-count-гард); против Mistral-48% — только concurrency-cap, против тихого усечения — стриминг даёт лишь детекцию (continuation ≠ стриминг). **Дёшево-подтверждённые кандидаты пост-прогона:** fractional/ms Retry-After · quota-429→terminal · HTTP/2 keepalive · CostSource-маркер · xAI identity-гард · план native-Gemini-судьи · cache_control на GLM (÷5 входа, но ~2% стандарта). Q7-таблица квирков — кандидаты до вендор-сверки, в `00-provider-quirks.md` НЕ абсорбированы. Промт → архив. Решения о внедрении — после чтения владельца, отдельными D.
## Оркестратор №7 — параллельный трек: промт research/21 (обзор LLM-транспорта чужих харнессов) выдан, 20.07
По решению владельца — параллельно пере-прогону. В `/home/ubuntu/projects/tmp/` склонированы 11 репо (лицензии сверены поштучно): codex/gemini-cli/**grok-build (офиц. xAI, open-sourced 15.07.2026, Apache-2.0)**/goose/aider/cline/openai-go — Apache-2.0; opencode/anthropic-sdk-go — MIT; litellm — MIT-ядро (`enterprise/` не читать); crush — FSL-1.1 (читать можно, копировать нельзя). **Leaked-форки Claude Code — ВНЕ периметра** (контаминация; офиц. трекер/чейнджлог — онлайн). Промт: `LLM_TRANSPORT_RESEARCH_SESSION_PROMPT.md` — Q1 cache-раскладка инъекции (до ×50 на входе flash), Q2 rate-limit адаптив (Mistral-арм), Q3 finish_reason-таксономия, Q4 retry/fatal vs 04-unhappy-paths, Q5 usage/ledger, Q6 streaming-надёжность, Q7 issue-sweep по нашим провайдерам → кандидаты в 00-provider-quirks. Жёстко: $0 (никаких вызовов), backend read-only (патчи — только после пере-прогона), file:line-грунтовка, выход `research/21` некоммиченным.

View file

@ -14,9 +14,9 @@
- `architecture/` — синтез. **Источник истины по решениям — [`05-decisions-log.md`](architecture/05-decisions-log.md) (D1D39.16); при конфликте с любым доком он выше.**
- `01-decisions.md` — принципы Р1Р10; `02-mvp-plan.md` — фазы и приёмка (v3, 09.07); `03-implementation-notes.md` — контракты Фазы 0; `04-unhappy-paths.md` — ~70 режимов отказа → механизм; `06-memory-risk-registry.md` — реестр рисков банка памяти; **[`07-strategic-review.md`](architecture/07-strategic-review.md) — стратегический аудит (09.07): вердикт end-to-end, топ-риски, курс-коррекции**; **[`08-sync-audit-ledger.md`](architecture/08-sync-audit-ledger.md) — верифицированный ледджер синк-аудита «сломанного телефона» (65 находок, D39)** · **[`09-target-architecture.md`](architecture/09-target-architecture.md) — целевая 7-слойная архитектура + фазовый план арх-ресета (D39; инвариант общности §0.1)** · [`10-prompt-architecture.md`](architecture/10-prompt-architecture.md) — консолидированная промпт-заметка (концерн 4); **[`11-implementation-plan.md`](architecture/11-implementation-plan.md) — РАТИФИЦИРОВАННЫЙ план стройки пере-прогонного стека (D39.12; дизайн-оф-рекорд бэкенд-пака, три рубежа верификации)**; `components.puml`/`pipeline.puml` — диаграммы v3 (владелец смотрит PlantUML-расширением VS Code; вручную НЕ рендерить).
- `experiments/` — эмпирика «Полигона»: `00-provider-quirks` (читать перед любым вызовом провайдера), `01-token-calibration`, `02-refusal-benchmark`, `03-local-stand`, `04-editor-quality`, `06-local-extraction`, `07-coverage-precision`, `08-cost-model-v2` (актуальная денежная модель), `09-pilot-protocol` (пилот Ф2.5 + поправки D13), `10-explicit-benchmark` (18+ violence-рука канала B), `11-erotica-benchmark` (erotica по трём парам/регистрам — закрытие D14.4, D22).
- `research/` — фактура исследований 0405.07: `0110` базовые, `11-gap-*` добор критиком, `12-*` режимы отказа/отзывы/таксономии (+ два внешних материала с провенанс-шапками), `13` валидация памяти, `14` адаптивная память, `15` голос и состояние (принят, D21), **`16` ридер-IDE (принят с ревью-шапкой, D29)**, **`17` внешняя критика GPT-5.6 (принят с ревью-шапкой, D25)** — у 16/17 читать шапку прежде тела. **`18` рычаги качества (два отчёта, D36)** · **`19` нарезка+когезия+контракт t/e (D39.1)** · **`20` банк-майнинг W1.5 (D39.6)** — у всех ревью-шапки. ⚠ Часть под superseded-баннерами (01/02/03/04/05/09 и gap-1/2/5) — **читай баннер прежде содержимого**.
- `research/` — фактура исследований 0405.07: `0110` базовые, `11-gap-*` добор критиком, `12-*` режимы отказа/отзывы/таксономии (+ два внешних материала с провенанс-шапками), `13` валидация памяти, `14` адаптивная память, `15` голос и состояние (принят, D21), **`16` ридер-IDE (принят с ревью-шапкой, D29)**, **`17` внешняя критика GPT-5.6 (принят с ревью-шапкой, D25)** — у 16/17 читать шапку прежде тела. **`18` рычаги качества (два отчёта, D36)** · **`19` нарезка+когезия+контракт t/e (D39.1)** · **`20` банк-майнинг W1.5 (D39.6)** · **`21` обзор LLM-транспорта чужих харнессов (23.07: наш транспорт опережает/вровень со всеми 11; рекомендации DEFER до после пере-прогона, Q7-квирки — кандидаты до вендор-сверки)**у всех ревью-шапки. ⚠ Часть под superseded-баннерами (01/02/03/04/05/09 и gap-1/2/5) — **читай баннер прежде содержимого**.
- `PROGRESS.md`**журнал** (CURRENT-STATE сверху, ниже хронология; НЕ источник решений).
- **Активные хендофф-промты (пост-D39.19, 20.07):** [`PERERUN_SESSION_PROMPT.md`](PERERUN_SESSION_PROMPT.md) (**операционная сессия пере-прогона — ТЕКУЩИЙ шаг**: главы 15, ОДИН resnapshot, армы glm/mistral/deepseek-pro, риг D39.7, блайнд-пакет D39.8) · [`LLM_TRANSPORT_RESEARCH_SESSION_PROMPT.md`](LLM_TRANSPORT_RESEARCH_SESSION_PROMPT.md) (параллельный ресёрч: 11 чужих харнессов в `/home/ubuntu/projects/tmp/`, $0, backend read-only → research/21) · [`ORCHESTRATOR_SESSION_PROMPT.md`](ORCHESTRATOR_SESSION_PROMPT.md) (хендофф №5 оркестратора) · [`POLYGON_PACKAGE4_SESSION_PROMPT.md`](POLYGON_PACKAGE4_SESSION_PROMPT.md) (residual пилот/18+/echo). **ПАК-11 + ПРЕП ЗАВЕРШЕНЫ.** Гейт DeepSeek 24.07 закрыт факт-чеком 20.07 (наши слаги не под депрекацией, цены совпадают; повторный чек 24.07 вписан в промт). Закрытые — в `archive/prompts/` (свежие: преп→D39.19, пак-11/R1→D39.17, арх-cleanup→D39.16).
- **Активные хендофф-промты (пост-D39.19, 20.07):** [`PERERUN_SESSION_PROMPT.md`](PERERUN_SESSION_PROMPT.md) (**операционная сессия пере-прогона — ТЕКУЩИЙ шаг**: главы 15, ОДИН resnapshot, армы glm/mistral/deepseek-pro, риг D39.7, блайнд-пакет D39.8) · [`ORCHESTRATOR_SESSION_PROMPT.md`](ORCHESTRATOR_SESSION_PROMPT.md) (хендофф №5 оркестратора) · [`POLYGON_PACKAGE4_SESSION_PROMPT.md`](POLYGON_PACKAGE4_SESSION_PROMPT.md) (residual пилот/18+/echo). **ПАК-11 + ПРЕП ЗАВЕРШЕНЫ.** Гейт DeepSeek 24.07 закрыт факт-чеком 20.07 (наши слаги не под депрекацией, цены совпадают; повторный чек 24.07 вписан в промт). Закрытые — в `archive/prompts/` (свежие: преп→D39.19, пак-11/R1→D39.17, арх-cleanup→D39.16).
- `archive/` — закрытые сессионные промты (только история, инструкции оттуда не исполнять).
## Статус (2026-07-19, пост-D39.16 — стройка пере-прогонного стека)

View file

@ -1,5 +1,7 @@
# Промт ресёрч-сессии: обзор LLM-транспорта чужих харнессов (research/21)
> **АРХИВ (23.07.2026): ОТРАБОТАН ПОЛНОСТЬЮ.** Сдан и залендён `docs/research/21-llm-transport-survey.md` (ревью-шапка с эрратумом и поправкой применимости — там). Все Q1Q7 закрыты; рекомендации DEFER до после пере-прогона; Q7-кандидаты ждут вендор-сверки. Инструкции ниже не исполнять — только история.
**Статус: АКТИВЕН (выдан 20.07.2026, оркестратор №7).** Роль — ресёрч (полигон-профиль). Идёт ПАРАЛЛЕЛЬНО операционному пере-прогону: **`backend/` строго read-only, НИКАКИХ патчей** — рекомендации применяются только после пере-прогона отдельным решением. Это $0-сессия чтения кода: **не запускать чужие CLI, не делать НИ ОДНОГО вызова моделей, ключи не трогать**.
## Материал

View file

@ -0,0 +1,227 @@
# research/21 — Обзор LLM-транспорта чужих харнессов
> **РЕВЬЮ-ШАПКА ОРКЕСТРАТОРА (лендинг 23.07.2026).** Спот-чек адверсариальный, author≠reviewer: 7/7 несущих цитат о НАШЕМ коде подтверждены по file:line (`httpllm.go` jitter/клиент/429/parseRetryAfter, `provider_openai.go` additive, `llm.go` vojo) + 5/5 выборочных цитат из клонов байт-в-байт (mistral-strip, opencode z.ai-overflow, GLM finish-словарь, zai cache_control, grok-build shared_http). **Эрратум:** §1.1/§2 пишут «Mistral → 400», улика (докстринг litellm) говорит **422** extra_forbidden — класс верен, код статуса в отчёте неточен. **Поправка применимости (проверено исполнением):** наш wire — строго single-shot `system+system+user` (`render.go:223-227`), assistant-сообщений/reasoning-полей не шлём → квирки «Mistral extra_forbidden» и «deepseek multi-turn 422» для ТЕКУЩЕГО пере-прогона ЛАТЕНТНЫ (станут несущими при continuation #17 / любом multi-turn); GLM-overflow — инпуты юнитов ≪ окна (гард = future-proofing, не сегодняшний риск). Идущий пере-прогон НЕ трогать. **Все рекомендации — DEFER до после пере-прогона; Q7 — кандидаты до вендор-сверки (правило 10.07), в `00-provider-quirks.md` НЕ абсорбированы.**
**Статус: ПРИНЯТ (залендён 23.07); черновик сдан ресёрч-сессией 23.07.** Дата: 2026-07-23. Роль — ресёрч (полигон-профиль). Периметр: `$0`-сессия чтения кода, ни одного вызова моделей, `backend/` read-only. Материал — 11 склонированных харнессов в `/home/ubuntu/projects/tmp/`. Рекомендации применяются ТОЛЬКО после пере-прогона, отдельным решением. Все Q7-кандидаты — именно **кандидаты**: абсорбирует оркестратор ПОСЛЕ вендор-сверки (правило двух направлений, 10.07).
## Метод, лицензии, надёжность
- **Оркестрация.** 11 репо-агентов (survey Q1Q6) ∥ 6 провайдер-агентов (quirk-mining Q7-код) → 6 синтез-агентов (по вопросу) + Q7-дедуп → адверсариальная верификация (author≠reviewer): 57 агентов, 0 ошибок. Онлайн-жатва трекеров (Q7) — отдельно, из главной сессии (`gh` + WebFetch).
- **Самопроверка исполнением поймала баг (мандат 12.07 в действии).** Синтез-агенты Q1 (prompt-cache — вопрос №1) и Q3 (finish_reason) вернули **плейсхолдер-заглушки** («test»), схема их не отсеяла — ровно тот класс, о котором предупреждает мандат. Сырьё survey по Q1 (18 находок) и Q3 (17 находок) — целое; Q1/Q3-синтез пере-выведен вручную из survey-находок + **независимая адверсариальная верификация 8 несущих цитат свежими агентами** (все CONFIRMED, детали ниже). Два REFUTED в авто-верификации — это и есть те заглушки; в отчёт не вошли.
- **Дисциплина цитат.** Каждая находка о чужом коде — с `repo/file:line`; спорное верифицировано чтением второго места (call-site/тест). Пометки [CONFIRMED]/[PARTIAL] — вердикт адверсариального ре-чтения (PARTIAL = паттерн реален, но формулировка/оценка завышена — см. per-question). НИКАКОГО копирования чужого кода: только описание паттернов.
**Лицензии (per-repo, апстрим):**
| repo | апстрим | язык | лицензия | примечание |
|---|---|---|---|---|
| codex | openai/codex | Rust | Apache-2.0 | Responses API only |
| gemini-cli | google-gemini/gemini-cli | TS | Apache-2.0 | @google/genai |
| grok-build | xai-org/grok-build | Rust | Apache-2.0 (© SpaceXAI) | **официальный xAI**, open-sourced 15.07.2026 |
| goose | block/goose | Rust | Apache-2.0 | declarative-провайдеры |
| aider | Aider-AI/aider | Python | Apache-2.0 | обёртка над litellm |
| cline | cline/cline | TS | Apache-2.0 | @anthropic-ai/sdk + AI-SDK |
| opencode | sst/opencode | TS | MIT | Vercel AI SDK |
| litellm | BerriAI/litellm | Python | **MIT-ядро** (`enterprise/` — иная лиц., **НЕ читалась**) | самый богатый провайдер-слой |
| crush | charmbracelet/crush | Go | **FSL-1.1** (читать можно, **копировать нельзя**) | транспорт делегирован во внеш. `charm.land/fantasy` |
| openai-go | openai/openai-go | Go | Apache-2.0 | референс SDK |
| anthropic-sdk-go | anthropics/anthropic-sdk-go | Go | MIT | референс SDK |
**Итог одной строкой.** Наш транспорт в базовой форме **опережает или вровень** со всеми 11: единый `retryLoop`, honored-Retry-After с 5-мин капом, fail-loud terminal 4xx, billed-decode-типизация, per-adapter reasoning-семантика, served-model биллинг, double-count-гард, min_max_tokens-флор — то, что другие имеют частично или не имеют. Значимого рычага против Mistral-48% или тихого усечения ни один харнесс **не даёт**. Ценность обзора — в **точечных догоне** (fractional Retry-After, quota-429→terminal, HTTP/2 keepalive, GLM-cache_control, native-Gemini usage) и в **Q7-квирках, прямо задевающих пере-прогонные армы glm/mistral/deepseek-pro**.
---
## §1. Топ-рекомендации (ранжированы по ожидаемому импакту)
Формат: приоритет · [вердикт] · рекомендация · **какая метрика двинется и на сколько** · гейт. «Держим как есть» с внешним подтверждением — тоже вывод (мы там ведём).
### Надёжность / тихий провал (высший приоритет — задевает пере-прогонные армы)
1. **[VERIFIED, NEW] Mistral: strip output-only полей перед отправкой.** Mistral — строгая `extra_forbidden`-схема входа: реплей `reasoning_content`/`thinking_blocks` или сообщения с `null`-значениями → **HTTP 400**. Наш билингвальный редактор возит src→dst-блок; если сборщик когда-либо приложит reasoning-поле (эскалация/второй хоп), **mistral-арм редактора упадёт**. Метрика: **надёжность mistral-editor-арма — из «падает на первом же запросе с reasoning-полем» в 0**; ноль COGS. Гейт: проверить наш message-builder перед тем, как mistral-арм пойдёт прод-путём (он и так за rate-guard, D39.12). Ev: `litellm/litellm/llms/mistral/chat/transformation.py:392-405` (`_strip_output_only_fields`, assistant-only).
2. **[VERIFIED, NEW] GLM молча глотает context-overflow.** z.ai/GLM, по комментарию opencode, может **принять переполненный контекстом промпт без 4xx** — модель просто усекает вход. Для нашего несущего glm-5-редактора это значит: волатильный хвост (инъекция банка памяти) **тихо отваливается**, и чистый 2xx отгружает деградированную правку без единого сигнала ошибки — ровно «сломанный телефон», против которого арх-ресет D39. Метрика: **качество editor-арма** — конвертирует тихий обвал в громкий фейл; предотвращает молчаливое усечение банк-хвоста. Действие: pre-send гард «оценка токенов vs `context_window`» для GLM (Capability может нести `context_window`), + маппинг context-length 400/413 → отдельный terminal `ContextOverflow`. Гейт: одна-харнессовая примета (opencode-комментарий, не wire-трасса) → **вендор-сверка z.ai обязательна** перед абсорбцией; порог оценщика — консервативный. Ev: `opencode/packages/opencode/src/provider/error.ts:30-31`; goose `is_context_length_exceeded_message` `goose/crates/goose-providers/src/http_status.rs:181-249`.
3. **[VERIFIED, NEW] GLM finish-reasons: `sensitive`→content_filter, `network_error`→stop.** GLM отдаёт нестандартные finish-строки вне OpenAI-словаря. `sensitive` — это контент-фильтр GLM (наш редактор — GLM!), а `network_error`, отмаппленный в `stop`, — **риск тихого провала** (сетевую ошибку выдаёт за чистое завершение). Наш контракт `finish=stop-only` + echo/coverage-гейты это ловят downstream, но матчер finish должен знать оба значения. Метрика: **корректность finish/undercount** — GLM-фильтр перестаёт выглядеть как валидный stop. Ev: `litellm/litellm/litellm_core_utils/core_helpers.py:120-122`.
4. **[CONFIRMED] Quota/credits-429 → отдельный TERMINAL, не retryable.** Сейчас ВСЕ 429 retryable (`httpllm.go:341-342`): ключ с кончившимися кредитами в середине волны сжигает 3 попытки + до 3×5мин honored-Retry-After под удержанной USD-резервацией — и всё равно падает. opencode и goose классифицируют это как fatal (детерминизм: оператор должен пополнить, ретрай не поможет). Метрика: **надёжность/wall-clock — fail-loud за 1 попытку вместо 3+backoff; волна не виснет до ~15мин** на мёртвом ключе. Гейт: узкий body-marker (`insufficient_quota`/`quota_exceeded`, +402) + drift-guard-тест (#12). Ev: opencode `packages/llm/src/route/executor.ts:242-245` + `schema/errors.ts:87-96`; goose `http_status.rs:181-249` (402→`CreditsExhausted`).
5. **[CONFIRMED] HTTP/2 keepalive на общем `http.Client` (без стриминга!).** На длинной thinking-тяжёлой правке НИ ОДНОГО байта тела не течёт, пока весь JSON не готов → прокси/LB может idle-закрыть сокет посреди генерации. Наш общий клиент (`httpllm.go:161-174`) собран **без keepalive-тюнинга**. HTTP/2 PING держит транспорт живым независимо от DATA-фреймов. Метрика: **надёжность — убирает класс mid-generation RST на длинных editor-вызовах**; каждый несостоявшийся reset = несостоявшийся ре-билл. Гейт: проверить, что фронты платных провайдеров не реджектят HTTP/2 PING (иначе HTTP/1.1 для них). Ev: grok-build `shared_http.rs:86-96` (http2 keepalive 15s/5s); openai-go `default_http_client.go:10-14` (ResponseHeaderTimeout).
6. **[VERIFIED, NEW] Gemini `limit: 0` в 429/499/503 = ЖЁСТКИЙ terminal, не транзиент.** Судья Gemini: 429, чьё сообщение содержит `limit: 0`, — проект с нулевой квотой, ретрай **никогда** не пройдёт (жжёт время). gemini-cli матчит `/limit:\s*0/` и делает terminal независимо от статуса. Метрика: **надёжность judge — не крутим 3 бесполезные попытки на нулевой квоте.** Ev: `gemini-cli/packages/core/src/utils/googleQuotaErrors.ts:238-249`.
7. **[VERIFIED, NEW] xAI: `x-should-retry:false` в ответе форсит FATAL поверх статуса.** Официальный grok-харнесс чтит header `x-should-retry` как авторитет над кодом: провайдер может пометить content-caused 5xx неретраебельным (экономит до `MaxAttempts1` ПЛАТНЫХ попыток). Три реализации (openai-go, anthropic-sdk-go, grok-build) сходятся. Дёшево, безвредно при отсутствии header (наши OpenAI-compat ноги в основном его не шлют; xAI/OpenAI — шлют). Метрика: **$ / надёжность — до 2 платных ретраев сэкономлено на server-marked-fatal 5xx; no-op при отсутствии.** Ev: openai-go `internal/requestconfig/requestconfig.go:383-388`; anthropic-sdk-go `internal/requestconfig/requestconfig.go:262-267`; grok-build `retry.rs:188-197`.
8. **[VERIFIED, NEW] Локаль/ollama: HTTP 200 с ошибкой В ТЕЛЕ стрима.** ollama возвращает 200, даже когда стрим несёт `error`-поле — успех/провал судится по событию, не по коду. Наш local-адаптер/liveness (WSL2-стенд) должен парсить тело, не только статус. Метрика: **надёжность local-fallback — ложный «жив» при битой локали.** Ev: codex `codex-rs/ollama/src/client.rs:190-197,227-235`.
### Деньги / точность биллинга
9. **[PARTIAL→реально] xAI reasoning: identity-гард против латентного 3044% overcount.** Наш `additive`-путь (`provider_openai.go:101-102`) добавляет `reasoning_tokens` **безусловно**. litellm фолдит их только когда `total == prompt+completion+reasoning` (иначе reasoning уже внутри completion). Сегодня xAI Chat Completions — additive-режим (наш верен), но гард делает нас **само-корректирующимися вместо «по слагу»**. Метрика: **xAI output-COGS overcount — 0% сегодня, но кап латентного ~3044% двойного счёта** (та самая drift-величина, что vojo уже оплатил, наш `llm.go:42`), если xAI когда-нибудь свернёт reasoning в completion. Гейт: живая grok-usage-проба в `00-provider-quirks.md` (правило двух направлений). Ev: `litellm/litellm/llms/xai/chat/transformation.py:289-353`; grok-build `xai-chat-state/src/usage.rs:44-61` (читает reasoning как **subset** — но это ДРУГОЙ эндпоинт, xAI-native, не Chat Completions).
10. **[CONFIRMED] CostSource/Estimated-маркер на settle-estimate строках.** Честную половину (settl'им резерв-оценку, не $0) мы уже делаем (`stagerun.go:469-473`, `422-436`). Не хватает легенды телеметрии: goose несёт `CostSource::{ProviderReported,Estimated}`, crush ставит `EstimatedUsage=true`. Без флага estimated-строки неотличимы от реальных zero-token вызовов и косят token-based COGS-аналитику. Метрика: **целостность телеметрии — «доля estimated в спенде» становится queryable; никаких безмолвных null-token строк.** Дисциплина: estimated-токены **display-only**, НЕ кормят `CostUSD`. Ev: goose `conversation/token_usage.rs:17-22`; crush `internal/agent/agent.go:1896-1927`.
11. **[CONFIRMED] План: судья Gemini → нативный `generateContent`.** На OpenAI-compat-слое Gemini роняет thoughts-поле → мы деривим reasoning вычитанием (`totalpromptcompletion`). Нативный эндпоинт отдаёт `usageMetadata.thoughtsTokenCount` первым классом **и структурный `finishReason`** вместо композитной строки `content_filter: PROHIBITED_CONTENT` — один переезд чинит и usage, и finish (пересечение с Q3). Метрика: **робастность reasoning-учёта Gemini** (нет derive-by-subtraction, который тихо даст 0, если слой перенесёт thinking в completion) + **корректность finish.** Гейт: за Ф2-нативным-Gemini (реальная транспорт-работа: auth/retry/cache_control); до него — additive_total + промежуточный inclusive-vs-additive identity-чек. Ev: litellm `vertex_and_google_ai_studio_gemini.py:1729-1745,1908-1944`; opencode `protocols/gemini.ts:338-361`.
### $ / cache (вопрос №1 — но импакт скромнее, чем звучит)
12. **[CONFIRMED] Держим Р5-раскладку; ГАРАНТИРУЕМ байт-идентичность константного префикса; НОВОЕ — cache_control на GLM.** Обзор подтверждает нашу раскладку с трёх сторон: (а) opencode инжектит cache-маркеры **только** для `anthropic-messages`/`bedrock-converse`, OpenAI/Gemini-implicit-cache **осознанно пропускает** (`cache-policy.ts:39-42`) — ровно наш сплит; (б) goose **физически переносит** волатильный блок (turn-context) в ХВОСТ, «иначе он инвалидирует message-level cached prefix (Anthropic хеширует tools→system→messages)» (`anthropic.rs:323-357`, CONFIRMED) — это и есть наша боль «инъекция банка бьёт префикс»: банк/STM **обязаны** идти строго после константного префикса; (в) litellm **срезает** cache_control для OpenAI-compat (`gpt_transformation.py:380-402`, дефолт-strip, с carve-out для кастом-base-гейтвеев). **Несущее уточнение:** `prompt_cache_key` (стабильный routing-ключ) есть у OpenAI-family/xAI/**Mistral**, но **НЕ у deepseek-native и НЕ у GLM** (litellm deepseek-dir: ноль ссылок; opencode эмитит ключ лишь для openai/azure/xai/mistral/deepinfra/cerebras) — значит для нашего draft (deepseek-v4-flash) и editor (glm-5) единственный рычаг — **литеральный префикс-автокэш**, и всё, что мы можем, — держать `system+brief+style-sheet+summary` байт-в-байт стабильным. **НОВОЕ (VERIFIED):** ZAI/GLM, в отличие от дефолтного OpenAI-compat-strip, **СОХРАНЯЕТ cache_control** (`litellm/litellm/llms/zai/chat/transformation.py:23-34`, «GLM supports cache_control — don't strip it») → большой стабильный билингв-префикс редактора (system/style/глоссарий) можно кэш-маркировать на GLM. Метрика: **вход-COGS редактора — cache-hit GLM $0.2 vs miss $1.0 (÷5) на входной доле**; НО вход ≪ выход (редактор доминирует выходом, `08-cost-model` §), поэтому реальная экономия **~2% стандарта** (как и предсказывал cost-model: «deepseek auto-cache ~2%, не рычаг»). Честно: Q1 — вопрос №1 по названию, но **низкий по $-импакту**; ценность — «мы уже правы» + один новый GLM-рычаг + фикс-гарантия стабильного префикса. Гейт: cache-цены/поведение GLM — вендор-сверка; mistral prompt_cache_key — тоже (см. Q7).
### Мелкое / отложенное (полнота)
13. **[CONFIRMED] `parseRetryAfter` — принять `Retry-After-Ms` и дробные секунды.** Наш `strconv.Atoi` (`httpllm.go:426`) режет любой не-integer → `Retry-After: 1.5`/`Retry-After-Ms` дают 0 и слепой exp-backoff. opencode/openai-go/anthropic-sdk-go все парсят ms первым. Метрика: **надёжность/латентность — чтит sub-second хинты вместо BackoffBase(500ms)+jitter**; чистый апсайд под нашим 5-мин капом. Ev: opencode `route/executor.ts:93-95`; openai-go `requestconfig.go:396-449`; anthropic-sdk-go `requestconfig.go:275-328`.
14. **[PARTIAL] Проба (не билд!): что DeepSeek/GLM/Mistral реально шлют на 429.** `obs.LogLLMExchange` уже пишет headers+body — проверить в пере-прогоне, есть ли `x-ratelimit-{limit,remaining,reset}`/body-retry-поле. opencode парсит эти окна, но тратит их на observability — рычаг «пейсить ДО 429» никто не построил. **Не строить пейсер сейчас** — решать по данным (правило двух направлений). Ev: opencode `route/executor.ts:112-148`; litellm `router.py:2823-2847` (pre-call RPM-чек внутри семафора — форма «пейсить до 429», если есть budget-header).
15. **[CONFIRMED] Держим rateGuard как есть; Mistral-48% = ТЮНИНГ `max_concurrency`, не алгоритм.** Весь обзор сошёлся: единственный другой проактивный лимитер — семафор litellm (`router.py:2823`), и он работает лишь потому, что у litellm есть sibling-деплойменты для роутинга вокруг 429 — чего у нас нет. Все прочие 10 — реактивны и влетели бы в наши 48%. **Умный backoff не чинит token-bucket/concurrency-cap тир** — только кап исходящей конкуренции ниже потолка тира. Метрика: **надёжность — mistral N-∥ retry-fail ~48%→~05%** при `max_concurrency` под потолком тира; ноль кода, ноль COGS. Гейт: per-tier калибровка; пере-замер при mistral-editor-арме. Ev: litellm `router.py:2823-2847`; goose `openai.rs:337-348` (Mistral — только max_tokens-remap, не rate).
16. **[PARTIAL, GATED] HTTP/1.1-escape на последней попытке — диагностика тихого усечения.** grok-build построил `send_with_retry_escaping_pool` (`xai-grok-http/src/lib.rs:432-475`) ровно чтобы уйти с «отравленного» HTTP/2-пула, и их truncation-регрессия — в том же модуле → **правдоподобная причина** нашего тихого усечения на 28k. Но корень НЕ подтверждён (может быть finish=length, который мы уже лечим) → CLAUDE.md запрещает гадать: **гейтить как эксперимент с замером h2-vs-forced-h1**, не лендить дефолтом. Метрика: truncation-rate 28k (baseline неизвестен — потенциально крупнейшая тихая утечка качества). Ev: grok-build `retry.rs:231-246`.
17. **[PARTIAL, DEFER] assistant-prefill continuation на finish=length.** Единственный механизм ЧАСТИЧНОГО восстановления во всех 11 (aider `base_coder.py:1492-1521`): вместо ре-рана всего вызова — дописать усечённый dst-блок как assistant-prefix и до-вызвать со свежим max_tokens. Наш finish=length сейчас ре-ранит весь запрос (`escalation.go:17-35`), пере-биллит уже сгенерированный префикс. Это **правильный ответ на «нужен стриминг для truncation» — не нужен, нужен continuation** (стриминг его НЕ даёт). Метрика: **$ — экономит ре-билл уже-эмитнутого префикса (~4060% editor-генерации) на событие усечения.** Гейт: **HIGH-риск для детерминизма** (мульти-хоп, golden/snapshot; наш src→dst-блок наивный сплайс может побить; Gemini/GLM prefix-continuation-семантика различна) → per-model `supports_assistant_prefill` + адверсариальный golden-ревью; **скорее DEFER**.
18. **[PARTIAL] Прочее мелкое, чистый апсайд/тесты:** (а) proportional jitter вместо fixed `rand(250ms)` (`httpllm.go:144`) — де-синк N-∥ на mistral (gemini-cli ±30%, openai-go 25%); (б) drift-guard тест, пиннящий status→retryable-мапу и finish-парсер как **префикс/substring**-матч (чтобы композит `content_filter: PROHIBITED_CONTENT` классифицировался) — аналог aider `_load`, который на импорте валит, если litellm `*Error` не расклассифицирован (`aider/exceptions.py:74-76`); (в) кап BilledDecodeError-ре-биллов ниже MaxAttempts (grok-build держит Serialization non-retryable, с регрессией «laundering в retryable дал full-budget шторм»).
**Явные REJECT (что НЕ берём — с причиной):**
- **Не берём** авто-своп модели на 429 (gemini-cli `action:'silent'`) — противоположно нашему fail-loud + ломает детерминизм; gemini-cli #23889 показал баг «сообщение дублируется 3050×» на pro→flash-фолбэке.
- **Не берём** 1h/uncapped honored-Retry-After (goose 3600s clamp; openai-go/anthropic-sdk-go uncapped) — виснет платная волна под USD-резервацией; наш 5-мин кап верен.
- **Не берём** no-jitter multiplicative backoff (aider) — thundering-herd под N-∥ волнами.
- **Не берём** `retry_429:false` (codex) — каждый tier-blip станет hard-fail в середине книги.
- **Не берём** идемпотентность-ключ: обзор отвечает на вопрос «у кого кроме OpenAI» — **НИ У КОГО не шлётся** (даже codex не шлёт OpenAI-у). Держим не-шлём.
- **Не берём** streaming ради «снижения обрывов/ре-биллов»: **ни один харнесс не резюмит частичную генерацию** — все ре-ранят весь запрос (codex full-history, gemini-cli full-turn, goose full-turn, opencode non-retryable break, anthropic no-resume). Стриминг покупает **ДЕТЕКЦИЮ**, не resume.
- **Не берём** брутальный body-substring/regex-стиль классификации ошибок (aider ~30-regex батарея) — та самая «exact matchers dead» хрупкость, что мы уже флагаем.
---
## §2. Q7 — таблица квирк-кандидатов
Все**кандидаты**, абсорбция после вендор-сверки (правило 10.07). Статус: **NEW** / **sharpens** (уточняет реестр) / **tracked** (только корроборация). «Verified» = адверсариально ре-прочитан в коде. Жатва трекеров помечена `#issue`+дата.
### Прямо задевает пере-прогонные армы (glm / mistral / deepseek-pro)
| Провайдер | Симптом | Статус | Ev (code / issue+дата) |
|---|---|---|---|
| **mistral** | Строгая `extra_forbidden`: реплей output-only `reasoning_content`/`thinking_blocks` или `null`-value сообщений → **400**; стрипать assistant-поля. | NEW·verified | `litellm mistral/chat/transformation.py:392-405` |
| **glm-zai** | Молча **принимает context-overflow** (нет 4xx) → тихо усекает вход. | NEW | `opencode packages/opencode/src/provider/error.ts:30-31` |
| **glm-zai** | finish `sensitive`→content_filter, `network_error`→stop (вне OpenAI-словаря; `network_error`→stop = риск тихого провала). | NEW·verified | `litellm core_helpers.py:120-122` |
| **glm-zai** | **СОХРАНЯЕТ cache_control** (в отличие от дефолт-strip OpenAI-compat) — COGS-рычаг для билингв-редактора. | NEW·verified | `litellm zai/chat/transformation.py:23-34` |
| **glm-zai** | Disable-thinking **эндпоинт-зависим**: native z.ai `thinking:{type:disabled}` vs routed OpenAI-compat `reasoning:{enabled:false}`. | sharpens·verified | `cline .../routing/glm-thinking.ts:31-58` |
| **glm-zai** | Множественные base URL: OpenAI-compat `/api/paas/v4` И Anthropic-Messages `/api/anthropic` (goose гоняет thinking через второй). | NEW | `goose .../declarative/definitions/zai.json:3,13,20` |
| **deepseek** | Thinking-ON **multi-turn**: 422 «reasoning_content must be passed back» — эхать reasoning_content на каждом assistant-сообщении. | NEW·verified | `litellm deepseek/chat/transformation.py:62-100` (issue #28045); litellm#28461 (2026-05-21), #26395 (2026-04-24) |
| **deepseek** | v4-flash thinking-ON отдаёт `"reasoning": null` вместо `reasoning_content` — нестабильность имени поля. | NEW | litellm#28461 (2026-05-21) |
| **mistral** | Отвергает `max_completion_tokens`, требует legacy `max_tokens` (мы уже шлём max_tokens). | tracked·verified | `goose openai.rs:335-348` |
| **mistral** | `seed` не под тем именем — детерминизм через `extra_body.random_seed`. | NEW·verified | `litellm mistral/chat/transformation.py:179-180` |
| **mistral** | Поддерживает prompt-caching через `prompt_cache_key` (стабильный id). | NEW | `opencode patches/@ai-sdk%2Fmistral@3.0.51.patch:80-81` |
| **deepseek** | base по умолчанию расходится: litellm `/beta`, crush+наш реестр `/v1` (у /beta — устаревший комментарий рядом = ровно наша «code-language» ловушка). | NEW·verified | `litellm deepseek/chat/transformation.py:261,278` |
### xAI / Gemini / Kimi (судья, канал B, кандидаты-редакторы)
| Провайдер | Симптом | Статус | Ev |
|---|---|---|---|
| **xai-grok** | reasoning-учёт **эндпоинт-split**: Chat Completions = ADDITIVE (`total=prompt+completion+reasoning`), Responses/native = subset. Наш путь — Chat → additive верен. | sharpens·verified | `litellm xai/chat/transformation.py:289-353`; grok-build `xai-chat-state/usage.rs:44-61` (subset) |
| **xai-grok** | `x-should-retry:false` в ответе → FATAL поверх статуса (даже 429/5xx). | NEW·verified | `grok-build client.rs:207-227 + retry.rs:176-190` |
| **xai-grok** | HTTP/2-пул «отравляется» (тихие LB/Cloudflare/GOAWAY-дропы) → ретрай на том же коннекте фейлит одинаково; лечат HTTP/1.1-rebuild. | NEW | `grok-build retry.rs:231-246; xai-grok-http/lib.rs:432-475` |
| **xai-grok** | Slug-gated param-дропы: grok-3-mini/grok-4/grok-code-fast отвергают `stop`; grok-4/code-fast — `frequency_penalty`. | NEW·verified | `litellm xai/chat/transformation.py:150-169` |
| **xai-grok** | Пустая строка finish_reason на tool-call (вместо `tool_calls`); чинят при наличии tool_calls. | NEW·verified | `litellm xai/chat/transformation.py:223-232` |
| **xai-grok** | Давится message-level `name`-полем (стрипать, issue #9720). | NEW·verified | `litellm xai/chat/transformation.py:207-221` |
| **xai-grok** | `num_sources_used` (Live Search) = **$0.025/источник** ($25/1000); датированная семантика к реестровому «игнорировать нестандартные cost-поля». | sharpens | `litellm xai/cost_calculator.py:55-84` |
| **gemini** | `candidatesTokenCount` **включает thinking НЕ всегда** — варьирует per-response; litellm детектит динамически, иначе ±учёт. | sharpens·verified | `litellm vertex_and_google_ai_studio_gemini.py:1729-1745` (PR#10141) |
| **gemini** | `MALFORMED_FUNCTION_CALL`: litellm→`stop`, opencode→`error` (харнессы РАСХОДЯТСЯ). Маппинг unknown→`stop` = **риск тихого провала**. | NEW·verified | `litellm core_helpers.py:100-124` |
| **gemini** | 2.5 «minimal» reasoning не достигает нуля: per-model floor (pro=128, flash=1, flash-lite=512); 3.x — `thinkingLevel`-enum, полностью не отключить. | sharpens | `litellm .../gemini.py:823-838,867-913`; constants.py:144-151 |
| **gemini** | 3.x требует/предпочитает `temperature:1.0` (харнесс инжектит, если не задано). | NEW | `litellm .../gemini.py:1238-1241` |
| **gemini** | `limit: 0` в 429/499/503 = terminal, не транзиент. | NEW | `gemini-cli utils/googleQuotaErrors.ts:238-249` |
| **kimi** | Reasoning-kimi (k2.5/k2.6): корректно **ОМИТить** temperature (не форсить 1). Наш K2.6 — reasoning → кандидат сменить `force:1`→omit. | sharpens·verified | `litellm moonshot/chat/transformation.py:131-146`; cline#10544 (2026-05-04, `400 invalid temperature: only 1 is allowed`) |
| **kimi** | Multi-turn tool-call: reasoning_content обязателен на каждом assistant-tool-сообщении (litellm вставляет `' '`). | NEW | `litellm moonshot/chat/transformation.py:148-192` (issue #23765) |
| **kimi** | reasoning-OFF = `thinking:{type:disabled}` (как GLM); k2.6 — `thinking.type`. | NEW | `cline .../routing/provider-option-rules.ts:344-379` |
| **kimi** | Дефолтный host расходится: goose `api.moonshot.cn`, litellm/наш реестр `api.moonshot.ai` (intl). | tracked | `goose .../moonshot.json:13-14` |
### Инфра / прочее
| Провайдер | Симптом | Статус | Ev |
|---|---|---|---|
| **ollama (local)** | HTTP 200 с `error` в теле стрима — судить по событию, не коду (наш local-liveness). | NEW·verified | `codex codex-rs/ollama/src/client.rs:190-197,227-235` |
| **glm-zai** | crush health-probe special-case: для ZAI «connected» = любой статус кроме 401 (наш pre-run live-probe: для GLM 401/403=down, прочее=up). | NEW | `crush internal/config/config.go:937` |
| **deepseek** | content нельзя слать OpenAI list/blocks — только плоская строка (мы шлём строки — не баг сейчас). | NEW·verified | `litellm deepseek/chat/transformation.py:115-125` |
| **deepseek** | cache-поля `prompt_cache_hit_tokens`/`_miss_tokens` (hit+miss==prompt). | tracked·verified | `litellm types/utils.py:1648-1653` (реестр стр.66) |
**Дубликаты онлайн-жатвы (корроборация, не новьё):** Kimi temp=1 повторяется (K2.5 тоже) — cline#10544; deepseek multi-turn 400 — claude-code#68995 (2026-06-17); mandatory-thinking-эндпоинты реджектят disable — claude-code#65863 (2026-06-06), #69379 (2026-06-18); Gemini quota-429-фолбэк баг-склонен — gemini-cli#26002/#23889/#9248/#4646; xai reasoning_effort slug-специфичен — litellm#16204 (2025-11-03); Mistral empty-content → None — litellm#12197 (2025-07-01); Kimi K3 существует — litellm#33921 (2026-07-19, ре-чек слага к квартальному).
---
## §3. Per-question разборы
### Q1 — Prompt-cache дисциплина ($) · [Q1/Q3-синтез пере-выведен вручную + верифицирован]
**Наше сейчас.** Р5: стабильный префикс (system+brief+style-sheet+summary) несёт `CacheBoundary`; волатильный хвост (глоссарий+STM+чанк). Anthropic-адаптер маппит boundary→`cache_control{ephemeral,ttl}` (≤4), суммирует input+cache_read+cache_creation в PromptTokens; OpenAI-compat игнорят флаг, автокэш по префиксу; `cacheRead()` читает оба варианта DeepSeek-полей.
**Cross-repo (все high-confidence).** Три семейства: (1) **Anthropic-маркерное** (grok-build 1 ephemeral на last-system; aider — блок-порядок + маркеры на стабильных блоках + warming-ping каждые `5*605`с под 5-мин TTL, `base_coder.py:1348/1340-1373` CONFIRMED; cline — last-user-текст + фейковый `' '`-парт чтобы маркер не схлопнулся; opencode — 4-breakpoint budget в invalidation-порядке tools→system→messages `anthropic-messages.ts:511-538`; litellm — config-driven `cache_control_injection_points`; anthropic-sdk-go — per-block ephemeral 5m/1h). (2) **OpenAI-family — только ключ:** codex/opencode/openai-go `prompt_cache_key` (стабильный routing-ключ, заменяет `user`), стрип cache_control (litellm `gpt_transformation.py:380-402`, дефолт-strip с carve-out для кастом-base). (3) **Gemini — контекстный кэш вне промпта:** litellm требует **один непрерывный блок** (`vertex_ai/context_caching/transformation.py:21-48`, CONFIRMED); gemini-cli explicit-кэш вообще не создаёт.
**Ключевые уточнения (VERIFIED свежими агентами):** goose **физически переносит** волатильный turn-context в хвост, «иначе инвалидирует cached prefix» (`anthropic.rs:323-357`) — прямой ответ нашей боли; `prompt_cache_key` работает у OpenAI-family/xAI/Mistral, но **НЕ deepseek-native/GLM**; GLM **сохраняет** cache_control (`zai/chat/transformation.py:23-34`).
**Берём/не берём.** Берём: (1) держать константный префикс байт-идентичным, банк/STM строго в хвост — рек #12; (2) cache_control-маркировка на GLM — новый рычаг; (3) для Gemini-explicit-кэша (если Ф2) — cached-блок должен быть непрерывным. Не берём: `prompt_cache_key` для draft/editor (deepseek/glm его не чтут). **$-импакт скромен (~2% стандарта)** — вход ≪ выход редактора; Q1 «вопрос №1» по важности вопроса, не по деньгам.
### Q2 — Rate-limit адаптив
**Наше сейчас.** `retryLoop` (exp backoff cap 30s, honored-Retry-After cap 5min, +rand(250ms), MaxAttempts 3) + отдельная ось: per-model `rateGuard` (семафор + min_interval, wire-neutral, не snapshot-folded). `parseRetryAfter` — только integer-header. Не читаем `x-ratelimit-*`, нет AIMD/cooldown. Mistral ~48% N-∥.
**Cross-repo.** Единственный другой проактивный лимитер — litellm семафор с pre-call RPM (`router.py:2823-2847`), работает лишь из-за sibling-деплойментов. opencode парсит retry-after-ms + `x-ratelimit-*`/`anthropic-ratelimit-*`, но тратит на observability. goose предпочитает body `retry_after_seconds` над header. gemini-cli — server-delay как **floor** backoff. codex Retry-After-header **не парсит вовсе** (только regex по тексту ошибки), `retry_429:false`. grok кап Retry-After 120s + hard-cap 429-ретраев=2.
**Берём/не берём.** Берём: fractional/ms Retry-After (#13), 429-header-проба (#14), body/message Retry-After fallback за vendor-гейтом (#18), опц. model-cooldown (defer). Держим: rateGuard + Mistral=тюнинг-кап (#15). Не берём: silent model-swap, 1h Retry-After, no-jitter backoff, retry_429:false. **Вывод: против Mistral-48% ни один харнесс не даёт алгоритма — только concurrency-cap работает.**
### Q3 — finish_reason таксономия · [пере-выведен вручную + верифицирован]
**Наше сейчас.** Нейтральные stop/length/content_filter/refusal; контракт finish=stop-only; length→ретрай с бо́льшим max_tokens (+ min_max_tokens-флор); Gemini композит `content_filter: PROHIBITED_CONTENT` (exact-матчеры уже мертвы).
**Cross-repo (все high).** litellm — единый статический `_FINISH_REASON_MAP`, **unmapped → warn + `stop`** (CONFIRMED; `MALFORMED_FUNCTION_CALL`→stop) — **риск тихого провала** (усечённую/битую/дегенеративную генерацию выдаёт за чистый stop). opencode — closed 6-value enum + **структурная детекция усечения** (`route/client.ts:382-391`, CONFIRMED: стрим без терминального finish-события → hard error). codex — Responses-события (`response.completed`/`.incomplete`; ранний close = ошибка). grok-build — 4-value StopReason + **server-side doom-loop-детектор** (`x-grok-doom-loop-check`; `DoomLoopDetected`→retry ≤250ms; CONFIRMED, «confident» = thinking-канал tail_repetition≤8) — релевантно нашей эхо/дегенеративной петле (research/15). cline — **reasoningFloor = budget+1024-reserve** (`gateway.ts:120-181`, CONFIRMED) — кросс-валидирует наш min_max_tokens. goose — **ОМИТит max_tokens** при unset (противоположно нашему флору; `openai.rs:1459-1474`, CONFIRMED). anthropic-sdk-go — богаче: +`model_context_window_exceeded`, `pause_turn`, `refusal`.
**Берём/не берём.** Держим: finish=stop-only + min_max_tokens-флор (cline подтверждает reserve-логику; наш флор — верный выбор для thinking-моделей, в отличие от goose-омита). Берём: finish-матчер как префикс/substring (drift-guard #18); знать GLM `sensitive`/`network_error` (§2). **Не берём** litellm-стиль «unknown→stop» — это ровно то, против чего наш строгий контракт + echo/coverage-гейты. Кандидат-заметка: xAI doom-loop-header как ранний сигнал дегенеративной петли (за vendor-сверкой). Структурная детекция усечения (opencode/codex) достижима **только со стримингом** → см. Q6.
### Q4 — Таксономия ошибок retry/fatal
**Наше сейчас.** Единый `retryLoop`: 429&≥500→retryable; прочие non-2xx→terminal fail-loud; network/timeout→retryable (unless ctx done); 2xx-undecodable→BilledDecodeError (retryable unless >16MiB); 2xx-empty→billed success. Идемпотентность — не шлём. Anthropic 529 ловится тем же ≥500.
**Cross-repo.** opencode — tagged-union, QuotaExceeded(429+body)=fatal, context-overflow под-классификация. goose — централизованная таблица (402→CreditsExhausted, 400/413→ContextLengthExceeded). openai-go/anthropic-sdk-go — **x-should-retry** override + body-rewind; retry 408/409/429/≥500. gemini-cli — network-code allowlist (undici timeouts), maxAttempts 10. aider — declarative EXCEPTIONS-таблица по классу litellm-исключения + `_load` drift-guard. codex — two-tier (transport 429/5xx/transport + семантик is_retryable whitelist; ServerOverloaded=terminal). litellm — Retry-After чтит только 0<x60s. crush/cline делегируют SDK.
**Берём/не берём.** Берём: quota-429→terminal (#4), context-overflow terminal + GLM-precheck (#2), x-should-retry (#7), drift-guard-тест (#12/#18), кап billed-decode-ре-биллов, proportional jitter. Держим: network/timeout retryable, MaxAttempts 3, honored-Retry-After 5-мин-кап (не 60s litellm, не uncapped SDK), не-шлём идемпотентность, 529-в-≥500. Не берём: opencode non-retryable network/timeout, gemini maxAttempts 10, aider retry ContentPolicyViolation (наш 18+: детерминированный отказ, ретрай жжёт деньги), brittle-regex-стиль, 408/409.
### Q5 — Usage-учёт
**Наше сейчас.** Neutral Usage: PromptTokens(total), CachedTokens (оба DeepSeek-варианта), CacheCreationTokens, CompletionTokens, ReasoningTokens (subset/additive/additive_total). Anthropic суммирует 3 части. Served-model биллинг (`PriceForResponse(requested,served)`). Double-count-гард (uncached=promptcachedwrite≥0). Settl'им резерв-оценку на paid-2xx-zero-usage (не $0).
**Cross-repo.** litellm — per-response reasoning-reconciliation с identity-гардами. grok-build (офиц.) — биллит по SERVER cost-полю (`cost_in_usd_ticks`), reasoning отдельно/informational, `cost_missing_calls`-счётчик. opencode — dual (inclusive + non-overlapping breakdown, undefined-not-zero). goose/crush/aider/cline — usage-estimator fallback + CostSource-флаги; crush читает OpenRouter `Usage.Cost` override. codex/gemini-cli — served-model через header/modelVersion.
**Берём/не берём.** Берём: xAI identity-гард (#9), CostSource-маркер (#10), план native-Gemini thoughtsTokenCount (#11), опц. server-cost-поле xAI (проба). Держим (мы ведём): served-model биллинг, double-count-гард, cache-fold, честный settle-estimate (не фабрикуем токен-математику как goose-estimator). Не берём: codex single-vendor usage-shape (мис-букнет xAI/Gemini), nested-only DeepSeek-cache (потеряет hit-скидку), aider DeepSeek-fallback (вычитает ЦЕНУ из ТОКЕНОВ — живой мис-бук), streaming-usage-плюмбинг (мы non-streaming). Defer: split cache-creation 5m/1h (только если Anthropic вернётся / mixed-TTL).
### Q6 — Streaming vs non-streaming надёжность
**Наше сейчас.** Non-streaming ONLY (`StreamingLLMClient` отложен). Один attempt под `context.WithTimeout(attempt_s, дефолт 300; 240 конфиг)` покрывает connect+headers+body одним бюджетом. finish=length→ре-ран с бо́льшим max_tokens. Нет keepalive/idle-timeout/first-byte-timeout.
**Cross-repo.** codex/opencode/cline/crush/grok — stream-only (buffered-caller дренит SSE); goose/gemini-cli/aider/litellm — оба. **Ключевые примитивы, которые даёт только стриминг:** per-event **idle-timeout, сбрасываемый на каждом событии** (codex `responses.rs:503-529`); composed header+chunk+total через AbortSignal.any (opencode); **content-progress timer** (`last_content_chunk_at`, grok — ловит thinking-stall/эхо-мину рано); **stream-closed-before-finish = error** (opencode/codex). anthropic-sdk-go **HARD-отказывает** длинный non-streaming (`CalculateNonStreamingTimeout`: если `expectedTime=1h·maxTokens/128000 > 10min` → «streaming required»). openai-go ResponseHeaderTimeout=10min (только time-to-headers). Единственное частичное восстановление во всех 11 — **assistant-prefill continuation** (aider), и оно на NON-streaming пути.
**Критический нюанс (обосновывает вердикт).** idle/stall-timeout, который все ценят, существует **только со стримингом**: на non-streaming пути нет inter-chunk-разрывов, сервер держит headers до конца генерации → любой «first-byte/idle» коллапсирует в total attempt_s. Стриминг покупает **ДЕТЕКЦИЮ** (ранний catch зависа + stream-closed-signal + keepalive), **никогда автоматический RESUME**. По собственной математике Anthropic 28k выход ждёт ~24 мин, а её жёсткий non-streaming кап (Opus 8192) ≥ всего нашего диапазона → `attempt_s=240` внутри сертифицированного вендором безопасного non-streaming конверта.
**Берём/не берём.** Держим non-streaming дефолтом + `StreamingLLMClient`-отсрочку, но с **явным trip-wire**: стриминг ТОЛЬКО для длинного editor-арма, ТОЛЬКО если тихое усечение сохранится на верху 28k на вебновелл-срезе, и **buffered** (fold SSE→полный LLMResponse, opencode-паттерн — сигнатура `Complete()`, golden/детерминизм, все гейты байт-идентичны). Если trip-wire сработает — idle/stall-timeout как ЕДИНСТВЕННЫЙ новый механизм. Берём СЕЙЧАС (без стриминга): HTTP/2 keepalive (#5), assistant-prefill continuation-оценка (#17, defer). Не берём: streaming-only архитектуру (жрёт usage-fidelity — aider падает на локальные ESTIMATE), idle-timeout в текущий non-streaming (коллапсирует в total), reclass empty-2xx как retryable (double-bill), стриминг ради снижения обрывов (никто не резюмит).
---
## §4. Appendix — per-repo (что смотрели / что пропустили)
- **codex** (Rust, Apache-2.0). Смотрели: `core/src/{client,client_common,responses_retry,util}.rs`, `codex-api/src/{sse/responses.rs,api_bridge.rs}`, `codex-client/src/retry.rs`, `model-provider-info/src/lib.rs`, `ollama/src/client.rs`, `protocol/src/error.rs`. Пропустили: TUI/apply-patch/cloud-tasks (не транспорт). Особенность: Responses-API-only, стрим-only, Retry-After-header не парсит.
- **gemini-cli** (TS, Apache-2.0). Смотрели: `core/src/core/{geminiChat,contentGenerator,loggingContentGenerator}.ts`, `utils/{retry,googleQuotaErrors}.ts`, `agent/event-translator.ts`, `utils/historyHardening.ts`. Пропустили: CLI/devtools/MCP. Особенность: model-fallback на 429 (баг-склонен), `limit:0`=terminal.
- **grok-build** (Rust, Apache-2.0, **офиц. xAI**). Смотрели: `xai-grok-sampler/src/{client,retry,shared_http, actor/request_task, stream/chat_completions}.rs`, `xai-grok-http/src/lib.rs`, `xai-grok-sampling-types/src/{conversation,doom_loop}.rs`, `xai-chat-state/src/usage.rs`. Особенность: doom-loop-детектор, HTTP/2-pool-escape, reasoning subset НА ЭТОМ (native) эндпоинте. Наиболее авторитетно по xAI-квиркам.
- **goose** (Rust, Apache-2.0). Смотрели: `goose-providers/src/{openai,openai_compatible,google,http_status}.rs`, `goose-provider-types/src/{retry,formats/{openai,anthropic,google},conversation/token_usage}.rs`, `goose/src/providers/usage_estimator.rs`, `declarative/definitions/*.json`. **Пропустили как ложный след:** `goose/src/tracing/rate_limiter.rs` — пейсит OTLP-телеметрию, НЕ LLM (проверено вручную). Особенность: turn-context-релокейшн, declarative-провайдеры.
- **aider** (Python, Apache-2.0). Смотрели: `aider/{llm,sendchat,models,exceptions}.py`, `coders/{base_coder,chat_chunks}.py`. Особенность: обёртка над litellm; assistant-prefill continuation; warming-pings; `_load` drift-guard.
- **cline** (TS, Apache-2.0). Смотрели: `sdk/packages/llms/src/providers/{ai-sdk,gateway, routing/*}.ts`, `sdk/packages/shared/src/agent.ts`, `.../vendors/types.ts`. (Провайдер-хендлеры живут в `sdk/packages/llms`, не в `apps/vscode/src/core/api` — там только `index.ts`.) Особенность: reasoningFloor, per-TTL cache-split, GLM/kimi thinking-routing.
- **opencode** (TS, MIT). Смотрели: `packages/llm/src/{cache-policy,route/{client,executor},protocols/*,schema/*,provider-error}.ts`, `packages/opencode/src/provider/{transform,error,provider}.ts`, `packages/core/src/util/retry.ts`. Особенность: compile-time cache-policy, структурная truncation-детекция, tagged-union ошибки.
- **litellm** (Python, MIT-ядро; **`enterprise/` НЕ читалась**). Смотрели: `litellm/{main,router,utils,cost_calculator,exceptions}.py`, `litellm_core_utils/{core_helpers,completion_timeout}.py`, `types/utils.py`, `llms/{deepseek,mistral,xai,moonshot,zai,openai,vertex_ai}/**`. Самый богатый провайдер-квирк-слой (Q3/Q4/Q5/Q7).
- **crush** (Go, **FSL-1.1 — read-only, не копировали**). Смотрели: `internal/agent/{agent,usage_fallback,loop_detection,errors}.go`, `internal/config/{provider,config}.go`, `internal/app/provider.go`. **Пропустили (внешнее):** реальный wire-транспорт — в `charm.land/fantasy`/`catwalk` (не в репо) + `openai/openai-go/v3`. Особенность: OpenRouter `Usage.Cost` override, EstimatedUsage-флаг, ZAI-probe-special-case.
- **openai-go** (Go, Apache-2.0, референс). Смотрели: `client.go`, `default_http_client.go`, `option/{requestoption,middleware}.go`, `internal/requestconfig/requestconfig.go`, `internal/apierror/apierror.go`, `chatcompletion.go`. Референс: Retry-After-Ms, x-should-retry, proportional jitter, idempotency-key, PromptCacheKey.
- **anthropic-sdk-go** (Go, MIT, референс). Смотрели: `client.go`, `default_http_client.go`, `option/{requestoption,middleware}.go`, `internal/requestconfig/requestconfig.go`, `message.go`, `shared/constant/constants.go`. Референс: 529, x-should-retry, CalculateNonStreamingTimeout, per-TTL cache-split, model_context_window_exceeded.
---
## Сообщение оркестратору (кратко)
research/21 готов (черновик, не коммичен — лендите вы). Главное: **наш транспорт в базе опережает/вровень со всеми 11** — единый retryLoop, 5-мин-кап Retry-After, fail-loud terminal, billed-decode-типизация, served-model биллинг, min_max_tokens-флор, double-count-гард. Значимого рычага против **Mistral-48%** (только concurrency-cap) и **тихого усечения 28k** (стриминг даёт лишь ДЕТЕКЦИЮ, не resume; continuation — не стриминг) никто не даёт.
**Самое ценное — Q7-квирки, задевающие пере-прогонные армы (все кандидаты, за вами вендор-сверка):** (1) **Mistral extra_forbidden** — mistral-editor-арм упадёт 400 при реплее reasoning-полей; (2) **GLM молча глотает context-overflow** — тихое усечение банк-хвоста на glm-5 (сломанный телефон); (3) **GLM finish `sensitive`/`network_error`**; (4) **GLM СОХРАНЯЕТ cache_control** (COGS-рычаг); (5) **kimi reasoning → ОМИТить temperature**, не force:1 (кандидат сменить нашу capability).
**Дёшево-и-подтверждено к внедрению (после пере-прогона):** fractional/ms Retry-After, quota-429→terminal, HTTP/2 keepalive, CostSource-маркер, xAI reasoning identity-гард, план native-Gemini-судьи.
**Процессная заметка (мандат 12.07):** синтез-агенты Q1/Q3 вернули плейсхолдер-заглушки, схема не поймала — самопроверка исполнением поймала, Q1/Q3 пере-выведены из целого survey-сырья + независимая верификация (8/8 CONFIRMED). Ещё один датапоинт, что «схема-валидно» ≠ «содержательно».