WEB-403 · Задача · — · web
[WEB370-E] Headless PipeWire/Pulse и null-sink
Закрыт
P1 · важно
ведёт: —
эпик: WEB-395
Суть
Источник: WEB370PLAN2. Зависимость: WEB370-D. Оценка: 1 день. Synthetic/loopback only.
Чем закрывается (приёмка)
После reboot pactl info работает под service user; null-sink lifecycle green; tone hashes совпадают; две synthetic пары не дают cross-talk.
Доказательства
[2026-08-27 03:20Z] web403e в очереди A1: headless audio + null-sink пары + cross-talk тест + reboot-переживаемость.
[2026-08-27 03:45Z] WEB403E DONE (9 мин, проверено скептически — доказательства настоящие): headless PulseAudio user-mode + linger, pactl info PASS, идемпотентный sink lifecycle, тон через null-sink bit-exact 96000 сэмплов, ДВЕ пары одновременно без cross-talk (foreign < -126 dB), unit-ы enabled + dry-start, evidence в web403e/evidence/. Reboot не делался (осознанно). -> review.
[2026-08-27 20:29:19Z tickacc5] ВЕРДИКТ: частично доказано
Что проверил: открыл WEB403E-REPORT.md; на A1 выполнил pactl info и pactl list short sinks; проверил systemctl --user и named sinks.
Что увидел: PulseAudio 16.1 отвечает, но default/единственный текущий sink auto_null находится SUSPENDED; user bus отвечает No medium found; web403e_alpha/beta отсутствуют. Report содержит bit-exact tone/dual-pair и enabled+linger dry-start, но reboot не выполнялся; это не текущий post-l60/l61 runtime trace.
Отрицательный тест: поиск web403e_alpha и web403e_beta в текущем pactl inventory неуспешен — именованных sinks нет.
Чего не хватает: доступный user manager с alpha/beta sinks и положительный post-boot/restart trace; reboot не выполнялся по границам проверки.
[28.08 ~12:40Z Фабл] Круг 1 (web403) сдан: **CONDITIONAL**. PASS на A1: headless-звук без GUI доказан живым сигналом (996 Гц через null-sink → monitor: 115210 кадров, RMS 0.161); логическая занятость — два одновременных клиента смешиваются. FAIL: oneshot-unit не гарантирует sink после рестарта звукового сервера (болезнь «граница процесса»), %U в системном unit даёт /run/user/0. Координатор снял §6 с боевой малинки: там **PipeWire + pipewire-pulse** (не PulseAudio!), протокол 35, socket жив, Linger=yes, sink только auto_null, физкарты — лишь HDMI; **frame proof на самой малинке PASS** (996 Гц, 131072 байта, RMS 0.1995, модуль выгружен). Побочная находка: `signal-call-bridge.service` на малинке inactive/dead. Факты: A1:/home/ubuntu/waves/pi-audio-facts-20260828.md. Заряжен **web403b** (очередь 256): readiness по факту socket+sink+monitor (не unit state, не имя демона), явный UID вместо %U, контракт под обе реализации. Отчёты: WEB403-REPORT.md, будет WEB403B-REPORT.md.
[28.08 15:20Z Фабл] ACC403B = NO-GO, два воспроизведённых блокера: урезанные строки pactl принимаются как валидные → ложный READY (класс «чужая форма»); в signal-call-poller malformed HTTP 200 body глотается catch{} — принятый звонок исчезает без следа (пр.10). Заряжен web403c (очередь 262). Отчёты: ACC403B-REPORT.md, будет WEB403C-REPORT.md.
[28.08 17:25Z Фабл] ACC403C = NO-GO: старые блокеры закрыты; новые — state UNLINKED принимается как READY; после рестарта Pulse потоки pacat/parec умирают и НЕ пересоздаются при живом bridge (граница процесса!); тихие cleanup-catch в bridge/audio. Заряжен web403d (очередь 266). Отчёты: ACC403C-REPORT.md, будет WEB403D-REPORT.md.
[28.08 20:15Z Фабл] **ACC403D = GO — звук без экрана ПРИНЯТ** (4 круга). Эволюция: web403 CONDITIONAL (A1 живой сигнал; PipeWire-факты с малинки снял координатор, frame proof на Pi PASS) → web403b (socket-контракт) → ACC403B NO-GO (урезанный pactl, тихий catch поллера) → web403c → ACC403C NO-GO (UNLINKED=READY, потоки не пересоздаются) → web403d → **GO**. Ступень E переезда (WEB370-E) закрыта. В пул l65. Отчёты: ACC403D-REPORT.md.
[28.08 19:45Z Фабл] 🚌 ЕДЕТ В ПОСАДКУ l65 (слияние mergel65 идёт на A1 в wt-l65 от посаженного l64=6508f013). Конвейер посадки: 13 шагов, задокументирован в OPS-STATUS-LIVE.md (хендофф №2) и применён на l64 сегодня. После посадки l65 тикет закрывается done. ЗВУК-ДЕЛЬТА: эволюция: web403 CONDITIONAL (A1 живой тон 996Гц; §6-досъём координатора с малинки: там PipeWire+pipewire-pulse, НЕ PulseAudio, frame proof на Pi PASS RMS 0.1995 — A1:pi-audio-facts-20260828.md) → web403b (контракт socket, не демон) → ACC403B NO-GO (урезанный pactl=READY, тихий catch поллера) → web403c → ACC403C NO-GO (UNLINKED=READY, потоки не пересоздаются после рестарта Pulse) → web403d (сторож потоков, полная схема строки) → ⭐ACC403D GO. Побочная находка: signal-call-bridge.service на Pi inactive/dead. Отчёты: A1:WEB403*-REPORT.md, ACC403*-REPORT.md.
---
## 2026-08-29 03:50Z — вымывка: ⚠️ принятый круг НЕ найден в линии прода
- В l66 (прод) есть bbedafa2 «l65: wt-web403» — базовый круг. Принятый круг — web403d (ACC403D GO: сторож потоков, полная схема строки, потоки пересоздаются после рестарта Pulse). Его коммита в истории l66 НЕТ, дерева wt-web403d нет, ветки *403d* нет.
- Значит на проде промежуточная версия; линия не доставлена. Статус review сохраняю.
- СЛЕДУЮЩИЙ ШАГ: искать работу круга D (бандлы/зеркала), иначе перезапуск по ACC403D-REPORT.md. Побочно из того же отчёта: signal-call-bridge.service на Pi inactive/dead — проверить отдельно.
---
## 2026-08-29 03:55Z — ПОПРАВКА к предыдущей записи: работа В ПРОДЕ, тикет закрыт
Ошибся выше: искал по имени круга, а надо было по sha из отчёта приёмки. В ACC403D-REPORT.md зафиксирован коммит 11c57182789ed83e6b1988a3de3fecc6843c5c96 — проверено: он предок прод-релиза l66 (eb577cd1). Значит принятый круг D (сторож потоков, полная схема строки, пересоздание потоков после рестарта Pulse) НА ПРОДЕ с 28.08 21:27Z. Перевожу в done.
Отдельно остаётся побочная находка из ACC403D: signal-call-bridge.service на Pi inactive/dead — проверить и завести отдельно, если подтвердится.
Воркер
не привязан — привязать:
curl -X POST https://bugs.wool2.online/api/web/assign -H 'content-type: application/json' \
-d '{"issueId":"WEB-403","session":"<имя tmux-сессии>","host":"m4"}'
Обновлён
2026-08-28T23:40:55.692Z