You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

64 KiB

Задачи по проекту

Сюда пишется список задач с короткой аннотацией. Если задача большая и имеет ТЗ - то ТЗ оформляется отдельным файлом, а сюда помещается аннотация и ссылка на ТЗ.

Текущие задачи

[+] Live: независимая подача decoder и устранение вечного ожидания AV1 на SM — 14.10.2026: Причина: Android подавал максимум три кадра и читал видео только на 80ms вперёд от остановившегося clock; c2.android.av1-dav1d.decoder требовал заполнения своего конвейера. KEY уже был принят, но UI продолжал ждать KEY. Общий cursor теперь запрашивает следующий видеокадр независимо от PTS показа; audio сохраняет временной lookahead. Bridges готовят один ответ на запрос, получение ответа/AVAILABLE не создают скрытого prefetch. Android StreamDecodePump держит один input и один output, обслуживает выход перед входом и использует готовность codec. KEY/decoder ожидания разделены; старт clock/audio после первого decoded frame, low latency при поддержке. Защитный guard учитывает наблюдённый decoder lead; EOF освобождает inflight metadata и не блокирует audio tail. Desktop использует тот же контракт: один рабочий AVPacket, два готовых изображения, EAGAIN сохраняет вход, FIN дренирует decoder до EOF. Кодек/rotation меняют video revision, аудиошкала сохраняется. 151 тест ядра без ошибок/пропусков, proxy/integration/burst/load прошли; check.sh — 126s. Четыре CTest stream/audio timing прошли; восемь Kotlin pump-сценариев прошли, APK обоих ABI и vibechat собраны. Проверены 4/8 входных кадров при замороженном clock, сетевые паузы, поздний ответ чтения, пустой EOS и guard. Настоящие FFmpeg кадры с задержкой выхода в четыре кадра: запуск после 80ms и полный drain короткого потока из трёх кадров. Реальный AV1 на SM-A525F: первый decoded frame через 67–117ms после KEY в проверенных запусках, длительный показ и поворот работают; завершённый запуск показал 21609/21609 decoded/shown, без discarded. Исправленный APK установлен на SM. Сетевой протокол и формат RS остаются прежними; colo2/Q8 не обновлялись. Архитектура: doc/stream.txt, doc/service_lifecycle.md. Логи: /tmp/av1-pump-{full-check,ring-test,bridge-test,service-test,gui-tests,android-final-build,sm-live}.log.

[+] Live: публикация с desktop ChatGUI — 14.10.2026: Камера, микрофон, экран и окно через Qt >=6.6 Multimedia/FFmpeg; Wayland/XWayland использует системный портал. Отдельный controller сохраняет эфир при закрытии окна, сырое превью обновляется до 30Hz независимо от encode. Выбор рабочего H.264/H.265/VP9/AV1/H.266, разрешения/FPS, bitrate и поворота 0/90/270 с отметкой верха. Encoder проверяет два принудительных KEY, затем открывает чистую сессию; hardware имеет приоритет. Смена видеонастроек сохраняет capture, звук и source_epoch; libx264 меняет bitrate без смены encoder. Ошибка видеорежима откатывает последнюю подтверждённую конфигурацию; fatal Opus завершает эфир и освобождает микрофон. Stereo Opus/128kbps с общим gain и текущими настройками компрессора рации; mono input обозначается явно. Общий C stream_publisher для Android/desktop: ограниченные очереди/admission/KEY recovery, uAV2/RS, FIN/drain 2s, согласованные 100ms TX snapshots (video queue, all-connection inflight, send buffer, ACK_1s). Протокол не меняется. Microphone lease публикации эксклюзивен, прежняя совместная работа голосовых функций сохраняется. 151 тест ядра и proxy/integration/burst/load прошли; полный check.sh — 129s. Все 32 CTest ChatGUI прошли. Publisher отдельно: 11 проверок прошли, экранный сценарий запущен отдельно под Xvfb/private D-Bus — без пропусков. Проверены реальные H.264/H.265/VP9/AV1 encoder/decoder, сохранение decoder при изменении libx264 bitrate, настоящий X11 screen/window capture, непрерывный неподвижный экран, сырое превью, два стереотона, H.264 → VP9 и rollback без смены audio/source_epoch, Opus failure, FIN и concurrent detach/leak count. vibechat и APK arm64-v8a/x86_64 собраны, Kotlin unit tests прошли; Windows runtime/installer fixtures прошли. Физическая камера, захват через Wayland portal и Windows runtime вручную не проверялись; VVC encoder отсутствует. Устройства/colo2 не обновлялись. Архитектура: doc/stream.txt, doc/service_lifecycle.md. Логи: /tmp/desktop-stream-{full-check,final-gui-tests,final-publish-test,screen-test,android-build,runtime-test,installer-test}.log.

[+] Live: выбор видеокодека/битрейта и статистика отправки 10Hz — 14.10.2026: Android показывает доступные Surface encoder в порядке H.264/H.265/VP9/AV1/H.266, проверяя профиль, разрешение/FPS и диапазон bitrate; аппаратные encoder имеют приоритет. Битрейт выбирается отдельно (Авто либо пресет), LIVE обновляется без перезапуска encoder, при отказе используется смена видеоконфигурации с rollback. Звук и source_epoch сохраняются. uAV2: прежний 32-byte header, пять video_codec IDs, KEY = config_length:4BE/config/access unit. Конфигурация повторяется при каждом KEY и защищена общей подписью/RS; оба плеера выбирают decoder по codec ID. NAL parameter sets объединяются без дублирования, partial codec config собирается с пределом 64KiB. Publisher каждые 100ms показывает остаток video queue, общий inflight, полный send buffer и ACK_1s. Буфер учитывает отдельные очереди video/audio, ожидающие RS-выдачи и ETCP/normalizer без двойного учёта input_send_q; историю кольца не включает. ACK всех соединений учитывается один раз при подтверждении найденного пакета; окно — десять завершённых buckets по 100ms, переживает REINIT/close пира и не требует BBR link. Статистика имеет отдельный StateFlow; строки не меняют высоту превью при обычном изменении чисел. Реальные H.264/H.265/VP9/AV1, отдельная decoder configuration, FIN и смена revision проверены. H.266 проверен на уровне формата/KEY; реального VVC encoder в тестовом окружении нет. Устранена блокировка нового desktop viewer старыми control records в лимите подготовки медиа. 151 тест ядра прошёл без ошибок/пропусков; check.sh с proxy/burst/load — 119s. Qt stream/audio timing и Kotlin-проверки прошли; vibechat и APK arm64-v8a/x86_64 собраны. Устройства/colo2 не обновлялись. Протокол и формулы: doc/stream.txt, lifecycle: doc/service_lifecycle.md. Логи: /tmp/stream-codecs-{full-check,final-gui-tests,android-build,media-test,tx-test,native-test}.log.

[+] Live: воспроизведение из RS-кольца и минутная адаптация задержки — 14.10.2026: Android и desktop используют общее кольцо кодированных данных, метаданные PTS/KEY и отдельные cursor каждого reader. Пауза player не останавливает live ingest/selector; длинные кадры собираются ограниченными проходами с отложенным продолжением без ожидания новых пакетов. Убрана фиксированная стартовая буферизация 150ms; вне кольца остаются ближайшие кадры и рабочая порция PCM. Общий контроллер хранит 60 секундных минимумов запаса. История корректируется по фактическому простою/услышанному материалу, включая аппаратную очередь и расход ранее поставленного ускоренного PCM. После полной здоровой минуты плавный темп до x1.1 уменьшает задержку до безопасного остатка; SoundTouch сохраняет высоту звука и стереобаланс. Обычная нехватка сохраняет decoder references; GAP, вытеснение и разрыв медиапоследовательности начинают новый KEY и новую историю. FIN дочитывается каждым reader; close завершённого publisher сохраняет кольцо для локальных owners. Проверены шестисекундная пауза сетевого reader без restart, точные remote/local FIN drain, независимые cursors, поздняя повреждённая RS-часть, большой кадр, разрывы, конфигурация и границы PTS. Реальные H.264/Opus: 30fps при audio latency 200ms, preroll, revision/rotation, stereo x1.1 без изменения тона, физические аудиочасы, громкость и баланс памяти. Диагностика показывает запас/минимум, коррекцию, темп и wait/resume. 150 тестов ядра прошли без ошибок/пропусков; полный check.sh с proxy/burst/load — 129s. Три Qt stream/audio timing теста прошли; vibechat и APK arm64-v8a/x86_64 собраны. Устройства/colo2 в этой задаче не обновлялись. Архитектура: doc/stream.txt, lifecycle: doc/service_lifecycle.md. Логи: /tmp/stream-playback-{clock-test,full-check}.log, /tmp/stream-final-{gui-tests,desktop-build,android-build}.log.

[+] Live: переменный размер RS и одна подпись внутри пачки — 13.10.2026: RS принимает фактическую длину, уменьшает все части одной пачки до одинакового минимального размера и дополняет максимум k-1 нулями; один контекст/матрица используются повторно, без аллокаций RS на encode/decode. Источник подписывает метаданные и содержимое один раз, затем RS защищает сообщение вместе с 64-байтной подписью. Проверка источника выполняется после восстановления; неверная подпись/подписанные поля дают один GAP без закрытия owner. Следующая корректная пачка принимается. Ретранслятор пересылает части до decode, сохраняя малую задержку. Дескриптор хранит максимальный размер, кольцо/очереди/метрики — фактические длины; слоты по-прежнему резервируются по максимуму. При 6+2 содержимое 1000 байт даёт части 243 байта вместо 1300; полная вместимость содержимого — 7345 байт. Wire version=5; бинарники участников трансляции нужно обновить вместе. Формат описан в doc/stream.txt. Проверены все 28 пар потерь, малые/полные пачки, подмена содержимого/подписи/поля времени/индекса, padding, неверный ключ, фактический учёт байтов, пересылка до проверки и продолжение после отвергнутой пачки. 149 тестов ядра прошли без ошибок/пропусков; полный check.sh, включая proxy/burst/load, завершился за 131 с. Desktop stream/audio timing прошли; vibechat и APK arm64-v8a/x86_64 собраны, новый encoder проверен в обеих native-библиотеках APK. Логи: /tmp/stream-batch-{core,media,service,android-native,full-check}.log, /tmp/stream-batch-{desktop-build,gui-tests,apk-build}.log.

[+] Live: callback обнаружения поставщиков — 13.10.2026: Принятые изменения Merkle и BGP помечают roster оптимизаторов соответствующего канала устаревшим. Сверка/пробы выполняются после callback одним объединённым отложенным проходом в uasync. Новый доступный поставщик опрашивается сразу; существующие пробы, цикл и backoff ошибок сохраняются. Временно пустой буфер повторно опрашивается через 100 мс в пределах фиксированных 5 с, чтобы ранняя подписанная опция не оставляла недостающие субпотоки до обхода через 30 с. Регрессия с настоящим Merkle/BGP и задержанным READY: до исправления проверка задержки падала, после принятого объявления INFO получен через 6 мс. Повторные callbacks не размножают пробы; общий старт 8/2 и освобождение всех tracked allocations проверены. 149 тестов ядра, 43 Android-теста и desktop stream/audio timing прошли; GUI и APK собраны. Логи: /tmp/stream-provider-callback-{before,retry,full-check}.log, /tmp/stream-provider-callback-{gui-tests,android-build}.log.

[+] Live: выбранная выдача отменяла помощь до READY/ACCEPT — 13.10.2026: Первое открытие desktop 17:07:41.035 → первый кадр 17:07:44.500 заняло 3.464 с; запрос помощи отправлен через 99 мс, первый FEC через 2.490 с, KEY ещё через 0.796 с, prefill/показ заняли 0.178 с. Повторное открытие заняло 0.983 с. Merkle объявил буфер colo2 до READY: selector выбирал его INFO, но отменял STARTING-запрос, потому что выдача ещё не ACTIVE. Четыре CANCEL закрыли собственную выбранную выдачу. Запрос теперь удерживается также выбранными CONNECTING/INFO/REQUESTED upstream; INFO-пробы, ENDED/CLOSED и чужие downstream не удерживают его. Аренда/idle и проверки поколений сохранены. Регрессия с задержанным READY и настоящим Merkle/ETCP воспроизводит ошибку до исправления и проходит после него без преждевременного CANCEL и tracked allocation leaks. На colo2 всё ещё работает 14e2cdc2: опрос субпотоков раз в 100 мс и секундная задержка STATUS. В сохранённом запуске helper генерировал STATUS в 18:07:42.465 и 18:07:43.476; для полного ускорения нужен новый бинарник сервера. Логи: /tmp/stream-first3s-{desktop,colo2,sm}.log, /tmp/stream-first3s-regression-{before,after}.log, /tmp/stream-first3s-colo2-version.log.

[+] Live: ускорить начальное подключение — 13.10.2026: Дедлайн помощи 100 мс и первый пригодный INFO выбирают поставщика; DATA использует один общий старт. Управление просыпается по событиям, подтверждение поколения и новые состояния помощи не ждут 1 с. READY требует восстановленной FEC-пачки. Регрессии: прямой/relay победитель, поздние ответы, отмена до дедлайна, пустой источник, дубликаты, общий индекс 8/2 и освобождение ресурсов. Начальная очередь аудио прогревает Opus и обрезается по первому KEY; prefill 150 мс начинается после него. 149 тестов ядра, 43 Android-теста и desktop stream/audio timing прошли; GUI и APK собраны. В сетевом тесте первый восстановленный блок через помощника получен за 192 мс, n=8/r=2. Проверены поздний прямой INFO, отмена запроса до READY, отсутствие помощи для пустого доступного источника и отсутствие дополнительных STATUS на повторы REQUEST. Все tracked allocations освобождены. Desktop-регрессия прогревает 800 мс реального stereo Opus до KEY: звук молчит до начала видео, затем сохраняются 30fps, stereo balance и смена revision при физической audio latency 200 мс. Логи: /tmp/stream-startup-full-check.log, /tmp/stream-startup-service-final.log, /tmp/stream-startup-desktop-tests.log, /tmp/stream-startup-android-final.log. Контракт: doc/stream.txt, раздел 21. Замеры приведены для тестового стенда.

[+] Live: сквозное стерео и три компактные кнопки поворота — 13.10.2026: CAMCORDER/Opus/компрессор/Android AudioTrack/desktop output используют два канала, Opus AUDIO 128kbps. audio_codec=2 обозначает stereo; 960 кадров на канал дают 1920 PCM-отсчётов. Capture/playback timestamps считают кадры на канал; mono-пакеты upmix выполняет libopus. Три кнопки 0/90/270 подсвечивают выбранную и показывают верх цветной гранью на самой кнопке; положение грани учитывает камеру и экран, наложение на превью удалено. 148 тестов ядра, 43 Android-теста и desktop stream/audio timing прошли. Проверены stereo balance после AGC/Opus и независимые каналы на audio device (отношение энергий 15.99 при исходном 16). APK/чатгуи обновлены; SM подтвердил channels=2 и ненулевой lrDifference. Повороты 90/270 и возврат 0 проверены во время публикации без смены audio codec handle/epoch; desktop показал ~30fps. Логи: /tmp/stream-stereo-sm-final.log, /tmp/stream-stereo-final-desktop-tests.log.

[+] Android live: CAMCORDER и компрессор с настройками рации — 13.10.2026: AudioRecord.CAMCORDER, 48kHz mono; общий audio_compressor перед Opus AUDIO/64kbps, lookahead=0, без изменения PTS. DataStore передаёт включение, max_gain и общий rise_rate из настроек рации в audio worker; обновления применяются без перезапуска захвата/эпохи. 43 Android-теста и 631 проверка компрессора прошли, включая реальный Opus roundtrip, live bypass, смену gain, отсутствие накопления output и утечек. APK установлен на SM. На SM подтверждены CAMCORDER(5), переключение on/off/on в одном codec handle и восстановление исходных enabled=true/max_gain=45/rise=6. Desktop продолжил показ ~30fps. Лог: /tmp/stream-camcorder-sm-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.

[+] Desktop live: очередь видео вытесняла будущие кадры до показа — 13.10.2026: SM → colo2 доставлял ~30fps, desktop декодировал ~30fps, но videoQ=6 постоянно выбрасывал ближайший кадр до достижения его PTS аудиочасами. Регрессия H.264/Opus 30fps с физической audio latency 200ms на старом коде не показала ни одного кадра. Видео ограничено 128 кадрами/256MiB; при пределе сохраняются ближайшие к показу. Добавлены decode/show FPS, late/pressure и PTS очереди относительно часов; поштучное нормальное вытеснение транспортного буфера перенесено в trace. Исправленный test_stream_view: 8/8; test_audio_timing прошёл. Живой просмотр SM → colo2 после обновления: средний showFps=29.81 за 40s, videoQ=8–9, pressure=0. Метрики: /tmp/stream-desktop-fixed-live-metrics.log; краткие просадки showFps до 22.4 остаются наблюдаемыми.

[+] Android: категории диагностики и обрезанный текст уровня — 13.10.2026: список берётся из native-ядра, включая stream/video/reality/dm/call/aec. Поля уровня используют минимальную высоту вместо фиксированных 48 dp; изменения диагностики применяются сразу без перезапуска при выходе из настроек. Общий уровень сохраняется в [global] debug_level; оба парсера принимают все категории, а превышение лимита логируется. Регрессия: test_config_debug, файл и INI-текст.

[ ] Стриминг 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.

[+] Стриминг: помощь суперузлов по запросу — 13.10.2026: автоматический запрос при невозможности получения k субпотоков, внутреннее владение точной эпохой, общий буфер со зрителями, аренды и остановка без downstream. Relay-only экземпляры не удерживают друг друга. Подписанное управление с подтверждением поколения, таймаут READY, защита от поздних запросов и пустой END. Routed ID перенесён на 0x3C из-за конфликта с MEMBER_FILES; wire v4. Исправлено владение CM handles репликации медиа при смене роли суперузла. Контракт: doc/stream.txt, раздел 21. 148 тестов прошли, 1 пропущен; test_stream_service и отдельный --relay-only завершились без утечек.

[ ] 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 IPv4: резервное определение типа NAT по IP/netif — уточнённый план 12.10.2026 в doc/nat_detection.txt. Одна группа и отдельный тестовый UDP-порт на уникальный IP/netif, общий кэш с generation/TTL. При NO_OBSERVER/NO_HELPER применять пригодную оценку STUN с явным source; измеренный ETCP приоритетен. mapped адрес тестового сокета не переносить на рабочий. Проверить дубликаты, переход STUN -> ETCP, различия по портам и жизненный цикл; namespace-стенд. Реализовано 12.10.2026: группировка, кэш/TTL, история портов через reload, source в подписанном NODEINFO/SQLite/мониторе и приоритет частичного ETCP. 145/145 тестов; три ASAN-теста без утечек; реальные cone/restricted/dependent NAT и переключение STUN -> ETCP прошли в изолированном стенде.

[ ] 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.

[ ] Стриминг: реализация по stream.txt — 10.10.2026: ТЗ и этапы: doc/stream.txt, разделы 15–16. Основа данных реализована в src/stream: подписанные FEC-блоки 1300 байт, общий буфер 32 МБ, относительные timestamp-метрики, источник с таймером 100 мс и категория stream. test_stream_core прошёл; ./check.sh: 143 passed, 0 failed, 0 skipped; proxy/full, burst и load — PASS. 11.10.2026 подключены жизненный цикл CHAT, локальные handles/API и события потребителя, атомарные опции мембера через Merkle, подписанные профили и BGP-фильтр кандидатов. test_stream_service прошёл на четырёх ядрах: две группы, смена эпохи/членства, restart, rollback профиля, закрытие из callback и нулевой остаток аллокаций после destroy. Лог: /tmp/stream-service-test-final.log. Исправлена выявленная утечка BGP node_paths при удалении узла. Общий ./check.sh: 144 passed, 0 failed, 0 skipped; proxy/full, burst и load — PASS. Лог: /tmp/stream-service-check.log (107 с). 11.10.2026 подключена сетевая выдача raw ETCP через собственный NCD owner: INFO/поколения, handles/watermark, общий старт от первого DATA, курсоры/пути/GAP/LOOP, подпись END и аренда/RENEW. Routed REVERSE_REQ/CLOSED подписываются end-to-end. Явные receive API позволяют открыть/закрыть выдачу и начать новую попытку. Сетевая цепочка источник -> relay -> получатель, две группы/FEC на одном ETCP, GAP/restart, повторы/reverse, END, lease timeout и REINIT прошли под ASAN/LeakSanitizer без ошибок/утечек. Логи: /tmp/stream-network-asan-core.log и /tmp/stream-network-asan-service.log. После восстановления обычной сборки ./check.sh: 144 passed, 0 failed, 0 skipped; proxy/full (9/9), burst и load — PASS. Лог: /tmp/stream-network-check.log (88 с). Wire и численные пределы зафиксированы в doc/stream.txt, раздел 17. 11.10.2026 подключены timestamp-метрики/rates/stops, nonce/метрики INFO и RTT uint32 мс, A/D/X/Q выдач/пиров/модуля, интервалы 200мс и история 10с, подтверждение перегрузки 500мс. OVERLOAD с frozen rates, FEC/альтернативами при выборе, SELECT/CLOSED, неизменным сроком 2с и fallback; глобальный бюджет нескольких пиров требует backlog и локальной загрузки, CPU отдельно не режет. 4-секундный предел возраста control/ожидающих заданий, GAP/X при истечении и наблюдаемый статус accepting. Частичная/сильная/глобальная разгрузка, короткий глитч и поздний SELECT прошли под ASAN/LeakSanitizer без ошибок/утечек. Логи: /tmp/stream-pressure-asan-core.log и /tmp/stream-pressure-asan-service.log. Обычная сборка восстановлена; ./check.sh: 144 passed, 0 failed, 0 skipped; proxy/full (9/9), burst и load — PASS. Лог: /tmp/stream-pressure-check.log (90 с). Wire версии 2 и пределы обновлены в doc/stream.txt, раздел 17. 11.10.2026 подключён автоматический планировщик: stream_subscribe_open начинает получение, ручной режим выделен в stream_subscribe_manual_open. INFO-only пробы, цикл 32/1с/30с, проверенные пути/RTT/метрики/слоты, backoff, распределение FEC, перенос с перекрытием и failover. Первый DATA задаёт общий N; пустой источник и курсор last+1 ждут данные, END без DATA также подписан и доставляется. Сохранён желаемый режим frontend; stream owners удерживают ACTIVE до close, затем восстанавливается STANDBY. Статус/настройки — stream_selection_get_info/configure; wire версии 3 и пределы — doc/stream.txt, раздел 17. На четырёх ядрах проверены 400 непрерывных пачек, общий планировщик владельцев, цикл 30с, FEC spread, overlap до проверенного DATA, остановка relay/CLOSED и восстановление без разрыва ETCP. Core/service, NCD и standby transport прошли ASAN/LeakSanitizer; остаток аллокаций — ноль. Логи: /tmp/stream-optimizer-asan-{core,service,ncd,standby}.log. Односторонняя смена stream generation восстанавливается по nonce INFO без разрыва ETCP и вращения эпох другой стороны; регрессия и весь service-тест прошли ASAN/LeakSanitizer: /tmp/stream-generation-asan-service.log. ./check.sh: 144 passed, 0 failed, 0 skipped; proxy/full (9/9), burst и load — PASS. Лог: /tmp/stream-optimizer-check.log (97с). Следующий этап — длительные/масштабные сетевые проверки: NAT/reverse, мультилинк, одновременная перестройка, несколько автоматических источников/групп и mobile standby на устройстве.

[+] test_reality_tls: коллизии порта слушателя — 10.10.2026: В общем прогоне 140 passed, 1 failed: stcp_server_create не смог занять порт 34922, bind errno=98 (EADDRINUSE). Причина: выбор порта как 34000 + time(NULL) % 1000 без гарантии его доступности. Слушатель создаётся с port=0; stcp_server_get_port возвращает назначенный ОС порт для подключения клиента. Логи показывают фактические порты REALITY и HTTPS. Сборка прошла; 8 параллельных TLS/HTTP-тестов прошли при занятом всём прежнем диапазоне 34000–34999. ./check.sh: 141 passed, 0 failed, 0 skipped; proxy/full, burst и load — PASS.

[ ] 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-сборка проходят.

[ ] REALITY: исправить формат ClientHello и продолжение TLS-потока — 07.10.2026: supported_groups и signature_algorithms не содержат внутренние двухбайтовые длины списков. После ClientHello/ServerHello идёт STCP без TLS record framing; это распознаётся пассивным наблюдателем.

[ ] Завершить проверку реакций и голосов на SM — 07.10.2026: причина отказа установлена: у записей корней signed_by=0/NULL были нулевые/отсутствующие подписи дерева. Проверка корня ключом канала остаётся обязательной; добавлены причины отказа и проверка доверенного Ed25519. Исправлено применение подтверждённой подписи при равной/старой версии профиля и её сохранение при нулевом блоке в более свежем профиле. Создание канала проверяет обе подписи корня до записи собственного мембера. На local восстановлены шесть подписей канальными приватными ключами без изменения остальных полей записей. Разовый скрипт и резервная копия: /home/user/utun2-backups/root-certificates-20261007. Проверены все 18 участников local и 17 участников копии SM; тесты требуют отказа при нулевой/поддельной подписи. Linux/Android/desktop собраны; ./check.sh: 133 passed, 0 failed, 1 skipped; proxy/full, burst, load и 7 Qt-тестов — PASS. Осталось установить APK на SM (RZ8R72MG64B) и проверить реакцию/голос на устройстве: SM отключился от ADB во время работы.

[ ] 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.10.2026: в cc-probe.log также отличаются Qt и другие DLL. tools/chatgui/build.sh пропускает раскладку при наличии основного комплекта, без сравнения версий; рекурсивная раскладка копирует только отсутствующие зависимости. Runtime GCC обновляется отдельно; для остальных DLL нужно продумать обновление с сохранением приоритета собственной сборки FFmpeg и проверить запуск приложения.

[ ] Android: время жизни config provider — 03.10.2026: utun_bridge_init() передаёт адрес локального utun_config_provider_t в utun_config_set_provider(), который хранит указатель. После возврата из init он недействителен; перед использованием cfg_get_* обеспечить постоянное хранение provider.

[ ] uasync: ложные ERROR об утечке перед cleanup — 01.10.2026: test_dm_e2e и существующий test_conn_mgr проходят, но uasync_destroy() пишет Timer leak до освобождения отменённых heap/immediate таймеров. После cleanup счётчики сходятся, финальная проверка проходит. Перенести предварительные счётчики в DEBUG; ERROR оставить для реального расхождения после cleanup, отдельно показывать активные и отменённые таймеры.

[ ] Общий лимит check.sh после clean — 01.10.2026: расчёт по времени предыдущего прогона дал 205с вместе с полной сборкой и оборвал проверку после успешных тестов до test_uasync_socket_race. Повторный запуск на готовой сборке с большим лимитом прошёл за 206с, включая proxy/burst/load. Разделить бюджет сборки и запуска тестов либо учитывать clean при расчёте.

[ ] Паузы аудио Qt при звонке с SM — 01.10.2026, звонок 939a3ea36f3eeac3, прямой LAN TCP 192.168.40.250:44604 ↔ 192.168.40.247:44173. Tcpdump: общие паузы входящего трафика до 645мс; ping до роутера в среднем 100мс, до SM 128мс. ПК на 2.4ГГц, SM на 5ГГц. Одновременно CallAudio: cb падает до 20–40/с вместо 100/с, буфер Qt растёт до 2с, на SM повторяется refill. В 8с strace аудиопоток продолжает обслуживать PulseAudio без долгих syscall; причина редких аудиоколлбэков пока не установлена. Добавить измерения интервалов и длительности callback, кадров capture/playback и сводку CALL_STATS; сравнить сетевые задержки после подключения ПК к 5ГГц или кабелю. Повторный звонок b2a423ed2d36ed83 (01:25:31–01:27:39): DIRECT сохраняется, RTT 2–3мс; в начале на SM gap tone длится 1.8–2.0с примерно каждые 6с. На Qt частота callback падает вплоть до 4/с, входящий PCM продолжает приходить: буфер 65→465→1465→2079мс за 3с, затем растёт до нескольких секунд, dropped=0. Локализовано прекращение обслуживания duplex-аудио Qt; ожидание backend и задержка обработки PCM пока не разделены. Часы SM отстают от Qt примерно на 1.24с. Добавлена диагностика backend/устройств, времени между callback и длительности capture/playback, фактической частоты callback и PCM кадров за интервал. Счётчики сбрасываются до старта устройства; нужна повторная запись с новой сборкой.

[ ] Оставшаяся задержка запуска аудио SM — после обновления 01.10.2026, звонок 2b9ad4e21a54d8ba: стартового gap tone нет на обеих сторонах; Qt стабильно работает около 100 callback/с, max_idle=15.3мс, буфер 55мс, RTT=2мс. На SM первый capture появляется через 1140мс от startAudio (1164мс от ACCEPT). router.start=781мс, получение снимка устройств=0мс, AudioRecord create=24мс, startRecording=7мс; от начала startRecording до первого кадра=328мс. Capture worker стартует раньше playback, но общий выигрыш пока не виден. AudioTrack create=21мс, play=327мс; система сообщает AudioPortCache contention=497мс и восстановление AudioTrack при setPreferredDevice. Разделить замеры регистрации callback, BT-профиля и применения маршрута; отдельно проверить первый AudioRecord.read. На SM входящий буфер за время подготовки вырос до 1149мс и к концу звонка снизился до 570мс; ускорение старта playback также сократит начальное накопление. Реализован независимый запуск AudioTrack и AudioRecord в play/capture потоках; частичный старт отменяется до освобождения устройств/native. AEC измеряется после готовности обоих. Добавлены callbackMs/btProfileMs/applyMs/refreshMs, длительность первого read и время первой записи playback. Резерв теперь зависит от изменения задержки доставки по timestamps CALL_MEDIA, отдельно от глубины очереди; стартовое накопление и догон не повышают запас. Сохранность FIFO и uint32 wrap проверяются регрессиями. Сборки ядра, Qt и Android после clean успешны; три аудиотеста прошли. Полный check: 113 PASS, 0 FAIL, 1 SKIP (auto_socket_dynamic требует root); proxy/burst/load прошли. Регрессия refill учитывает остаток SoundTouch: два новых кадра могут уже заполнить запас 60мс. SM и Q8 обновлены 01.10.2026 в 03:03. Выигрыш по времени требует пробного звонка с новой версией.

[ ] Гонка invite-файла в test_chat_join_e2e — wait_file() проверяет только существование файла, а wf() создаёт его до записи. Читатель иногда получает пустую ссылку и ошибку префикса utun://. Публиковать готовый файл атомарно.

[ ] Некорректное время в выводе check-proxy — успешные basic_1mb и stress_sessions иногда печатают огромные положительные/отрицательные миллисекунды, хотя итоговая скорость и длительность передачи выглядят нормально. Проверить расчёт вывода.

[ ] Linux ONNX Runtime: повторная регистрация схем при запуске теста — 03.10.2026: test_silero_vad при загрузке модели печатает серии Schema error: ... already registered. Инференс, речь, тишина и reset проходят; отдельно проверить состав и загрузку Linux-библиотек ONNX. Диагностика: /tmp/vad-compressor-silero-tests.log; Android-сборка таких сообщений не содержит.

[ ] test_tcp_proxy_full: некорректное время в диагностике — 03.10.2026: полный check.sh проходит, но строки basic/stress/concurrent/half_close выводят огромные или отрицательные миллисекунды (например, -1611883348002232012ms). Отдельно проверить формат/аргументы вывода длительности; /tmp/vad-compressor-check.log.

[ ] debug_parse_config: формат и индексы категорий — parser ожидает :, документация описывает =; преобразование битовой маски осталось после перехода enum на индексы. Разбор.

[ ] DM: прямой p2p чат с любым пользователем группы — отдельная DM-подсистема. ТЗ и архитектура: /doc/dm_arch.md. Статус: реализовано (dm_core/dm_mailbox/dm_crypto), тесты test_dm (крипто) и test_dm_e2e (интеграция). Остались задачи ниже.

[ ] Звонок (P2P аудио) — голос 1:1, из CHAT-группы или p2p-чата (DM). Отдельный каталог src/call/. Сигналинг + conn_mgr + аудиопоток (Opus) с backpressure (локальный буфер отправки при переполнении роутера) + адаптивный джиттер-буфер (SoundTouch, ускорение до 1.6x) + тоны (глитч/завершение) + watchdog 20с. Android: переключение источника (трубка/громкая/гарнитура). Архитектура: /doc/chat_call_arch.md.

[ ] **DM-звонки** (fallback `group_id==0`) — не сделано: `call_is_online`/`call_start`
    требуют реальную группу (`topo_groups_find`), для DM (group_id==0) маршрута нет.

Рефакторинг: per-instance chat/dm (однопоточный test_dm_e2e)

[ ] BGP-гонка: дропнутый REQUEST_TABLE (отдельная задача, как договорились).

**Место:** `topo_group_new_conn()` в `src/routing_layer/topo_group.c:571`. Дедуп-ветка
«conn already in senders_list» (строки 579–587) делает `return` БЕЗ повторной отправки
`topo_group_send_table_request()`.

**Зачем дедуп:** тот же `ETCP_CONN` стреляет `ETCP_CONN_STATUS_UP` дважды (UDP-линк,
затем TCP-линк). Повторная обработка задваивает `active_conn_count`, из-за чего
переподключение не стартует. Поэтому `return` в дедупе — правильный.

**В чём гонка:** REQUEST_TABLE — это то, что заставляет пира отдать свою таблицу
(NODEINFO/узлы группы). Сценарий «разнесённого старта»:
1. A↔C соединение поднято. A шлёт C `REQUEST_TABLE` для группы G (`topo_group_new_conn`
   → `topo_group_send_table_request`, `topo_group.c:602`).
2. У C группа G ещё **не создана** (создаётся позже, по мере загрузки каналов/синка).
   C получает `REQUEST_TABLE`, но `topo_group_handle_request_table` не находит G →
   дропает запрос.
3. C наконец создаёт G (`topo_groups_create_group` → обход connections →
   `topo_group_new_conn(G, conn_A)` на стороне C) → C шлёт A свой `REQUEST_TABLE`.
   A отвечает своей таблицей → **C узнаёт A**.
4. Но A больше не шлёт C `REQUEST_TABLE` → **A так и не узнаёт C** в группе G.
Итог: при разнесённом старте A не видит C в CHAT-группе (односторонняя видимость).

**Фикс (предполагаемый):** в дедуп-ветке не просто `return`, а предварительно
идемпотентно `topo_group_send_table_request(group, conn)`:
```c
if (((struct TOPO_GROUP_CONN_ITEM*)se->data)->conn == conn) {
    topo_group_send_table_request(group, conn);   /* повторно, идемпотентно */
    DEBUG_INFO(..., "conn already in senders_list, re-request table (%s)", conn->log_name);
    return;
}
```
`topo_group_send_table_request` не ведёт состояния — просто шлёт REQUEST_TABLE,
пир отвечает снимком таблицы (идемпотентно). Лишний дубль таблицы безвреден.

**Замечание:** в однопоточном `test_dm_e2e` (и `test_chat_join_e2e`) из-за
детерминированного порядка группа успевает создаться до прихода REQUEST_TABLE —
поэтому тест проходит. Реальная гонка остаётся для асинхронных сетей. Отдельный
воспроизводимый тест для этой гонки пока не написан.

[ ] «packet undecryptable» на линках C (вторичное). A, узнав B через BGP, через topo_group_connect пытается поднять прямой A↔B линк (seskey 4777737b), но B не настроен принимать A → crypto-шум каждые ~1с. Разобраться с авто-подключением (не пытаться соединяться с узлами, для которых нет [client]/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_reconnect — флаки под параллельной нагрузкой make check -j4: phase 4 (reconnect после server restart) таймаутит (sent=480 recv=0), при одиночном запуске стабильно TEST PASSED. Наш код (chat_join/chat_sync) его не трогает.