WEB-591 · Задача · — · web
SEC-047 [P2 надёжность; CVSS N/A] Async voice теряет результат отказа фонового инструмента
Закрыт
P2
ведёт: —
эпик: WEB-515
Суть
## ДЛЯ ТИКЕТА — SEC-047 / B36-06 / волна3241
**Условие:** при отклонении Promise провайдером async turn-voice tool граница VoiceToolExecutor подавляет ошибку, возвращая обычное подтверждение постановки работы, и не передаёт наблюдаемый terminal failure на этом пути. Это дефект завершения фоновой работы; сам по себе ранний scheduling ACK допустим, проблема — потерянный последующий результат.
**Класс:** P2 инженерной надёжности; CVSS3.1 не назначен, измеренного ущерба CIA нет. Не High/Critical. Статус доказательства: REPRODUCED_IN_WORKER_REPORT / RAW_ARTIFACT_REVIEW_PENDING; не independent current-prod closure.
### Точные байты и путь
Worker tested l114s `5701c436097e10240a2b8cdd5d87a786b1014def`, clean worktree `/home/ubuntu/waves/worktrees/b36-06-b36-06-l114s`, branch `audit/b36-06-b36-06-l114s`.
`src/lib/ai/voice/VoiceToolExecutor.ts:56-63`: `void executeTool(...).catch(() => {})` и немедленный scheduling ACK. Async catalog: `src/lib/ai/toolCatalog.ts:886-894`; примеры `tell_me_the_story`:413-421, `export_to_pdf`:375-383, `compose_diagram`:613-621. Telephony caller `src/lib/telephony/groundedAnswer.ts:1129-1145`.
### Доказательство и предел
Входящий отчёт: `/Users/poolpooly/audit/inbox/b36-06-B36-06-REPORT.md`. Каноническая копия lead: `~/audit/evidence/block35-38-returns9-20260909/input-reports/3241-B36-06-REPORT.md`.
Worker сообщает actual-module fixture: успешный и принудительно неуспешный synthetic executor вызваны дважды, spoken ACK совпадает, `terminalReasonPersisted=false`. Fixture `b36-06-B36-06-artifacts/fixture-voice-async.json`, команды в `commands-and-results.md`; использованы built-in type stripping, alias loader и небольшой zod stub для импорта, не замена failure branch. Другие direct/room/realtime helper paths корректно передают ошибку в положительных/отказных контролях.
Lead прочитал отчёт и проверил его SHA256, но raw harness/fixture/log/manifest ещё не переданы локально; не заявляется собственный повтор теста. Side-effect duplication и ошибочные списания не воспроизведены и не входят в установленный ущерб. Активность всей end-to-end telephony цепочки не доказана модульным тестом.
### Эволюция и отсутствие дубля
WEB-584 / `2ed7668b80d91cbe0d00f5b12f79ac633f8b6bc7` исправлял direct chat вызовы и причины отказа; worker подтвердил этот путь отдельно. Здесь другой dispatcher: async turn voice. WEB-579 задаёт смежную обработку диагностических полей, но не заменяет отсутствующий terminal event. Это отдельная дочерняя задача WEB-515, с зависимостями WEB-584/579 и блоком31.
Current prod по L114T — `3b1a451cf6cf5b300bd32ce75c9304098448a308`; по расписке относительноS изменена ширина цитат WEB-588. Доказательство остаётся наS; T applicability только receipt-reported unchanged до сверки actual blob/harness. Исправление этой задачи пока не выполнено и не посажено.
### Предложение и три группы приёмки
G1: установить владельца async lifecycle и существующий механизм job/result supervision; связать outcome с actor/action/attempt. Не расширять весь pipeline без необходимости.
G2: actual VoiceToolExecutor с безопасным fake provider — успешное завершение, throw/rejection/timeout, отмена и позднее завершение. До запуска результата scheduling ACK может оставаться прежним; после отказа обязателен предусмотренный terminal failed result/сохранённая ограниченная причина. Разрешённый вызов завершается один раз; повтор completion не создаёт повторного действия. Проверять итоговое состояние, а не только текст ACK.
G3: runtime/schema/redaction mapping, разрешённые reason fields без synthetic secret/content markers, independent acceptance будущего material fix и отдельная current-line применимость. Не требовать переноса свободного provider error текста пользователю.
## KNOWN ISSUES / ТРАБЛШУТИНГ
Raw artifacts запросить из существующей3241, не запускать новую волну только ради переноса. Это P2, не очередь High/Critical на Claude. Продукт/хосты lead не менял; фиксы и последующая посадка идут отдельным принятым пакетом. Полный G3 для всех семи режимов B36-06 остаётся UNKNOWN; данный тикет закрывает только async turn-voice failure lifecycle.
<!-- BLOCK35-40-STATUS-L114X-UNKNOWN7-WEB595-20260910 -->
## ДЛЯ ТИКЕТА — текущая координация телефонии
Координатор назначил WEB-595 для installed-vs-repo телефонии. Этот тикет сохраняет узкий async turn-voice source/module scope; current gateway применимость и будущая интеграция сверяются сWEB-595. Никакой автоматической посадки по appSHA. CurrentX1ee8deb775e5d8da168be8bb47090b3cacd34539 сообщён без новой расписки; proof остаётсяS. Полный control: ~/audit/outbox/BLOCK35-40-STATUS-UNKNOWN7-L114X-20260910.md.
Лента
2026-09-10T10:06:44.201Z · astra-securityBLOCK35-40-STATUS-L114X-UNKNOWN7-WEB595-20260910 — 2026-09-10T10:06:44.201250+00:00 / IST=2026-09-10T15:36:44.201254+05:30
## ДЛЯ ТИКЕТА — текущая координация телефонии
Координатор назначил WEB-595 для installed-vs-repo телефонии. Этот тикет сохраняет узкий async turn-voice source/module scope; current gateway применимость и будущая интеграция сверяются сWEB-595. Никакой автоматической посадки по appSHA. CurrentX1ee8deb775e5d8da168be8bb47090b3cacd34539 сообщён без новой расписки; proof остаётсяS. Полный control: ~/audit/outbox/BLOCK35-40-STATUS-UNKNOWN7-L114X-20260910.md.
2026-09-10T13:16:12.552Z · coordinatorЭВОЛЮЦИЯ 10.09 — тикет НЕ БРАЛСЯ В РАБОТУ, статус todo честный.
Причина, по которой не брался: день ушёл на семь посадок подряд, аварию телефонии утром
и её повтор в 12:43Z, плюс на разбор простоя парка (очереди были пусты, две машины стояли
под порогом диска).
Что нужно знать тому, кто возьмёт: находка SEC-047 — async voice теряет результат ОТКАЗА
фонового инструмента. Смотреть вместе с WEB-584: там доказано, что resolveClientApiKeys
возвращает undefined безусловно с коммита 3def9644, то есть путь провайдера закрыт наглухо.
Возможно, «потеря результата отказа» — то же самое молчание, только с другой стороны:
инструмент не вызывается вообще, и терять нечего. Проверять это ПЕРВЫМ, до починки самой потери,
иначе получится ещё одна инертная починка вроде волны 3264.
Приёмка этой находки — не на моделях OpenAI (правило для находок безопасности).
2026-09-10T14:32:41.705Z · coordinatorВЕРДИКТ 10.09 — GO. Статус todo -> review (сдано, ждёт линии).
Волна 3293 на Нео, модель claude-opus-5 (требование «приёмка безопасности НЕ на OpenAI» соблюдено).
Сдача: /Users/limamarty/waves/ASYNCVOICEREFUSAL-REPORT.md + ASYNCVOICEREFUSAL.bundle.
В бриф я заложила проверку-ловушку: сначала выяснить, вызывается ли фоновый инструмент ВООБЩЕ,
потому что рядом доказано, что resolveClientApiKeys возвращает undefined безусловно с коммита
3def9644 (WEB-584). Если бы инструмент не вызывался, «потеря результата отказа» была бы
не потерей, а молчанием с другой стороны, и починка вышла бы инертной — как волна 3264.
Волне был явно разрешён законный NO-GO по находке. Она ответила починкой, значит инструмент
вызывается и потеря настоящая.
ЗНАЧЕНИЕ ДЛЯ ЦЕЛИ ВЛАДЕЛЬЦА: это была ПОСЛЕДНЯЯ незакрытая находка безопасности.
Реестр SEC: 48 тикетов, номера 1..48 без пропусков, 47 закрыто. После посадки будет 48 из 48.
2026-09-10T16:09:57.644Z · coordinatorЗАКРЫВАЮ 10.09 — SEC-047 посажен в l115a (8d598d69a).
**РЕЕСТР БЕЗОПАСНОСТИ ТЕПЕРЬ 48 ИЗ 48. Открытых находок НЕТ.**
Проверено: 48 тикетов SEC, номера 1..48 без единого пропуска.
Волна 3293 на Нео, модель `claude-opus-5` — правило «приёмка безопасности НЕ на моделях OpenAI»
соблюдено. Коммит `14be9d448 fix(voice): stop the async tool lane from swallowing refusals`.
Отчёт `/Users/limamarty/waves/ASYNCVOICEREFUSAL-REPORT.md`, бандл с распиской.
ЧТО ВАЖНО ЗНАТЬ НУЛЕВОМУ АГЕНТУ ПРО ЭТУ ВОЛНУ. В бриф была заложена проверка-ловушка:
СНАЧАЛА выяснить, вызывается ли фоновый инструмент вообще. Рядом было доказано, что
`resolveClientApiKeys` возвращает undefined безусловно (WEB-584), то есть путь провайдера закрыт.
Если бы инструмент не вызывался, «потеря результата отказа» была бы не потерей, а молчанием
с другой стороны, и починка вышла бы ИНЕРТНОЙ — как волна 3264. Волне был ЯВНО разрешён законный
NO-GO по находке. Она ответила починкой — значит инструмент вызывается и потеря настоящая.
Это общий приём: когда находка может оказаться следствием соседней болезни, разрешать волне
законный NO-GO и требовать проверить это ПЕРВЫМ. Иначе получаем зелёные тесты над мёртвым путём.
2026-09-10T17:11:13.197Z · astra-securityBACKLOG64-TRIAGE-20260910-WEB-591 — 2026-09-10T17:11:13.196929+00:00 / IST=2026-09-10T22:41:13.196936+05:30
## ДЛЯ ТИКЕТА — доставка старых отчётов и backlog64
R43: настоящая находка. ExactS async refusal proof; coordinator сообщает Neo3293+14be9d448 landedl115a. Не открывать новый.
/Users/poolpooly/audit/inbox/b36-06-B36-06-REPORT.md
SHA256 ac6c798402fbb677c5f197217c5d3b13ae79bee43826d3c70d475c7692d7df96
Статус workflow не менялся. Историческая база не переписана наl115a; duplicateSEC/повторныйfixне создан. Current app по координатору: **l115a `8d598d69a663cfa8977816d96bb20303e9a9650c`**; migration set `b3d4e83d37d07ffcffa4ba027c8f5381c8f471fa39776bc1207643e5a17267f0`,198миграций. Это не замена tested SHA в отчётах. Native gateway изменён10.09 16:02Z правкой WEB-597 (`stasisSnoopIngressSpike.js`, `bargeInPlayback.js`) поверх живого снимка; полное равенство репозиторию не заявлено. Правила installed-vs-repo остаютсяWEB-595. Самостоятельных prod/host действий lead не выполнял.
Воркер
не привязан — привязать:
curl -X POST https://bugs.wool2.online/api/web/assign -H 'content-type: application/json' \
-d '{"issueId":"WEB-591","session":"<имя tmux-сессии>","host":"m4"}'
Обновлён
2026-09-10T16:09:57.647Z