WEB board

всеканоны и докиворкеры↗ iOS↗ Легаси
WEB-340 · Дефект · — · web

P0: извлечение сущностей (doc_ner) отказывается billing-гардом — request_identity_missing → сущности не пишутся, вкладка греется вечно (даже с включённым NER)

Закрыт P0 · горит ведёт: fable-coordinator
Суть
P0: извлечение сущностей (doc_ner) отказывается billing-гардом — request_identity_missing → сущности не пишутся, вкладка греется вечно (даже с включённым NER)

## 2026-08-23 17:01 UTC — КОРЕНЬ по логам прода (v4-081ff4fb5, NER уже ON)
Owner импортировал статью (Untitled Document, id 1787503668382, 6361 chars, создан 16:47:50Z ПОСЛЕ включения NER). metadata.entities пусто, updatedAt==createdAt — базовое извлечение не отработало. Логи note-clone-3010:
- `[billing][request_identity_missing] channel:doc_ner note:'no request-scoped identity: wrap the entry point in runWithBillingRequestContext()'` → `[billing][billing_guard_request_identity]` → `[GRAPH-0341] entity persistence FAILED: 'This request could not be given a stable identity, so it was refused to protect against duplicate charges.'` (повторяется 17:44/17:46/17:53...).
- Модель РЕАЛЬНО извлекла: `[GRAPH-1091] entity-verify kept=3 dropped=1 sourceId=- windows=1` — но sourceId пуст и биллинг-гард отказал → не сохранилось.
КОРЕНЬ: doc_ner-путь (базовое извлечение processDocumentRuntime.ts + фоновый runDeepenAnalysisJob в deepenAnalysisJob.ts) вызывает vendor вне runWithBillingRequestContext → guard рубит каждый вызов (класс WEB-053/WEB-334 request_identity, теперь на каналах doc_ner). Это ПОЧЕМУ включение NER не помогло: extraction структурно отказан.
МОДЕЛЬ (вторично, не блок): gpt-5.4-nano разрешена в манифесте (openai:gpt-5.4-nano:chat.completions), но провайдер вернул датированный gpt-5.4-nano-2026-03-17, которого нет в DOC_NER_MODEL_PRICING → `[billing][settling_at_max] usage_untrusted: unpriced model` (перебор до max, безопасно, но жжёт кап $2/мес). Также `Error generating title: This model is not enabled in the current release` — отдельная модель title-gen, не блок тегов.
AUTO_TAG (owner «Не вдалося згенерувати теги»): в 17:52 был транзиент `accounting_unhealthy 503` (учёт сейчас здоров ok:True) + 409 duplicate от ретраев. Основная причина тегов на ЭТОМ доке — тот же doc_ner identity? нет, auto_tag отдельный канал; но проверить обёртку auto_tag тоже.

## ЧТО НАДО
1. Обернуть doc_ner vendor-путь в runWithBillingRequestContext со СТАБИЛЬНОЙ идемпотентной идентичностью: базовое извлечение (processDocumentRuntime→maybePersistDocumentEntities) и фоновый runDeepenAnalysisJob (deepenAnalysisJob.ts — fire-and-forget из route). Ключ идемпотентности из (sourceId, contentHash/fingerprint, userId, operation=doc_ner[/deepen]) — deepen уже строит callId doc_ner_deepen:sourceId:jobId, использовать как основу. Гард обязан ПРИНЯТЬ вызов.
2. Проверить/обернуть auto_tag фоновый путь тем же способом (autoTagService) — чтобы теги на импортированных доках не падали.
3. Модель-прайс: добавить датированный алиас gpt-5.4-nano-2026-03-17 в DOC_NER_MODEL_PRICING (config.ts) ИЛИ нормализовать датированный→базовый в resolveDocNerPricing/resolveDocNerModel, чтобы usage был trusted (не settle_at_max). Проверить не задевает другие каналы.
ТЕСТЫ (негативные обязательны): (a) doc_ner base extraction в тесте с request-context → guard принимает, entity persist ok; без context → прежний отказ (докажи, что обёртка реально нужна); (b) deepen job идемпотентен (повтор не двойной charge); (c) datated model → trusted pricing (не settle_at_max); (d) auto_tag фон с context → ok. Проверки: фокус-сюиты billing-request-context + doc_ner + autoTag + pricing; scoped tsc rc=0. Не трогать флаг NER, не менять SKU/цены существующих моделей кроме добавления алиаса. Груз следующей посадки.
ВЫХОД: git diff <base>..HEAD > /home/ubuntu/waves/web340-fix.patch; /home/ubuntu/waves/WEB340-FIX-REPORT.md (лог-цитаты до/после, карта обёрток, негативные тесты); маркер WEB340_FIX_READY.
Воркер
не привязан — привязать: curl -X POST https://bugs.wool2.online/api/web/assign -H 'content-type: application/json' \ -d '{"issueId":"WEB-340","session":"<имя tmux-сессии>","host":"m4"}'
Обновлён
2026-08-23T21:38:17.546Z