WEB board

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

P1 [телефония 8000]: приветствие съедается блокировкой, 1.8 МБ речи звонящего выбрасывается — ответ до владельца не доезжает

Закрыт P1 · важно ведёт: —
Суть
Владелец позвонил на 8000 в 14:06Z 10.09 сразу после посадки l114z, спросил про тетрадь — ассистент не ответил. Разбор показал: дело НЕ в распознавателе тетради (он посажен и доказан в выкаченном коде), а в шлюзе.

Звонок callId=144a4bfb-1eb2-4ae2-9752-4379a72c5687, 14:06:29 - 14:07:08Z, из /tmp/ag-asterisk-logs/gateway.out:

  provider_selected=openai provider_effective=openai fallbackUsed=false
  upstream_session_started
  barge_in detected turnIndex=0 / 1 / 2  (три перебивания подряд)
  call_summary providerAppendCount=553 providerAppendBytes=353920
               dropped_audio_bytes=1833600
               greeting_blocked=[missing_live_bridge,external_channel_not_ready,already_requested]
  final status=caller_hangup stage=caller_audio

Читается так: голос владельца ДО модели дошёл (553 куска, 345 КБ), но приветствие заблокировано тремя причинами сразу, и 1.8 МБ его речи шлюз ВЫБРОСИЛ. Владелец трижды пытался перебить и положил трубку.

ДИНАМИКА. 09.09 было хуже: до провайдера доходило НОЛЬ байт, 434 КБ выбрасывалось (см. историю по barge-in, волна 3195 это частично вылечила — providerAppendCount 0 -> 2704). Сейчас звук доходит, но приветствие всё равно съедается и часть речи теряется.

ПОЧЕМУ ЭТО ОТДЕЛЬНЫЙ ТИКЕТ ОТ WEB-580. Фикс распознавания тетради живёт в приложении (src/lib/ai/conversationContext.ts, посажен в l114z, доказан подсчётом токенов в выкаченном коде). Телефонный путь идёт через шлюз, и до приложения вопрос владельца в исправном виде не доезжает. Пока эта блокировка жива, любой фикс на стороне приложения владелец по телефону НЕ УВИДИТ.
Чем закрывается (приёмка)
1) Объяснить КАЖДУЮ из трёх причин блокировки приветствия: missing_live_bridge, external_channel_not_ready, already_requested — что это, кто их выставляет, file:line на каждую.
2) Объяснить, почему при поднятой сессии провайдера (upstream_session_started, providerAppendCount=553) приветствие всё ещё считается заблокированным.
3) Устранить потерю речи: dropped_audio_bytes должно стать пренебрежимо малым, показать числа до и после на воспроизведённом звонке.
4) Приветствие обязано проигрываться. Негативный тест: повторный запрос приветствия в одном звонке не должен навсегда защёлкивать already_requested.
5) НЕ сломать перебивание (barge-in): оно починено 09.09 волной 3195, показать, что оно живо.
6) Работать ТОЛЬКО от снимка ЖИВОГО шлюза, не от дерева репозитория. 10.09 посадка кандидата, собранного из репозитория, сломала звонки целиком (403 origin_boundary_rejected) и была откачена — правила в WEB-595.
Доказательства
Лог звонка: /tmp/ag-asterisk-logs/gateway.out на A1, callId=144a4bfb-1eb2-4ae2-9752-4379a72c5687.
Предыдущий звонок владельца 12:55Z (callId=ffe3fe0c-2498-40f8-b305-cbe0c907e491): та же тройка greeting_blocked, providerAppendCount=323, dropped_audio_bytes=1310400 — то есть дефект воспроизводится стабильно, а не разово.
Состояние шлюза: живой, после отката 12:45Z, readiness ready, Greeting pre-warmed OK.
Лента
2026-09-10T16:09:57.654Z · coordinator
ПОСАЖЕНО 10.09 16:02Z. Статус in_progress -> review: жду подтверждения владельца на живом звонке.

Волна 3296 (A2), коммит `686aae0e6 fix(telephony): preserve caller audio through greeting`.
Отчёт `/home/ubuntu/waves/GWGREETING-REPORT.md` (41 КБ), девять требований PASS.

ДВЕ ПОПРАВКИ К ИСХОДНОЙ ДИАГНОСТИКЕ — обе мои ошибки, обе важны нулевому агенту:
1) `dropped_audio_bytes=1833600` — это НЕ выброшенная речь звонящего. Счётчик считает НАМЕРЕННО
   ПОДАВЛЕННЫЕ байты ответа АССИСТЕНТА при barge-in, и так и должно быть. Я доложила владельцу
   «1.8 МБ твоей речи выброшено» — это была неправда.
2) `greeting_blocked=[...]` — НАКОПИТЕЛЬ за всю историю звонка, а не текущее состояние.
   Видеть в нём три причины не значит, что они верны одновременно.

НАСТОЯЩИЙ ДЕФЕКТ всё же был: до начала и во время генерации приветствия код очищал входящие кадры,
и отдельного счётчика этой потери НЕ СУЩЕСТВОВАЛО — в телеметрии её не было видно ни одним числом.
Корень расхождения `missing_live_bridge` при живой сессии: `provider_session_started` испускается
внутри `start()` до возврата моста (`openaiRealtimeWsBridge.js:826-835`), а `call.liveBridge`
присваивается уже ПОСЛЕ возврата (`stasisSnoopIngressSpike.js:14135`).

ЧТО СДЕЛАНО: буферизация речи звонящего на время приветствия (новые
`bufferInitialGreetingCallerAudioFrame`, `drainInitialGreetingCallerAudioFrames`, потолок 750 кадров),
освобождение защёлки приветствия на любом исходе (`releaseInitialGreetingRequestClaim`),
и разведение метрик: `dropped_audio_bytes` (звонящий, теперь честный 0) против
`suppressed_assistant_audio_bytes`, плюс `initial_greeting_buffered_audio_bytes` и
`initial_greeting_dropped_audio_bytes`. Перебивание не тронуто: flush/cancel и `SILENCE_BUDGET_MS=300`
сохранены, три последовательных перебивания в бюджете.

🔴 КАК ЭТО САЖАЛОСЬ, и почему НЕ так, как утром (правила — WEB-595):
- кандидат = КОПИЯ ЖИВОГО шлюза + два поправленных файла, НЕ дерево репозитория;
- перед рестартом `diff -rq` против резервной копии: РОВНО два файла, ни одного лишнего,
  ни появившихся, ни исчезнувших. Утром там было 19 — и звонок лёг;
- `node --check` на обоих файлах;
- ПОСЛЕ рестарта и ДО того, как звать владельца: в `/tmp/ag-asterisk-logs/gateway.out` должна
  появиться строка `[gateway] Greeting pre-warmed ✓`. Появилась. Утром на её месте был
  `403 origin_boundary_rejected`, и я этого не посмотрела.
Резервная копия: `/home/pi/ag-voice/infra/sip/backups/gateway-lane8000-pre-20260910T160217Z.tar.gz`.
Откат: `land-lane8000.sh /home/ubuntu/sip-cand-web597 rollback`.

⚠️ ПРО ПРЕДПОЛЁТ САМОДОСТАТОЧНОСТИ: на этом кандидате он даёт FAIL, и это ОЖИДАЕМО.
Все его претензии — к самому живому шлюзу, а не к правке: файлы `.orig` и `.bak`, тест с vitest,
и `laneClaim.js:14 -> ../../../config/telephony-security-policy.json`, который лежит ВНЕ дерева
шлюза (`/home/pi/ag-voice/config/`) и в живом расположении прекрасно разрешается.
Инструмент писался для ВЕНДОРЕННЫХ кандидатов. Для живого кандидата решающие проверки другие:
дифф в два файла, `node --check` и `Greeting pre-warmed ✓`.

Состояние после посадки: служба active, readiness ready, охрана configured, snoop ready,
порты 4574/8088/4084 слушают, диалплан 8000 ведёт в Stasis + AGI, в живом файле 9 упоминаний
новых счётчиков. `ag-sip-native-opus-experimental` = failed, но он лежит с 05.09 20:25Z и к этой
посадке отношения не имеет (лэйн native-only).
2026-09-10T16:23:05.845Z · coordinator
ЗАКРЫВАЮ 10.09 — ВЛАДЕЛЕЦ ПОДТВЕРДИЛ НА ЖИВОМ ЗВОНКЕ.
Позвонил на 8000, спросил про тетрадь — ассистент НАЗВАЛ ТЕТРАДЬ.
Это то самое, чего не происходило в 14:06Z, когда приветствие блокировалось, а речь в начале
звонка терялась. Правка волны 3296 работает на боевом.
Воркер
не привязан — привязать: curl -X POST https://bugs.wool2.online/api/web/assign -H 'content-type: application/json' \ -d '{"issueId":"WEB-597","session":"<имя tmux-сессии>","host":"m4"}'
Обновлён
2026-09-10T16:23:05.852Z