Files
utun2/doc/tasks.md
T

505 lines
64 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Задачи по проекту
Сюда пишется список задач с короткой аннотацией. Если задача большая и имеет ТЗ - то ТЗ оформляется отдельным файлом, а сюда помещается аннотация и ссылка на ТЗ.
## Текущие задачи
[+] **Android: приём рации через SCO после отпускания PTT** — исправлено 22.10.2026:
Общий MediaAudioController сохраняет разговорный тракт для SCO-only выхода, даже без подписчиков микрофона.
AudioTrack рации снова использует USAGE_VOICE_COMMUNICATION: Android учитывает playback как разговорную активность.
Добавлены логи фактического routedDevice/mode/SCO и аппаратная проверка после закрытия последнего input.
Samsung + C1 PRO: PHONE → Bluetooth → PHONE, 35с приёма без микрофона и холодный запуск SCO без PTT прошли.
На Q8 прошли общий захват/переключения/сохранение playback. JVM 145/145, сборки ядра и APK успешны.
[ ] **Android: просмотр трансляции через SCO без работающей рации** — воспроизведено 22.10.2026:
Media-выход с USAGE_MEDIA после закрытия микрофона теряет SCO: mode=0, sco=false,
хотя общий контроллер продолжает владеть выходом и сам больше не закрывает разговорный тракт.
AudioService учитывает VOICE_COMMUNICATION playback/record для активности MODE_IN_COMMUNICATION.
Повтор: adb -s RZ8R72MG64B shell am instrument -w -e output media com.utun.chat/com.utun.chat.data.MediaAudioProbe.
Радио с USAGE_VOICE_COMMUNICATION проходит ту же проверку, media-вариант её не проходит.
Сохранить media-назначение/громкость обычных выходов; для SCO переключать аппаратный AudioTrack на VOICE_COMMUNICATION.
При пересоздании только аудиовыхода сохранить недописанный PCM, учесть уже записанный буфер и непрерывный played;
видео и его кодеки не перезапускать. Проверить оба направления смены выхода и длительный playback без микрофона.
[+] **media_async: файловые примитивы и точные контракты .h** — исправлено 22.10.2026:
ma_copy_file проверяет существование/идентичность, сохраняет один regular-файл при ./ или hardlink;
ссылки назначения отклоняются, копирование идёт через соседний temp с проверенными записью/close/publish.
Общие примитивы lib/file_io используются также video, сохраняя публикацию видео только в completion.
ma_uuid возвращает ошибку RNG и обнуляет выход; media_index не регистрирует блоки при отказе media/block UUID.
ma_file_size и переменные вызывающего кода — int64_t; проверяются смещения, число блоков и размеры выделений.
Обход передаёт ошибки, пропускает ссылки/reparse points, проверяет длину/глубину; Windows использует wide API.
Контракты .h и service_lifecycle описывают синхронные отказы, лимит 16 до completion и отсутствие отката work при отмене.
Неверные аргументы дают -1, closing/destroy — CANCELLED; повторный вход в destroy диагностируется и отклоняется.
Новый test_media_primitives проверяет сохранность при I/O/fdopen ошибках, RNG/seek без записей блоков в БД,
sparse-размеры на границах 2/4 ГиБ, ошибки обхода, ссылки/глубину и ownership задач с внедрением ошибок.
Все шесть тестов media_primitives/video/media_index/attachment_send/services/dm_worker прошли ASAN/UBSan с detect_leaks=1.
Общий check.sh: 176/176 и proxy/burst/load. Windows runtime/сборка не проверялись: кросс-компилятора в окружении нет.
Логи: /tmp/media-primitives-full-check-final.log, /tmp/media-primitives-final.log, /tmp/media-asan-test_*.log.
[+] **media_index: пути без обрезания и единая media_base** — исправлено 22.10.2026:
Общие location/path проверяют границу базы, компоненты и пределы UTF-8 путей (1024/512 с NUL).
Путь в 550 байт полностью сохраняется, читается и удаляется. Проверки предшествуют файловой подготовке.
Выдача использует UTF-8 file_io; загрузчик проверяет общую базу, stop/start сохраняет выбранную базу БД.
Писатели, backfill, выдача и удаление используют один формат; контракты находятся в media_index.h.
[+] **media_index_commit: атомарная регистрация и проверяемые повторы** — исправлено 22.10.2026:
Единый commit регистрирует весь авторский/скачанный файл через SAVEPOINT; key=NULL означает скачанный файл.
Проверяются геометрия/массивы, bind/step/finalize и управление транзакцией.
Ошибка второго блока откатывает оба пути регистрации; обычная ошибка сохраняет внешнюю транзакцию.
SQLite может сама откатить её целиком — это обнаруживается и диагностируется.
Совпадающий повтор сохраняет node_sign и timestamp; противоречащие метаданные дают ошибку без замены старых.
Файловые изменения worker не входят в SQL-атомарность.
[+] **Удаление канала: дождаться исходящих медиа и учесть незавершённые файлы** — исправлено 22.10.2026:
Канал ждёт свои video/register completions; новые исходящие задачи отклоняются до завершения удаления.
Последний completion продолжает удаление. Подготовленные ожидающие отправки не становятся новыми сообщениями.
Контекст остаётся у владельца во время синхронного MSG_SUBMITTED; повторный вход обработчика проверен.
До worker путь учитывается в media_preparations; успешный commit снимает запись в той же транзакции.
После ошибки хеширования/отмены опубликованная копия остаётся известна для очистки канала.
Проверены две ожидающие задачи, повтор удаления, создание того же channel_id и удаление из обработчика события.
[+] **media_index_delete_channel: ошибки и повторяемая частичная очистка** — исправлено 22.10.2026:
Полный снимок и проверка путей предшествуют удалению; внешняя транзакция отклоняется.
Общие файлы других каналов сохраняются; ENOENT считается успехом.
SQL/файловые ошибки возвращают -1, записи неочищенных путей сохраняются для повтора.
Проверен отказ DELETE после unlink: повтор завершает очистку без восстановления файла.
Очистка включает media_preparations; ошибки очистки и удаление метаданных канала сообщаются раздельно.
[+] **media_index_init: ошибки всех индексов доходят до запуска чата** — исправлено 22.10.2026:
Проверяется каждый CREATE INDEX. Ошибка прерывает chat_core_init с освобождением собственных ресурсов;
общая БД ядра сохраняется. Проверены запрет каждого индекса и успешный повтор старта после снятия запрета.
Дополнительно исправлены дубликат start (отказ без callback) и доступ к dl после синхронного завершения QUERY.
Тесты используют реальную схему БД и проверяют новый контракт владения.
Итог: check.sh — 177/177, proxy/burst/load PASS, 159с.
Девять тестов index_regressions/index/delivery_download/download_timeout/services/delivery_full/delivery_chat/attachment_send/video
прошли ASAN/UBSan с detect_leaks=1. Windows runtime/сборка не проверялись: кросс-компилятора нет.
Логи: /tmp/media-index-full-check-final.log, /tmp/media-index-final-test_media_index_regressions.log,
/tmp/media-index-asan-test_*.log. Новый тест: tests/test_media_index_regressions.c.
[+] **media_delivery QUERY/QUERY_RESP: проверять длины до чтения записей** — исправлено 22.10.2026:
Проверяются точный размер, счётчики и все записи до SQL/изменений состояния. Ответ связан с media_id,
UUID попытки, группой и end-to-end отправителем router; дубликаты, истёкшие и старые ответы игнорируются.
test_media_query защищает точную границу payload под ASAN и проверяет все усечения, чужие ответы,
повреждение последней записи без изменения первой, отмену и повторный start того же media_id.
[+] **media_delivery QUERY: устранить потерю блоков и держателей из-за разных лимитов** — исправлено 22.10.2026:
Одна пачка до 32 block_id — один полный ответ, до четырёх кандидатов на каждый блок (максимум 1604 байта).
Нулевой результат и ошибка БД различаются. Неполная пачка не принимается; держатели других пачек и текущие CM сохраняются.
QUERY имеет отдельный дедлайн и курсор источников каждого блока; чанки не продлевают поиск остальных блоков.
Источники своей CHAT-группы, автор последний; HAVE_BLOCK не зависит от курсора поиска.
Peer-слоты переиспользуются после освобождения; SLOT/SEARCH/RETRY различаются, OVERLOADED соблюдает retry_after.
Отменяется поздний CM UP, события обрабатываются после open. Устранено двойное освобождение при отказе router.
Проверены 65 блоков/260 записей, старт 4100 блоков, сборка с 13 держателями при 10 слотах,
настоящий watchdog при входящих чанках, SQL-ошибка второго блока, RNG/send failures и отсутствие повторного done_cb.
Сетевой integration проверяет содержимое QUERY_RESP вместо безусловного smoke PASS.
Восемь тестов query/delivery_download/download_timeout/delivery_sql/delivery_integration/delivery_chat/delivery_full/services
прошли ASAN/UBSan с detect_leaks=1. Итоговый check.sh: 178/178, proxy/burst/load PASS, 172с.
Логи: /tmp/media-query-regressions.log, /tmp/media-query-full-check-final.log, /tmp/media-query-asan-final-test_*.log.
Windows runtime/сборка не проверялись: кросс-компилятора нет. Контракты — в соответствующих .h.
[+] **media_delivery QUERY_RESP: устранить неверное поле chunk** — исправлено 22.10.2026:
Неиспользуемые chunk/rtt удалены из нового формата QUERY_RESP. Блок однозначно задаётся block_id,
а его номер загрузчик берёт из сохранённых метаданных; позиция в выборочной пачке не считается номером блока.
[+] **media_delivery CHUNK: прогресс только после проверенного приёма и записи** — исправлено 22.10.2026:
Реальные router callbacks/SQLite, корректные подпись блока и ключ автора. CHUNK с data_len=1 без payload
оставляет файл пустым, но устанавливает bytes_received=1, RECV и обновляет last_progress_tb.
То же при внедрённом fwrite=0/ENOSPC. Текущий unit-тест допускает 456 байт при expected_size=100.
Проверять полный payload, геометрию/непрерывность, текущего держателя и попытку до файловых операций;
не считать дубли и неудачную запись прогрессом. Нужна привязка пакетов к отдельной попытке передачи блока.
Стенд /tmp/media-block-audit.c; логи /tmp/media-block-audit-truncated.log, /tmp/media-block-audit-write.log.
Реализованы строгие размеры/непрерывность, tuple группы/держателя/блока/UUID и отдельный temp каждой попытки.
Прогресс публикуется после проверенного close. Регрессии: tests/test_media_blocks.c, включая реальные I/O-сбои.
[+] **media_delivery DONE: проверка ключа и конечный результат ошибки хеша** — исправлено 22.10.2026:
Для настоящей Ed25519 пары с pubkey[0]=0 корректно подписанный блок отвергается: наличие ключа определяется
первым байтом. При отсутствии ключа проверка заменяется сравнением wire block_sig с метаданными.
Отдельно: при верной подписи блока и несовпадающем хеше файла state=DONE, validated=0/1, active=1;
три проверки watchdog возвращают 0, done не вызывается. Итоговая ошибка должна завершать загрузку,
а публикация назначения и регистрация допустимы только после проверенных чтения/записи/close/SHA256.
Обязателен ключ ровно 32 байта; проверяется подпись метаданных по фактическим байтам и ожидаемый размер.
Сборка идёт в собственный temp, SHA-256 проверяется всегда, затем publish и регистрация SQLite.
Ошибка до publish сохраняет старое назначение; ошибка SQLite сохраняет подготовленный опубликованный файл.
Регрессии с настоящим pubkey[0]=00, неверной подписью/хешем, сбоями I/O/rename/SQLite: tests/test_media_blocks.c.
[+] **media_delivery progress_cb: отмена освобождает dl внутри обработчика DONE** — исправлено 22.10.2026:
progress_cb вызывает media_download_cancel, md_dl_finish освобождает dl; media_download_handle_done затем
вызывает md_dl_send_have_block с освобождённым указателем. ASAN heap-use-after-free, чтение 8 байт.
Обработчик явно удерживает контекст. Terminal снимает загрузку с индекса и отменяет её timers/CM/waiters;
освобождение и done выполняются после выхода последнего удерживающего обработчика, ровно один раз.
После progress проверяется terminal: отменённая загрузка не продолжает финализацию. Один перенос callback
в конец функции/отложенный финализатор не заменяет владение. Relay-получатели отдельно удерживают файл блока.
Проверить также отмену с повторным start того же media_id, отмену на последнем progress и поздние пакеты.
Лог /tmp/media-block-audit-cancel-asan.log; стенд вне репозитория /tmp/media-block-audit.c.
Реализовано явное удержание контекста обработчиком; отдельные ссылки producer/выдач удерживают файл блока.
Единый TX pump готовых/растущих источников соблюдает backpressure для DATA и DONE; remote CANCEL привязан к UUID.
Проверены отмена/повторный start из последнего progress и старые relay-читатели при успехе/отмене новой загрузки.
Полный ./check.sh: 179/179, proxy/burst/load PASS (/tmp/media-block-full-check-final.log).
Десять целевых наборов ASAN+UBSan с detect_leaks=1: PASS (/tmp/media-block-asan-test_*.log).
Windows runtime/сборка не проверялись. Синхронные проверка и сборка блоков остаются в uasync.
[ ] **media_delivery: исправить репликацию суперузлов** — воспроизведено 22.10.2026 через реальные router callbacks/SQLite:
SUPER_REPL с num_entries=1 и одним заголовком: ASAN use-after-poison при чтении id в media_delivery.c:622.
ACK от известного пира в другой router-группе без ожидающей пачки: inflight 0→255, tx_cursor=77, запускается timer.
HELLO двух пустых узлов: после 20 доставок остаётся следующий HELLO, обмен сам не завершается.
Для 9 записей sender ставит 4 одинаковые пачки первых 4 записей. По таймауту 20000→40000 при inflight=4
отправляет 0 повторов, хотя timer снова вооружён. На потерю ACK эта схема не восстанавливается.
При id=4294967297 первая запись остаётся 64-битной, но seq максимума пачки усечён до 4.
Ошибка INSERT второй строки оставляет первую применённой, сохраняет RX cursor=2 и отправляет ACK=2: теряются данные.
Группа из тела HELLO переопределяет router-группу (111→333); ответ включает записи групп 111 и 222.
Старая пачка уменьшает сохранённый RX cursor 2→1. После supernode stop/start чужие записи удалены,
но cursor=2 сохранён и рекламируется в HELLO. Принятая запись не будит выдачу третьему готовому супер-пиру.
Уточнение прежней записи: смешения направлений курсоров в БД нет — md_ss_set вызывается только при приёме REPL;
ACK обновляет peer_last_recv_id в памяти. Исправлять нужно подтверждение ожидающей пачки и жизненный цикл курсоров.
Стенд вне репозитория /tmp/media-super-audit.c; обычные логи /tmp/media-super-audit-{ack,hello,pages,timeout,wide,sql,group,purge,replay,forward}.log.
ASAN: /tmp/media-super-audit-truncated-asan.log, exit=1 ожидаем из-за подтверждённой ошибки, не успешный regression.
Направление исправления: peer/state по (group,node), группа только из router, проверка ролей обоих участников;
bounded HELLO request/response с корреляцией и поколениями, 64-битные ID, одна неизменяемая ожидающая пачка с UUID;
ACK только этой пачки, retry тех же байтов с backpressure; весь RX packet + cursor в одном savepoint после полной проверки.
При удалении принятых данных инвалидировать соответствующие RX cursors, после commit будить остальных пиров своей группы.
Регрессии: потеря/дубли/перестановка/старые сеансы, id>2^32, SQL rollback, две группы/один пир, role stop/start,
восстановление БД источника и сходимость трёх узлов без HELLO-эха. Исправление кода ещё не выполнялось.
[+] **test_stream_service: убрать зависимость bootstrap-проверки от гонки TCP-handshake** — исправлено 22.10.2026:
Падение на строке 409: REINIT=0 при probes=1/subflows=1/failures=0 и доставленной первой пачке.
Встречный TCP-линк успевает сообщить peer_reset_id до ETCP CONFIRM: начальная эпоха уже известна,
поэтому etcp_session_receive не вызывает REINIT. При другом порядке событий REINIT=1 и тест проходит.
Холодная подписка проверяет одну пробу/выдачу и доставку без ошибок, число начальных REINIT диагностическое.
Отдельная автоматическая подписка удерживает INFO_RESP, выполняет настоящий REINIT и продолжает ту же пробу.
Проверяются новые epoch/nonce, отсутствие лишних проб/CLOSED и пустой локальный буфер перед получением DATA.
Ручные проверки старых ответов и исходного deadline сохранены; ожидания привязаны к поколениям и событиям.
Добавлен --bootstrap-only: 8 повторов с ускоренными и 2 с обычными часами прошли.
Полный test_stream_service прошёл ASAN/UBSan с detect_leaks=1; check.sh — 175/175 и proxy/burst/load.
Изолированная потеря pending-пробы вызвала ожидаемый отказ новой автоматической проверки; мутация убрана.
Логи: /tmp/stream-service-original-failure.log, /tmp/stream-bootstrap-repeat-*.log,
/tmp/stream-service-asan-final.log, /tmp/stream-bootstrap-mutant.log, /tmp/stream-bootstrap-full-check-final.log.
[+] **video: сохранность файлов, JPEG и подготовка MP4** — исправлено 22.10.2026:
Одинаковые файлы/алиасы и недопустимые пути отклоняются без изменения исходника.
JPEG и MP4 пишутся в эксклюзивный временный файл; запись, drain, trailer и close проверяются.
Только успешный completion публикует результат; отмена до callback сохраняет старое назначение.
Превью получает задержанные B-кадры. MOV/H.264/AAC проходит remux в MP4; остальные профили
перекодируются с audio FIFO, сохранением временного смещения и хвоста ресемплера.
Атомарный global slot удерживается до completion, ошибки имеют точную фазу и контекст в логе.
Контракты описаны в src/video/video.h и doc/service_lifecycle.md.
test_video проверяет реальные кадры/сигнал, 1080p→720p, PCM/MP3/AAC, resample 12345→12000 Гц,
файловые ошибки, отмену, повтор из callback и конкурентные start; test_video_no_ffmpeg — стабы.
Оба теста, test_services и test_attachment_send прошли ASAN/UBSan с detect_leaks=1.
Отдельная конфигурация всего ядра/тестов без FFmpeg собрана, оба video-теста прошли.
Логи: /tmp/video-asan-final.log, /tmp/video-services-asan.log, /tmp/video-attachment-send-asan.log,
/tmp/video-without-ffmpeg-build-final.log; общий прогон: /tmp/video-full-check-final.log.
[+] **tcp_io: владение connect-таймером и повторный FIN** — 21.10.2026:
Замена таймаута сохраняет старый таймер при ошибке создания нового; <=0 отменяет таймер.
Возвращаемые ошибки и диапазон INT_MAX/10 проверяются API и TCP-прокси; connect/error/destroy отменяют таймер.
FIN различает fin_pending и fin_local, ошибка shutdown идёт в on_error без ложного on_fin_sent.
Уточнены отложенное освобождение, синхронные callbacks очередей и платформенный выбор IPv6/маршрута.
Проверено: 15 сценариев test_tcp_io, test_tcp_io_flush, test_proxy_regressions и test_socks_http_proxy
(16 загрузок с побайтной сверкой). test_tcp_io и flush также прошли ASAN с detect_leaks=1 без ошибок.
Логи: /tmp/tcp-io-fix-unit.log, /tmp/tcp-io-fix-asan-unit.log, /tmp/tcp-io-fix-asan-flush.log,
/tmp/tcp-io-fix-proxy-regressions.log, /tmp/tcp-io-fix-socks-http.log.
[ ] **Desktop publisher: проверить восстановление после недопустимого FPS в Xvfb-тесте** — 20.10.2026:
Широкий screenAndWindowCapture прошёл закрытие управления с active=1 и продолжением публикации,
затем не получил видео revision>=3 после запроса fps=61 и возврата engine.config().video.fps к 15.
Перед этим применены VP9/rotation=90; worker продолжает кодировать generation=4.
Причина и связь с UI-изменениями не установлены; отдельная проверка закрытия управления PASS.
Лог /tmp/desktop-stream-controls-xvfb.log, тест tools/chatgui/tests/test_stream_publish.cpp.
[ ] **Проверить одновременную собственную и удалённую трансляции в multiview** — 20.10.2026:
Собственный preview и удалённые readers по отдельности проверены; их совместный живой сценарий в одном канале не проверялся.
На desktop/Android проверить переход в управление своей публикацией и возврат, fullscreen/Back/Esc,
сохранение удалённых readers и общего звука, отсутствие местного звука и остановку собственной публикации.
[ ] **Multiview desktop: terminal CLOSED оставляет аудиовход и timer** — проверка 20.10.2026:
fail(reason, false) ставит complete=true/failed=false, но tick снимает audio только по ended/failed.
После STREAM_CLOSE_GROUP воспроизведено complete=1, failed=0, attached=1, timer=1.
При valid=0 каталог сохраняет плитки, поэтому состояние живёт до ручного закрытия окна.
Отделить завершение от разрешения retry и освобождать output при любом terminal CLOSED.
Временный regression-проверочный стенд и лог: /tmp/multiview-review/test_stream_view.cpp,
/tmp/multiview-review/lifecycle.log. Исходники реализации при проверке не менялись.
[ ] **Проверить ожидание запросов ключей в test_encrypted_attachment** — 21.10.2026:
До rebase исправлений control_server: check.sh вне sandbox 165/166; отдельный повтор также
phase=5/heartbeats=12001, ожидание двух pending incoming-запросов после перезапуска автора.
Логи: /tmp/control-server-full-check.log, /tmp/control-server-attachment-recheck.log;
артефакты общего прогона: /tmp/utun_encrypted_attachment_6JMO0c. Код вложений в этой работе не менялся.
[ ] **Разобрать нестабильную загрузку storage-узлов в test_media_delivery_chat** — 19.10.2026:
В том же общем прогоне storage st1/st2 не собрали файл, n2 исчерпал попытки блока 0 (15/19 внутренних проверок).
Отдельный повтор прошёл 19/19. Причина не установлена; сравнить маршруты и готовность storage под общей нагрузкой.
Логи: tests/logs/test_media_delivery_chat.log, /tmp/phone-busy-media-recheck.log.
Повторилось 21.10 при аудите ID сервисов: 164/165, те же 15/19 внутренних проверок.
Отдельный запуск и 16 параллельных повторов прошли. Причина остаётся открытой;
тест теперь сохраняет подробный media/router лог и БД при отказе в /tmp/utun_mdc_*/.
Логи /tmp/service-ids-full-check.log, /tmp/service-ids-media-chat-debug.log, /tmp/service-ids-media-chat-stress/.
[ ] **Разобрать нестабильное ожидание ACK в test_local_transport** — 19.10.2026:
Общий check.sh: 161/162, chat_adapter упал на строке 173 при ожидании LOCAL_DELIVERY_FORBIDDEN для request=508.
В логе получатель дважды отклонил приглашение и отправил ACK; отправитель до проверки получил только late ACK request=507.
Отдельный повтор прошёл. Причина не установлена; проверить доставку UDP и шаги ускоренных часов под параллельной нагрузкой.
Логи: /tmp/config-name-local-transport-failure.log, /tmp/config-name-local-transport-retry.log.
Ещё один общий прогон 19.10: 161/162, chat_adapter упал на строке 145 при ожидании доставки request=501.
Получатель принял приглашение и дважды отправил ACK; до проверки в логе отправителя нет приёма этого ACK. Отдельный повтор прошёл.
Логи: /tmp/utun-stream-preview-local-transport-failure.log, /tmp/utun-stream-preview-local-transport-retry.log.
[ ] **Разобрать нестабильную проверку аудиопауз desktop-трансляции** — 17–20.10.2026:
test_stream_view::realH264RenderingAndClose нестабильно получает silenceGaps=3–4 вместо 2.
Зафиксированы pcm_short с got=96/480 и 288/480; видео продолжало выводиться.
Сбой повторялся с общей нагрузкой и после её завершения; изолированные повторы проходили.
Проверить актуальные PCM workers/часы под нагрузкой; единичный PASS не подтверждает устранение.
Логи: /tmp/stream-zoom-full-view-audio-gap.log, /tmp/stream-zoom-full-view.log,
/tmp/multiview-review/desktop-review.log, /tmp/multiview-review/audio-original.log.
[ ] **Устранить коллизию порта при перезапуске узла в test_dm_e2e** — 16.10.2026:
Общий check.sh при проверке Windows-курсора: 155/156, test_dm_e2e упал в phase=9 на создании B2.
Повторный bind 127.0.0.1:33843 вернул Address already in use; отдельный повтор теста проходит.
Проверить владение/резервирование порта между остановкой B и созданием B2 при параллельном прогоне.
Логи: /tmp/win-stream-cursor-dm-e2e-failure.log, /tmp/win-stream-cursor-dm-e2e-retry.log.
[ ] **Проверить Windows-трансляцию на исходной машине после исправлений playback/stop** — 16.10.2026:
Цикл ожидания позднего аудио исправлен; join и закрытие микрофона выполняются асинхронно,
QVideoFrame::toImage() вынесен в долгоживущий image worker. Linux/Xvfb-регрессии проходят.
Осталась свежая трансляция Windows → Samsung и stop после пересборки Windows: исходный Qt backend ещё не проверен.
На RYS HFR USB2.0 Camera проверить сообщение об отсутствии PCM, отзывчивость при завершении WASAPI,
отказ/согласие на CPU после отказа NVENC. Причина frames=0 микрофона пока не установлена;
подробный AudioDiag реализован только для Linux. libx265 3440×1440 на исходном CPU выдаёт около 2–3fps.
Логи: 4.log, /tmp/stream-viewer-new-run.log, /tmp/late-audio-test.log,
/tmp/stream-persistent-image-xvfb.log, /tmp/stream-audio-stop-full-check.log.
[ ] **Проверить появление значка свежей трансляции на SM после сна через colo2** — 16.10.2026:
Пробуждение и перезапуск SM во время сна уже проверены на обновлённом colo2:
новый линк снимает прежний таймер, Merkle завершается без ожидания полного сна 120с.
Осталась визуальная проверка значка новой desktop-трансляции после возврата SM в foreground;
в прежнем прогоне активных источников не было (count=0).
Логи: /tmp/stream-wake-live-{sm,colo2}-*.log.
[ ] **Проверить остаточные паузы видеозвонка на актуальном playout** — 15.10.2026:
После исправления TX flush живой звонок 12694689407894286842 дал SM 29.87fps без drops,
desktop 29.91fps/3 late drops за последние 20с; отдельные промежутки SM доходили до 63.8мс.
В старой трассе краткие invalid audio clock сбрасывали якорь, точная причина invalid не была видна.
После переработки playout/ACK и чтения аудиочасов 19–20.10 повторить оба направления на устройствах,
сопоставить gap_pts_us/gap_rx_us/gap_dispatch_us и причины недоступности часов, если паузы сохраняются.
Текущий контракт и результаты поздних проверок: doc/call_video.txt.
[ ] **Доступность разговорного динамика в UI звонка** — при подключённой проводной гарнитуре Samsung убирает
EARPIECE из Telecom endpoints, но кнопка остаётся доступной по наличию физического встроенного устройства.
Нажатие создаёт отложенный запрос, который исполняется после отключения гарнитуры. Согласовать UI с доступными endpoints.
Также выбор проводной гарнитуры в CallScreen сейчас запрашивает BLUETOOTH_CONNECT при отсутствии этого разрешения;
проверку разрешения нужно привязать к выбранному типу гарнитуры.
[ ] **Ручная приёмка видеозвонков Android и ChatGUI после последних исправлений** — 14–20.10.2026:
Сигналинг, CAPS, реальные codecs/камера/render и A/V подключены; живые звонки уже проводились.
Осталась полная проверка после изменений Full HD/50–60fps, HEVC High tier, Surface ACK и фоновых codec probes:
Windows ↔ Samsung/Q8, камеры и оба направления, первый и повторный звонок, смена камеры/разрешения/кодека/битрейта,
A/V, завершение и освобождение Surface/видеопорта. Аппаратные probes не заменяют эту проверку.
Архитектура, контракты и выполненные проверки: doc/call_video.txt, doc/chat_call_arch.md.
[ ] **Тесты: нестабильное завершение test_stcp_traffic** — 14.10.2026:
В полном прогоне после NCD CLOSE server получил 1029466/1048576 bytes (done=0), client — 1048576 (done=1).
Упала проверка test_stcp_traffic.c:216; отдельный повтор прошёл. Причина не установлена, сетевой код в задаче zoom не менялся.
Проверить завершение двусторонней передачи относительно закрытия handle; первичный лог сохранён: /tmp/stream-zoom-stcp-first.log.
[ ] **Тесты: диагностировать нестабильную проверку TX snapshot в test_android_stream** — 14.10.2026:
В полном прогоне один раз упала строка 177: snapshot успешен и 0 < video_bytes < 500000 после test_clock_run_for(ua, 1000).
Сам publisher обновляет snapshot таймером 1000; текущий CHECK не выводит result/sample_us/video_bytes.
Отдельный повтор и следующий полный прогон прошли. Добавить значения и проверить ожидание конкретного снимка;
причина не установлена, Kotlin-аудиовывод этот C-тест не вызывает.
Логи прогонов: /tmp/stream-audio-check-host.log, /tmp/stream-audio-native-retry.log, /tmp/stream-audio-check-final.log.
[ ] **Общий AGC: клиппинг после резкого роста сигнала при max_gain=45dB** —
на SM при проверке CAMCORDER с настройками рации rise=6/release=30 наблюдались
4581 обрезанный отсчёт за интервал около 1s. Это общий алгоритм radio/stream,
плавное снижение gain может не успеть за скачком входа. Проверить ограничение пиков
без щелчков и ухудшения адаптации. Лог: `/tmp/stream-camcorder-sm-live.log`.
[ ] **Desktop: выход после SIGTERM оставляет GUI после остановки ядра** — 13.10.2026:
при обновлении live-плеера старый vibechat завершил ядро/worker, но процесс остался
в QCoreApplication::exec с работающим audio output. В логах также DM SELECT после
уничтожения SQLite (`bad parameter or other API misuse`). Проверить отмену Quit
в MainWindow::closeEvent (всегда ignore), порядок уведомлений и отключение GUI от БД.
Снимок: `/tmp/stream-desktop-shutdown-backtrace.log`, лог vibechat 13:04:09.
[ ] **Стриминг SM → colo2 → desktop: восстановление частично остановившихся субпотоков** —
13.10.2026: помощь подключилась за ~8 с, все 8 субпотоков через colo2 приняты с общего индекса 5844.
Позже шесть субпотоков перестали продвигаться около seq=111625; четыре restart не восстановили
просмотр, desktop завершился по таймауту в 11:10:48 (colo2: 12:10:48). На SM публикация продолжилась,
colo2 снял свою подписку через 3 с. В том же интервале сервер видит RX timeout/переподключения TCP к SM;
первопричина остановки выдач пока не установлена: stream на colo2 наследовал error, детальных логов не было.
Повторить с заранее включённой диагностикой stream/etcp на SM и colo2, проверить upstream handles,
аренды, позиции и повторное согласование. Логи: `/tmp/stream-live-gui-final.log`,
`/tmp/stream-live-colo2-final.log`, `/tmp/stream-live-sm-final.log`.
Повтор 13.10 со stereo: до 15:20 desktop показывал ~30fps, затем video/audio очереди опустели;
decodeFps упал до 7–18 и viewer завершился по таймауту в 15:21:13 после пяти restart.
SM при этом сохранял ~30fps без dropped. Новые логи: `/tmp/stream-stereo-desktop-delivery-stall.log`,
`/tmp/stream-stereo-colo2-delivery-stall.log`, `/tmp/stream-stereo-sm-delivery-stall.log`.
[ ] **Android: отмена асинхронного запуска до готовности ядра** — при проверке
мониторинга 12.10.2026 обнаружено: `NativeLib.stop()` пропускает native stop,
если `isReady()==false`, а `instance_lite_stop()` возвращается при `g_inst==NULL`.
Поэтому запрос stop до завершения конструктора может не отменить запускаемый
поток. Согласовать отмену с состоянием потока и единым сигналом завершения;
проверить stop до SERVICE_STARTED, отказ конструктора и последующий start.
[ ] **Android: повторные отказы persisted node snapshots** — замечено 12.10.2026
на устройстве D2AR10P3600820 при проверке live media. В сохранённой БД ряд узлов
регулярно получает `invalid persisted snapshot` в `topo_node_sqlite_snapshot_load`,
затем NCD сообщает `node not found`; повторные попытки засоряют лог.
Лог: `/tmp/stream-av-device-initial.log`. Причина пока не установлена: текущий
текст объединяет отказ deserialize, несовпадение ID и отказ verify. Разделить
диагностику этих ветвей и проверить повторные попытки загрузки отвергнутого снимка.
Существующую БД устройства при проверке стриминга не очищали.
[ ] **STUN IPv6** — отдельный этап: IPv6 endpoint/config/DNS и XOR-MAPPED,
scope/netif, тесты IPv6/NAT66. IPv4-оценки не переносить на IPv6 или TCP.
[ ] **check.sh: изоляция сетевых integration-тестов** — после основного набора
автоматически запускает check-proxy/burst/load при доступном sudo. Скрипты
меняют rp_filter, таблицу 100 и iptables главного namespace; cleanup выставляет
rp_filter=1 вместо сохранённого значения. Перенести тесты в отдельный namespace
и проверять неизменность родительской сети, как в tests/stream_netns.
[ ] **Стриминг: оставшиеся длительные и масштабные сетевые проверки** — 10–12.10.2026:
Реализация ядра, публикации, приёма и автоматического выбора поставщиков завершена; контракт — doc/stream.txt.
Есть 16-процессный namespace-стенд с NAT/reverse и выбором UDP/TCP: tests/stream_netns/README.md.
Осталось подтвердить покрытие длительной нагрузки, смены адресов/мультилинка, одновременной перестройки
нескольких ретрансляторов, нескольких автоматических источников/групп и mobile standby на устройстве
(doc/stream.txt, раздел 16). Сохранённые проверки отдельных этапов не закрывают всю матрицу.
[ ] **Member files: исчерпание кеша результатов массовых изменений** — 10.10.2026:
Воспроизведено test_member_files_browser::recursiveDeletion(server-busy): из 76 объектов удаляются 64,
следующая команда получает MF_BUSY, остаются 12. storage.c: STORE_RECEIPTS=64, RECEIPT_TB=1200000 (120 секунд).
Лимит общий для успешных COMMIT/MKDIR/RENAME/REMOVE; затрагивает также рекурсивное копирование.
Нужен отдельный этап управления временем жизни receipts с сохранением идемпотентности повторных запросов;
простое вытеснение старых записей нарушает гарантию повторного ответа. После исправления изменить регрессию
на успешное удаление более 64 объектов и проверить повторные запросы/потерю ответа.
[ ] **Desktop: провалы вероятности VAD при компрессии** — диагностика 09.10.2026:
Воспроизведение пользователя: длительная гласная, затем временная нечувствительность; ближе к концу лога несколько повторов.
Новый лог 14:32:14–14:34:38: на 14:34:07–18 и 14:34:20–38 все 556 окон с RMS > -30dBFS имеют p < 0.5;
PCM непрерывен, errors=0, RX-gate не мешает, clips=5 не растёт. Сигнал не исчезает, порог остаётся 0.5.
--probe-stream: C-обёртка + реальный AGC + две Silero на одинаковом PCM, отличие — один reset состояния второй модели.
Синтезированный flite ah растянут до 24.576с: без AGC/клиппинга p первой секунды следующей речи 0.027 против 0.674 после reset.
При AGC 1dB (clips=0) — 0.012 против 0.662. Влияние истории модели подтверждено, провал на десятки секунд целиком не воспроизведён.
Лог стенда: /tmp/vad-vowel-context.log; запуск: test_silero_vad lib/silero_vad.onnx --probe-stream /tmp/vad-vowel-context48.pcm 993.
Вход стенда: mono s16le/48кГц, reset_window — индекс окна 512/16кГц; режим проверяет без AGC, 1dB и 15dB.
Автоматические сбросы в рабочем VAD не добавлялись; test_silero_vad PASS.
Уточнение: низкая вероятность держится десятки секунд, затем распознавание восстанавливается; краткий клиппинг это не объясняет.
Локальный лог 14:00:10–14:00:58: 15 сбросов AEC при пропусках референса, 16 clipped samples в VAD; vad DEBUG не был включён.
Добавлены секундные уровни raw/clean/reference и причина bypass/reset AEC; отдельное предупреждение о клиппинге VAD.
Секундный отчёт захвата работает также без PCM: возраст кадра, очередь, максимальная задержка и предупреждение о простое.
TRACE каждого окна содержит DC, число нулей и gain вместе с вероятностью/уровнем/паузой между окнами; видны сбросы и RX-gate.
В локальном build/vibechat.cfg включены vad=trace, aec/radio/call=debug, general=info; после диагностики вернуть обычные уровни.
Стенд --probe повторяет одинаковый PCM без reset: AGC 15/30dB после паузы обрезает пики (468/5625 samples на чистой записи).
Полного провала всей фразы почти до нуля стенд не воспроизвёл; нужен повтор живой речи с новыми логами для связи с AEC/AGC.
Алгоритмы обработки сигнала пока не менялись; исправление причины выбирается по результатам повтора.
[ ] **Linux headless CMake: актуализировать зависимости общего ядра** — 07.10.2026:
чистая сборка tools/chatgui-android/build_headless останавливается на lib/speex_aec.c:
speex/speex_echo.h не найден. utun_setup_sources включает этот исходник, но UTUN_INCLUDE_DIRS не содержит
lib/speexdsp/include. Проверить полный состав Speex/voice зависимостей отдельного каркаса;
основная Autotools C-сборка и Android NDK-сборка проходят.
[ ] **Завершить проверку реакций и голосов на SM** — 07.10.2026:
Исправления подписей корней и их сохранения реализованы, проверены тестами; local и копия SM проверены.
Последующие APK уже устанавливались на SM, поэтому прежнее ожидание подключения ADB неактуально.
Осталась явная проверка реакции/голоса на устройстве с текущей БД и сборкой.
Разовый скрипт и резервная копия подписей: /home/user/utun2-backups/root-certificates-20261007.
[ ] **rlottie: разбор предупреждений GCC 15 в импортированных исходниках** — 05.10.2026:
при сборке `tools/chatgui/rlottie_src` GCC сообщает `-Wuninitialized` в
`VArenaAlloc::reset()`: fFirstBlock/fFirstSize/fFirstHeapAllocationSize читаются
после явного вызова деструктора. Проверить сохранение значений до разрушения
и повторный reset с реальными выделениями. Также проверить `-Wfree-nonheap-object`
в `vcow_ptr`: статическая модель default_s сохраняет базовую ссылку.
Лог: `/tmp/utun-rlottie-vendor-build.log`. Сборка библиотеки и подключение её
экспортированного CMake-пакета к ChatGUI на Linux прошли; Windows ещё не проверен.
[ ] **ChatGUI Windows: подтверждение обновления runtime компилятора** — 05.10.2026:
`cc-probe.log`: cc1 запускается из корня, но в `tools/chatgui/build` завершается
с `0xC0000139`; локальные DLL GCC/math/runtime отличаются от UCRT64.
Перед обеими точками сборки добавлено обновление существующих копий этих DLL;
раскладка FFmpeg использует для них UCRT64. Проверены обновление, повторный вызов,
сохранение кодеков и ошибки. Требуется Windows-прогон `check_cc.bat`: cc1 после
обновления, повтор команды Ninja и сборка Opus должны завершиться с кодом 0.
[ ] **ChatGUI Windows: обновление остальных DLL приложения после обновления MSYS2** — 05–06.10.2026:
Пропуск раскладки при наличии основного комплекта уже убран: зависимости проверяются на каждой сборке,
Qt DLL/плагины и собственный комплект FFmpeg копируются заново; runtime GCC обновляется отдельно.
Осталось определить обновление прочих уже существующих транзитивных DLL: рекурсивный проход
по-прежнему копирует только отсутствующие файлы. Сохранить приоритет собственной сборки FFmpeg
и проверить запуск приложения после обновления MSYS2.
[ ] **Android: время жизни config provider** — 03.10.2026: `utun_bridge_init()`
передаёт адрес локального `utun_config_provider_t` в `utun_config_set_provider()`,
который хранит указатель. После возврата из init он недействителен; перед
использованием `cfg_get_*` обеспечить постоянное хранение provider.
[ ] **Общий лимит check.sh после clean** — 01.10.2026: расчёт по времени предыдущего
прогона дал 205с вместе с полной сборкой и оборвал проверку после успешных тестов
до `test_uasync_socket_race`. Повторный запуск на готовой сборке с большим лимитом
прошёл за 206с, включая proxy/burst/load. Разделить бюджет сборки и запуска тестов
либо учитывать clean при расчёте.
[ ] **Повторно проверить паузы desktop-аудио при звонке с SM** — 01.10.2026:
В звонках 939a3ea36f3eeac3/b2a423ed2d36ed83 частота callback падала до 4–40/с,
входящий PCM продолжал приходить, очередь росла до нескольких секунд без dropped.
Диагностика backend, интервалов callback и capture/playback уже добавлена; позднее менялись аудиовывод и его буферы.
Нужен повтор на текущей сборке с CALL_STATS и временными метриками, чтобы проверить сохранение исходного сбоя.
Сетевую задержку оценивать отдельно: в одном из прежних звонков DIRECT RTT был 2–3мс.
[ ] **Измерить оставшуюся задержку запуска аудио SM после исправлений** — 01.10.2026:
В исходном звонке 2b9ad4e21a54d8ba первый capture приходил через 1140мс от startAudio;
router.start=781мс, startRecording → первый кадр=328мс, AudioTrack.play=327мс.
Независимый запуск capture/playback, отмена частичного старта и подробные замеры уже реализованы;
позднее добавлен выбор AAudio/AudioTrack. Осталось измерить текущую сборку на SM:
callbackMs/btProfileMs/applyMs/refreshMs, первый AudioRecord.read и первая запись playback,
начальное накопление очереди. Старые длительности не считать характеристиками текущей реализации.
[ ] **Гонка invite-файла в test_chat_join_e2e** — `wait_file()` проверяет только
существование файла, а `wf()` создаёт его до записи. Читатель иногда получает
пустую ссылку и ошибку префикса `utun://`. Публиковать готовый файл атомарно.
[+] **Linux ONNX Runtime: повторная регистрация схем при запуске теста** — проверено 21.10.2026:
Причина в системной сборке `1.23.2+dfsg-6ubuntu1`: Runtime вручную регистрирует схемы,
затем динамическая `libonnx.so.1` повторяет регистрацию в `OpSchemaRegistry::map()`.
Подтверждено GDB (`/tmp/silero-schema-gdb.log`) и исходниками обеих библиотек.
Текущая Linux x64 CMake-сборка переключена на [официальный Runtime 1.23.2](https://github.com/microsoft/onnxruntime/releases/tag/v1.23.2).
Архив `onnxruntime-linux-x64-1.23.2.tgz` распакован в `.cache/onnxruntime/`;
SHA-256: `1fa4dcaef22f6f7d5cd81b28c2800414350c10116f5fdd46a2160082551c5f9b`.
Для существующего include `onnxruntime/onnxruntime_c_api.h` создана ссылка
`.cache/onnxruntime/include/onnxruntime` → `../onnxruntime-linux-x64-1.23.2/include`.
В CMake явно заданы абсолютные пути: `ONNXRUNTIME_INCLUDE_DIR=<repo>/.cache/onnxruntime/include`,
`ONNXRUNTIME_LIB=<repo>/.cache/onnxruntime/onnxruntime-linux-x64-1.23.2/lib/libonnxruntime.so`.
Выбор сохраняется в `tools/chatgui/build/CMakeCache.txt`; после удаления cache его нужно повторить.
`ldd` подтверждает официальный Runtime без отдельной `libonnx`; весь `test_silero_vad` проходит без `Schema error`.
Лог проверки: `/tmp/silero-runtime-test.log`, полный вывод — `tools/chatgui/build/Testing/Temporary/LastTest.log`.
[ ] **debug_parse_config: формат и индексы категорий** — parser ожидает `:`, документация
описывает `=`; преобразование битовой маски осталось после перехода enum на индексы.
[Разбор](etcp_full_suite_findings.md).
[ ] **Повторно проверить crypto-шум при автоподключении в сценарии A–C–B**:
В старом test_dm_e2e попытка прямого A↔B через topo_group_connect давала packet undecryptable примерно раз в секунду.
Наблюдение относилось к прежним настройкам приёма и архитектуре подключений; устранение не подтверждено.
Воспроизвести на текущих NCD/ETCP и установить точную причину по логам до изменения политики подключения.
Отсутствие [client] само по себе не считать основанием запрета: CHAT использует собственных NCD-владельцев.
[ ] **lwip/proxy: утечка pcb в FIN_WAIT_2** — `tcp_shutdown(pcb,0,1)` (half-close по FIN от
exit) не ставит `TF_RXCLOSED`, поэтому таймаут FIN_WAIT_2 в `tcp_slowtmr` не срабатывает:
если браузер никогда не пришлёт FIN, pcb навсегда остаётся в FIN_WAIT_2 (утечка, не crash).
Двойной free по TIME_WAIT уже закрыт (detach по локальному закрытию + guard abort).
## Открытые флаки
[ ] **test_etcp_transport: таймаут восстановления REALITY-сессии** — 18.10.2026:
в общем `./check.sh` сценарий `reality=1 simultaneous=0 restart=0` завершился
`Session recovery timed out: phase=1 stream=15 control=6`. Перед таймаутом —
`record socket read failed: err=104`, клиент ждал server-handshake.
Отдельный повтор того же бинарника прошёл. Причина нестабильности пока не установлена;
изменения Android JNI/UI транспортные исходники не затрагивали.
[ ] **test_etcp_reconnect** — флаки под параллельной нагрузкой `make check -j4`:
phase 4 (reconnect после server restart) таймаутит (`sent=480 recv=0`), при одиночном
запуске стабильно `TEST PASSED`. Наш код (chat_join/chat_sync) его не трогает.