Files
MikrotikManager/docs/ux-ui-stage-12.md
T

928 KiB
Raw Blame History

Этап 12: итоговая приёмка UX/UI

Актуальное продолжение 2026-10-12: завершён12.5.182 — атомарная проверка полного WireGuard peer-среза, без записи корректного префикса при ошибке/дубликатах. OwnSQL51/37534ms/backend build/source455+524/1040compiled/native2/browser2 passed. Backend ux-peer182 healthy, frontend ux-status181 без изменений; ownDB/role/container удалены. Следующий183 — явная диагностика optional peer endpoint failure и покрытие истории;12.5 открыта.

План: ux-ui-plan.md. Фактические результаты: ux-ui-progress.md. Подготовлен после сводных проверок 11Б; завершение каждого блока требует локального коммита без push.

Блок Проверка и результат Критерий остановки
12.1 Общая оболочка, автоматический аудит доступности, клавиатура/фокус, 320px/ПК и обе темы Исправлены доказанные нарушения, непроверенные состояния перечислены
12.2 Достоверность источников дашборда: неполный BGP, nullable counters/traffic, неверные DTO Unknown/partial не становятся zero/down/empty; last good сохраняется
12.3 Производительность больших списков и таблиц на фиксированных локальных данных Записаны размер fixture, измерения и практические ограничения
12.4 Сквозная регрессия интерфейса, права, context; production/contracts/backend builds и ReUI checklist Итоговая матрица с результатами и точными исключениями
12.5 Внешняя приёмка PG/RouterOS/Telegram/интеграций Протокол тестового окружения; локальные моки не заменяют эту проверку

Сначала воспроизвести предполагаемые проблемы общей оболочки: health popover принимает только status:ok, тогда как shared health допускает подтверждённый legacy ok:true; проверить согласованность. Проверить реальные accessible names header triggers и skip link focus. Использовать установленный axe-core для автоматической части; отсутствие violations не означает полного соответствия или замену screen reader/manual проверки.

Клавиатурный сценарий должен предоставлять эквивалент действий мышью (W3C SC 2.1.1); программные имена/роли/состояния проверяются отдельно (W3C SC 4.1.2). Проверка reflow включает 320 CSS px; широкие таблицы проверяются как отдельные области прокрутки, а не как разрешение переполнения страницы (W3C SC 1.4.10).

Внешние ограничения 11Б сохраняются: migrations0008/0009, PG isolation/CAS/rollback, реальный restore/UDP workers, RouterOS, Telegram, MaxMind/RIPE, Portal/Evolution, CI/Gitea. Processing не разрешается повторять без доказуемой остановки всех отправителей; timeout или checkbox не являются таким доказательством. BGP-prefix evaluator отсутствует и честно обозначен UI; отдельного live GRE расписания нет. Производственный выпуск не разрешён одним успешным browser/DI прогоном.

12.1 — оболочка: контраст, клавиатура и health (2026-10-03)

Подтверждённые нарушения автоматического axe-аудита исправлены на уровнях потребителей: доступный фокус main для skip link; высота toggle правила не менее24px; контраст API badge, подписей групп/Telegram и статуса backend. В открытом системном мониторе значения используют text-foreground, цвет остаётся у значка/полосы; длинная подпись переносится. Установленные ReUI/Base UI primitives и глобальная тема не изменены. Health использует shared getBackendHealth, подтверждённый legacy ok:true согласован с выбором источника; неподтверждённый ответ не становится успехом. axe-core4.11.3 закреплён прямой dev dependency.

Проверки:20 browser сценариев —12 audit комбинаций alerts/settings/releases×320/1440×light/dark,4 открытых monitor/menu, клавиатура skip/apps/monitor с возвратом фокуса, legacy health,2 неподтверждённых health; violations нет. После переноса подписи дополнительно4 открытых слоя.14 профильных layout/settings/release проверок:13 прошли сразу, release fixture встретила transient Windows file lock; исходные bytes восстановлены, ограниченный retry только при записи fixture, повтор всех3 releases прошёл. Typecheck и ESLint изменённых компонентов/тестов прошли. ReUI checklist: сохранены композиции, API props проверены по установленным исходникам; имена/роли, реальные состояния, scroll/security проверены в границах сценариев. Снимки shell-monitor-light/dark-320/1440 добавлены.

Границы: audit охватывает стабильные описанные состояния, не все модалки/формы и не ручную работу screen reader; нет заявления полного соответствия WCAG. Production build и общая регрессия предусмотрены в12.4. Далее12.2.1: строгий BGP catalog на дашборде, partial и nullable counters без подмены нулями; затем остальные источники.

Снимок ПК Телефон
Светлый монитор 1440 320
Тёмный монитор 1440 320

12.2.1 — строгая сводка BGP дашборда (2026-10-03)

Дашборд перешёл с legacy sessions на существующий /api/bgp/catalog и bgpCatalogSchema. Malformed DTO, дубликаты, conflict sessions/failures и переполнение суммы отклоняются до публикации. Failure устройства не становится отсутствием сессий: источник сообщает ошибку, последний успешный KPI/время сохранены. Nullable prefixesRx установленной сессии даёт неизвестные префиксы, неизвестный/custom state — неизвестные префиксы и число установленных сессий; успешный пустой каталог подтверждает0. Exact Established не путается с NotEstablished. ACL проверяется до/после запроса, прежняя revision защита polling сохранена.

Проверки:16 browser dashboard-data/permissions прошли (включая5 invalid/partial кейсов с unknown→success→failure/cache→recovery,2 nullable/state кейса и поздние ответы);3 unit (агрегация/строгий DTO/permission parity), typecheck и ESLint прошли. Новые fixtures содержат полный реальный DTO. ReUI checklist применён: KpiStatGrid сохранён, изменены data/copy, theme/primitives без изменений.

Далее12.2.2: проверить traffic DTO/длины серий без искусственных60 точек и нулей; затем servers/probes/overlay/Internet path. Реальная телеметрия RouterOS остаётся внешней проверкой.

12.2.2 — строгий traffic DTO и агрегация серий (2026-10-03)

Перед публикацией traffic проверяются обязательный servers, уникальные id, конечные неотрицательные rates, совпадающие длины RX/TX и общей оси всех устройств. Ошибочный/missing/null DTO сохраняет последний успешный снимок и время; других источников ошибка не затрагивает. Удалена искусственная минимальная длина60 и дописывание недостающих точек нулями. Успешный пустой каталог даёт пустую историю, существующий chart показывает её штатное пустое состояние.

Проверки:21 browser dashboard/permissions,5 unit dashboard BGP/traffic/ACL, typecheck и ESLint прошли. ReUI chart/KPI композиции сохранены. Обнаруженное ограничение: backend buildTrafficFromSamples сам возвращает0 для ненаблюдавшихся интервалов; строгий reader не может отличить их от измеренного0 без расширения API. Далее12.2.3: добавить совместимые признаки наблюдений и использовать их на dashboard; затем servers/probes/overlay/Internet path.

12.2.3 — наблюдаемость трафика от backend до дашборда (2026-10-03)

/traffic/servers добавляет совместимое observations: независимые признаки RX/TX для последнего снимка и60 временных корзин, реальный sampledAt. Старые числовые поля и default buildTrafficFromSamples сохранены; наблюдаемость opt-in для DTO серверов. Корзина считается измеренной только при валидных дельтах всех включённых интерфейсов; отсутствие, сброс, неверная дата/счётчик и переполнение не подтверждают0. Новые guards не меняют корректные дельты.

Дашборд валидирует masks/timestamp, неизвестные скорости показываются как—, в графике null/разрывы; измеренный0 видим. Legacy ответ без observations принят структурно, но измерения неизвестны с объяснением. По нескольким устройствам любой неизвестный вклад сохраняет неизвестную сумму; время измерения — самое раннее из агрегируемых снимков. Общий ReUI chart поддерживает nullable series; композиция/подписи единиц сохранены, описание отделяет историю и последний измеренный снимок. Другие потребители legacy numeric traffic продолжают прежнее поведение; расширение не является их повторной приёмкой.

Проверки:27 browser dashboard/permissions,12 traffic detail/list (периоды, ошибки, одиночные значения, измеренный0 и пропуски),6 unit BGP/traffic/ACL; backend test:traffic-rate с новыми сценариями empty/single/zero/reset/partial/all interfaces/invalid-time/overflow и совместимостью numeric DTO прошли. Frontend typecheck/lint, backend/contracts build прошли. Не запускалась общая backend suite/реальная БД. ReUI checklist применён к chart/KPI, primitives/theme сохранены.

Далее12.2.4: серверы и пробы дашборда — строгие DTO и unknown статус, затем overlay/Internet path. Реальные RouterOS измерения и внешняя приёмка остаются отдельными.

12.2.4 — строгие каталоги серверов/проб, unknown серверов (2026-10-03)

Servers использует выбранные поля serverReadSchema и строгие id/latency/sessions; probes — обязательные поля, unique id и диапазоны RTT/loss/series/status. Malformed каталоги отклоняются до публикации, сохраняется cache/время источника. Nullable статус сервера отображается как unknown, warning в очереди; offline KPI считает только явно offline, unknown/degraded перечислены отдельно, недоказанное состояние не называется исправным. Sessions обязательны как в реальном DTO; дополнительная WAN информация остаётся совместимой.

Проверки:34 dashboard/permissions browser и8 dashboard unit, typecheck/ESLint прошли. Initial failing unknown fixture был дополнен обязательным sessions реального DTO; финальный прогон34 прошёл. ReUI KPI/queue композиция сохранена, изменены только data/copy. Далее12.2.5: реальные ping наблюдения/временная ось; backend сейчас подставляет100%/down/нули при отсутствии samples, этот блок ещё не устранил такие backend подстановки. Затем overlay/Internet path.

12.2.5 — реальные ping наблюдения и разрывы RTT (2026-10-03)

/uptime/overview совместимо добавляет observations.samples и общие rangeStartAt/rangeEndAt. Сохраняет исходные числовые поля legacy клиентов; metadata содержит реальные отсортированные timestamp/RTT/loss/status без искусственных samples и ограничена концом снимка (поступление нового sample во время чтения не нарушает окно). Дашборд предпочитает наблюдения: legacy/empty становятся unknown/null, измеренный0 остаётся0, реальный down/100% остаётся ошибкой. Malformed/duplicate/unordered/out-of-window samples сохраняют cache. Source freshness показывает фактическое время, неизвестные проверки исключают утверждение «без ошибок» и дают warning/— в KPI; отсутствующий каталог источника не рисует offline.

RTT агрегируется в60 настоящих временных корзин; средний по источнику не дополняется нулями/интерполяцией. Пропуски — null; изолированная точка видима. Нечитаемый на320px SVG заменён установленной композицией ChartContainer/Recharts, как ReUI PRO chart-23 и существующий TrafficRxTxChart; Frame/OpsPanel сохранены. Скорости RX/TX вынесены из заголовка в переносимую строку, перекрытие устранено. Header таблицы «RTT · 1 ч» вместо неверных «60с».

Проверки:40 dashboard/permissions browser прошли после финального chart; дополнительно6 ping сценариев и снимки1440/320.11 unit dashboard (включая sparse axis/unknown/zero/invalid metadata), чистые backend observations assertions, typecheck/ESLint, frontend production/contracts build(34pages), backend/contracts build прошли. ReUI MCP подтвердил chart-23/Chart API; читались установленные исходники, checklist применён; primitives/theme не изменены. Другие uptime страницы продолжают legacy numeric API и этим блоком не переприняты. Реальные PG/RouterOS measurements не тестировались.

Доработка Референс Схема / локальные снимки
Читаемый RTT с пропусками Chart23 Observations → временные корзины → линии/разрывы/точки; 1440, 320
Неизвестное состояние в сводке Stats12 Snapshot → known/unknown → KPI/очередь → объект

Далее12.2.6: strict GRE/WireGuard/VXLAN и device failures на dashboard; затем Internet path и сводная приёмка12.2. Внешние ограничения сохраняются.

12.2.6 — полные каталоги GRE/WireGuard/VXLAN (2026-10-03)

Dashboard читает существующие строгие schemas GRE/VXLAN/WireGuard, требует явный результат failures (реальный backend передаёт его всегда для общего каталога), проверяет уникальность устройств/интерфейсов. Device failures/malformed/missing/duplicate не становятся успешным пустым каталогом: последний снимок соответствующего kind и время остаются, остальные источники обновляются независимо. Unknown status не переименовывается в down; допустимый VXLAN status передаётся напрямую. KPI указывает «последний успешный снимок» при неполном обновлении; очередь не утверждает исправность. Старый сервер с legacy каталогом без failures требует обновления API и получает честную ошибку, а не ложное отсутствие туннелей.

Проверки:49 dashboard/permissions browser (9 новых invalid/partial/cache/recovery cases),3 overlay unit, typecheck/ESLint прошли. Unused callback dependency удалена; installed ReUI/Frame/KPI unchanged, checklist применён. Fixtures содержат полные DTO, включая failures. Далее12.2.7: strict Internet path snapshot/fallback; отдельно устранить swallowed ошибки backend collector до сводной приёмки12.2.

12.2.7 — строгий снимок Internet path и запасные запросы (2026-10-04)

Снимок валидируется до публикации: обязательные коллекции, даты, ссылки на устройства, runtime/route для enabled home. Повреждённый сохранённый null с датой не считается отсутствием снимка. Filters stale/error, malformed speed/WAN и diagnostic error не превращаются в пустые успешные данные. После ошибки сохраняются последний снимок и время; независимые источники обновляются. Настроенный WAN без наблюдаемого default route не создаёт выдуманный маршрут/100 Mbps uplink; состояние unknown.

Проверки:56 dashboard/permissions browser (7 новых cache/recovery cases),4 unit, typecheck прошли; ESLint без ошибок, два прежних unused-helper warning в dashboard-internet-path. ReUI Frame/base-nova и общие компоненты не изменены. Backend collector пока скрывает часть RouterOS ошибок — это обязательный следующий блок12.2.8, затем проверка метрик Internet path и сводная приёмка12.2. Реальный PG/RouterOS не проверен.

12.2.8 — подтверждение полного сбора Internet path (2026-10-04)

Backend больше не скрывает ошибки обязательных GRE/routes/DHCP/address чтений пустыми массивами или null. Pure/DI граница собирает enabled homes и возвращает collectionComplete только после всех обязательных ответов. Неудачный сбор завершается до insert, существующий снимок остаётся; ошибки settings тоже освобождают collecting в finally. Malformed RouterOS rows отклоняются. Повреждённый сохранённый JSON/object даёт HTTP502 вместо успешного null.

Frontend требует collectionComplete:true: legacy сохранённые снимки не доказывают полноту и сохраняют последний подтверждённый cache/ошибку до свежего сбора. Это согласованное изменение backend/frontend, миграция/удаление данных не нужны; при выпуске обновить обе части и дождаться успешного scheduler run. Права и правила сетевых операций не изменены.

Проверки: pure/DI backend (успех, disabled home, ошибки шести readers, отсутствующий route/WAN, malformed RouterOS и stored JSON),4 frontend unit,12 path/permissions browser, frontend typecheck и backend/contracts build прошли. ESLint без ошибок; прежний unused import убран. Реальные PG insert/rollback, RouterOS API и scheduler cycle остаются внешней приёмкой. Далее12.2.9: проверить, не выдаются ли configured capacity/server RTT за измерения отдельных hops; затем сводная приёмка12.2 и12.3 производительность.

12.2.9 — метрики отдельных участков Internet path (2026-10-04)

Configured WAN maxDl/maxUl, общий RTT сервера и GRE эвристики больше не выдаются за наблюдения Home→JH/JH→Exit. Метрики берутся из профильных проб: ping требует дату и отсутствие ошибки, speed — дату/lastStatus:done/отсутствие ошибки. Legacy без metadata и неудачная проба дают неизвестное; ноль остаётся нулём; RX/TX не подменяют друг друга, при обратной пробе направления меняются. Primary и Current используют одинаковую границу подтверждения.

Active WAN выбирается только по наблюдаемому default interface/route; первый configured uplink и просто bound DHCP не доказывают выбор. Summary unknown больше не маркирует Оффлайн. Подпись поясняет, что JH/Exit — кандидаты, а default route подтверждает WAN; карта различает рекомендацию оптимизатора и наблюдаемый default route. Алгоритм сетевых операций/оптимизатора не изменён.

Проверки:61 dashboard/permissions browser, включая4 новых hop-состояния и320px,6 path unit (success/error/undated/zero/directions/unmatched WAN), typecheck и ESLint без ошибок/предупреждений в изменённых frontend файлах. Удалены прежние unused helpers/imports; ReUI Frame/Badge/StatusBadge сохранены. Далее12.3: фиксированные большие fixtures, измерения и ограничения; сводная регрессия12.4 должна включить12.2 и production build. Реальный traffic path/PG/RouterOS не проверен.

12.3.1 — ограничение DOM таблицы серверов (2026-10-04)

На фиксированном каталоге1000 ServerRead (501462 JSON bytes) прежняя таблица выводила1000 строк/41569 DOM nodes. Штатная client pagination ReUI/TanStack теперь выводит50 строк (initial page size50),2644 DOM nodes; поиск/сортировка выполняются по всему каталогу. При выбранном меньшем page size навигация остаётся доступной даже если фильтр даёт менее50 результатов. Малые каталоги при default50 сохраняют прежний вид.

Проверки:36 browser large-servers+servers (права, формы, операции, URL/filters), затем1 расширенный large-case (page size5/фильтр9 результатов/вторая страница/возврат50), typecheck/ESLint прошли. Дев-замеры одного локального Edge прогона: доready3345ms, после1058ms и1543ms; это наблюдение с разной прогретостью dev compiler, не production SLA/статистическая оценка. Полный JSON всё ещё загружается/валидируется на клиенте. ReUI MCP DataGridPagination API и checklist прочитаны; primitives/shared theme unchanged.

Следующий блок12.3.2: большие списки CompactDataGrid/статистика и явная карта оставшихся специализированных таблиц. Этап12.3 целиком ещё не принят;12.4 требует сводной browser/context проверки и production build.

12.3.2 — ограничение DOM общего CompactDataGrid (2026-10-04)

Общая компактная таблица теперь использует штатную client pagination50 строк; сохранены исходные data/columns/row callbacks и загрузка/empty/detail. Навигация сохраняется при выбранном меньшем размере. На1000 строк статистики (88894 JSON bytes массива users) DOM уменьшился12585→1210 nodes, rendered rows1000→50. Доready5195ms, после2928/1195ms в отдельных dev прогонах; прогретость отличается, production SLA не заявляется. Полный ответ и pivot columns по-прежнему находятся в памяти.

Проверки:25 statistics/migrated/catalog/snapshot browser прошли; large-case сначала ошибочно ожидал прямую кнопку последней страницы из нового upstream API, установленная версия использует группы. Тест исправлен под фактические штатные ellipsis controls, повтор1 large-case прошёл (последняя страница, назад, сортировка всего1000 набора,320px). Typecheck/ESLint прошли; ReUI API/checklist изучены, установленный primitive не переписан.

Не считать12.3 завершённым:28 специализированных grids используют manualPagination:true и требуют раздельного разбора (часть получает server page/limit). Скрытые строки AttentionRows тоже всё ещё создаются в DOM. Далее12.3.3: управляемое раскрытие большой очереди проблем, затем профильный разбор специализированных grids/ограничений и12.4 регрессия/build.

12.3.3 — DOM очереди проблем дашборда (2026-10-04)

AttentionRows больше не создаёт весь скрытый список: первые5 всегда видны, native details монтирует следующие50 по запросу, кнопка добавляет по50. Закрытие удаляет скрытые строки и сбрасывает порцию; полный счётчик/ссылки сохраняются. Нет скрытых1000 anchors до действия пользователя. Раскрытие выполняется обычным summary и клавиатурой, используется существующий Button; Frame/AttentionQueue primitives unchanged.

Проверки:62 dashboard/permissions browser (включая1000 проблем: DOM5→55→105→5→55, переход к серверу,320px),20 dashboard unit, typecheck/ESLint прошли. На fixture1000 offline servers начальный dashboard:831 DOM nodes,1081ms ready в одном dev прогоне. Порционное раскрытие может по запросу пользователя постепенно создать весь список; полноценная виртуализация очереди не заявляется.

Далее12.3.4: большой каталог BGP, учитывая сохранение страницы при фоновом обновлении. Другие27 специализированных manualPagination grids и wide pivot остаются отдельными ограничениями.12.4 сводные проверки/production build ещё не приняты; внешняя приёмка не заменяется локальными данными.

12.3.4 — большой каталог BGP и контекст страницы (2026-10-04)

BGP использует штатную client pagination50. При обновлении того же каталога страница сохраняется (autoResetPageIndex:false); при уменьшении результатов индекс ограничивается последней существующей страницей. Сессия из URL открывает соответствующую страницу по pre-paginated row model; изменение сортировки/page size пересчитывает её положение. Client фильтры/сортировка и раскрытие работают по всем данным, права/сетевые операции неизменны.

На фиксированных1000 сессиях DOM25657→1932 nodes, rendered1000→50. Единичные dev ready до2990ms/после898ms не являются production SLA.13 BGP/routing/link/large browser, typecheck/ESLint прошли, включая обновление на странице2, поиск последней сессии, URL последней страницы/детали и320px. ReUI DataGridPagination повторно использован; upstream API и установленная групповая навигация различаются, primitive не менялся.

Доработка Референс Схема
Серверы/CompactDataGrid/BGP Data Grid Filtering2 Полный каталог → поиск/сортировка → страница50 → детали
Большая очередь проблем List9 Полный счётчик → первые5 → раскрыть50 → добавить50 → объект
flowchart LR
  A["1000 строк API"] --> B["Проверка DTO и фильтры"]
  B --> C["ReUI/TanStack: 50 строк в DOM"]
  C --> D["Страница и детали сессии"]
  D --> E["Обновление сохраняет страницу"]

Этап12.3 ещё в работе: остальные27 manualPagination grids/широкие pivot не проверены на1000 строк. Следующий шаг: production build накопленных изменений, профильная регрессия переходов дашборда; затем12.3.5 остальные grids, отдельно Firewall порядок/drag и server-paged traffic без слепой client миграции. Итоговая12.4 и внешняя12.5 не приняты.

Промежуточная регрессия12.2–12.3 (2026-10-04)

Frontend production/contracts build на3978976 прошёл:34 страницы.123 browser после build прошли:20 accessibility shell, GRE/WireGuard/VXLAN/uptime links и операции/права/ошибки,3 больших каталога. Штатные fixtures теперь содержат sessions/failures, BGP catalog, collectionComplete и реальные ping observations; speed fixtures имеют полный nullable metadata. Не ослаблялась проверка DTO ради тестов. Regenerated monitor screenshots восстановлены до прежних проверенных bytes, случайные визуальные diff не включены.

Измерения и точный список27 оставшихся manualPagination grids сохранены в ux-ui-performance.md; это карта последующей приёмки, не объявление всех таблиц исправными. Typecheck/ESLint fixtures прошли.20 dashboard unit и backend pure/DI подтверждены предыдущими блоками; реальные PG/RouterOS не запускались.12.3/12.4/12.5 ещё в работе.

Далее12.3.5: проверка сохранения страницы общего CompactDataGrid при повторном dashboard polling (100 проб), затем uptime ресурсы/speed/schedule большие fixtures. Build должен быть повторён после новых изменений общей основы.

12.2.10 — обязательные поля объектов RouterOS (2026-10-04)

Сборщик Internet path проверяет не только array/string record, но и обязательные поля конкретного источника: route dst-address, DHCP interface, IP address/interface, GRE .id/name/local-address/remote-address. Строковый error record или пустой объект больше не проходят как подтверждённая сущность/пустая маршрутизация/синтетический GRE. Настоящий пустой массив остаётся допустимым; auto local-address0.0.0.0 сохраняется.

Pure/DI профиль дополнен malformed entity/error record/valid empty/valid route/valid GRE; профиль, ESLint и backend/contracts build прошли. Сетевые операции не изменены, живой RouterOS не проверен. Далее завершить12.3.5:89 browser уже прошли после сохранения страницы CompactDataGrid, требуется повторный frontend production build и локальная фиксация этого блока.

12.3.5 — сохранение страницы CompactDataGrid при опросе (2026-10-04)

На100 активных пробах воспроизведено: после получения нового DTO страница2 сбрасывалась на1. Общий CompactDataGrid теперь отключает autoResetPageIndex и ограничивает индекс последней существующей страницей только при сокращении набора. Одинаковый каталог с новыми измерениями сохраняет контекст;100→1 не оставляет пустую страницу. Штатные pagination/filter/sort компоненты сохранены.

Проверки:89 browser dashboard/permissions/large-statistics/statistics/migrated/snapshot прошли, включая воспроизведённый regression и сокращение100→1. Typecheck/ESLint прошли. Повторный frontend production/contracts build после изменения общей основы прошёл:34 страницы; backend/contracts build также прошёл после12.2.10. ReUI validate_usage ok для DataGrid table/recordCount/isLoading/tableLayout/i18n и Frame dense; checklist применён. Предыдущая123 browser приёмка остаётся профильным checkpoint до этого изменения, не общей12.4.

Далее12.3.6: фиксированные1000 ресурсов uptime/1000 speed probes/1000 schedule entries; измерить DOM, проверить URL/детали, pagination/polling/уменьшение набора и права. Использовать карту производительности для остальных27 specialized grids; Firewall порядок/drag и traffic server page требуют отдельной проверки. Затем12.4 полный browser/context прогон и итоговая матрица,12.5 реальные PG/RouterOS/интеграции. Этап12 пока не завершён. Все изменения сохраняются локально, push не выполнялся.

12.3.6 — исходный замер1000 speed probes (2026-10-04)

Штатная fixture collector-probes обновлена под numeric device IDs и каталог имён; старая использовала названия вместо ID, строгий reader правильно отклонял её. Новый large-case измерил1000 строк/23590 DOM nodes,3741ms ready в одном dev прогоне.4 browser профиля (12 speed/sort,11 scheduler jobs/run, demo schedule,1000 speed baseline) и ESLint прошли. Это исходный замер, ограничение DOM speed grid ещё НЕ реализовано; production UI этим блоком не изменён.

Следующий шаг12.3.7: probes-speed-probes-data-grid client pagination/сохранение страницы и URL/операции на1000 пробах; затем1000 uptime resources и расписаний, остальные27 grids из ux-ui-performance.md.12.3/12.4/12.5 не завершены. Последние production frontend/contracts и backend builds прошли в12.3.5/12.2.10. Локальные коммиты, без push.

12.3.7 — пагинация большого списка speed-проб (2026-10-04)

ProbesSpeedProbesDataGrid использует штатную ReUI client pagination по50 строк; обновление сохраняет страницу, сокращение набора ограничивает индекс. Сортировка работает по всему набору. Проверено1000→1, последняя страница20 и320px; небольшой список12 записей и демо-расписание сохраняют поведение.

4 browser collector-probes прошли.1000 строк дают50 rendered rows/739 узлов внутри секции speed-проб,11265 DOM nodes всей страницы,2310ms ready в одном dev прогоне против baseline23590 nodes/3741ms. Каталог1001 устройства в ServerTileRail остаётся полностью в DOM: общая производительность страницы ещё не принята. Полные DTO остаются в памяти; API и правила сетевых операций не менялись. Следующий блок12.3.8:1000 uptime resources; затем каталог устройств/расписания и остальные grids.12.4/12.5 не завершены.

12.3.8 — большой список ресурсов мониторинга (2026-10-04)

UptimeResourcesDataGrid использует ReUI client pagination по50 строк с сохранением страницы при обновлении и ограничением индекса при уменьшении набора. DataGridShell исправлен: pagination выводится также при собственных children/ScrollArea; раньше такой потребитель не получал панель страниц. Установленные primitives и тема сохранены.

1000 ресурсов: baseline1000 строк/38655 DOM nodes/4328ms dev; после50 строк/2580 nodes/1578ms. Проверены глобальная сортировка, страница20, поиск записи1000/URL/reload, обновление страницы2,1000→1,320px и отсутствие POST при чтении по ссылке.8 browser больших таблиц/collector-probes прошли после исправления оболочки;52 прежних uptime links сценария прошли. Первый large-case воспроизвёл отсутствие pagination при children; финальный прогон прошёл. Typecheck/ESLint, frontend production/contracts build (34 страницы), ReUI validate_usage/checklist прошли.

Полные ресурсы остаются в памяти. Этот fixture использует CPU10%, список1000 предупреждений ресурсов ещё не проверен; ServerTileRail остаётся следующим отдельным потребителем. Далее12.3.9: большой список предупреждений ресурсов, затем каталог устройств/расписания и специализированные grids.12.4/12.5 не завершены, реальная PG/RouterOS нагрузка не проверена. Локальный коммит, без push.

12.3.9 — порционный список предупреждений ресурсов (2026-10-04)

Список1000 серверов с CPU90% воспроизведён через обычный uptime overview:2009 warning nodes/4739 nodes страницы. ResourceWarnings применяет существующий шаблон AttentionRows:5 начальных записей,55 после раскрытия,105 после кнопки,5 после закрытия,55 при повторном раскрытии. Счётчик1000 остаётся полным, причины предупреждений и пороги не менялись. Начальная секция21 nodes, вся страница2751 nodes; таблица50 строк.

9 browser ресурсов/URL/reload/320–1440px и отдельный large-case с WCAG-tagged axe audit предупреждений прошли; Enter/summary и порционное раскрытие проверены. Typecheck прошёл. Полный ESLint uptime page имеет исходную ошибку react-hooks/set-state-in-effect в setSpeedDraft после загрузки интерфейсов (подтверждена на HEAD2762f07),6 исходных unused warnings; с временным отключением этого правила остальные правила не дают ошибок. Это ограничение проверки, правило в файле не отключалось. Последний production build —12.3.8, после ResourceWarnings не повторялся.

Следующий шаг12.3.10: устранить исходную ошибку синхронизации speedDraft с доступными интерфейсами, проверить формы и production build; затем ServerTileRail на1000 устройствах и оставшиеся25 grids. Демо GRE schedule хранится только в React state, live отдельного расписания нет:1000 entries пока не проверены.12.4/12.5 не завершены; локальная приёмка не доказывает реальные PG/RouterOS операции. Без push.

12.3.10 — синхронизация интерфейсов формы speed-проб (2026-10-04)

Исходный set-state-in-effect устранён: недоступный интерфейс очищается при получении списка endpoint и при повторном открытии формы с кэшем. Проверка относится только к совпадающему src/dst serverId; активный интерфейс сохраняется. Effect с синхронным setSpeedDraft удалён, правило ESLint не отключалось. Права и подтверждение сохранения API сохранены.

54 browser uptime links прошли, включая2 новых сценария active=false/true с холодной загрузкой и повторным открытием/проверкой PUT. Typecheck и полный ESLint изменённой страницы/тестов прошли без ошибок (6 исходных unused warnings). Повторный frontend production/contracts build прошёл:34 страницы; включает ResourceWarnings12.3.9. Живые интерфейсы RouterOS не проверены.

Следующий блок12.3.11: ограничение DOM ServerTileRail на1000 устройствах с поиском по всему каталогу, выбранным сервером из URL, клавиатурой и мобильным Sheet. Затем оставшиеся25 grids: scheduler ограничен11 job keys, speed history backend limit200, остальные требуют проверки потребителя/API.12.4/12.5 не завершены. Коммит локальный, без push.

12.3.11 — ограничение DOM бокового каталога устройств (2026-10-04)

ServerTileRail сохраняет существующую композицию Frame/Item/List9, а страницы управляются штатными TanStack v9/DataGridPagination. До50 устройств в DOM, поиск по полному каталогу, группировка по площадкам и выбор из URL сохранены. Home/End/стрелки открывают страницу выбранного устройства; ручное перелистывание не меняет URL и сохраняется при повторном получении каталога. Эффект выбора использует стабильный setPageIndex: объект useTable в v9 меняется при рендере и иначе возвращал страницу назад. ID карточек уникальны для desktop/mobile, активный descendant указывается только для смонтированной карточки своего списка.

1000 speed probes/1001 устройства: вся страница11265→1778 DOM nodes,50 строк speed grid/739 nodes секции; dev ready1016ms в одном прогоне. Rail<=50 устройств,<=1200 nodes; открытый Sheet также ограничен50. Проверены последняя страница/URL, Home/End/ArrowDown, поиск записи1000, refresh страницы2, граница двух площадок,320px/возврат фокуса. На снимке исправлены растущий footer и длинное многоточие. Axe выявил контраст EN: ServerTypeBadge теперь text-foreground с прежним цветным фоном. Повторный WCAG-tagged audit mobile обеих тем прошёл; снимки просмотрены.

47 browser BGP/диагностика/collector-probes прошли после финальной правки, Typecheck/ESLint и frontend production/contracts build(34 страницы) прошли. ReUI validate_usage/checklist применены; primitives/theme не изменены. Полный список остаётся в памяти; это pagination, не серверная выборка/виртуализация. Общая регрессия ещё не завершена: main config содержит1091 тест в163 файлах.

Следующий блок12.3.12: проверить тот же эффект зависимости от объекта table в BGP при выбранной сессии из URL и ручном переходе страницы. Затем общая регрессия12.4 по группам и оставшиеся25 специализированных grids;12.5 внешняя PG/RouterOS приёмка отдельно. Без push.

12.3.12 — ручная страница BGP при выборе сессии из URL (2026-10-04)

Воспроизведён возврат со страницы19 на20 после ручного Previous при selectedSessionId из URL. Эффект BGP больше не зависит от меняющегося объекта useTable: используются стабильный setPageIndex и вычисленный индекс выбранной сессии. Глобальная сортировка и первичное восстановление выбранной сессии сохранены; ручная страница19 сохраняется при refresh, reload восстанавливает linked session на20.

16 browser BGP/data/links/1000 sessions прошли после исправления; Typecheck/ESLint и frontend production/contracts build(34 страницы) прошли. Метрики BGP50 строк/1932 nodes остаются. Реальный BGP/RouterOS не проверен.

Следующий шаг12.4.1: общий main browser прогон (1091 тест в163 файлах) с JSON отчётом; ограничить ранние падения20, затем разобрать причины и профильные повторы. Это проверка после изменения общей основы;12.3 ещё имеет25 specialized grids и широкую pivot для проверки. После main — context конфигурации и итоговая матрица;12.5 внешняя приёмка отдельно. Без push.

12.4.1 — общая регрессия и актуальные fixtures (2026-10-04)

Main Playwright/Edge на c4110fa:1091 сценарий в163 файлах,1088 passed/3 failed/0 skipped/0 flaky,24.9 минуты,workers1/retries0. Все три падения воспроизведены как устаревшие fixtures: admin-tables обслуживал legacy /api/certificates вместо /api/certificates/state; Filters ожидал демо Community, не предоставляя подтверждённый Evolution catalog. Fixtures обновлены по strict schemas; keyboard/SAN/sort/write assertions сохранены. Повтор обоих файлов:6 passed. Полный прогон после fixtures не повторялся: production код не менялся; это1088 успешных сценариев общей регрессии плюс исправленные3 в профильном повторе, а не новый единый1091/1091 прогон.

Typecheck и ESLint двух изменённых файлов прошли. Production/contracts build34 страницы ранее прошёл на том же production HEAD c4110fa. Исходный отчёт сохранён в main-regression-2026-10-04.json, новые просмотренные снимки rail320px — в docs/ux-ui/screens/large-server-rail-dark-320.png и large-server-rail-light-320.png. Перегенерированные исторические screenshots восстановлены; чужие изменения не включены. Карта производительности уточнена по фактическим backend caps (scheduler11/flows50/speed history200/pivot51×16 с Other); большие browser профили оставшихся25 grids и pivot ещё требуются.

Следующий блок12.4.2: единый последовательный context прогон23 исключённых файлов с backend URL local, затем backend-switch. После context — оставшиеся границы производительности12.3 и матрица builds/checklist.12.5 реальная PG/RouterOS/интеграционная приёмка отдельно. Локальный коммит, без push.

12.4.2 — context-регрессия и чистые проверки источников (2026-10-04)

Новая playwright.ux-context.config.ts переиспользует основной список23 testIgnore как testMatch, добавляет backend-switch.e2e.ts и запускает24 файла последовательно на3101 с NEXT_PUBLIC_BACKEND_URL=local. Индивидуальные конфигурации сохранены.205 passed/0 failed/0 skipped/0 flaky,7.0 минут,Edge/workers1/retries0. Проверены поздние чтения/записи при backend/demo/ABA, scoped unknown checkpoints, health, фоновые jobs/экспорт и смена контекста сетевых объектов. Отчёт: context-regression-2026-10-04.json.

28 unit-проверок прошли:8 lib dashboard/Evolution профилей и4 чистых/DI backend профиля traffic-rate/BGP parser/OSPF values/Internet path snapshot. Реальная БД, migrations и сетевое применение не запускались. Typecheck и ESLint новой конфигурации прошли. Production код с момента c4110fa не менялся; frontend/contracts build34 страницы на нём принят.12.4 ещё требует итоговой матрицы и backend build;12.3 — оставшихся специализированных границ. Внешние ограничения12.5 остаются.

Следующий блок12.3.13: browser профиль широкой pivot51×16 (50/15 cap + Other), глобальная сортировка/последняя страница/refresh/320px/переход к двум измерениям и возврат. Затем speed history200 и probes-schedule по фактическому API. Коммит локальный, без push.

12.3.13 — широкая pivot и доступные действия ячеек (2026-10-04)

Профиль фактического backend cap51×16 (50 строк/15 колонок плюс Other) воспроизвёл отсутствие горизонтальной области прокрутки. CompactDataGrid получает отдельную horizontalScroll опцию со штатными DataGridContainer/DataGridScrollArea/DataGridTable; включена только у StatisticsPivotGrid. Pagination остаётся за пределами ScrollArea через DataGridShell. Primitive/theme не менялись. Агрегаты Other теперь текст, не кнопки без действия; имя обычной кнопки содержит оба измерения, значение и действие.

Fixture17311 JSON bytes,50 строк в DOM; после исправления2574 nodes/1017ms dev ready на1440 и2313/762ms на320. Это единичные dev наблюдения, не SLA. Проверены page2 с Other, сортировка всего51-row набора, scrollLeft до крайних колонок, отсутствие page overflow, Enter→userId50/service15, подтверждённый GET с двумя параметрами, Back/reload, отсутствие POST. В отчёте нет обещания сохранения page при refresh: отдельного refresh у статистики нет, reload восстанавливает URL и начальную страницу.

24 browser statistics/large/migrated-tables прошли; финальные2 pivot повторены после типизации injected axe. Tagged WCAG axe области grid прошёл на320/1440; снимки просмотрены. Typecheck/ESLint и production frontend/contracts34 страницы/backend build прошли. Main/context отчёты12.4.1/12.4.2 относятся к предыдущему production HEAD; эта локальная delta проверена профильными24+2, общая регрессия после неё не повторялась.

Следующий блок12.3.14: проверить200 speed-test history по реальному backend cap, ограничить строки DOM и сохранить сортировку/страницы/320px. Затем probes-schedule и оставшиеся специализированные grids;12.4 итоговая матрица/12.5 внешняя приёмка ещё не завершены. Локальный коммит без push.

12.3.14 — история200 speed-test запусков (2026-10-04)

История GET runs имеет backend limit200. Baseline200 rows/7583 DOM nodes/1339ms dev ready на fixture73075 JSON bytes. Штатная client pagination50, autoResetPageIndex=false и clamp при сокращении дают50 rows/2361 nodes/1271ms в финальном прогоне. ReUI ScrollArea открывает крайние колонки на320px, footer остаётся вне области прокрутки. Правила запуска сетевых операций не менялись.

Проверены page4 с первой записью, глобальная числовая сортировка TX, refresh на page2 без сброса,200→1/clamp, scroll/reflow320, tagged axe grid и отсутствие POST при refresh Speed.54 existing uptime browser прошли; новый профиль первоначально использовал неверное имя refresh («Обновить данные» вместо «Обновить»), после исправления прошёл полностью. Typecheck/ESLint и production frontend/contracts build34 страницы прошли. Снимок просмотрен. Повтор полного main/context после этой delta не выполнялся; отчёты12.4 сохраняют границы HEAD.

Статический аудит следующего grid: ProbesScheduleDataGrid используется только в demo ScheduleTab (INIT_RULES3), live использует уже ограниченный ProbesSpeedProbesDataGrid. Следующий блок12.3.15 — проверить1000 speed probes непосредственно в live расписании диагностики, refresh/error cache/уменьшение; не создавать вымышленное live GRE расписание. Затем admin/network grids. Отдельное ограничение достоверности истории: reloadSpeedData очищает обе коллекции при отказе одного GET, backend legacy rates использует null→0. Эта приёмка ограничивает DOM, не принимает указанное поведение данных; оно требует отдельного fullstack блока после профилей. Локальный коммит, без push.

12.3.15 — live расписание1000 и отказ на последней странице (2026-10-04)

Уточнён consumer: ProbesScheduleDataGrid только demo/INIT_RULES3; live /probes использует ProbesSpeedSchedule→ProbesSpeedProbesDataGrid, уже принятый на1000 в12.3.7. Существующий большой профиль усилен проверкой503 на page20:50 строк и951–1000 из1000 остаются, полученное время не обновляется, отображается последний успешный список. Recovery1000→1 очищает ошибку и clamp страницы, POST не отправляется. Не добавлялось вымышленное live GRE расписание.

15 browser collector-probes/probes-schedule прошли: включает initial unknown/malformed/timeout/permissions/320px, demo device/tunnel selection и Rail1001 обе темы/границу площадок.1000 live rows:50 DOM rows/739 nodes секции/1778 page nodes/938ms dev ready. Typecheck и ESLint теста прошли. Production код не менялся с e5cf057; build34 страницы принят в предыдущем блоке. Исторические generated screenshots восстановлены.

Следующий блок12.3.16:certificates1000 через strict per-device state, pagination/поиск всего каталога/числовая сортировка/детали/refresh/уменьшение/320px. Далее users/backups/network grids; отдельная достоверность speed history остаётся в12.3.14.12.4 итоговая матрица и12.5 внешняя приёмка не завершены. Локальный коммит без push.

12.3.16 — каталог1000 сертификатов и refresh деталей (2026-10-04)

Fixture strict per-device certificatesStateSchema,1000 сертификатов одного устройства/329034 JSON bytes. Baseline1000 rows/29666 DOM nodes/2689ms dev ready; после client pagination50 и горизонтального ReUI ScrollArea:50 rows/2145 nodes/1098ms. autoResetPageIndex=false/clamp сохраняют страницу и корректно сокращают1000→1. Воспроизведено закрытие SAN при refresh: autoResetExpanded=false сохраняет детали по стабильному составному ID устройства/RouterOS.

Проверены page20/Enter/SAN, refresh страницы и раскрытия, поиск записи1000 по полному каталогу с URL/server/reload, глобальная числовая сортировка срока, ScrollArea/reflow320, tagged axe grid, сокращение и отсутствие POST. После последней production правки19 из20 browser прошли; narrow layout прерван разовой UNKNOWN open PNG ошибкой Windows. Повтор всех3 layout прошёл без изменения UI. Typecheck/ESLint и production frontend/contracts build34 страницы прошли. Снимок просмотрен; из-за горизонтальной прокрутки имя строки уходит из видимой области — следующий UX блок сохраняет идентификацию строк.

Следующий блок12.3.17: штатное закрепление колонки имени сертификата и измерения pivot при horizontal scroll, проверить доступ к остальным ячейкам на320px/ПК. Затем users/backups/network grids. Осталось23 manualPagination:true файла, включая demo-only и bounded источники; это не23 доказанных дефекта. Достоверность speed history, итоговая матрица12.4 и внешняя приёмка12.5 остаются. Коммит локальный, без push.

12.3.17 — идентификатор строки при горизонтальной прокрутке (2026-10-04)

Имя сертификата и измерение pivot закреплены штатным TanStack columnPinning/start и ReUI columnsPinnable. CompactDataGrid получает optional pinnedColumnId и размеры колонок; default consumers сохраняют прежний режим. Мобильные размеры проверены по реальным bounding boxes: имя160/status120 для сертификатов, измерение140/метрики и итог110 для pivot. Ранние180/150 ширины перекрывали часть значения на320px; финальные размеры устраняют это. Дублирующий status icon в имени сертификата скрыт только на телефоне, полное имя остаётся в title/details.

Scoped scroll-padding-inline-start на viewport обеспечивает видимость кнопки ячейки при keyboard focus возле закреплённого измерения. Проверены полностью видимые статус/итог/действие вне pinned области, границы имени, Enter→двойной срез,320/1440/axe/sort/search/refresh/expanded/1000→1.29 browser в7 файлах прошли после финальной правки. Typecheck/ESLint и production frontend/contracts34 страницы прошли. Снимки сертификатов/pivot/history обновлены и просмотрены. Повторяющаяся UNKNOWN open historical PNG в certificate-layout устранена использованием штатного info.outputPath: текущие layout артефакты отдельно от сохранённых исторических снимков, assertions не ослаблялись.

Следующий блок12.3.18:users1000 через strict API, пагинация/весь поиск/refresh деталей/ошибка и восстановление/правильный пользователь в действии/320px. Затем backups/network grids; достоверность history из12.3.14 и финальная матрица12.4 остаются. Полный main/context после delta ещё не повторён;12.5 внешняя приёмка отдельно. Локальный коммит без push.

12.3.18 — каталог пользователей1000 и поиск по всему списку (2026-10-04)

Strict appUserReadSchema fixture1000/263680 JSON bytes. Baseline1000 строк/37505 DOM nodes/2174ms dev ready; после client pagination50:50 строк/2393 nodes/921ms. Поиск по имени, логину и email добавлен через общую DataPageToolbar, фильтрует весь каталог. KPI и данные формы остаются полными; поиск локальный, без URL persistence. Stable ID/autoResetPageIndex=false/autoResetExpanded=false и clamp сохраняют страницу и детали при refresh/503 и корректно сокращают1000→1.

Штатные ReUI ScrollArea и pinning имени180/actions106 обеспечивают полностью видимые действия на320px; декоративный avatar скрыт на телефоне. Проверены page20, клавиатура/детали, ошибка и recovery, глобальные поиск и сортировка, правильный пользователь в форме после sort, возврат focus, отсутствие POST, reflow и tagged axe.32 browser users-data/layout/operations/large-users прошли; TypeScript и ESLint без ошибок. Мобильный снимок просмотрен. Production build прошёл:34 страницы и contracts.

Следующий блок12.3.19: backups1000, проверка фактического источника/пагинации/поиска/refresh/действий/320px. Осталось22 manualPagination:true файла, включая ограниченные и demo источники. Достоверность speed history и финальная матрица12.4 остаются; внешняя приёмка12.5 отдельно. Коммит локальный, без push.

12.3.19 — резервные копии1000 и возврат фокуса (2026-10-04)

GET /backups/listBackups возвращает весь каталог без DB cap. Fixture1000 проходит backupItemDtoSchema,171812 JSON bytes. Baseline1000 rows/43580 DOM nodes/2626ms dev ready; финально50 rows/2462 nodes/898ms. Client pagination50/autoResetPageIndex=false/clamp, полный search/Filters до pagination, штатный ReUI horizontal ScrollArea и pinning filename. Проверены page20/refresh/503 cache/recovery, весь поиск с URL/reload, числовая глобальная сортировка,1000→1, отсутствие запросов записи,320px и tagged axe.

На телефоне действия постоянно видимы и имеют явный минимум44px; rem-based size-11 при root font-size проекта давал около40px. Имя110/actions176 сохраняют видимость всех трёх кнопок в реальном viewport266px внутри Frame. Декоративная иконка хранения удалена из имени: статус остаётся в отдельной колонке. Воспроизведена потеря focus после отмены: cell renderer remount менял элемент. Штатный finalFocus разрешает тот же стабильный row/action, при удалении строки fallback на Обновить; проверены оба диалога и правильный filename после sort.

После финального production кода39 из40 browser прошли, narrow layout прерван Windows UNKNOWN open historical PNG. Backups layout и dialog layout теперь пишут info.outputPath, assertions сохранены; повтор layout+large4 passed. TypeScript/ESLint и production contracts/frontend34 страницы прошли. Мобильный снимок просмотрен. Осталось21 manualPagination:true файла; это не21 доказанный дефект. Следующий блок12.3.20: строгая достоверность speed history и независимые состояния чтения, затем network grids/финальная матрица12.4;12.5 внешняя приёмка отдельно. Коммит локальный, без push.

12.3.20 — независимое чтение speed-проб и истории (2026-10-04)

Promise.all с общей очисткой заменён независимыми обработчиками каждого GET: готовый ресурс появляется без ожидания второго, при API/malformed array ошибке прежний список и receivedAt сохраняются. На speed вкладке видны freshness и отдельные ReUI warning alerts. Первоначально неизвестный список не выдаётся за пустой: нет ложного Нет speed-проб, KPI показывают —. Revision/context/write guards исключают поздние ответы прежнего чтения.

58 из59 browser uptime-links/large-history/new-data прошли; первоначальный race fixture задерживал только первый GET, а StrictMode запускает две initial волны. Исправлено задержкой всей старой волны и ожиданием реально полученного позднего ответа; все4 новых browser прошли. Проверены оба initial failures, partial success,503/malformed/cache/freshness/recovery и late response. TypeScript/ESLint без ошибок (9 исходных предупреждений uptime страницы), production contracts/frontend34 страницы прошли. DOM history200 остаётся50 rows/2343 nodes в этом dev профиле.

Это приёмка состояний чтения, а не полного DTO: legacy backend null→0 и fallback status/protocol остаются. Следующий блок12.3.21: общий строгий контракт speed history, сохранение null rates от DB до grid/KPI, pure mapper/unit и browser неизвестных/ошибочных значений. Затем большие network grids и итоговая матрица12.4; внешний12.5 отдельно. Коммит локальный без push.

12.3.21 — строгая история скорости от DB до UI (2026-10-04)

Общий speedHistoryResponseSchema в contracts проверяет обязательные rates, finite/nonnegative или null, enums status/protocol/direction, duration/date/server IDs и уникальность run IDs. Pure mapSpeedHistoryRun сохраняет null rates и реальные нули; PostgreSQL timestamp нормализуется в ISO без изменения времени. Backend больше не подменяет неизвестные поля status=done/protocol=tcp/direction=both/duration=10/rate=0: некорректная запись возвращает502 с понятным сообщением. DB cap200 сохранён, миграция БД не требуется.

Frontend safeParse отклоняет invalid/duplicate данные и сохраняет последний успешный список/receivedAt по12.3.20. History grid показывает Неизвестно для null, sortUndefined=last; KPI maximum использует только известные rates. Связанная карточка speed-пробы не подставляет прежние999 Мбит/с вместо null нового результата и не объявляет done только по timestamp. Подтверждённый0 остаётся0. Контракт rates теперь number|null: backend/frontend должны обновляться вместе; сетевые write/start операции не менялись.

60 browser uptime-links/history200/speed-data прошли после финальной production правки; ещё5 speed-data после добавления320px/no overflow/снимка прошли.4 pure mapper/schema tests без PG прошли; typecheck/ESLint без ошибок (9 прежних предупреждений uptime), backend build и production frontend/contracts34 страницы прошли. Мобильный снимок просмотрен. Реальное чтение PG/RouterOS не проверялось. Большая history200:50 rows/2367 DOM nodes/1150ms dev ready, не SLA.

Следующий короткий блок12.4.3: delta context users/backups после их pagination/search/focus изменений, зафиксировать проверенный HEAD. Затем12.3.22: строгий speed-probes DTO и смена источника данных; независимые read states не заменяют эту проверку. Далее network grids и итоговая общая матрица12.4. Полный main/context после последних delta ещё не повторялся;12.5 внешняя приёмка отдельно. Коммит локальный без push.

12.4.3 — context delta последних admin изменений (2026-10-04)

На a558412 выполнены backups-context и users-context через общий playwright.ux-context.config.ts:36 passed/0 failed/skipped/flaky, Edge/3101/workers1/retries0, наблюдаемые1.4m. Проверены поздние reads при backend/mode switch, schedule/storage writes, create/job poll, delete/restore/download, создание/удаление пользователя. HTTP ответы подставные, реальных внешних операций не было. Отчёт: docs/ux-ui/acceptance/context-delta-2026-10-04.json.

Текущий main inventory по --list:1102 теста/169 файлов. Это перечень, не1102 passed. Ранее main1091 дал1088 passed и3 устаревших fixtures, после исправлений6 профильных прошли; полный context205 прошёл на прежнем HEAD. Последние production delta приняты профильными проверками и builds, полная повторная main/context регрессия остаётся в12.4. Stage12 не закрыт.

Следующий шаг12.3.22: strict speed-probes DTO и speed state при смене backend/mode, включая неизвестный каталог перед записью. Затем оставшиеся большие network grids, общая матрица и12.5 внешняя PG/RouterOS/integration приёмка. Текущий блок записан локальным коммитом без push; посторонние изменения skills/AGENTS/tsbuildinfo сохранены. Остаток квоты около3% перед записью журнала.

12.3.22 — общий каталог speed-проб и изоляция источника (2026-10-04)

Схема из probe-schedule-response перенесена в contracts: shared speedProbeReadSchema/speedProbesResponseSchema проверяют enums/duration/boolean/server IDs/уникальность ID и nullable observed values. Uptime и live schedule используют один контракт; ping-after-BT поля сохраняются, optional legacy отсутствие остаётся неизвестным. Pure backend mapSpeedProbeRead сохраняет null/0/false, нормализует DB timestamps; недостоверная запись возвращает502 вместо protocol/direction/duration/enabled fallback.

UptimeRoute keyed по probe ID/mode/backendUrl: каталог, история, freshness, интерфейсы и формы относятся к своему источнику. UI create/toggle/edit/delete/start и bulk writer защищены speedCatalogReady; первоначальная неизвестность и malformed refresh не допускают полной замены неподтверждённого списка. Cached строки и receivedAt сохранены; warning объясняет, что нужно успешно обновить данные. Навигационный счётчик unknown показывает —, переключатель получил доступное имя.

60 browser uptime и6 после финальной copy/a11y правки прошли;8 новых context scenarios backend/mode × probes/history × success/error прошли. Второй consumer/diagnostics/schedule/history47 browser прошли, включая1000 probes и1001 rail. Unit mapper3 + shared reader2 прошли без PG. Typecheck/ESLint без ошибок (9 прежних uptime warnings), backend build и frontend/contracts production34 страницы прошли; ReUI checklist и scoped axe error alert пройдены,320px снимок просмотрен. Context файл включён в агрегированную отдельную конфигурацию. Коммит локальный без push.

Следующий блок12.3.23: строгий PUT speed-probes до DB mutation, отказ без удаления malformed строк и транзакционная полная замена. Текущий backend PUT всё ещё имеет permissive normalize/filter и последовательные mutations; защита UI не заменяет серверную проверку. Затем network grids/полная main/context матрица12.4;12.5 реальная PG/RouterOS/integration приёмка отдельно.

12.3.23 — атомарная запись speed-проб (2026-10-04)

Общий write DTO требует явный probes массив, уникальные ID, безопасные положительные ID устройств, разные источник/назначение, целую длительность от3 секунд, protocol/direction/enabled. Missing/null/malformed каталог отклоняется400 целиком до обращения к хранилищу; явный probes:[] сохраняет намеренное удаление последней записи. Измерения из запроса исключены и не перезаписывают подтверждённые наблюдения.

Backend заменяет каталог в одной Drizzle transaction с pg_advisory_xact_lock для полной замены из разных процессов. Upsert обновляет только конфигурацию и порядок, timestamp создания сохранён. Ошибка refreshScheduler после commit возвращает ok:true с отдельным предупреждением; UI показывает предупреждение и требует подтверждённый ответ ok:true, сохраняет черновик при malformed acknowledgement. Неверная длительность отклоняется до PUT без parseInt fallback.

65 browser uptime/save/read сценариев прошли. HTTP/DI проверены malformed/no side effects, моделируемый rollback, explicit empty replacement, порядок и сохранение измерений, scheduler warning; signed JWT401/403/write проверен без PG. Typecheck, backend build, ESLint без ошибок (9 прежних uptime warnings) прошли. Production frontend build проверен отдельно. Реальный PostgreSQL rollback/advisory lock и работа scheduler на устройстве остаются внешней приёмкой12.5; модель DI не доказывает их.

Следующий блок12.3.24: большой OSPF route catalog — аудит фактического источника, пагинация50, поиск/сортировка по полному списку, refresh/error/recovery и320px. Затем остальные network grids и общая матрица12.4. Коммит локальный без push.

12.3.24 — большой каталог OSPF-маршрутов (2026-10-04)

Аудит источника: /ospf/catalog опрашивает полный RouterOS ipRoutes и объединяет маршруты устройств без page/limit. Grid переведён на штатную TanStack v9 client pagination50; сортировка применяется ко всему отфильтрованному каталогу. Страница сохраняется при refresh и ограничивается при сокращении списка/поиске. Назначение закреплено штатным columnPinning start/end, горизонтальная прокрутка использует DataGridScrollArea. Подобраны ширины, чтобы значение области не перекрывалось на320px; длинный префикс переносится.

1000 routes/200347 JSON bytes:50 DOM rows/1356 page nodes/930ms dev ready. Проверены page20, refresh, поиск дальнего маршрута/URL/reload, глобальная Cost сортировка,503 cache/unknown/freshness,1000→1 recovery,320px/no page overflow/полная видимость области/axe.22 профильных OSPF browser +1 после окончательной правки ширин прошли; lint/typecheck и production build прошли, мобильный снимок просмотрен. Ранние прогоны выявили неверное left API pinning (исправлено на v9 start/end) и две неверные предпосылки нового теста (ID и поле поиска); итоговые проверки прошли без ослабления assertions. Полный DTO остаётся в памяти, реальная задержка RouterOS не измерена.

Следующий блок12.3.25: BFD sessions большого каталога OSPF,50 DOM rows/поиск/sort/cache/320px. После него оставшиеся network grids и общая матрица12.4; внешняя12.5 отдельно. Коммит локальный без push.

12.3.25 — большой каталог BFD-сессий (2026-10-04)

Источник /ospf/catalog читает и объединяет полный RouterOS bfdSessions без pagination cap. OspfBfdDataGrid использует client pagination50, сохранение страницы при refresh и clamp при сокращении/поиске. Роутер закреплён штатным start/end pinning, горизонтальная прокрутка через DataGridScrollArea; последняя метрика полностью видима на320px. Метрики и режимы unknown/null остаются прежними, сетевые операции не изменены.

1000 BFD/323133 JSON bytes:50 DOM rows/1956 page nodes/983ms dev ready.12 browser прошли:page20/refresh/global Rx sort/поиск по всему remoteAddr каталогу/URL/reload/503 cache/unknown/recovery1000→1/320px/axe, включая прежние null/zero и layout сценарии. Lint/typecheck и production build прошли, мобильный снимок просмотрен. Полные DTO остаются в памяти; реальный RouterOS опрос не проверен. Осталось19 manualPagination:true specialized grids, включая bounded/demo, это не19 доказанных дефектов.

Следующий блок12.4.4: повтор общей context матрицы213 scenarios после последних delta. Затем12.4.5 общий main прогон текущего HEAD и12.3.26 оставшиеся network grids. Внешняя12.5 отдельно. Коммит локальный без push.

12.4.4 — повтор общей context матрицы (2026-10-04)

На HEAD5b2a291 повторена вся playwright.ux-context.config.ts:213 из213 сценариев/25 файлов,7.5min,0 unexpected/0 skipped/0 flaky; Edge,workers1,retries0,maxFailures12. Включены новые8 uptime speed context сценариев и все прежние source/ABA/операции/unknown checkpoint profiles. Доказательство: docs/ux-ui/acceptance/context-repeat-2026-10-04.json с точным HEAD и результатами по файлам.

15 explicit pure/DI файлов дали36 passed/0 failed, включая strict speed DTO и HTTP/JWT write route; PostgreSQL/RouterOS не использовались. Общий backend npm test не запускался из-за реальных purge/DB операций. Основная матрица последних delta ещё не повторена целиком.

Следующий блок12.4.5: общий main прогон текущего HEAD с сохранением JSON evidence. Затем12.3.26 оставшиеся network grids; аудит также выявил fmtBytes(0)→— в WireGuard detail/peer grid, исправить в следующем UI блоке с различением missing/zero. Внешняя12.5 отдельно; stage12 не завершён. Коммит локальный без push.

12.4.5 — повтор основной регрессии (2026-10-04)

На HEAD21859be полный playwright.config.ts дал1110 из1110 passed/171 файл за26.6min;0 unexpected/0 skipped/0 flaky, Edge/workers1/retries0/maxFailures12. Прежние3 устаревшие fixtures из12.4.1 исправлены и теперь прошли в общей матрице. Включены последние speed read/write и большие OSPF/BFD профили, двухтемная доступность оболочки, права, responsive и сквозные API scenarios. Доказательство: docs/ux-ui/acceptance/main-repeat-2026-10-04.json с точным HEAD и результатами по файлам. Context213/25 и unit36 приняты отдельно в12.4.4. Исторические PNG, пересозданные этим прогоном, восстановлены по явному проверенному списку; новые принятые OSPF/BFD снимки сохранены.

Это общая локальная регрессия текущего кода, не полная итоговая приёмка stage12. Аудит показал оставшийся опасный Ping PUT: normalize/filter перед последовательными DB deletes/updates, а uptimeProbeSamples удаляются каскадно. Также подтверждён fmtBytes(0)→— в WireGuard detail/peer grid. Network performance map сохраняет19 manualPagination:true specialized grids; CommRecs ограничен24 на HomeCard (lib/route-optimizer-data.ts), общий список HomeCard этим не ограничен. Тесты реальных PG/RouterOS/integrations не выполнялись.

Следующий блок12.3.26: строгий Ping write DTO до DB, атомарная замена, защита записи неизвестного каталога, подтверждение scheduler warning и точная copy о каскадном удалении истории. Затем12.3.27 WireGuard missing/zero counters и оставшиеся network grids. Внешняя12.5 отдельно; коммит локальный без push.

12.3.26 — атомарная запись каталога Ping-проб (2026-10-04)

Shared write DTO проверяет весь список до DB: обязательный массив, уникальные ID, безопасные ID устройств, непустые имена/цели, boolean и целые интервалы. Некорректные строки не отбрасываются с последующим удалением других проб. Замена выполняется в PostgreSQL transaction с advisory lock; конфигурация обновляется отдельно от измерений. Оmitted interval/dashboard сохраняются для существующих строк, явный пустой список означает удаление. Ошибка refreshScheduler после commit возвращает подтверждённое ok:true с предупреждением.

UI проверяет Ping-каталог до публикации, сохраняет последний успешный список при ошибке и запрещает замену неподтверждённого каталога. Первоначально неизвестные количества показаны как —. PUT требует подтверждённый ответ; malformed ack сохраняет черновик. Один ReUI Alert показывает причину и время последнего успешного списка. Диалог удаления точно описывает каскадное удаление Ping history; speed history сохраняется. Снимок320px: Ping catalog error.

Проверки: uptime-links62/62; context uptime/backend-switch11/11; pure/HTTP DI6/6 (включая JWT401/403, отсутствие mutations до validation и моделированный rollback с историей). TypeScript без incremental и ESLint прошли (9 исходных warnings Uptime); backend и frontend production build прошли. ReUI Alert API/usage проверены, primitives/base-nova не изменены. Fixture backend-switch дополнен реальным backend полем showOnDashboard. Общая регрессия1110/213 относится к предыдущим HEAD, после delta целиком ещё не повторена.

Реальный PG rollback/advisory lock/RouterOS не проверены; DI не заменяет внешнюю12.5. Whole-catalog PUT остаётся last writer wins без revision/ETag. Resources entries остаются legacy DTO (проверена только array оболочка). Следующий блок12.3.27: WireGuard missing/zero RX/TX в деталях и таблице пиров; далее network grids. Коммит локальный, без push.

12.3.27 — достоверные счётчики WireGuard (2026-10-04)

Нулевые RX/TX отображаются как 0 Б, отсутствующие значения — как — в таблице пиров и раскрытии интерфейса. Направления подписаны для accessibility. Backend принимает только целые неотрицательные десятичные счётчики в safe integer диапазоне: строки вроде12junk, дроби/минус/unsafe больше не превращаются в показания. Существующие правила сетевых операций не изменены.

Проверки: wireguard-links/tables29/29, включая обе композиции zero/missing и старые сценарии операций/ссылок; pure mapper1/1; TypeScript без incremental, ESLint изменённых файлов и backend/frontend production build прошли. Реальные RouterOS ответы не проверены. Следующий блок12.3.28: большой каталог интерфейсов WireGuard, пагинация50/refresh/search/320px; полный peer grid и раскрытие большого списка пиров остаются отдельным объёмом. Коммит локальный без push.

12.3.28 — большой каталог интерфейсов WireGuard (2026-10-04)

Полный API /wireguard не ограничивает каталог страницей. Таблица теперь использует client pagination50, глобальную сортировку, сохранение page/expanded при обновлении и clamp после сокращения списка. Composite ID server/interface сохранён. ReUI DataGridScrollArea и штатное start pinning удерживают имя на320px; длинные имена переносятся. Кнопка раскрытия доступна с клавиатуры, меню действий видно без hover и имеет44px цель.

Профиль1000 интерфейсов/316026 JSON bytes:50 строк/2136 DOM nodes/1573ms до ready в локальном dev с HTTP-моками (не оценка RouterOS или production latency). Проверены page20, Enter/раскрытие и refresh, поиск записи1000, глобальная числовая сортировка порта,503/cache/page, горизонтальная прокрутка с закреплением имени/меню, axe grid и1000→1 с правильным объектом в диалоге удаления.29 прежних browser прошли; большой профиль после уточнения локального поиска и вертикального scroll1/1. TypeScript без incremental/ESLint и frontend production build прошли. Снимок320px просмотрен.

Поиск/вкладка/статус WireGuard пока локальные, сервер/interface контекст в URL сохраняется; восстановление остальных фильтров записано отдельным остатком. Осталось18 manualPagination:true specialized grids, включая bounded/demo источники; это не18 доказанных дефектов. Следующий блок12.3.29: полный peer grid1000/50 DOM/действия/320px. Unbounded раскрытие peers одного интерфейса и внешняя12.5 остаются. Коммит локальный без push.

12.3.29 — большой каталог пиров WireGuard (2026-10-04)

Peer grid теперь использует client pagination50, clamp и сохранение страницы при refresh. Полный поиск/сортировка выполняются до страницы, composite server/interface/peer ID сохранён. Штатные ReUI ScrollArea/start pinning удерживают идентификатор на320px, действия имеют44px цель. Подтверждение удаления теперь показывает имя и точный ID пира, а не только интерфейс.

Профиль1000 пиров одного интерфейса/119347 JSON bytes:50 строк/2596 DOM nodes/1369ms ready в локальном dev с HTTP-моками. Проверены page20/refresh, поиск записи1000, сортировка по всему каталогу, выбранные server/interface/keep в URL,503/cache/page, zero/missing RX/TX,320px/axe grid,1000→1 и точный пир в dialog.29 старых browser прошли; после уточнения dialog повтор большого профиля и обоих delete-сценариев3/3. TypeScript без incremental/ESLint и production frontend build прошли. Снимок320px просмотрен.

Осталось17 manualPagination:true specialized grids, включая bounded/demo источники. Следующий блок12.3.30: ограничить DOM раскрытия большого списка пиров одного интерфейса. Восстановление WireGuard search/tab/status из URL, аудит подписи «онлайн» по факту handshake и внешняя12.5 остаются; presence старого handshake не доказывает текущую доступность. Общая main/context после delta целиком ещё не повторена. Коммит локальный без push.

12.3.30 — порционное раскрытие пиров WireGuard (2026-10-04)

Раскрытие интерфейса ограничено50 пирами на страницу, сохраняет страницу при refresh и ограничивает её при сокращении списка до отображения. Имена и точные IDs действий сохранены. На320px карточки имеют две колонки внутри sticky области шириной экрана; кнопки44px, пагинация доступна с клавиатуры и показывает диапазон/общий счётчик. На ПК сохраняется компактная строка полей.

Профиль1000 пиров:50 карточек/2388 DOM nodes. Проверены Enter/страница20/refresh,320px при крайнем horizontal scroll/доступ к действиям/axe detail, правильный последний пир в delete dialog и1000→1.31 browser прошли; после устранения setState-in-effect повтор большого detail1/1. TypeScript без incremental, ESLint и production frontend build прошли. Снимок320px просмотрен. Измерения используют локальные HTTP-моки, RouterOS latency не измерена.

Следующий блок12.3.31: убрать вывод «онлайн» из наличия старого handshake, показать отсутствие данных отдельно. Официальный RouterOS last-handshake — время после последнего успешного рукопожатия: https://help.mikrotik.com/docs/spaces/ROS/pages/69664792/WireGuard. Затем WireGuard URL filters/context и оставшиеся network grids.17 manualPagination:true grids/общая регрессия после delta/внешняя12.5 остаются. Коммит локальный без push.

12.3.31 — рукопожатие не подменяет доступность WireGuard (2026-10-04)

Убрана оценка «пиров онлайн» по presence старого last-handshake. KPI «Данные рукопожатия» считает непустые сведения в ответе и явно сообщает, что доступность пиров не проверена. Колонка «Пиры» показывает число записей. Старое время рукопожатия отображается без зелёного вывода о доступности; отсутствующее/пустое значение — «Нет данных». В мобильных деталях видна подпись Endpoint.

Основание: официальный RouterOS WireGuard, last-handshake означает время после последнего успешного рукопожатия. Порогов актуальности/новых правил сетевых операций не введено. Проверены missing/empty/1h/0s в обеих композициях и KPI2/4. Семь прежних/table/large browser прошли, новый handshake сценарий после уточнения adaptive KPI селектора1/1. TypeScript без incremental/ESLint и production frontend build прошли. Снимок320px просмотрен.

Следующий блок12.3.32: WireGuard URL search/tab/status — reload/история/сохранение server/interface/неверные параметры без расширения среза. Первоначально неизвестные общие KPI WireGuard и freshness/source switching требуют отдельного аудита; этот блок исправляет именно смысл handshake.17 остальных specialized grids/общая регрессия после delta/внешняя12.5 остаются. Коммит локальный без push.

12.3.32 — контекст фильтров WireGuard в URL (2026-10-04)

Поиск q, вкладка tab и статус интерфейса status сохраняются в URL; reload/назад/вперёд восстанавливают срез. Native history updates сохраняют server/interface, посторонние параметры и hash; ввод поиска использует replace, смена вкладки/статуса — push. Статус относится к интерфейсам, peer view сохраняет его для возврата. Неверные/повторяющиеся фильтры и поиск длиннее200 не расширяют список: показываются предупреждение и явный сброс только фильтров с сохранением устройства. Создание/импорт заблокированы до исправления ссылки.

Проверки:34 browser профильных/large/URL прошли; четыре новых invalid-filter сценария выявили пропущенную блокировку header-кнопки, после исправления повтор4/4. Pure URL1/1, TypeScript без incremental/ESLint и production frontend build прошли. Профили1000 интерфейсов/пиров/деталей включены. DTO server/interface context не расширен и его legacy parse не заявлен новым strict контрактом. Общие правила ReUI/base-nova сохранены.

Следующий блок12.3.33: WireGuard чтение при смене backend/mode и поздних ответах, первоначально неизвестный каталог/KPI, cache/freshness и запрет изменения неизвестного источника. Затем оставшиеся17 specialized grids. Общая main/context после delta и внешняя12.5 остаются. Коммит локальный без push.

12.3.33 — достоверное чтение и контекст WireGuard (2026-10-04)

GET WireGuard проверяется до публикации: форма DTO, уникальные composite server/interface IDs и peer IDs внутри интерфейса, уникальность failed sources, отсутствие одновременно результата и failure одного устройства. Каталог устройств проверяется по subset общего serverRead контракта; оба списка преобразуются до изменения state/receipt time. Отсутствующий server status показан как unknown. Ошибочный ответ сохраняет последние данные; inline ReUI Alert показывает постоянную причину и время получения. Первоначально неизвестные и неопрошенные scope KPI показаны как —, failed device не становится подтверждённым пустым каталогом; sidebar count неизвестного устройства не подставляет0.

Mounted/revision guards исключают позднее чтение/ошибку старого источника; content key включает backend/mode. Старые операции не показывают toast в новом контексте и не запускают повторное чтение прежнего backend после unmount. Мутации неизвестного/error каталога закрыты; исходные API пути и правила сетевых операций сохранены. История также не загружается из obsolete component.

Проверки: финальный основной WireGuard профиль40/40; дополнительные strict identity/failures/device/cache сценарии7/7; context read/toggle × backend/mode × успех/ошибка8/8, повторён после strict device parser. TypeScript без incremental/ESLint и production frontend build прошли. Ошибка/cache320px просмотрена. Detail viewport test прокручивает первую карточку, resize проверка ожидает применения media layout; assertions не ослаблены. Добавлен wireguard-context в общий context config (новая общая матрица ещё целиком не повторена).

Scope proof ограничен HTTP-моками и read/toggle context сценариями; реальный RouterOS/PG не проверены. Backend fallback running/disabled/type и остальные source-context операции требуют дальнейшего аудита, strict frontend не доказывает достоверность отсутствующих raw RouterOS flags. Следующий блок12.3.34: VXLAN1000/50 DOM/refresh/search/sort/export/320px; затем остальные17 specialized grids и общая main/context приёмка. Внешняя12.5 отдельно. Коммит локальный без push.

12.3.34 — большой каталог VXLAN (2026-10-04)

Полный /vxlan API не ограничен страницей. Таблица использует client pagination50, global sort, сохранение страницы при refresh и clamp после поиска/сокращения. ReUI ScrollArea/start pinning сохраняют имя/VTEP на320px; длинные значения переносятся, меню экспорта видно без hover и имеет44px цель. Composite server/tunnel ID и неизменяемый export snapshot сохранены.

Профиль1000 туннелей/227787 JSON bytes:50 строк/2137 DOM nodes/1249ms ready в локальном dev с HTTP-моками. Проверены page20/refresh, поиск записи1000/глобальный VNI sort,503/cache/unknown/page,320px/закрепление имени/axe, экспорт устаревшего snapshot и1000→1 с точным VNI1000.22 browser (large/table/links/freshness/GRE-VXLAN layouts) прошли. TypeScript без incremental/ESLint и production frontend build прошли. Снимок320px просмотрен.

Осталось16 manualPagination:true specialized grids, включая bounded/demo источники. VXLAN поиск пока локальный; server/tunnel URL контекст сохранён. Следующий блок12.3.35: GRE tunnels1000/50 DOM/search/sort/refresh/действия/320px. OSPF neighbors сопровождаются большим SVG графом, поэтому ограничение одной таблицы не докажет производительность всего экрана; отдельный аудит topology остаётся. Общая main/context после delta и внешняя12.5 отдельно. Коммит локальный без push.

12.3.35 — большой каталог GRE-туннелей (2026-10-04)

GET /api/gre/tunnels возвращает полный каталог без ограничения строк. ReUI client pagination50 ограничивает DOM; refresh сохраняет страницу, уменьшение/поиск корректирует её, MTU сортируется по всему каталогу. На320px имя закреплено, обе кнопки кода/меню видны без hover и имеют44px; composite identity и существующие permissions/mutation guards сохранены.

Профиль1000 туннелей/351894 JSON bytes:50 строк/2748 DOM nodes/1609ms ready в dev с HTTP-моками.20 browser (large/links/freshness/toggle/delete/IPsec-GRE tables/layouts) прошли; large повторён1/1 с проверкой disabled edit/delete после503. Поиск записи1000, page20/refresh/global MTU sort, cache/page/unknown,320px/axe/pinning, устаревший export snapshot и1000→1 с точным MTU2399 проверены. TypeScript без incremental/ESLint прошли; production frontend build прошёл. Снимок320px просмотрен.

Осталось15 manualPagination:true специализированных таблиц; GRE pools в live всегда пусты и доступны только как demo, поэтому их пагинация не приоритет для live. Firewall использует DnD исходного порядка; OSPF neighbors дополнительно рисует SVG topology. Следующий блок12.3.36: карта оставшихся источников/ограничений и безопасная последовательность performance доработок. Поиск GRE пока локальный; реальные RouterOS/PG и внешняя12.5 не проверены. Общая main/context регрессия после delta остаётся отдельной. Коммит локальный без push.

12.3.36 — актуальная карта оставшихся таблиц (2026-10-04)

Обновлён ux-ui-performance.md:15 manualPagination:true файлов сопоставлены с JSX/источниками и действующими ограничениями. Удалены6 уже принятых таблиц из активной карты. Scheduler11, traffic top50, community recommendations24 на HomeCard, demo GRE pools/schedule и неподключённый Subusers отделены от неограниченных live каталогов. OSPF topology и Firewall DnD остаются отдельными рисками; optimizer имеет комбинаторные массивы и много HomeCard. Измерения WireGuard/VXLAN/GRE внесены без выдуманного baseline.

Проверка документа: автоматическая сверка15 файлов с точным поиском исходников, существования относительных ссылок и отсутствие уже принятых файлов в активной карте; git diff --check. Код продукта не изменён, повтор сборки не требуется. Следующий блок12.3.37: честное обозначение ограниченного top50 traffic conversations; затем Communities1000/recursive groups и остальные шаги карты. Внешняя12.5 и общая main/context регрессия после delta остаются. Коммит локальный без push.

12.3.37 — границы выборки сессий трафика (2026-10-04)

FlowAnalyticsPanel сообщает фактическое число строк после фильтра и размер полученной выборки, объясняет top по объёму до50 и локальную область фильтра. Пустой выбранный фильтр имеет собственную причину, вместо общей parent emptyHint; сводка общего conversations не подменяется числом строк. Backend cap/read/network операции не изменены.

Новый сценарий выявил реальное перекрытие второй строки tabs таблицей: scoped TabsList теперь имеет автоматическую высоту, фиксированную высоту вкладок и перенос. Обычный click без force работает.Финальный browser профиль28/28 прошёл одним запуском на окончательных файлах, включая123 total/1 selected/0 filtered/reset/320px. Первоначальные падения нового теста привели к исправлению перекрытия tabs, корректировке роли выбранной строки и точной причине пустого фильтра; assertions не ослаблены. TypeScript без incremental/финальный ESLint и production frontend build прошли. Снимок320px просмотрен.

Следующий блок12.3.38: Communities1000 с полным поиском/sort/refresh/выбором/320px по актуальной performance карте.15 manualPagination:true остаются, traffic cap50 не требует фиктивной пагинации. Общая main/context после delta и внешняя12.5 отдельно; реальные RouterOS/PG не проверены. Коммит локальный без push.

12.3.38 — большой каталог Communities (2026-10-04)

ReUI pagination50, global sort/search, сохранение страницы при refresh и clamp при уменьшении списка. Закреплено значение community; копирование и явная кнопка деталей имеют44px/доступные подписи. Выбор по ID не привязан к странице и сохраняется при сортировке/обновлении; удалённая запись закрывает детали. Кнопка деталей работает с клавиатуры. Права/источник/отсутствующие prefix counts сохранены.

19 browser (large Communities и Evolution consumers) прошли:1000/190573 JSON bytes →50 rows/2216 page nodes/1206ms dev ready; page20/refresh/search1000/global sort/cache/320px/pinning/axe, clipboard stub,1000→1→0/selection. TypeScript без incremental/ESLint прошли. Первый production build не получил Google Fonts, повторная обычная сборка успешно собрала34 страницы. Снимок320px просмотрен. Реальная интеграция Evolution и системный clipboard не проверены. Поиск/выбор Communities пока локальны, восстановления из URL нет.

Осталось14 manualPagination:true specialized grids. Обнаружено прежнее ложное подтверждение clipboard: handleCopy ставит copied до завершения writeText и игнорирует reject. Следующий блок12.3.39: исправить ack/error/pending копирования и поздние ответы при смене источника; затем12.3.40 recursive groups+endpoints. Общая main/context регрессия после delta и внешняя12.5 отдельно. Коммит локальный без push.

12.3.39 — подтверждение копирования Communities (2026-10-04)

Clipboard success показывается только после resolved writeText; reject/недоступный API сохраняет значение и показывает ReUI Alert с повтором/ручным копированием. Pending блокирует повторный вызов и кнопки списка/деталей; активная операция и timer защищены mount/revision guard, источник страницы уже ключуется sourceKey. Уведомления pending/success доступны через role=status.

5/5 browser (4 clipboard cases и large Communities повтор) прошли: отсутствие преждевременной галочки, двойное нажатие, reject→retry, поздний успех/ошибка после unmount. TypeScript без incremental/ESLint и production frontend build прошли. Clipboard подменён promise в браузере; системные разрешения и смена backend/mode именно во время clipboard отдельно не проверены. Не утверждаем, что уже начатая запись в системный clipboard отменяется при unmount.

Следующий блок12.3.40: recursive routes1000 групп и1000 endpoints одной группы, pagination/URL expansion/global sort/refresh/cache/320px.14 manualPagination:true остаются. Общая main/context регрессия и внешняя12.5 отдельно. Коммит локальный без push.

12.3.40 — большие группы рекурсивных маршрутов (2026-10-04)

ReUI pagination50 групп, global sort, refresh без сброса страницы и clamp. Первичное/новое URL раскрытие находит группу в sorted model и открывает её страницу; обычный переход страниц не навязывает возврат к выбранной группе. Строка показывает3 gateway и точное число остальных. Раскрытие имеет отдельные страницы50 endpoints, сортирует всю группу по distance, сохраняет страницу при refresh и корректирует её при сокращении. На320px route закреплён, edit/delete44px и доступны через горизонтальный scroll; детали ограничены viewport и доступны с клавиатуры.

35/35 browser (large/table/links/layout/values/data) прошли:1000 групп/212347 JSON bytes →50 rows/2118 nodes/1457ms dev ready;1000 endpoints →50 cards/1126 nodes. Проверены URL page20, full search/global Table sort, refresh/cache/permissions/1000→1, expanded endpoint page20/refresh/clamp и320px/axe. TypeScript без incremental/ESLint и production frontend build прошли. Группы320px, endpoints320px просмотрены. Изменение/удаление получает всю исходную группу, профильные операции прошли на малых fixtures; большой write payload в этом блоке не проверялся.

Осталось13 manualPagination:true specialized grids. Большая RouteSheet пока рендерит все endpoints и все варианты gateways для каждого endpoint; performance формы не принят. Следующий блок12.3.41: ограничить DOM формы/вариантов шлюзов без потери скрытых данных/валидации/PUT payload, проверить1000 endpoints и1000 gateways. Затем Filters порядок/Firewall DnD и остальные этапы карты. Общая main/context после delta и внешняя12.5 отдельно. Коммит локальный без push.

12.3.41 — большая форма рекурсивного маршрута (2026-10-04)

RouteSheet показывает10 endpoints, но хранит весь draft. Предыдущая/следующая страница и прямой переход по номеру endpoint доступны с клавиатуры; add открывает страницу нового элемента, удаление корректирует индекс. Валидация ищет ошибки во всём draft и открывает страницу первого невалидного endpoint. RecursiveGatewayChoices сохраняет прежние карточки/семантику статуса; показывает5 вариантов (выбранный первым) и ищет по всему каталогу IP/name. Ручной gateway ввод сохранён.

22 профильных browser прошли; финальный large повтор1/1 после прямого перехода/скрытой ошибки.1000 endpoints ×1000 gateways →10 cards/1569 modal nodes,50 gateway choices. Проверены первая/последняя страницы, поиск шлюза1000, скрытый невалидный endpoint1000 без PUT, ошибка503/сохранение draft/повтор,320px; PUT содержит1001 строки, обе скрытые правки и неизменную другую группу. TypeScript без incremental/финальный ESLint и production frontend build прошли. Форма320px просмотрена. Общие сетевые правила и права не изменены; реальный RouterOS PUT не проверен.

Следующий блок12.3.42: Filters1000/порядок через границу страниц/whole-catalog PUT/search/sort/refresh/cache/320px.13 manualPagination:true specialized grids остаются. Общая main/context после delta и внешняя12.5 отдельно. Коммит локальный без push.

12.3.42 — большой список Filters (2026-10-04)

ReUI pagination50/clamp/закреплённые номер и community; доступные действия44px без hover. Индекс и крайние позиции берутся из полного orderedRules через Map. Поиск сортирует весь срез, очистка поиска возвращает исходный порядок (manualSorting), перемещение отправляет все правила.

10 профильных browser и финальный large1/1 прошли:1000/120894 JSON bytes →50 rows/2266 nodes/1880ms dev ready. Проверены down r50 через границу страницы, keyboard up обратно, полный PUT1000/403 rollback, search1000/global sort/clear, refresh/page/cache503/блокировка действий/1000→1,320px/ScrollArea/axe. TypeScript без incremental/ESLint и production build прошли. Filters320px просмотрен. DTO целиком остаётся в памяти; реальные RouterOS операции не проверены. Старое уведомление ошибки перемещения сохраняется после refresh; это отдельное состояние операции, не успех чтения.

Осталось12 manualPagination:true specialized grids. Следующий блок12.3.43: Firewall1000/pagination/порядок DnD и действия, точный RouterOS destination через границу страниц. Общая main/context после delta и внешняя12.5 отдельно. Коммит локальный без push.

12.3.43 — большая таблица Firewall и порядок (2026-10-04)

ReUI pagination50/clamp/ScrollArea, закреплённые номер и chain. DnD получает ID текущей страницы, кнопки44px up/down используют соседей полного отфильтрованного списка внутри server/family/table. Callback прежний: RouterOS destination рассчитывается по полному источнику, включая скрытые строки. DnD мышью/клавиатурой сохранён; action menu44px видим без hover. Переключателям добавлены доступные имена с rosId.

13+22 профильных main browser, финальный large1/1 и context4/4 прошли.1000/253248 JSON bytes →50 rows/3054 nodes/2082ms dev ready. Down r50→destination *52, keyboard up r50→*51, DnD page2 r51→*53,403 rollback/refresh page/search1000/cache503/1000→1,320px/action44px/axe проверены. TypeScript без incremental/финальный ESLint и production build прошли. Firewall320px просмотрен. Полный DTO остаётся в памяти; real RouterOS не проверен. Global sorting большого multi-server среза отдельно не проверена, reorderable сохраняет manualSorting.

Обнаружено прежнее ограничение: dataError после полного GET failure сохраняет кэш, но не блокирует действия, в отличие от partial failures. Следующий блок12.3.44: явная блокировка stale операций/повторного чтения/восстановления; затем большой редактор сценария и OSPF/optimizer.11 manualPagination:true specialized grids остаются. Общая main/context после delta и внешняя12.5 отдельно. Коммит локальный без push.

12.3.44 — блокировка устаревших операций Firewall (2026-10-04)

readTrusted отделён от текста dataError: после HTTP/DTO failure кэш сохраняется, но toggle/edit/delete/create/move/address-list/history restore заблокированы. Очистка ошибки при retry не разблокирует действия до корректного ответа. Существующие partial failures дополнительно сохраняют scoped блокировку; поздний read после мутации не сбрасывает подтверждение. Статус объясняет блокировку и сохранённый список, операции RouterOS не изменены.

29/29 main browser (data/partial/save/delete/toggle/move/history/large),2/2 новых stale cases и4/4 context прошли. Проверены503/некорректный DTO, неизменная строка, отключённые switch/menu/create/history, pending retry без writes, восстановление после успешного GET. TypeScript без incremental, ESLint нового теста и production build прошли. ESLint страницы имеет4 исходных set-state-in-effect errors (506/754/883/2081 в HEAD1e9889f) и2 unused warnings; сравнение ESLint API с HEAD подтвердило тот же набор в текущем файле (последняя строка2085). Это не полный lint pass; исправление прежних эффектов отдельно.

Следующий блок12.3.45: большой редактор локального сценария Firewall — pagination/глобальный порядок/сохранение всего draft/симуляция/320px. Затем OSPF таблица+topology/optimizer.11 manualPagination:true остаются. Общая main/context после delta, lint cleanup Firewall и внешняя12.5 отдельно. Коммит локальный без push.

12.3.45 — большой редактор сценария Firewall (2026-10-04)

ReUI pagination50/clamp/ScrollArea, закреплённые номер и chain, действия44px без hover; номера и up/down края считаются по полному draft. ScenarioSheet320px занимает всю ширину viewport. Кнопки редактирования/удаления сценария получили44px и доступные имена. Локальный сценарий не отправляет операции RouterOS.

Финальные6/6 browser (tables и large scenario) прошли.1000 правил →50 rows/1847 modal nodes. Проверены down50 через страницу/up51 обратно/delete51, полный сохранённый localStorage draft999/точный порядок/последнее правило неизменно,320px/полная кнопка44px/axe. Симуляция вычисляет скрытое последнее правило #999 и блокирует пакет; API writes0. TypeScript без incremental, ESLint grid/test и production build прошли. Сценарий320px просмотрен. Четыре исходных lint errors страницы/2 warnings из12.3.44 остаются; отказ записи localStorage отдельно не проверен.

Обнаружено: trace999 создаёт15529 page DOM nodes; ограничение редактора не означает принятие всего симулятора. Следующий блок12.3.46: страницы трассировки/полный verdict/переход к результату и сохранение отмены/повторного запуска. Затем Firewall lint cleanup, OSPF таблица+topology/optimizer.10 manualPagination:true specialized grids остаются. Общая main/context после delta и внешняя12.5 отдельно. Коммит локальный без push.

12.3.46 — ограниченная трассировка Firewall (2026-10-04)

Trace показывает50 шагов, общий verdict/counts/номера относятся ко всему расчёту. Предыдущая/следующая страница и переход к правилу результата44px; новая симуляция/reset/preset/scenario начинают с первой страницы. Строки переносятся на320px, исправлен контраст passthrough и пояснений. runEpoch защищает от старого таймера после stop→новый run; unmount инвалидирует запуск.

6/6 browser на начальной pagination и финальный large1/1 после mobile/epoch/axe прошли: trace999 уменьшен15529→1293 page DOM nodes,50 steps на странице/49 на последней. Full verdict#999, page2, keyboard jump951–999,320px/axe, stop→instant run и продвижение clock1000ms без старого evaluating, reset проверены. TypeScript без incremental/ESLint теста/production build прошли; ESLint API baseline/current подтверждает те же4 исходных ошибки страницы и2 warnings. Трассировка320px просмотрена. Алгоритм вычисления не изменён: instant по-прежнему делает обновления полного steps на каждом правиле, CPU complexity не принята нагрузочным тестом. Данные остаются полными в памяти.

Следующий блок12.3.47: Firewall lint cleanup четырёх старых эффектов без потери draft/URL/filter/focus. Затем OSPF таблица+topology/optimizer; ошибки localStorage и большой multi-server sort отдельно.10 manualPagination:true остаются. Общая main/context после delta и внешняя12.5 отдельно. Коммит локальный без push.

12.3.47 — формы, URL и lint Firewall (2026-10-04)

RuleSheet/AddressListSheet корректируют собственный draft при смене контекста до commit дочерних элементов, сохраняя ввод при API ошибке и pending. Sheet не перемонтируется; finalFocus возвращает к исходной кнопке меню строки, fallback — create/add. Address-list фильтр отсутствующего списка сбрасывается до вывода детей и не возвращается при повторном появлении списка. Query server применяется один раз после каталога через guarded state adjustment; начальный useState недостаточен для асинхронного URL-контекста. Удалены дубли unused styles.

6+20 main browser и4/4 context прошли: reopen старого rule/address после несохранённого draft, create с пустым draft, Escape/focus, удаление/возврат фильтра,8 save cases/ошибки API/права/partial/cache/stale, обе большие таблицы/trace и поздние ответы. TypeScript без incremental/ESLint страницы и нового теста/production build прошли. Четыре исходные lint errors/2 warnings устранены без suppression; подход соответствует React: Adjusting some state when a prop changes. Сетевые правила не изменены, real RouterOS не проверен.

Следующий блок12.3.48: полный профиль OSPF1000 соседей/1001 SVG узел, таблица и topology вместе; определить точную границу DOM до изменений. Затем ограничение таблицы/графа, optimizer. LocalStorage отказ сценария и большой multi-server sort Firewall остаются отдельными проверками.10 manualPagination:true остаются. Общая main/context после delta и внешняя12.5 отдельно. Коммит локальный без push.

12.3.48 — исходный профиль OSPF соседей и topology (2026-10-04)

Fixture полного DTO:1000 neighbors/1000 interfaces/одна instance,1001 distinct graph nodes;583875 JSON bytes.1/1 browser и ESLint теста прошли. Исходный экран:1000 table rows/14012 SVG descendants/32635 page nodes/6760ms dev ready.320px document width320, но это не доказательство читаемости. Профиль, desktop, mobile сохранены и просмотрены: узлы на фиксированной окружности перекрывают друг друга, граф не принят. Latency одного dev прогона не является production benchmark.

Продуктовый код не менялся; build повторно не нужен для теста/документации. Следующий блок12.3.49: client pages50 OSPF neighbors/полный поиск и sort/URL node/refresh/cache/clamp/320px. Принимать таблицу отдельно, не объявлять готовность всего экрана: граф14012 SVG требует12.3.50 — читаемый ограниченный срез topology с явными counts/выбором узла/переходами ко всем данным. Затем optimizer и общая main/context после delta.10 manualPagination:true остаются; внешняя12.5 отдельно. Коммит локальный без push.

12.3.49 — большая таблица соседей OSPF (2026-10-04)

ReUI pagination50/clamp/ScrollArea, закреплённый local router и кнопка узла44px. Новый/первичный URL node находит строку в глобальной sorted model и открывает её страницу; обычная pagination/refresh не навязывает возврат к выбранному узлу. Search/sort используют весь срез, selection не привязан к странице. Unknown/cost/null/права сохранены.

22/22 browser (large/data/layout/links/values) и финальные large повторы прошли;1000/583875 JSON bytes →50 table rows,1001 graph nodes/12015 SVG descendants/13597 page nodes/2827ms dev ready. URL remote1000→page20, refresh/ручная page19, search/reload/сохранение keep, global Cost sort/cache503/unknown/clamp1000→1/no writes,320px/pinning/axe проверены. TypeScript без incremental/ESLint grid+test/production build прошли. Профиль таблицы, таблица320px просмотрены. SVG количество зависит также от animation/reduced-motion состояния; baseline14k и текущие12k не означают изменение алгоритма графа. Dev latency не считается production benchmark.

Осталось9 manualPagination:true specialized grids. Весь экран не принят: граф1001 перекрывается; KPI1000 на320px переносит число; NodeDetailPanel локального узла рендерит все связи. Следующий блок12.3.50: читаемый ограниченный срез topology/явные counts/поиск и выбор любого узла/URL/полный источник, исправить отображение чисел. Затем12.3.51 большие node details, optimizer и общая main/context после delta. Внешняя12.5 отдельно. Коммит локальный без push.

12.3.50 — ограниченный срез topology OSPF (2026-10-04)

OspfTopologyScope использует полный источник: до8 incident edges/9 SVG nodes, focal выбранного URL узла или первого устройства, pagination/clamp/сброс при смене focal, точные полные counts, поиск всех узлов с пятью результатами. Малый граф до12 узлов/12 связей сохраняет прежнюю композицию; 1000 параллельных связей между двумя узлами тоже включают ограничение. Полный nodeState вычисляется по всем edges, а не видимой странице. Close возвращает фокус к узлу или поиску, если узел исчез из среза. KPI1000 на320px не дробится, HTML-кнопки выбора/pages/animation44px.

26/26 профильных main,8/8 context и финальные3/3 large прошли. Fixture1000 neighbors/1000 interfaces/1001 nodes/583875 bytes →50 rows/2 SVG nodes/27 descendants/1630 page nodes/1531ms dev ready для URL remote1000. Проверены page2/clamp после уменьшения1000→13→12, полная hidden Full-связь при первых Down, выбор remote1000 из всего каталога/keep, close/focus,320px/axe, bounded parallel1000. TypeScript без incremental, ESLint страницы/компонента/теста и production build прошли. Профиль, срез1440px, 320px сохранены и просмотрены. Dev latency не production benchmark. На большой топологии SVG доступен через горизонтальный scroll; все узлы доступны через поиск.

Это не приёмка всех вариантов графа: параллельные edges ограничены по DOM, но их подписи на общей линии могут перекрываться. Большая NodeDetailPanel ещё рендерит все1000 neighbors/interfaces — следующий12.3.51. Затем параллельные связи/optimizer/общая main-context регрессия после delta.9 manualPagination:true specialized grids остаются. Внешние RouterOS/PG/интеграции12.5 не проверены. Локальный коммит без push.

12.3.51 — большие детали узла OSPF (2026-10-04)

OspfDetailList: client pages50 отдельно для соседей/интерфейсов, поиск всего списка по peer/Router ID/interface/state и interface/area/cost; full counts сохраняются. Refresh не сбрасывает ручную страницу, shrink ограничивает её, новый nodeId пересоздаёт контекст списка. Close44px, Escape/focus прежние; сетевые правила не изменены.

4/4 large,15/15 profile keyboard/layout/URL/state/identity и финальный detail1/1 прошли. Полный fixture1000 neighbors/1000 interfaces →50+50 записей/635 panel DOM/2335 page DOM для URL node=1. Поиск ether1000/полный cost1000, no-match, page2/refresh, shrink1000→1/keep/node,320px/кнопки44/axe проверены. TypeScript без incremental, полный ESLint страницы/компонента/теста и production build прошли. Профиль, панель320px сохранены и просмотрены. Каталог не обрезается в памяти.

Следующий12.3.52: визуальная группировка параллельных links без подмены cost/state; затем optimizer и общая регрессия после всех delta.9 specialized manualPagination:true остаются. Внешние RouterOS/PG/интеграции12.5 не проверены. Локальный коммит без push.

12.3.52 — читаемые параллельные связи OSPF (2026-10-04)

TopologyGraph группирует видимые edges по неориентированной паре: одна линия/подпись количества на страницу, отдельные cost/state каждой связи в SVG title и accessible name. Для разных состояний нейтральный цвет, dashed без Full-анимации; Unknown не подставляется. Статусы узлов остаются по всем edges. Групповая подпись читается без hover; единственный peer расположен сбоку, подпись не накладывается на узел. Full table и node details доступны для просмотра всех связей.

9/9 browser (large topology/details/identity/states/layout/keyboard/reduced motion) и финальный parallel1/1 прошли.1000 links between2 nodes, page8 links →одна visual group, aria-label Full/cost1 и Down/cost2, подпись8 связей. TypeScript без incremental/ESLint страницы/scope/теста и окончательный production build прошли. Группировка1440px сохранена и просмотрена; PNG после проверки показал недостаточный opacity, исправлен и повторно проверен.

Следующий12.3.53: OSPF preview оптимизатора1000 rows/полная apply-ветка при pagination/search; затем матрицы и many HomeRouterCard.9 manualPagination:true specialized grids остаются. Общая main/context регрессия после delta и внешняя12.5 отдельно. Локальный коммит без push.

12.3.53 — большой OSPF preview оптимизатора (2026-10-04)

Штатные ReUI pages50/client sorting/clamp и ScrollArea, закреплённый interface120px оставляет место cost на320px. Именованная область preview включает поиск полного массива id/interface, полные counts и явное пояснение, что фильтр меняет только отображение. Контекстный key server/weight сбрасывает поиск/страницу при смене устройства; фоновый refresh сохраняет их. Применение не использует фильтр/видимую страницу, существующий POST pingWeight и строгий receipt сохранены.

47/47 профильных main,16/16 final preview/large/new context-search и8/8 backend/mode context прошли.1000 interfaces/245293 JSON bytes →50 rows/924 preview region DOM/1610 page DOM. Search ether1000→1 row/receipt1000 applied; Cost sort full array, page2/refresh/cache503/disabled apply/shrink1000→1/server+keep,320px/pinning/axe, смена server очищает no-match query. TypeScript без incremental/полный ESLint grid/page/двух тестов/production build прошли. Профиль, 320px сохранены и просмотрены. API fixture receipt исправлен по существующему контракту currentCost=from; контракт не ослаблен. Это проверка HTTP live-ветки с подменёнными ответами, не реальное применение RouterOS. Полный массив остаётся в памяти.

Осталось8 manualPagination:true specialized grids. Следующий12.3.54 — исходный профиль1000 HomeRouterCard с полным servers DTO; затем bounded cards/full-route/wan-matrix, честность24 commRecs. Общая main/context после delta и внешняя12.5 отдельно. Локальный коммит без push.

12.3.54 — исходный профиль домашних устройств оптимизатора (2026-10-04)

Полный optimizerServersSchema1000 home-router/179347 bytes, без подтверждённых WAN/probes/filters.1/1 browser и ESLint теста прошли.1000 HomeRouterCard/40668 page DOM/11496ms dev ready; document320px не шире viewport. Профиль, исходный320px сохранены. Это baseline, не приёмка производительности; dev latency не production benchmark. Нет WAN — это валидная live ветка, не подмена неизвестных данных нулями. Продуктовый код не менялся, build повторно не нужен.

Следующий12.3.55: ограниченный DOM HomeRouterCard/поиск полного каталога/URL/refresh/clamp/320px. Расчёт полного массива остаётся отдельным CPU риском; раскрытые full-routes и WAN dynamic columns требуют других профилей. Общая регрессия и внешняя12.5 отдельно. Локальный коммит без push.

12.3.55 — ограниченные карточки домашних устройств (2026-10-04)

OptimizerHomesList показывает5 карточек на страницу, поиск по полным label/id/IP/site/country. home_q/home_page в URL сохраняют server/keep/hash; поиск replaceState/reset page, pagination pushState, clamp после нового полного снимка нормализует URL. Малый каталог до5 без фильтра сохраняет прежнюю композицию. Расчёт и полный DTO не обрезаются; глобальные pinned/applied Sets остаются у родителя. Карточка при уходе со страницы перемонтируется, её локальная вкладка сбрасывается — восстановление вкладки отдельно не принято.

23 профильных main прошли; единственный сбой нового pin-сценария был неверным selector теста (row key home::community::index); исправлен, финальный suite8/8 passed.8/8 backend/mode context, TypeScript без incremental/полный ESLint страницы/компонента/тестов/production build прошли.1000 home-router/179347 bytes →5 cards/1870 page DOM/1606ms dev ready вместо40668/11496ms. Проверены page200/refresh, search1000/reload/back/keep/server, cache503/full snapshot, shrink1000→1/URL clamp, pin Community→page2→page1,320px/HTML pagination44px/axe. Профиль, 320px сохранены и просмотрены. Dev latency не production benchmark; native OSPF device select всё ещё содержит1000 options.

Следующий12.3.56: полный профиль WAN10×JH10×Exit10/1000 routes и раскрытой таблицы. WAN matrix columns/полный расчёт combinatorics и24 commRecs остаются самостоятельными ограничениями.8 specialized manualPagination:true остаются. Общая регрессия после delta и внешняя12.5 отдельно. Локальный коммит без push.

12.3.56 — исходный профиль1000 полных маршрутов (2026-10-04)

Полный валидный servers DTO21 устройство/4261 bytes:WAN10×JH10×Exit10 создаёт1000 full routes.1 browser/test lint passed; раскрытый список1000 rows/33049 table DOM/33780 page DOM/3738ms dev ready. Профиль сохранён. Это baseline, не performance acceptance; dev latency не production benchmark. Продуктовый код не менялся, build повторно не нужен. Далее12.3.57 ограничить DOM раскрытого списка50/page без потери global sort/индекса/best/refresh/clamp; затем WAN matrix/CPU combinatorics/24 commRecs и общая регрессия. Внешняя12.5 отдельно. Локальный коммит без push.

12.3.57 — страницы полных маршрутов оптимизатора (2026-10-04)

ReUI client pagination50 только раскрытого списка, autoResetPageIndex=false/clamp, fixed widths/ScrollArea, закреплённый исходный номер маршрута112px. _index/bestId вычислены по полному исходному списку, не странице/sort. Сворачивание/раскрытие явно reset page0; для1000 текст «Открыть все1000 комбинаций» не обещает одновременный DOM. Для<=50 прежний текст сохранён. Toggle44px. Расчёт модели/сети и полный массив не изменены.

6/6 профильных table/pin/empty/unknown cases и финальный large1/1 passed. Первые ошибочные expectations теста считали min index уникальным; исправлены по существующим равным значениям. Проверены50 initial/счётчик номера51/refresh/page20 951–1000, collapse5/open50, глобальный min sort включает номера за исходной page1 при ties,320px/pinning/axe/shrink1000→1/no writes.21 devices/WAN10×JH10×Exit10/4261 bytes →50 rows/1699 table DOM/2461 page DOM/1853ms dev ready вместо33049/33780. TypeScript без incremental/ESLint grid+test/production build passed. Профиль, 320px сохранены и просмотрены. Dev latency не production benchmark.

Осталось7 manualPagination:true specialized grids. Следующий12.3.58 — WAN matrix/динамические JH columns/CPU combinatorics. Срез commRecs24/восстановление вкладки карточки/native device options1000 и полный массив в памяти остаются. Общая main/context после всех delta и внешняя12.5 не закрыты. Локальный коммит без push.

12.3.58 — карта оставшихся рисков оптимизатора (2026-10-04)

Статический аудит после a16bfae, без продуктовых изменений/сетевых операций. Осталось7 manualPagination:true. WAN matrix рендерит все home.wans и все jumpHosts как columns, legs.find на каждую ячейку; Math.max(...legs.map(score)) тоже не имеет явной границы числа аргументов. DOM ограничение карточек и full routes не ограничивает эту матрицу. Следующие независимые fixtures:1000 WAN×1JH без Exit и10WAN×100JH без Exit — отделить rows/columns от full-route product. После baseline нужны page50 WAN/ограниченный набор JH columns/точные counts/поиск всех JH, map lookup по wan/jh без изменения состояния/best по полным legs.

buildLiveOptimizerData/assignProbesForWanJh делает DFS, когда WAN<=7 и WAN<=pool.length. Лимита pool нет. scoreProbeForWanIface допускает srcInterface="" для любого WAN; при7WAN/20 подходящих разных probes полное дерево содержит20P7=390700800 полных назначений (вывод из кода, не измеренный benchmark). Не запускать этот случай через Next/UI: сначала отдельный чистый CPU-профиль в дочернем процессе с жёстким timeout, без DB/RouterOS. Стратегию назначения/оптимальность нельзя менять без доказательства эквивалентности на малых наборах; простое обрезание pool может скрыть лучшее назначение.

commRecs строятся через filter(sourceServerId).slice(0,24), а HomeCard подписывает BGP community только длиной среза. Нужны полный source count/явное сообщение24 изN; нельзя выдавать24 за весь каталог или менять правила применения. Локальная вкладка карточки сбрасывается при pagination, native OSPF select1000 options остаётся. Общая main/context после delta и реальная внешняя12.5 ещё не закрыты. Этот блок — карта приёмки, не доказательство нагрузочной готовности. Product build a16bfae уже passed; для документации повтор не нужен. Следующий12.3.59 — указанные bounded profiles/CPU timeout. Локальный коммит без push.

12.3.59 — отдельные профили матрицы и CPU (2026-10-04)

2026-10-04. Live API подменён строгими DTO, без Exit и API mutations. Два браузерных профиля прошли: WAN1000×JH1 — 1000 строк,4 столбца,28019 DOM таблицы,28712 DOM страницы,4977мс dev-ready,108917байт; WAN10×JH100 — 10 строк,103 столбца,9803 DOM таблицы,10595 DOM страницы,2258мс dev-ready,16593байт. Время dev измеряет также загрузку/компиляцию и не является production benchmark.

Чистый расчёт7WAN×20 wildcard probes воспроизводится scripts/performance/optimizer-probes-profile.mjs, в отдельном child process с жёстким timeout10000мс. Расчёт не завершился за timeout; тяжёлый DFS нельзя воспроизводить в UI. Нет DB/API/сетевых операций. Следующий12.3.60 — страницы50WAN и ограниченное окно JH, поиск по полному каталогу, проверка обновления/сжатия и320px. Семантику назначения probes этим блоком не меняем.

12.3.60 — ограниченное отображение WAN matrix (2026-10-04)

2026-10-04. ReUI DataGrid/TanStack v9: клиентские страницы50WAN, окно5JH, поиск по полному WAN/JH каталогу, точные filtered/total counts. Fixed widths/горизонтальный DataGridScrollArea/закреплённый WAN; страницы сохраняются при refresh и нормализуются при сжатии каталога. Best score берётся из всех legs циклом без spread; Map WAN→JH сохраняет первый matching leg, как прежний find. Raw unknown/zero/даты и модель остаются раздельными. API writes отсутствуют.

WAN1000×JH1:1000→50rows,28019→1419tableDOM,28712→2149pageDOM,2264ms dev-ready. WAN10×JH100:103→8columns,9803→683tableDOM,10595→1492pageDOM,1785ms dev-ready. Полные исходные массивы остаются в памяти.

Проверены12browser + повтор2 после lint-правки, TypeScript без incremental, targeted ESLint, production build, ReUI validate_usage/checklist. Мобильные снимки docs/ux-ui/screens/optimizer-wan-matrix-{1000,100jh}-320.png просмотрены. Поиск последних объектов, последний диапазон, cache/refresh/clamp,320px/pinnedWAN и WCAG axe приняты. Общая регрессия после delta ещё требуется.6 manualPagination:true остаются; CPU DFS и срез24 commRecs не исправлены этим блоком.

12.3.61 — точное отсечение перебора проб (2026-10-04)

2026-10-04. DFS сохранил порядок WAN/pool, обязательный выбор совместимой пробы и первое назначение при равных totals. Отсекаются только ветви, чья верхняя граница не превосходит найденного bestSum. Две релаксации: сумма независимых максимумов remainingWAN и сумма наибольших remainingCount максимумов уникальных probe IDs. Каждое допустимое завершение ограничено обеими оценками; минимум также верхняя граница. Никакого изменения правил scores, fallback greedy для >7WAN/недостаточного pool, выбора интерфейсов, API или сетевых операций.

Независимый старый полный DFS в тесте совпал по exact probe IDs на1200 seeded fixtures с ties/incompatible/partial matching. Дополнительно equal20 сохраняет первые7 и проверен forced early choice.7 pure tests/type/lint,6 main browser и8 context прошли. Скрипт с child timeout10с теперь проверяет probe IDs: equal17.3ms(p0..6), varied16.6ms(p13..19), freshness60.9ms(p13..19). До правки equal превышал10с; первая слабая граница оставляла freshness2269ms, усиленная граница сократила его. Время child startup отдельно335–443ms, в расчёт не входит. Production build проходит.

Это профили7WAN×20, а не гарантия для любого размера/набора: DFS всё ещё экспоненциальный в худшем случае, исходный pool не ограничен; large mixed-interface/live нагрузка остаётся предметом production измерения. Следующий12.3.62 — скрытый срез24commRecs.

12.3.62 — исходный скрытый срез Community (2026-10-04)

2026-10-04. Live API fixture1000 правил Home1/1WAN/1JH/безExit, strict servers/rules DTO. UI показывает BGP community(24),24rows/504tableDOM/1197pageDOM/1916ms dev-ready. Это не performance-успех:976 правил вообще исключены до grid, counts не показывают реальный источник.1 browser/test lint passed, API writes отсутствуют. Следующий12.3.63 удаляет срез и ограничивает отображение pages50, сохраняя unknown indices безExit.

12.3.63 — весь Community-каталог с ограниченным отображением (2026-10-04)

2026-10-04. Удалён скрытый slice24 после фильтра sourceServerId; ownership и расчётная семантика сохранены. ReUI DataGrid pages50/full search/communityName/gateway/path, exact counts, full-model sort, fixed widths/horizontalScroll/pinnedCommunity. Row key формируется до фильтрации из прежнего home/community/index; pins сохраняются при search/sort/страницах/refresh. Global рекомендаций count теперь относится ко всем правилам. Live режим по-прежнему не применяет BGP-рекомендации; симуляция доступна только demo.

1000source→50 rendered/1024tableDOM/1751pageDOM/1851ms dev-ready; раньше24 rendered соответствовали24 в модели,976 правил терялись. Проверены page20 и правило1000/search/unknown indices безExit/no simulation buttons/refresh/clamp1/320px/pinned column/axe.7 main browser,8 pure tests (1200 assignment fixtures и новый1000 ownership/unknown), TypeScript, targeted lint и production build прошли. Снимок docs/ux-ui/screens/optimizer-community-320.png просмотрен.

Осталось5manualPagination:true: scheduler11 fixedkeys, live GRE pools пусты/demo ограничен fixtures, probes schedule толькоdemo, subusers не подключён, trafficflows серверныйtop50 принят с честным указанием среза. Не мигрировать искусственно недостижимые live каталоги. Дальше12.4.6/12.4.7 — повтор общей main/context матрицы после delta. Внешняя12.5 не выполнена.

12.4.6 — общая main регрессия после больших каталогов (2026-10-04)

2026-10-04, HEAD991f2b3.1162 сценария/190 файлов:1161passed,1unexpected,0skipped/0flaky за55.2min. Edge/1worker/retries0/maxFailures12. Единственный сбой terminal-data: поле не получило focus после успешного повтора BFD error. Вероятная гонка requestAnimationFrame с React commit/re-enable. Общая матрица НЕ объявляется полностью пройденной. Доказательство docs/ux-ui/acceptance/main-delta-2026-10-04.json; trace/error сохранены в tmp перед следующими тестами. Перегенерированные этим прогоном исторические PNG восстановлены по явному списку tmp/ux-main-regenerated-screens.json; собственные новые матричные/Community screenshots сохранены.

Все новые большие профили, Firewall/OSPF/optimizer сценарии вошли в этот общий прогон. Статический аудит дополнительно выявил полный join1000WAN в шапке HomeCard и полные site-строки JH/Exit в KPI: число DOM nodes не измеряет высоту текстовых сводок. Следующий12.4.6.1 — фокус после commit и профильный repeat; затем12.4.7 context. Внешняя12.5 отдельно.

12.4.6.1 — исправление гонки фокуса терминала (2026-10-04)

2026-10-04. requestAnimationFrame из finally заменён pendingFocus ref и DOM effect после commit. Поле получает focus только после снятия disabled; unmounted/blocked terminal не перехватывает фокус. Зависимость от lines покрывает быстрый запрос, даже когда executing=true/false попадают в один React batch. Порядок запросов, права, ownership и сохранение команд не менялись.

20 terminal-data/layout passed; все3 формы отказа повторены5раз:15/15passed,0unexpected/flaky. Evidence docs/ux-ui/acceptance/terminal-focus-2026-10-04.json содержит baseHead и SHA256 проверенного source. ESLint и production build прошли; отдельный non-incremental TypeScript повторён после завершения dev-сервера успешно. Первый параллельный tsc попал на временную перезапись .next/dev/types/routes.d.ts; исходники не имели этой ошибки. Исторические6 terminal PNG восстановлены по точному списку.

Это профильное закрытие единственного сбоя main12.4.6, не новый полный main прогон на исправленном HEAD. Следующий12.4.7 —221 context/26files (актуальная discovery; прежняя матрица213/25). Внешняя12.5 остаётся.

12.4.7 — общая context регрессия после delta (2026-10-04)

2026-10-04, HEADb1f8326.221/221passed/26files за15.8min,0unexpected/0skipped/0flaky,Edge/1worker/retries0/maxFailures12. Включены Firewall context и все поздние read/write/backend/mode/ABA/checkpoint сценарии. Evidence docs/ux-ui/acceptance/context-final-delta-2026-10-04.json. Terminal context прошёл на исправленном source. Перегенерированных tracked screenshots нет.

Main12.4.6 относится к991f2b3:1161/1162; единственный focus race исправлен и проверен20+15 в12.4.6.1. Полный main после этого маленького исправления не повторялся. Внешняя12.5 PG/RouterOS/integrations не выполнена; stage12 не завершён. Следующий12.3.64 — высота сводки1000WAN, затем дополнительные CPU/pool профили.

12.3.64 — компактная текстовая сводка WAN (2026-10-04)

2026-10-04. Baseline1000WAN:31783chars/13695px высоты summary на320px, хотя grid уже50rows/1419DOM. В HomeCard теперь preview первых3 WAN с прежними ISP/IP, точный remaining/total и понятная ссылка в copy на существующую вкладку WAN×JH. Для ≤3WAN описание не сокращено. Исходный массив/расчёт/поиск/таблица не срезаются.

Final1000WAN:134chars/86.5px высоты summary; WAN10:130chars/86.5px. В тест добавлены реальные размеры/длина preview, точные counts и мобильный snapshot.12 profile browser +1 screenshot repeat, full ESLint страницы/test и production build прошли. Полный search WAN1000, последняя страница, refresh/clamp/pinnedWAN/320px/axe сохранены. Снимок docs/ux-ui/screens/optimizer-wan-summary-320.png просмотрен;9 historical optimizer PNG восстановлены по явному списку.

Общие main/context доказательства относятся к прежним HEAD; этот небольшой текстовый delta проверен профильными сценариями. Исторический context-delta(a558412/36) сохранён отдельно от нового context-final-delta(b1f8326/221), чтобы ссылки12.4.3 не изменили смысл. Следующий12.3.65 — pure CPU7WAN×1000pool с hard timeout; не запускать в UI. KPI captions/native selector и худшая DFS/full-route комбинация не приняты этим блоком. Внешняя12.5 остаётся.

12.3.65 — CPU-профили pool1000 (2026-10-04)

2026-10-04, UI/source расчёта не менялись. Child script принимает integer count20–1000, hard timeout10с, без API/DB/браузера/сети.7WAN×1000: equal1217.5ms (IDs p0..6), varied7967.5ms (p13..19), freshness не завершился за10с, процесс остановлен. Startup отдельно ~0.4s. Freshness создаёт1000 разных возрастов, будущие timestamps не используются. ESLint скрипта прошёл; корректность ID проверяется после успешного завершения.

Это оставшийся CPU риск, а не performance приёмка. В current DFS повторяются Date.parse/trim/score и оценка upper для ветвей, уже достигших максимум. Следующий12.3.66: score cache только для bounded WAN≤7 DFS с одним snapshot time и early stop при достижении node upper, preserving first tie/order/forced picks/greedy fallback. Проверить1200 legacy oracle fixtures, raw observations, profiles20/1000. Худшая комбинаторика и весь full-route product по-прежнему не ограничены.

12.3.66 — точный выбор проб из большого pool (2026-10-07)

2026-10-07. Score matrix вычисляется только при exact DFS≤7WAN/pool≥WAN, с единым временем ранжирования на назначение JH. Сырые наблюдения/даты не меняются, greedy fallback сохранён. Допустимый score-first greedy путь даёт только lower total, не готовое назначение. Пока DFS не нашёл реальный witness, равные верхние границы НЕ отсекаются; первое равное назначение остаётся в исходном pool order. Node stop требует реального bestAssign. Для каждого кандидата child upper выводится из topK максимумов текущего узла с исключением занятой пробы; уже проигрышные siblings не пересканируют весь pool. Forced pick сохраняется, даже если ветвь отсечена.

1230 seeded сравнений с независимым прежним DFS совпали по точным probe IDs, включая30 смешанных наборов7WAN.10 pure tests прошли: ties/partial matching, single snapshot при переходе часа, прежний greedy для8WAN, unknown/zero/disabled/raw snapshots.51 main browser и8 context прошли; TypeScript без incremental, targeted lint и production build успешны. Historical9 optimizer PNG восстановлены по точному списку.

Pure child CPU1000: equal1217.5→15.6ms,varied7967.5→14.5ms,freshness10с timeout→16.7ms; CPU20:11.5–11.7ms. Child startup отдельно~0.25s. Exact IDs проверены во всех6 профилях. Evidence docs/ux-ui/acceptance/optimizer-probes-cpu-2026-10-07.json содержит source SHA256, baseline HEAD и результаты. Браузерная live ветка7WAN/1000probes:219902bytes/7rows/222tableDOM/1018ms dev-ready; timestamps соответствуют p993..999, после refresh сохраняются,320px без overflow, API mutations отсутствуют. Это не production SLA/нагрузка PostgreSQL/RouterOS и не гарантия произвольного mixed pool: худшая экспоненциальная сложность DFS и full-route product остаются.

Следующий12.3.67: KPI captions JH/Exit (повторы/пустая площадка/unknown), затем separate full-route CPU profile. Общая main/context регрессия12.4.6/7 относится к прежним HEAD; этот delta принят профильными51+8. Внешняя12.5 не выполнена.

12.3.67 — краткие и достоверные KPI-подписи площадок (2026-10-07)

2026-10-07. В существующем ReUI Stats12/KpiStatGrid footer переиспользован ReUI Badge outline/sm. Короткие уникальные названия (≤3 и≤24символов) показываются без повторов; большой/длинный список заменяется точным количеством площадок. Отдельно виден count узлов без площадки: пустые/whitespace/нормализованный — не считаются реальной площадкой. Нет полного join большого каталога. Неизвестный каталог сообщает «Площадки неизвестны»; нулевой topology pool — «Нет узлов в расчёте», потому что live topology исключает offline/disabled, а устройства могут существовать в inventory. Права/выбор узлов/расчёт/источники не менялись.

16 main browser +2 повторных новых профиля после copy-уточнения прошли:1000JH и1000Exit отдельно (без опасного cross product), repetitions/two sites/1000sites/long80chars/unknown/empty/offline/disabled/503 cache/recovery.320px без overflow, caption≤80px, scoped WCAG axe passed. Non-incremental TypeScript до dev, full page/helper/test lint и окончательный production build прошли. ReUI API/validate_usage проверены; primitive/theme не изменены. Historical9 optimizer PNG восстановлены, новые docs/ux-ui/screens/optimizer-sites-{jump-host,exit-node}-320.png просмотрены.

Далее12.3.68 pure child CPU profile full-route product≤100000/timeout10s/memory cap; не грузить тяжёлый baseline в UI. Остаточные DFS worst-case/full-route memory/native selector и внешняя12.5 не объявляются принятыми. Общая main/context регрессия относится к ранее записанным HEAD; текущий footer delta проверен профильными16+2.

12.3.68 — bounded CPU-профиль генерации полных маршрутов (2026-10-07)

2026-10-07. Pure child process без API/DB/браузера/сети, product≤100000/dimensions1–1000/timeout10s/V8heap256MB.1000WAN×1JH×1Exit1000routes≈16.9ms/heapDelta1.8MB;10×100×100100000routes≈329.6ms/22.0MB;100×10×100≈266.7ms/27.1MB. Первый измеренный прогон; точные повторные значения и source SHA256 в docs/ux-ui/acceptance/optimizer-routes-baseline-2026-10-07.json. Heap delta не peak/retained memory, время не production p95/SLA. Проверены count/first-last IDs/bestFirst/сохранение отсутствующих наблюдений. ESLint скрипта прошёл.

Baseline в UI не запускался. Повторный Array.find по1000wanJhLegs на каждую из100000комбинаций даёт лишние линейные сканирования. Следующий12.3.69: map lookup с сохранением первого matching leg и порядка routes/ties, профильный repeat. Полный product всё ещё хранится/сортируется в памяти; опасную произвольную размерность этот профиль не принимает. Далее аудит TX/RX и связи wildcard-пробы с конкретным WAN, прежде чем объявлять observed correctness закрытой. Внешняя12.5 отдельно.

12.3.69 — lookup leg и исключение ненужных расчётов без WAN (2026-10-07)

2026-10-07. WAN/JH map сохраняет первый matching leg, lookup вынесен из Exit loop. JH/Exit legs не строятся, если нет настроенного WAN: их не может использовать ни один full route. Порядок WAN/JH/Exit, сортировка/ties, raw source identity, all routes и unknown community indices сохранены.13pure tests прошли, включая1230 assignment oracle fixtures и новые проверки8route probe ownership/ties/zeroWAN.12browser (large homes/routes/observed/tables) passed; non-incremental typecheck до dev, targeted lint и production build успешны.

CPU final:1000routes13.3ms;100000(10×100×100)49.7ms;100000(100×10×100)44.0ms. До lookup ~284–329ms и267–287ms. Дополнительный zeroWAN baseline0×100×1000 строил100000unused JH/Exit legs:45.6ms/heapDelta24.6MB; после skip11.5ms/0.17MB. Новый profiler допускаетWAN0 и ограничивает также JH×Exit≤100000. HeapDelta не peak/retained memory; полный nonzero product по-прежнему хранится и сортируется в памяти. Evidence docs/ux-ui/acceptance/optimizer-routes-final-2026-10-07.json содержит source SHA256 и точные результаты.

После чтения реального producer обнаружены следующие вопросы достоверности:source btest выполняется на srcClient,TX/RX экспортируются без переименования,optimizer пока читаетTX какDL. srcInterface передаётся только after-ping, не bandwidthTest; поле не доказывает WAN скоростного теста. Producer parser/fallback отсутствующую скорость превращает в0, а explicit avg0 может заменяться mean series. Следующий12.3.70 фиксирует аудит с первичными RouterOS источниками и планирует точечные исправления данных/подписей. Команды/права/правила сетевых операций не менялись; real PG/RouterOS/integrations12.5 не выполнялись.

12.3.70 — аудит источника и смысла observed metrics (2026-10-07)

2026-10-07. Код сопоставлен с первичной RouterOS bandwidth-test документацией. Подтверждены неверное TX→DL, неподтверждённая связь btest с srcInterface/WAN, missing→0/explicit0→mean и отсутствие проверки terminal status перед success write. Это новые ограничения, которые ранее проверенные mock snapshots не доказывали. Отдельный протокол/таблица/схема: docs/ux-ui/optimizer-observed-audit-2026-10-07.md.

Только read-only audit/docs, без DB/RouterOS/сетевых операций. Дальше71direction mapping,72scope labels,73nullable rate parser/producer/DTO,74terminal confirmation. Фактические команды, права и routing rules не меняются этой серией; real12.5 отдельно. Исторические0 не переписывать автоматически.

12.3.71 — направление измерений DL/UL (2026-10-07)

2026-10-07. Для Home→JH RX клиентского bandwidth-test отображается как DL к Home, TX как UL от Home. JH→Exit использует тот же смысл; для reverse Exit→JH клиент на дальней стороне, поэтому TX→DL/RX→UL. Raw getter сохраняет nullable/zero/decimal и исходную дату; модельные maxDl/maxUl применяются к правильной стороне. Команды RouterOS, параметры теста, подбор probe IDs и правила операций не менялись. Ввод/трактовка скоростных данных исправлены по источнику srcClient и RouterOS CLI docs (ссылка в observed audit).

15pure tests passed:1230 assignment oracle fixtures, source ownership/ties/noWAN, новые asymmetric limits и forward/reverse/zero/null.51main browser и6 observed повторных (включая2новых direction/asymmetric сценария) прошли; TypeScript до dev, targeted lint и production build успешны. Старое ожидание ↓TX исправлено на ↑TX, а не ослаблено. Historical9 optimizer PNG восстановлены. Полная main/context матрица последнего общего прогона относится к прежним HEAD; этот delta проверен профильными сценариями.

Наблюдения по-прежнему не доказывают конкретный WAN bandwidth-test: следующее72scope labels. Backend producer missing→0/terminal status и OSPF metrics/route builder TX→DL требуют73–75. OSPF traffic fallback уже используетRX→DL, измеренная дата speed-probe намеренноnull и не требует изменения. Real12.5 отдельно.

12.3.72 — область скоростного снимка и единицы (2026-10-07)

2026-10-07. Матрица с probe snapshot явно объясняет:скорость — пара устройств, привязка WAN расчётная, DL кHome/UL отHome. В existing «Как читать расчёт» добавлена роль srcInterface для Ping после теста и выбор пути скорости маршрутизацией устройства. Скорости и model limits подписаны Мбит/с. Новых RouterOS параметров, routing rules, методов или API операций нет.

10browser (observed forward/reverse/null/zero,20/1000probes,1000WAN/100JH) прошли; TypeScript до dev, targeted lint и production build успешны. При noProbe измерения остаются неизвестными. Scope note находится один раз над таблицей, без повторения длинного предупреждения в каждой ячейке.

Остаются73missing→0/nullable consumer,74native terminal status,75OSPF direction. Чтение frontend consumer подтвердило ещё Math.round(null)→0 и доверие POST без runtime DTO; фиксировать73 вместе с producer. Границы мобильного pinnedWAN и соседней metric cell требуют отдельного76geometry теста, а не только проверки первого столбца. Внешняя12.5 отдельно.

12.3.73 — неизвестная скорость и подтверждение POST (2026-10-07)

2026-10-07. Backend parser возвращает null для отсутствующих/невалидных скоростей, переводит RouterOS SI bits/s в Мбит/с и сохраняет явный total-average 0 вместо замены средним. Серии включают только валидные значения; отсутствующие samples не получают нулей, временная геометрия пропусков здесь не реализована. Поля БД уже nullable, миграции и переписывания исторических записей нет. Frontend проверяет ok/result/runId и nullable finite nonnegative rates до публикации ответа. Контекст проверяется раньше DTO, поздний ответ чужого источника игнорируется. Running averages null; Math.round(null) исключён. Ошибка сохраняет предыдущие probe averages и подтверждённую историю.

7 pure parser/DTO +9 isolated scheduler journal tests прошли.71 main browser (uptime-links, speed-data, large-speed-history),8 context прошли; non-incremental TypeScript, targeted lint (9 существующих предупреждений uptime,0 errors), backend и frontend production build успешны. Первые два новых браузерных прогона обнаружили неверный KPI role selector и неоднозначность одинаковой подписи в истории/строке; selectors уточнены, финальный связанный профиль полностью passed. Historical large-speed-history-320 PNG восстановлен.

Следующий74: native terminal status ещё не проверяется перед done/DB write.75OSPF direction и76mobile metric geometry остаются. DTO доказывает целостность ответа, но не факт выполнения на устройстве. Реальная RouterOS/PG приёмка12.5 отдельно.

12.3.74 — подтверждённое завершение bandwidth-test (2026-10-07)

2026-10-07. Pure guard проверяет структуру native rows, все известные failure statuses и последний сообщённый status. Только done testing допускает дальнейший расчёт, after-ping и DB success write. Connecting/running, отсутствие статуса, неизвестный status, malformed response или error/failure/trap marker отклоняются с неизвестным результатом; native failures имеют краткие русские сообщения. Числовой enum не принимается как строковое подтверждение. Подтверждённый one-direction result может иметь null на другой стороне и0 на измеренной.

16 pure tests (3status,4rates,9scheduler) и backend build passed. Проверка placement/callers по source: HTTP и scheduled collection используют общий execute, их catch вызывает прежний failure recorder, который сохраняет старые probe averages и пишет error run с nullable rates. Полная DB/network orchestration не запускалась; это source review и pure guard tests, а не внешняя приёмка. Команда bandwidth-test и её параметры, locks, routing rules, permissions и DB schema не менялись.

Источник native statuses: RouterOS CLI bandwidth-test. Последний reported done допускает последующие rows без status, но любые failure markers отклоняются даже после completion. Реальный REST shape/версия RouterOS и PG writes требуют12.5. Следующие75direction OSPF и76mobile geometry.

12.3.75 — направление скоростных входов OSPF (2026-10-07)

2026-10-07. Источник выбирается через srcServerId текущего роутера, поэтому единый pure getter читает RX как DL и TX как UL. Getter используется raw observed и model speeds; route builder вызывает модельный helper вместо прежнего обратного сопоставления. Raw zero/null/fraction/source/date сохраняются. Модельные округление, floor1 и traffic fallback сохранены; formula Cost, pingWeight, unique probe assignment и порядок операций не менялись. Рекомендации Cost могут измениться из-за исправленных asymmetric inputs. Traffic fallback RX→DL/TX→UL уже был верен. Дата speed остаётсяnull, Ping date не подставляется.

Четыре backend suites passed: pure metrics (новые asymmetric80.75/30.25,0/null,rounding/floor/fallback), identity, plan и HTTP optimizer с DI/in-memory writes. Backend build passed. Source review подтвердил фильтрацию по srcServerId и вызов helper в builder. Реальный DB builder и RouterOS не исполнялись; HTTP suite подменяет buildOptimizationPlan и отдельно проверяет отсутствие операций до валидного плана. Frontend не менялся, повторный browser/build для него не требовался.

Следующий76: на320px проверить видимость всей соседней metric cell за pinnedWAN, исправить column sizing при подтверждённой проблеме. Общая main/context регрессия прежних HEAD требует обновления позже;12.5 остаётся внешней.

12.3.76 — читаемая мобильная WAN/JH матрица (2026-10-07)

2026-10-07. Геометрический baseline320px подтвердил дефект: viewport right303,pinned right197,cell right397 (200px колонка рядом с180px WAN). Пропорции ColumnDef на телефоне теперь112/160, desktop180/200 сохранены (actual table fill может расширять размеры). Hook useIsMobile и installed ReUI DataGridShell/ScrollArea/Table переиспользованы, primitive/hook/theme не менялись. Имя/интерфейс WAN ограничены truncate/min-w-0; полное значение остаётся DOM text/title и доступно поиску.

6 новых geometry cases320/390/1440×1/7JH проверяют всю metric cell и её speed text относительно pinnedRight/viewportRight, все7JH через переключение колонок, long WAN, отсутствие page overflow/API writes. Resize320→1440→320 прошёл, scoped WCAG axe passed. Related26browser, targeted lint, non-incremental TypeScript и frontend production build passed. Первый baseline намеренно failed на реальном переполнении, финальные assertions не ослаблялись. ReUI API и audit checklist прочитаны: v9useTable/dataGridFeatures/table/recordCount, existing layout/semantic tokens/security/scroll composition сохранены.

Доказательства: геометрия до/после, экран320px просмотрен. Historic9optimizer и2speed PNG восстановлены; предыдущие снимки не переписаны. Следующий12.4.8main/12.4.9context повтор на новом HEAD. Внешняя12.5 не выполнена.

12.5.0 — подготовка внешнего протокола (2026-10-07)

2026-10-07. Протокол12.5 подготовлен по фактическим backend routes/services/migrations: PG bootstrap0008/0009, backup/restore/rollback и writer lifecycle; outbox claim/dedupe/CAS/status-history; native bandwidth terminal/direction/scope, OSPF и остальные сетевые операции; реальные роли/интеграции. Каждая строка задаёт независимое подтверждение результата и очищенные артефакты. Локальные ссылки проверены. Внешние операции не выполнялись, credentials/dumps не читались и не сохранялись.

Source review: stopScheduler очищает таймеры, stopTrafficFlowListener запускает flush без ожидания, поэтому эти вызовы не считаются доказательством завершения всех writers. PG-6 и остановка senders остаются предметом реальной проверки, не закрываются checkbox/timeout. Протокол не добавляет команды к сетевым операциям и не объявляет реализованными отсутствующие BGP-prefix evaluator/live GRE schedule/processing recovery.

12.4.8 main1176 продолжает выполняться на runtime source HEAD579e816. Этот блок меняет только docs; исходники/конфигурация тестов не изменились после старта. Дальше завершить main, сохранить результат и запустить12.4.9context.12.5 не принята.

12.4.8 — общая main регрессия после исправлений оптимизатора/скорости (2026-10-07)

2026-10-07. Runtime HEAD579e816:1176/1176passed,0unexpected/skipped/flaky,34.9min. Edge/1worker/retries0/maxFailures12. После старта добавлен только внешний протокол docs5fedf7a; runtime diff579e816→current проверен пустым. Итог main записан отдельно от исторического12.4.6. Сырой JSON сохранён в tmp/ux-main-final-20261007.json. Исторические PNG, перегенерированные тестами, восстановлены по проверенному списку tmp/ux-main-regenerated-screens-20261007.json. Чужие skill/AGENTS/config/cache изменения не включены.

Этот общий прогон содержит новые large pool/site captions, direction/scope/nullable POST и6mobile geometry cases. Старый terminal focus race в этом прогоне не повторился. Source review дополнительно нашёл обновление speed probe только по id без endpoint ownership; snapshot update и run insert были отдельными операциями. Следующий небольшой12.3.77 защищает привязку пары и атомарность этих двух записей, без смены RouterOS команд; затем12.4.9 полныйcontext. Внешняя12.5 отдельно.

12.3.77 — пара устройств и атомарная запись speed-run (2026-10-07)

2026-10-07. Preflight сверяет probeId/srcServerId/dstServerId до создания RouterOS client/команды, mismatch/deleted даёт409. UPDATE snapshot success/error содержит id AND source AND destination и RETURNING id. Если пара изменилась/проба удалена за время native test, её snapshot не обновляется, история actual endpoints сохраняется с probeId=null. Snapshot и run insert теперь внутри одной Drizzle transaction для success и failure. Ad-hoc run без probeId сохраняет историю без обновления пробы. Команды, параметры, locks, permissions/schema не менялись.

25 pure/DI tests (9новых persistence: preflight, zero, source/destination/delete race, update/insert/pre-commit failures,ad-hoc;4rate,3status,9scheduler),5browser speed-test (новый409 и прежние ошибки/timeout/nullable/foreignrun), targeted test lint и backend build passed. Pure transaction в памяти моделирует rollback и отказ до commit, не доказывает потерю реального PG commit acknowledgement. Source placement и SQL predicates просмотрены; PG concurrency/transaction semantics требуют12.5.

Полный main1176 относится к579e816 до backend delta; frontend runtime после него не менялся, добавлен1профильный409тест. Следующий12.4.9context; после него12.3.78: adapter каталога сохраняет observations по id, нужно проверить смену пары и local publish после config save. Текущий77защищает пару при запуске/результате, не является CAS полной версии параметров пробы.

12.4.9 — общая context регрессия после speed ownership (2026-10-07)

2026-10-07, HEADa3fcba0.221/221passed,26files,0unexpected/skipped/flaky,7.5min. Edge/1worker/retries0/maxFailures12. Итог context сохранён отдельно от старых матриц; source tmp/ux-context-final-20261007.json. Смена backend/mode, ABA/late data/write/permission, закрытие scope и checkpoint прошли.

Main1176 на579e816 и backend ownership delta25pure/5browser наa3fcba0 остаются разными доказательствами, HEAD не подменён. Следующий78: при смене пары adapter upsert и frontend optimistic publish сохраняли старые observations; исправить после общего прогона и проверить профиль. Внешняя12.5 всё ещё не выполнена.

12.3.78 — снимок при изменении пары и приоритет истории (2026-10-07)

2026-10-07. Catalog replacement читает и блокирует существующие probe rows внутри прежней транзакции/advisory lock. Смена source/destination или новый id сбрасывает9наблюдаемых полей вnull, перестановка/enable и та же пара сохраняют measurements. История не удаляется. Frontend публикует configuration только после подтверждения; той же паре берёт последние observations из текущего state вместо readonly копии старого draft. Новый target получаетnull. Общий emptySpeedProbeObservations переиспользован через contracts; ReUI primitives/theme/composition сохранены.

Строка пробы выбирает running run, затем более новый подтверждённый run той же пары/интерфейсов только при существующем snapshot lastStatus/lastRunAt; иначе текущий snapshot. Это исключает старый history overlay после смены пары/возврата и сохраняет приоритет нового nullable результата над старым999. Первые два новых test runs выявили ошибки relative has/inert selector; исправлены проверки области формы/фонового state. Первый общий профиль72/73 показал реальную регрессию приоритета новогоnull над старым snapshot, она исправлена без изменения теста. Финальный73/73passed.

14pure (5новых frontend snapshot+9persistence), HTTP/DI/RBAC speed-probes write, contracts/backend build,73browser uptime/large history,8uptime context, non-incremental TypeScript, targeted lint (0errors,9предыдущих предупреждений uptime) и frontend production build passed. Финальная новая проверка: API save error сохраняет прежние80; успешная смена/возврат пары не показывает их как новый snapshot, history/KPI1run сохранены. Historic2speed PNG восстановлены. Реальное FOR UPDATE/concurrency требует12.5; здесь DI и source review.

Этот delta выполнен после общих main579e816/contexta3fcba0; общие результаты не переименованы в проверку нового HEAD. Следующий79: POST command body ещё использует parseInt/enum defaults; проверить строгий DTO до DB/native, сохранив валидные ad-hoc/scheduled сценарии и существующие команды/права. Полный CAS параметров пробы и реальные native timestamps также не объявлены проверенными. Внешняя12.5 отдельно.

12.3.78.1 — удаление неиспользуемого кода прежней таблицы (2026-10-07)

2026-10-07. Из uptime удалены неиспользуемые MiniBar/resBarColor/resPctColor/SortIcon/ResSortKey,2импорта и чистое вычислениеy1,3неактуальных eslint-disable directives. Reference search и предыдущий lint подтверждали отсутствие использования; активные render/API/measurement paths не менялись. Установленные ReUI primitives/hooks/theme не изменены.

Targeted lint страницы/helpers/tests теперь0errors/0warnings (до этого9warnings), non-incremental TypeScript и production frontend build passed. Для удаления неиспользуемых объявлений не добавлены повторяющие реализацию тесты; функциональный78 delta73browser/8context/14pure+backend HTTP/RBAC сохранён в предыдущем блоке. Следующий79: runtime command body schema до DB/native. Внешняя12.5 не выполнена; полная матрица относится к точным ранее указанным HEAD.

12.3.79 — строгие параметры команды speed-test (2026-10-07)

POST /uptime/speed-test проверяет runtime DTO до поиска устройств и запуска native операции. Отклоняются частичные/неканонические ID, неверные enum, дробная или недопустимая длительность, неверные типы текстовых полей и NUL. Валидные значения по умолчанию tcp/both/10s, ad-hoc без probeId, обрезка пробелов и прежние команды/права сохранены. Проверка вынесена в общий контракт, HTTP route — в фабрику с зависимостями. Ошибки запуска сохраняют нормализованные параметры; конфликт пары даёт409.

26 неверных HTTP bodies не вызывают поиск серверов, запуск или запись истории. Fastify inject проверил defaults/ad-hoc,404,409,400,502/timeout и JWT401/403/разрешённый mm:uptime:write. Дополнительно16 pure rate/status/persistence проверок, contracts/backend/frontend production builds, non-incremental TypeScript, targeted contract lint и diff check прошли. PostgreSQL и RouterOS не запускались; внешний12.5 остаётся открытым. Общие main/context результаты не объявлены проверкой нового HEAD.

Следующий12.3.80: текущая привязка защищает пару устройств, но не изменение интерфейсов, протокола, направления и длительности во время теста; проверить принадлежность snapshot полным параметрам без изменения сетевых команд.

12.3.80 — принадлежность результата параметрам speed-пробы (2026-10-07)

Preflight перед созданием RouterOS client проверяет id, оба устройства, оба интерфейса, протокол, направление и длительность. Изменение параметров возвращает409. Условный UPDATE успеха и ошибки сверяет те же поля; поздний результат сохраняется в истории с probeId=null и не перезаписывает изменённый snapshot. Enable/order/telemetry не относятся к параметрам измерения. Сетевые команды, locks и права сохранены.

23 pure rate/status/persistence проверки прошли: 7 новых проверяют каждый изменённый параметр для late success/error, неизменный контекст с явным0 и preflight. HTTP/DI проверил409 как для пары, так и для параметров, прежние26 invalid inputs/defaults/RBAC; backend/contracts build passed. Реального PostgreSQL/RouterOS не было: source review условного SQL и DI не заменяют12.5. Это сравнение параметров, не версия строки и не защита от ABA изменения с возвратом тех же значений.

Следующий12.3.81: каталог и frontend пока сбрасывают observations только при смене пары; распространить правило на все параметры измерения, сохраняя историю и enable/reorder.

12.3.81 — снимки и история при изменении параметров измерения (2026-10-07)

Общий sameSpeedMeasurement сравнивает пару, интерфейсы, протокол, направление и длительность в валидных read/write формах. Каталог читает полный конфигурационный снимок под прежним FOR UPDATE; смена любого параметра сбрасывает9 observations. Frontend публикует это правило только после API confirmation и выбирает историю по тем же параметрам. Enable/reorder сохраняют последние наблюдения, в том числе0; history не удаляется. ReUI компоненты и сетевые команды сохранены.

10 pure snapshot checks, HTTP/DI/RBAC каталога (все изменяемые параметры и сохранение0 при enable),74browser uptime/large history,8uptime context, targeted lint0errors/0warnings, non-incremental TypeScript и contracts/backend/frontend production builds прошли. Новый браузерный сценарий: save500 сохраняет80; успешная смена длительности20 и возврат10 оставляют snapshot unknown, история80 и KPI1run остаются. Перегенерированные3 исторических PNG восстановлены. Реальные PG locks/native tests требуют12.5.

Следующий12.3.82: POST receipt пока не возвращает серверное время, live publish использует время браузера и ставит Ping date даже без afterBtPing; исправить совместимо и проверить неполный/невалидный receipt. Общие main/context результаты не переименованы в проверки нового HEAD.

12.3.82 — серверное время результата и отсутствующий Ping (2026-10-07)

Backend возвращает createdAt из того же pingNow, который записывает в snapshot/history: время перед after-ping, не начало bandwidth-test. Frontend валидирует ISO timestamp, использует его в истории и локальном snapshot. Старый receipt без createdAt совместим: история сохраняет клиентское начало, snapshot использует время получения; это ограничение совместимости, не подтверждённое серверное время. Неопционально переданный неверный timestamp отклоняет receipt.

Без afterBtPing новая операция не получает lastPingAt; выбор нового done run не подставляет прежний Ping snapshot. Явный0 сохранён. 4 pure receipt проверки, HTTP/RBAC с server timestamp passthrough, types/lint и contracts/backend/frontend builds прошли. Финальный76/76 browser прошёл. Первый прогон остановлен после ошибки нового селектора: в selected-probe scope кнопка называется «Обновить данные»; исправлены только новые тесты, отдельно2/2 и затем полный76/76 passed. Проверены дата из сервера в таблице, старый99 не наложен, отсутствующий Ping и новый0. Исторические3 PNG восстановлены.

Проверка согласованности журналов до этого блока:104 одинаковых numbered records в обоих документах, все с датами, без пропусков/дублей. Следующий12.3.83: таблица и карточки пока выводят timeout при любом null RTT; неизвестный/отсутствующий результат должен быть отделён от подтверждённого отсутствия ответов. Внешняя12.5 открыта; общий main/context не объявлен проверкой нового HEAD.

12.3.83 — неизвестный RTT и отсутствие ответов Ping (2026-10-07)

История показывает «Нет данных» без afterBtPing, «RTT неизвестен» при null RTT и неопределённых/частичных потерях, «Нет ответов» при подтверждённых100% потерь. Ошибка и измеренный0 остаются отдельными состояниями. Карточка speed-пробы и связанная Ping-проба используют те же смыслы. Для null RTT шкала не заполнена как измерение. ReUI Data Grid/Frame и сетевые команды сохранены.

81/81 browser uptime/large history passed, включая5 новых состояний missing/unknown/loss100/zero/error в истории и карточке, отсутствие старого99 и reflow320px. Targeted ESLint0errors/0warnings, non-incremental TypeScript и contracts/frontend production build прошли. Для простой подписи не добавлены повторяющие реализацию unit tests. Исторические3 PNG восстановлены. Backend/native parsing не изменены; реальные native loss/status требуют12.5.

Следующий12.4.10: общая main матрица на новом HEAD после блоков79–83; затем12.4.11context. Предыдущие main1176(579e816)/context221(a3fcba0) сохраняются как отдельные результаты, не доказательство нового HEAD. Внешняя12.5 остаётся открытой.

12.4.10 — общая main регрессия после speed API/UI (2026-10-07)

Runtime HEAD9680a6422ba951a1737207663acbd6d562710b62:1186/1186passed,193files,0unexpected/skipped/flaky,32.8min. Edge/1worker/retries0/maxFailures12. Новый итог main; сырой источник tmp/ux-main-speed-final-20261007.json. Предыдущий main1176 на579e816 сохранён отдельно. Во время прогона HEAD и runtime не менялись. Исторические PNG восстановлены по проверенному списку tmp/ux-main-speed-regenerated-screens-20261007.json; перед запуском screenshots были clean.

Новые10 browser scenarios после прежней общей main вошли в матрицу: конфликт пары, смена пары/длительности, server timestamps/Ping и5 nullable Ping состояний. Дополнительно37pure snapshot/receipt/rate/status/persistence и HTTP/DI/RBAC обоих speed routes прошли на9680a64; contracts/backend/frontend builds уже passed по блокам79–83. В dev logs были отказы фоновых чтений localhost:8000 (OSPF/catalog/sidebar-counts/EvoBGP); backend не запущен, assertion failures нет. Это локальная UI/DI приёмка, реальные интеграции не проверены.

Следующий12.4.11: полная context матрица на том же runtime. Внешняя12.5 открыта: реальные PG transactions/locks/commit acknowledgement, RouterOS, интеграции и остановка worker требуют стенда. Чужие skill/AGENTS/config/cache изменения не включены.

12.4.11 — общая context регрессия после speed API/UI (2026-10-07)

221/221passed,26files,0unexpected/skipped/flaky,7.8min. Edge/1worker/retries0/maxFailures12. HEAD683148d6201aca73d1be267db8110ff1e14faf53; runtime9680a6422ba951a1737207663acbd6d562710b62. Между ними изменены только main report и документы; git diff по app/components/lib/packages/backend перед стартом пуст. Новый итог context, сырой источник tmp/ux-context-speed-final-20261007.json. Старые context221 наa3fcba0 и main1176 на579e816 сохранены отдельно.

Main1186/1186 на9680a64 и эта context матрица теперь включают runtime блоков79–83. Дополнительно7 чистых producer DTO checks подтвердили ISO преобразование PostgreSQL timestamp с сохранением instant, nullable/zero и отказ от неверных записей. Вместе с предыдущими37 —44 чистых теста; HTTP/DI/RBAC speed command/catalog и contracts/backend/frontend builds passed. Реального подключения к PostgreSQL/RouterOS не было.

Следующий12.5: подготовленный протокол внешней приёмки. По имеющимся локальным мокам нельзя подтвердить реальные PG rollback/row locks/commit acknowledgement, RouterOS и внешние интеграции. Для этого нужен отдельный стенд. Этап12 остаётся открытым до внешней приёмки; локальные матрицы не являются заявлением о полной production готовности. Локальные коммиты без push; чужие изменения сохранены.

12.5.1 — подготовка удалённого тестового Docker-стенда (2026-10-07)

По прямому поручению пользователя подготовлен временный сервер161.104.46.222,root,Debian13.7 trixie/x86_64. До установки Docker отсутствовал;1CPU/1973MiB RAM,23GiB свободно. Установлены Docker Engine29.8.2,Compose5.6.0,Buildx0.37.1 из официального apt repository,git/python3 и4GiB swap. Docker systemd enabled/active,hello-world passed. SSH и сетевые настройки подключения сохранены.

Создан /opt/mmapp-test (0700),Compose по main с отдельными именами/project/data,ограничением logs,loopback3000/8000 и фиксированными тегами. Пароль SSH не сохранён в репозитории; PG/JWT secrets сгенерированы на сервере в.env0600 без вывода. Compose config --quiet passed; SHA256 совпал с локальным шаблоном. Реальный PostgreSQL18.6 запущен,healthy и SELECT version() passed; порт БД не опубликован. Паспорт и дальнейшие команды, Compose, env-шаблон.

Это подготовка инфраструктуры, не приёмка PG-1/restore/native: backend/frontend ещё не собраны и не запущены, bootstrap не выполнен. Следующий12.5.2 — чистые CI build contexts,закреплённые образы без push,bootstrap/health и начало PG-протокола. Локально docker CLI отсутствует; серверный Docker готов. Публикация Gitea/CI не выполнялась; локальный коммит без push. Ресурсы стенда не представляют production performance.

12.5.2 — сборка Docker и запуск приложения на тестовом сервере (2026-10-07)

Собраны backend/frontend из закреплённого коммита4d88b97d490b2342aa4de81d093a0b8d4902e8d4,через чистые build contexts по CI main. Архив8MiB не содержит локальных.env/лицензии/ключей/node_modules. Образы mmapp-test/backend:ux-4d88b97 и mmapp-test/frontend:ux-4d88b97 созданы на сервере без push;version1.0.0-test.4d88b97,revision label сохранён. Контейнеры запущены наloopback;backend/PostgreSQL healthy,health напрямую/черезfrontend status:ok. SSH-туннель3000/8000 открыт для проверки.

Реальный PostgreSQL применил9миграций,включая0008/0009;CHECK разрешает5статусов outbox и resolution_version>=0. После restartbackend совпали контрольный uptime_settings(id1/retention14) и список миграций;health восстановился. Пустые servers/probes/history прочитаны через API. Первый live browser smoke:3экрана200,безJSerrors/API>=400,320px fits,безHTTP-моков. Снимок320px просмотрен.

Smoke обнаружил ошибку Internet path приHTTP200: внешний sampledAt пришёл строкой PostgreSQL вместоISO;корректный snapshot отклонён строгимfrontend. Общий smoke не является полной приёмкой: UI-source error сохранён в отчёте. Следующий12.5.3 — нормализация producer timestamp,пересборка и повтор live-smoke. PG backup/restore/concurrency/native/integrations не проверены. Внешний PG-1 проверен bootstrap/restart/schema/control-row в указанной границе.

12.5.3 — нормализация даты Internet path на границе API (2026-10-07)

Выявленный на реальном Docker/PG дефект исправлен mapper/GET latest: внешний PostgreSQL sampledAt преобразован вISO без смены instant;payload не изменён. Неверные дата/payload возвращают502. Строгийfrontend DTO сохранён. Pure collector/mapper tests и6frontend path contract tests прошли,contracts/backend build passed. Сетевые команды/правила не менялись.

Source673e5ba444ced304ea099a99108964e1c471482f:backend/frontend пересобраны с version1.0.0-test.673e5ba и revision labels;образыux-673e5ba запущены,backend/PG healthy. APIlatest отдаёт одинаковыеISO датыsnapshot/outer;записьPG и контрольные настройки/9миграций сохранились. Итоговый real browser smoke:3экрана200,54APIreads200,0JSerrors,320px fits,Internet path подтверждён,HTTP-моков нет. Первое повторное ожидание скрытой подписи свежести поправлено раскрытием штатного блока;проверка данных послеpatch прошла. Дашборд320px просмотрен.

Паспорт стенда содержит image IDs,версии,доступ и ограничения. SSH-туннельlocalhost3000/8000 открыт;приложение работаетнаloopback тестового сервера. Следующий12.5.4 — PG backup/restore/concurrency/права и остановка writers/workers по протоколу. NativeRouterOS/Telegram/Portal не проверены,вся12.5 не закрыта. Предыдущие общиеmain/context относятся к своимHEAD,не к этомуbackend patch. Локальные коммиты безpush;секреты/чужие изменения не включены.

12.5.4 — подключение первого реального CHR к тестовому стенду (2026-10-07)

По поручению пользователя в Docker-приложение161.104.46.222 добавлен CHR194.226.121.150,serverId1. HTTPS443 отклонял соединение;SSH read подтвердил www80 enabled,www-ssl443 disabled,сертификатов нет. Пользователь явно выбрал HTTP REST безTLS. Запись обновлена через штатныйPUT наport80/useSsl=false;дубликат не создан. Конфигурация RouterOS не изменялась;SSH использован только для чтенияresource/services/certificates.

Test-connection200:identityCHR,RouterOS7.24.5 stable,CHR OpenStack Foundation OpenStack Nova. Poll200/statusonline,GET200 подтвердилonline/версию/model/polledAt. После poll имя в приложении сталоCHR по штатнойidentity синхронизации. Typehome-router — default существующей формы/контракта;роль маршрутизации отдельно не назначалась. Очищенное доказательство содержит только несекретные поля;реальныйUI row виден,HTTP-моков нет.

Первое обновление из вспомогательного скрипта использовалоPATCH и получило404;по исходникам исправлен метод наPUT,успешный ответ200 подтверждён. Пароль не записывался в репозиторий/отчёт/вспомогательный файл;передан API для хранения в тестовойБД как предусмотрено приложением. Нет заявлений о speed/VPN/routing apply:сейчас проверены подключение и чтение/опрос. Для bandwidth-test потребуется второе устройство. Следующий12.5.5 — PG backup/restore/concurrency/права/workers и профильные сценарии сCHR по протоколу. Все коммиты локальные,безpush.

12.5.5 — второй CHR и подтверждённая пара устройств (2026-10-07)

По поручению пользователя добавлен CHR104.165.244.7,serverId2. HTTP REST80/useSsl=false,admin/пароль переданы только API через скрытыйprompt;в Git/отчётах/скрипте секрет отсутствует. Test-connection200/identityCHR/RouterOS7.24.5 stable,создание201,poll200,statusonline,повторныйGET200. Первая запись194.226.121.150(id1) такжеonline. Очищенный паспорт пары. Дубликат не создан,конфигурацияRouterOS не изменялась.

Имена обоих устройств после штатнойidentity синхронизации —CHR;различать поIP/id. Typehome-router(defaultконтракта),специальнаяроль отдельно не назначалась. Следующий12.5.6 — короткие nativeTCP bandwidth-test дляtransmit/receive/both и независимоеGET истории;PGbackup/restore/concurrency/права/workers и остальные12.5 остаются открыты. Все коммиты локальные,безpush.

12.5.6 — реальные TCP bandwidth-test на паре CHR (2026-10-07)

Source194.226.121.150(id1) → destination104.165.244.7(id2),RouterOS7.24.5;приложение673e5ba на161.104.46.222. Первыйtransmit3s вернул502/native «не смог подключиться»;GET истории подтвердилerror иTX/RXnull. Остальныеавтоматические запуски остановлены. ЧтениеRouterOS показалоbandwidth-server enabled=false наобоихCHR. Первоначальная ошибка.

Пользователь явно разрешил включитьслужбу наобоих устройствах сauthenticate=true. POSTset/независимыйGET200 подтвердилиenabled=true,authenticate=true,max-sessions100 сохранён. Это единственное изменение конфигурацииRouterOS в этом блоке;служба остаётся включённой для дальнейших тестов. Настройки и взаимныйPing:3ответаиз3 в каждом направлении,0%потерь,примерно53–56ms.

Повторные короткиеTCP tests transmit/receive/both по3s прошлиHTTP200;native массивзаканчиваетсяdone testing. Transmit:TX1771.419912Mbps/RXnull;receive:TXnull/RX1454.885984Mbps;both:TX1124.95272/RX863.660264Mbps. After-ping53–54ms/0%loss. Очищенные API receipts и независимый GET истории совпали поrunId/endpoints/direction/duration/averages/date/status. Nativeданные не подменены моками;неизмеренная сторонаnull,первый отказ не объявленdone/zero.

RealUI показывает3successful и1failedhistoryrows,неизмеренная сторона «Неизвестно»,320px fits. ПервыйUI-selector ожидал русские «Готово/Ошибка»,но существующаятаблица выводитdone/error;проверка уточнена пофактическим caption,продуктовый код не менялся. Это короткая функциональная проверкаTCP,не benchmark устойчивой скорости и неWAN-interface/source binding. Ad-hoc runs безprobeId:probe ownership/snapshot race этим не проверены. PGbackup/restore/concurrency/права/workers,ROS остальныеошибки/UDP/OSPF/VPN/интеграции ещё не приняты. Следующий12.5.7 — продолжение протокола;локальныйкоммит безpush,credentials в evidence отсутствуют.

12.5.7 — реальный архив PostgreSQL, права и конкуренция операций (2026-10-07)

Стенд 161.104.46.222, source 673e5ba, PostgreSQL/server и pg_restore/client 18.6. Очищенный отчёт. Для проверки прав временно включён AUTH_REQUIRED=true; JWT с тестовым issuer сформированы только в памяти контейнера. Восемь запросов backup/restore: anonymous и wrong issuer → 401, settings writer и wrong app → 403. Admin mm:settings:admin получил backup HTTP200, 475225 байт, PGDMP, SHA256 a6b66402b28bdb146cae9712c384979aa1c1000fee19cbc97c0ec045b673c002, outcome {} без предупреждений. Настоящий Portal SSO и отсутствие процессов при отказах отдельно не инструментированы: PG-7 принят только в границах HTTP RBAC.

PG-2: pg_restore --list прочитал 907 TOC entries, включая servers, uptime_settings, uptime_speed_test_runs и schema_migrations. Архив успешно восстановлен pg_restore --single-transaction --exit-on-error в отдельную mmapp_acceptance_20261007, exit0. Независимые SQL сравнили исходную/проверочную БД: два server ID/IP, retention14, девять миграций, пять speed history rows с одинаковым digest, servers_id_seq last_value2/is_called=true. Новая запись после restore не выполнялась; API restore основной тестовой БД этим не проверен. Архив содержит учётные данные и остался только на сервере: data/acceptance-private 0700, dump0600, вне Git. Проверочная БД сохранена, активных соединений к ней после теста0.

PG-5: отдельная SQL-транзакция временно удерживала ACCESS EXCLUSIVE lock таблицы servers, первый HTTP backup запустил реальный pg_dump. Независимое соединение наблюдателя подтвердило application_name=pg_dump/wait_event_type=Lock/wait_event=relation. Конкурирующий POST restore с валидным доверенным архивом получил409 «Операция с базой приложения уже выполняется». После ROLLBACK тестового lock первый backup вернул200/PGDMP/478793 байта. Первая попытка наблюдения использовала кешированный stats snapshot внутри удерживающей транзакции и не увидела процесс; исправлена отдельным observer connection, повторная проверка прошла. Первый контрольный SQL ошибочно называл таблицу uptime_speed_runs; исправлен на uptime_speed_test_runs.

Выявлен незакрытый PG-6: stopScheduler отменяет таймеры без ожидания текущих jobs; stopTrafficFlowListener вызывает flushPending без await и не подтверждает завершение worker. API restore основной БД не запускался. После проверки AUTH_REQUIRED возвращён в false, /api/auth/config это подтвердил, /health ok/version1.0.0-test.673e5ba; listener по-прежнему disabled/alivefalse/boundfalse. Код продукта и RouterOS в этом блоке не менялись. Следующий 12.5.8: обеспечить ожидание завершения jobs/flush/worker, проверить lifecycle перед PG-3/4; остальной протокол остаётся открытым. Локальный коммит без push.

12.5.8 — ожидание заданий планировщика перед операцией с БД (2026-10-07)

Исправлена первая часть обнаруженного в12.5.7 lifecycle: scheduler-running закрывает admission до ожидания всех активных jobs. Слот освобождается в существующем finally после collector и записи scheduler journal. Ожидание ограничено30сек; при таймауте pg_dump/pg_restore не запускается, исходная ошибка сохраняется, consumers проходят стандартную попытку перезапуска. Повторный запуск уже выполняющейся job по-прежнему отклонён. system-database-backup подключён к новым stopSchedulerForDatabaseOperation/restartSchedulerAfterDatabaseOperation; обычный stopScheduler для существующих потребителей сохраняет синхронный контракт.

Новые ручные запуски во время паузы получают409 «Планировщик приостановлен для операции с базой», вместо неверного «Задача уже выполняется». Alert collector hooks не планируют/не запускают новые jobs во время паузы; уже ожидающий hook проверяет паузу перед runner. RefreshScheduler защищён поколением: stop или более новый refresh отменяет продолжение старого после каждого await чтения настроек. Refresh в период database pause не создаёт интервалы; штатный restart прочитает актуальные настройки.

Изменены scheduler-running.ts, scheduler.ts, alert-collector-hooks.ts, system-database-backup.ts и scheduler route; новый lifecycle test включён в test:scheduler. Проверки: test:scheduler17/17 (3lifecycle,9recorded-run,5HTTP), test:system-database (7pure tests и HTTP/JWT scripts) passed; contracts/backend build passed. Проверены два одновременно активных jobs/отказ нового запуска, сохранение паузы до завершения, timeout с нулём вызовов database command, recovery, queued alert hook и HTTP409 с настоящим manual runner. Эти проверки не требуют native RouterOS apply или очистки тестовой БД.

Это локальный кодовый блок, не завершение PG-6. NetFlow ещё использует fire-and-forget flush/terminate; прочие ручные API writers и другие экземпляры не охвачены scheduler gate. Активный Docker source остаётся673e5ba, новый код пока не развёрнут. Восстановление основной тестовой БД не запускалось; данные/CHR/серверный auth режим не менялись. Следующий 12.5.9 — graceful stop с подтверждением завершения worker flush и выхода worker, затем сборка/развёртывание и наблюдаемая PG-6 приёмка. Локальный коммит без push.

12.5.9 — подтверждённая остановка NetFlow worker перед операцией с БД (2026-10-07)

Добавлена отдельная IPC команда shutdown для database operation; обычный stop остальных потребителей не подменён. Worker прекращает приём datagrams, закрывает UDP socket/таймер, ждёт принудительный flush без prune и pool.end(), затем отправляет shutdown-complete и закрывает parentPort. Основной процесс требует и acknowledgement, и exit0. Timeout30сек, неподтверждённый exit и ошибки отменяют database operation без принудительного terminate. Неуспешный stop остаётся latched: попытка restart не уничтожает worker с неподтверждёнными записями и возвращает существующее listenerError предупреждение.

Flush engine сериализован общей очередью: завершающий flush не обгоняет уже выполняющуюся запись; отказ одного вызова не ломает следующий. По окончании worker дополнительно ожидается очередь main engine. Listener admission закрыт на весь database operation: обычный start во время паузы отклонён; явный restartAfterDatabaseOperation снимает паузу только после успешного stop. Асинхронный spawn проверяет паузу после чтения контекста, поздний exit старого worker не сбрасывает ссылку на новый. system-database-backup подключён к отдельной паре stop/restart.

Проверки: четыре новых pure/protocol tests прошли — ack без exit недостаточен, exit без ack/exit1/timeout отменяют операцию, final flush ждёт in-flight rejected flush, настоящий worker thread подтверждает shutdown и штатно выходит. Это worker fixture для транспорта, не настоящий UDP collector с PostgreSQL. Новый тест включён в test:system-database. Существующие7pure database tests, HTTP/JWT scripts прошли; contracts/backend build после окончательных изменений passed; diff-check passed. Тесты с очисткой БД не запускались.

PG-6 ещё открыт: тест с реальным collector/UDP и длительным SQL, конкурирующие ручные API writers, вспомогательные writers и другие экземпляры не проверены. flushPending сохраняет прежнюю best-effort обработку ошибок отдельных хранилищ: подтверждение означает завершение попыток записи/закрытие pool, а не гарантию сохранения каждого packet. Новый код пока не развёрнут, активный source673e5ba; данные стенда/RouterOS не менялись, API restore основной БД не запускался. Следующий12.5.10 — запуск текущего collector в выделенной mmapp_acceptance_20261007, наблюдение UDP/SQL drain и безопасный контроль остальных writers перед развёртыванием/PG-3/4. Локальный коммит без push.

12.5.10 — настоящий NetFlow collector: UDP и ожидание SQL перед выходом (2026-10-07)

На161.104.46.222 запущен временный docker compose run --rm --no-deps backend с актуальным compiled dist изsourcef8da3e0; основной backend/frontend не пересоздавались. DATABASE_URL в памяти тестового процесса/унаследованного worker ограничен отдельной mmapp_acceptance_20261007. Приложение не подключено к этой БД. Очищенный отчёт, SHA256 архива и worker JS совпали с локальными файлами. Секреты/дампы не передавались в репозиторий.

Настоящий traffic-flow-collector-worker слушал127.0.0.1:4749 только внутри временного контейнера; синтетический NetFlowv5 datagram отправлен через реальный UDP socket, exporter map сопоставил127.0.0.1→server1. SQL-транзакция удерживала ACCESS EXCLUSIVE lock traffic_flow_settings, независимый pg_stat_activity наблюдатель увидел Lock/relation в проверочной БД. После shutdown и500ms worker ещё не вышел/stop promise не завершился. Успешная привязка нового probe socket к4749 доказала освобождение UDP до завершения SQL drain. После ROLLBACK lock полученыshutdown-complete иexit0; pool connections worker после выхода0.

Независимый SQL сравнил baseline1500bytes и итог3000bytes/20packets в двухflow rows: ровно+1500bytes одного тестовогоdatagram. Baseline обязателен: предыдущая неуспешная попытка оставила тестовую запись в этой выделенной БД. Первые попытки не завершили сценарий: staging mount /app/acceptance не находил backend dependency dotenv (выявлено после добавления диагностики); mount перенесён в /app/backend/acceptance. Затем10сек ожидания lock истекли; окончательный запуск дал initial tick2500ms перед observation и прошёл всеassertions. Это исправления harness, продуктовый код в этом блоке не менялся.

Проверочная БД теперь содержит синтетические flow rows и изменённые collector counters; прежнее сравнение12.5.7 описывает состояние на момент backup, не нынешнюю идентичность БД. Временный контейнер удалён штатным--rm, worker остановлен. Основной /health ok/version1.0.0-test.673e5ba/alivefalse/boundfalse, оба serverID/IP иuptime retention14 сохранены. КонфигурацияCHR/traffic-flow на маршрутизаторах не менялась.

Принята частьPG-6 для isolated collector/drain, не весь app-wide сценарий. Ручные API writers, вспомогательные writers, параллельные экземпляры и API restore не проверены; новый код ещё не развёрнут в основном приложении. Следующий12.5.11 — admission/drain ручных запросов и аудит остальных писателей, затем deployment и полнаяPG-6/PG-3/4 проверка. Локальный коммит безpush.

12.5.11 — ожидание ручных API-запросов и закрытие live-подписок (2026-10-07)

Добавлен DatabaseRequestGate и root onRoute hook перед регистрацией API. Каждый API handler получает lease до выполнения и освобождает его вfinally после фактического завершения, а не onResponse/socket close. ВключеныGET: некоторые чтения имеют lazy/cache side effects. /health и /api/auth/config остаются доступными. Backup/restore захватывают exclusive gate на весь handler, включая audit event; новый API-запрос получает409 с понятной причиной, конкурирующая database operation409. Ожидание30сек; timeout отменяет команду, не объявляет незавершённые запросы завершёнными; при повторной попытке они остаются в active registry.

Traffic flow live и server traffic live регистрируют abort callback. Exclusive gate останавливает их циклы и ждёт завершения asynchronous cleanup; не подменяет закрытие socket завершением обработчика. Отмена запоминается и приходит сразу при поздней регистрации callback, если ещё выполнялось первоначальное чтение сервера. Прочие длительные запросы не прерываются принудительно: при превышении30сек database operation отменяется. Gate локален одному Fastify instance; другие процессы/экземпляры не охвачены.

Аудит выявил detached writers: routes/backups.ts запускает event promise иqueueMicrotask/processBackupJob послеHTTP202; traffic-flow-ripe.ts запускает background resolver/loadPg и fire-and-forget persist/persistAsn. HTTP lease эти задачи не покрывает. Их нельзя считать завершёнными только поHTTP-ответу; PG-6 остаётся открытым, API restore не выполнялся. Код на сервере не пересобирался/не развёртывался, основной source673e5ba сохраняется.

Проверки:4новых gate tests passed — ожидание активного handler/отказ новых иконкурирующегоexclusive, timeout с нулёмdatabase commands иправильнымповторнымdrain, stream cancellation сожиданиемcleanup, Fastify child routes/GET409/health200/поздняярегистрацияabort/возобновлениеAPI. Полный test:system-database15pure/protocol tests иHTTP/JWT scripts passed; contracts/backend build passed; diff-check passed. Новые проверки включены вpackage script. Изменены index.ts, traffic.ts, traffic-flow.ts, добавлены gate service/plugin/test. RouterOS иданныестенда не менялись.

Следующий12.5.12 — зарегистрировать/дождаться detached backup jobs иaudit, закрыть admission идождатьсяRIPE resolver/persistence; послеэтого сборка/развёртывание ивнешняяPG-6/PG-3/4 проверка. Локальныйкоммит безpush.

12.5.12 — ожидание фоновых jobs, audit и записей RIPE (2026-10-07)

Добавлен общий process-local DatabaseBackgroundWork. Promise регистрируется до запуска отложенного тела; drain ждёт settlement всех задач, включая дочерние записи, которые регистрируются во время завершения parent task. Timeout30сек отменяет database operation; pending registry сохраняется для следующего drain. Rejection наблюдается отдельно и не ломает ожидание остальных задач; завершение drain не объявляет неуспешные записи успешными.

Backups HTTP202 теперь регистрирует job до microtask запуска и держит его учтённым до processBackupJob/terminal audit. Started/restore audit promises также учтены; ошибки audit не подменяют подтверждённую операцию. Выпуск сертификата изqueue учтён доprogress/terminal state/event. Опрос сервера учитывает detached dropExpiredPartitions/ensurePartitionsAround (DDL особенно опасен во времяrestore). Фоновые загрузки topology/catalog/интерфейсов/classification catalog также учтены, хотя часть изних только читаетБД/обновляетmemory cache.

RIPE учитывает loadPg, resolver worker иотдельные persist/persistAsn promises. Pause закрывает admission cache misses иочищает ещёневыданную best-effort enrichment очередь; текущие resolver иихSQL writes ожидаются. ПослеstopListener иscheduler drain database operation ждёт общий background registry; стандартный restart вновьразрешаетRIPE. Настоящий UDP worker передpool.end также вызываетpause/drain, поэтомуизолированные auxiliary writes не могут остаться заегоподтверждённымвыходом. Большая очередь/длительныйnativejob могут привести кtimeout иотменеоперации, анепринудительнойостановке.

Проверки: test:system-database19pure/protocol tests иHTTP/JWT scripts passed (4background,4HTTPgate,4shutdown,4restore,3operation). Новый integration fixture среальнымbackup handler подтвердилHTTP202 иdrain, которыйне завершается доотложеннойcreate task. RIPE test сотключённымpersist иподменённымfetch подтвердил0fetch во времяpause ивозобновлениепослеresume. Существующийbackups-operations HTTP test passed;10certificate execution tests passed; contracts/backend build послеокончательныхизменений passed; diff-check passed. Тесты неочищалиБД инеприменялиRouterOS config.

Код пока неразвёрнут, основнойruntime673e5ba сохраняется; данные/CHR/auth стенданеизменялись. PG-6 остаётсяоткрытым доинтегрированногонаблюдения всехпутей. Restore ещёнепроверен; отдельнотребуется cache invalidation послевосстановления, иначеmemory topology/RIPE/settings могут отражатьпредыдущуюБД. Другиеэкземпляры/хосты registry негарантируетостанавливать. Следующий12.5.13 — integrated HTTP/scheduler/background/UDP quiescence ввыделеннойпроверочнойБД, аудитcache invalidation/deployment, затемPG-3/4. Локальныйкоммитбезpush.

12.5.13 — сброс кэшей после подтверждённого восстановления БД (2026-10-07)

Добавлен invalidateSystemDatabaseCaches, вызываемый послеуспешногоpg_restore внутриrestore execution, доcleanup иперезапускаconsumers. Очищаются settingsRowCache, server/topology catalog, RIPE/index/ASN cache, интерфейсы, classification catalog, analytics/map hops, engine pending/recent/rings/minute accumulators иfact/engine ensured partition sets. Последнее исключаетповторноеиспользованиепамяткиосозданныхразделах, которыхуже можетнебытьввосстановленнойБД. Engine data epoch обновлён, runtime pending cap сохранён. GeoIP readers/file state не изменены: MMDB лежатвнеPostgreSQL dump.

Production invalidate/reset функции отделеныотForTests API; старыеимена сохраненыдлясуществующихтестов. RIPE invalidation сохраняетdatabase pause/enqueue/persist/fetch options: очисткакэшейне открывает admission воперации. Inflight tasks должныбытьпредварительнодренированы механизмами12.5.8–12; приошибкеpg_restore invalidation неприменяется.

Проверки: полныйtest:system-database21tests иHTTP/JWT scripts passed, затемновыйсовместныйcache/drain testpassed (всего22различныхtests). ПровереныудалениестарыхRIPE/interface/live данных безоткрытияRIPE, успешныйrestore→invalidate иотсутствиеinvalidate приошибкепроцесса. Совместныйfixtureснастоящимиoperation/restore helpers иbackground registry доказалпорядокstop listener→background drain→restore→invalidate→restart listener/scheduler; restart увиделочищенныйinterfacecache. Командаpg_restore вэтомfixture подмененаDI, это не реальныйPG-3. RIPE/ifindex/classify regression scripts иcontracts/backend build прошли; diff-check passed. БД/RouterOS влокальныхтестахнеизменялись.

Коднеразвёрнут: основнойruntime673e5ba сохраняется. PG-6 целикомоткрыт, чтение/rollback реальногоAPIrestore ещёнеподтверждено. PostgreSQL dump не содержитGeoIP/backup/certificate files; ихдоступностьнужноучитыватьвприёмке. Другиепроцессы/хосты gate/registry неостанавливает. Следующий12.5.14 — integrated real-PG HTTP/scheduler/background/UDP quiescence ввыделеннойпроверочнойБД, успешныйAPIrestore/ошибкапроцесса/sequence, затемdeploymentпроверенногообраза. Локальныйкоммитбезpush.

12.5.14 — реальный API restore: дефект очистки разделов и контроль rollback (2026-10-07)

Временный docker compose run --rm --no-deps backend использовалcompiled dist sourcef1aac49, mount/app/backend/acceptance, DATABASE_URL толькоmmapp_acceptance_20261007, HTTP127.0.0.1:8014 внутриконтейнера. Основнойbackend/frontend не обновлялись. Очищенный отчёт; SHA256 переданногоcompiled archive совпалслокальным. РеальныйbuildApp иAPI routes работалибезHTTP mocks; startScheduler=false приinitial build, стандартныеdatabase operation restarts выполнялиреальныйrefreshScheduler/consumer lifecycle.

GETbackup200/478810bytes/PGDMP полученвпамять безкопированиядампавGit. Отдельный тестовыйHTTP write handler менялretention14→16 подудерживаемымSQLlock. Concurrent POSTrestore не завершилсяраньшеwrite; новыйGETservers получил409. ПослеROLLBACKlock write завершился200; restore дождалсяего ивернул400 изнастоящегоpg_restore. Ошибка:cannot drop inherited constraint uptime_resource_samples_w_20261019_pkey of relation uptime_resource_samples_w_20261019. Существующий--single-transaction --clean --if-exists пытаетсяудалитьinheritedPK дочернегораздела. Сходныйконфликтописанвpgsql-hackers; текущийотказнепосредственновоспроизведённасервере/client18.6.

Первые2попыткиожидалиrestore200,ноостановилисьassert400; приватнаядиагностикаосталасьтольконасервере. Третийзапускпроверилизвестнуюошибкуиrollback: HTTP400/no ok,обаserverID/IP/enabled сохранены,5speed rows,9migration IDs,servers_id_seq last_value2/is_called=true иretention16 (последняяподтверждённаяHTTPwrite) совпалисожидаемымсостояниемдоrestore. Inheritedconstraint сохранился,count1. ЭтоPG-4 вграницеошибкиреальногоSQLпроцесса/контрольныхданных/sequence/constraint,неполныйchecksum всехтаблиц иневсе возможныеSQLотказы. УспешныйPG-3/новыйID послеуспешногоrestore не проверены.

Изолированныйконтейнерудалён--rm,егоscheduler/background/worker остановлены,соединениязакрыты. ПроверочнаяБД теперьretention16; основнойстендпо-прежнемуretention14,обаCHRзаписи сохранены,healthok/version1.0.0-test.673e5ba. Nativegre/BGP collector можетвыполнятьчтениеприштатномrestart,ноRouterOS apply/конфигурациянеизменялись. РеальныйPortal/browser restore UI иintegrated UDP+detached jobs втомжекритическоминтервалеэтимнепроверены.

Обнаруженныйдефектблокируетуспешнуюприёмкуrestore; коднеразвёрнутвосновномприложении. Следующий12.5.15 — исправитьочисткуpartition constraints внутриоднойтранзакции, безпредварительногонеобратимогоDROP ибезавтоматическогоповторапосленеизвестногоcommit, затемповторитьPG-3/4/полныйPG-6. Локальныйкоммитбезpush.

12.5.15 — транзакционное восстановление разделов PostgreSQL (2026-10-07)

Исправленреальныйдефект12.5.14. pg_restore --list проверяетобязательныеTABLE public servers/schema_migrations иопределяетприсутствующиевархивеизвестныеpartition parents приложения. ВременныйSQL полностьюформируется pg_restore --clean --if-exists --file безподключениякцелевойБД. Затемодинpsql -X --single-transaction --set ON_ERROR_STOP=on выполняет -c parent constraint preparation и -f SQLархива. РодительскиеPK/UNIQUE снимаютсячерезpg_catalog/format(%I) внутриэтойжетрaнзакции; inheritedchildconstraints удаляютсякаскадно, поэтомупоследующиеIF EXISTS DROP больше непадают. Подготовкаограниченаpublic/известнымиparents, присутствующимивархиве; нетотдельногоcommittedDROP/SQLпереписыванияданных/автоповтора. Транзакционныйрежимpsql охватываетобеопции-c/-f.

Customdump иSQL содержатприватныеданные: tempdirectory0700 (chmod такжеисправляетранее созданныйкаталог), файлы0600, обафайлаудаляютсяприуспехе/ошибке. Ошибкаdecode/неподходящийTOC непускаютtargetSQL. Архивдолженбытьдовереннымполнымbackup приложения; проверкадвухTABLE неявляетсяпроверкойвсейсхемыилидовериякSQLархива. CASCADEdependencies восстанавливаютсяизполногоархива; частичные/custom archives этимнепринимались.

Локальныепроверки:3новыхpartition-restoretests включенывtest:system-database; полныйнабор25pure/protocol tests иHTTP/JWT scripts passed, contracts/backend build passed. Провереныscope parent/table/schema, quotedcatalogidentifiers, полностьюdecode-before-targetSQL, одинpsqltransaction, отказdecodeбезtargetSQL. Существующийrestore lifecycle сохраняетcache invalidation толькопослеуспеха.

RealAPI evidence:161.104.46.222/PG18.6, isolatedcompiledf1aac49+partition-restoreworktreepatch (SHA256 patch совпал), mmapp_acceptance_20261007. Backup200/475305bytes; concurrentactiveHTTPwrite ждалSQLlock, новыйGET409. Restore200/oktrueбезwarnings, контрольныеservers/retention/speed/migrations/sequence совпалисархивом. СледующийINSERT disabledtestserver192.0.2.250 получилID3. Послеretention19 ивведенияeventtrigger, которыйпадаетнаCREATE INDEX, второйrestore400/необъявленуспешным. НезависимыеSQLпослеrollback подтвердиливсеперечисленныеконтрольныеданные/sequence3 и1587constraint descriptors. Eventtrigger/function удалены, temporarycontainer--rm/consumers/pool штатноостановлены.

ПроверочнаяБД теперьсодержитdisabledserver3/retention19; основнаясохранена:server1–2,retention14,healthok/source673e5ba. Во времяштатногоrestart ресурсныйcollector неожиданнопыталсяпрочитатьdisabledserver3 иполучилtimeout10s — отдельныйдефектдляследующегоблока. RouterOS apply не выполнялся. PG-3/4 принятывграницахrealAPI/контрольныхданных/новогоID/SQLrollback/constraints, безполногоchecksum/Portal/browser UI. Integrated UDP+detachedjobs втомжекритическоминтервалеимультиэкземплярыещёнеприняты; полныйPG-6 открыт. Новыйкоднеразвёрнутнаосновномстенде. Следующий12.5.16 — исправитьdisabled-server polling, integratedPG-6/deployment. Локальныйкоммитбезpush.

12.5.16 — выключенные серверы всех типов исключены из мониторинга (2026-10-07)

Аудит уточнилпричину12.5.15: uptime/RESTping намеренноиспользовалиenabled OR type=home-router, скомментариемобисключениидляLAN. Это существующееправило, непросто случайныйSQLдефект. Пользовательявновыбрал «Не опрашивать выключенные серверы любых типов». ПоэтомуисключениеHome Router удаленоосознанно, политикавключённоститеперьобщаядлявсехтипов.

НовыйlistEnabledMonitoringServers используетservers.enabled=true; подключёнкresources,scheduledping,manualpinggroup иRESTping. Плановыеspeed-пробы требуютвключённыхsource/destination ивключённойprobe; выключенныеendpointпропускаютсябезnativeoperation/ложногосэмплаошибки. Ручнойspeedguard проверяетобасерверапослечтенияизБД, доMikrotikClient/nativequeries, сявнойошибкой «Сервер отключён: включите его перед запуском теста». Уже начатыйдоотключениязапросможетштатнозавершиться; немедленнаяотменасетевойоперацииэтимнеобещается.

RealPG/CHR evidence: temporarycontainer/f3e2059+monitoringworktreepatch, mmapp_acceptance_20261007. Disabledserver3 последовательноимелтипыhome-router/exit-node/jump-host. Во всехслучаяхselected/resource IDs1–2, forwardednativeclients только1–2 (реальноечтениеresource/identity CHR, responses неподменены). Плановыепробы3→1/1→3 enabledtrue не запускались,runs0; manualspeed сdisabledsource/destination отказалдосозданияклиента. Повторныйзапускдобавилнезависимыйконтрольсэмплов: resourcecount3=1→1 (историческаяошибка12.5.15), RESTcount3=0→0, новыхсэмпловнет. Pingиспользуеттотжеqueryhelper,ноотдельныйnativepingfixtureвэтомблокенезапускался.

Временныеspeed probesудалены,server3 восстановленhome-router/enabledfalse, temporarycontainersудалены--rm. Рабочийстенд/source673e5ba/healthok инеизменённаяосновнаяБДсохранены. RouterOSконфигурациянеизменялась;толькоreadonlyresource/identity. SHA256compiledpatch совпалслокальным. Локальноspeed-test HTTP/RBAC (26invalidcases/401/403/dependencies),16speed-run-persistence tests,contracts/backend build иdiff-check прошли. Новыетривиальныемок-тестыSQLpredicate не добавлялись;поведениедоказано реальнойquery/collector матрицей.

Новыйкоднеразвёрнутнаосновномстенде. ПолныйintegratedPG-6,Portal/browserrestore ипрочие12.5 остаютсяоткрытыми. Следующий12.5.17 — integrated HTTP/scheduler/background/UDP quiescence иdeployment проверенногообраза. Локальныйкоммитбезpush.

12.5.17 — общая проверка PG-6 и обновление backend тестового стенда (2026-10-07)

Integrated PG-6 evidence: source4c12c55, настоящееbuildApp/API/worker/PG18.6, temporarycontainer иmmapp_acceptance_20261007. SQLsettings temporarilyвключилиUDP4749 внутриконтейнера иlocalhostexporter map; CHR traffic-flow конфигурациянеизменялась. ArchiveполученреальнымGETbackup. ВодноминтервалезадержаныHTTPhandler, workerSQLчерезACCESS EXCLUSIVE lock settingstable иbackground SQLtask черезproductionregistry.

Restore ждалHTTPhandler,новыеAPIGET409. ПослеHTTPcleanup UDPsocket освободилсяпри ещёзаблокированнойSQLзаписи. ПослеосвобожденияSQLworkerзавершился и1500bytes datagramсохранились; scheduler admissionpaused/activejobs0. Доreleasebackground psqlprocesses0/restoreне завершён, backgroundwrite ещёне выполнена. Послеrelease записьretention17 завершилась,restore200/oktrueбезwarnings вернулархивнуюretention14 иисходныйflow baseline. Послеrestart workerboundtrue/schedulerresumed, новыйUDPdatagram дал+1500bytes. Fixturebackground выполняетреальнуюSQLчерезregistry, анеRouterOSbackup/certificate; ихконкретныемеханизмыпроверенылокальнораньше. ЭтоPG-6 дляодногоэкземпляра, безмежхостовойкоординации. Temporarysettings/port/mgmtIP восстановлены, worker/jobs/pool/temporarycontainer штатноостановлены.

Deployment evidence: backend imageux-4c12c55,fullrevision4c12c55c9d4ca1fda2b901193a4969ba0e33e797,version1.0.0-test.4c12c55. Сборкана161.104.46.222 поCI-style context (база673e5ba, committedbackend/src/package4c12c55,безenv/лицензий/node_modules) прошла; PostgreSQLclient18.6 сохранён. ImageIDsha256:57878e320b7272edcc6efe1f6f5c140295510c85cb79b8ca12a900f7654cd917. Передupdateприватныйbackup546550bytes/SHA2701cc2fba4aa0ac34fe79ad5576012b775a8d4db7f1ec27cbc0c61342ed37cb сохранёнтольконасервере0600,контрольныеserverID/IP/enabled,retention14 и9миграций послеupdate совпали.

ComposeдобавленoptionalBACKEND_IMAGE_TAG, которыйпереопределяеттолькоbackend; default сохраняетMMAPP_IMAGE_TAG. На стендеMMAPP_IMAGE_TAG=ux-673e5ba/BACKEND_IMAGE_TAG=ux-4c12c55: frontendнепересобирался,егоimage/revision673e5ba прежние. ComposeSHA3052bd6ab5d9865f97605cebfb5ff27a4410cd3357b81153a65a87fb7c92582f совпаллокально/насервере,config--quiet passed. AUTH_REQUIREDfalse/SSH-only ports сохранены. Backendhealthy,health/APIauthconfig/servers/speed-test-runs200. Первыйsmoke ошибочноиспользовал/uptime/speed/history404; correctedcanonical/uptime/speed-test/runs200,продуктовогодефектаздесьнет.

Real browser smoke: dashboard/servers/filters200,320px fits,0JSerrors/0API>=400,HTTP-моковнет. RestoreосновнойБД не выполнялся;разрушающиесценарииоставалисьввыделеннойБД. Полныйпротоколещёоткрыт:Portal/browserrestore flow,остальныеnative/network/integrations иmulti-instanceконтрольнеприняты. Следующий12.5.18 — browser/RBACrestore иоставшиесясценарии. Локальныйкоммитбезpush.

12.5.18 — реальные права backup/restore и сценарии восстановления в браузере (2026-10-08)

Блокначат7октября,завершён8октября поAsia/Novosibirsk; отчётыдатированыподатеокончания. PG-7 evidence: temporarycontainerсреальнымimageux-4c12c55, AUTH_REQUIRED=true,mmapp_acceptance_20261007. JWTтестовогоissuerсозданытольковпамяти, безPortalSSO. 16GETbackup/POSTrestore:anonymous/wrongissuer/expired/invalidsignature401;settingsreader/writer/trafficadmin/missingapp403. Instrumentation productionchild_process.spawn (безподменывыполнениякоманд) подтвердилаpg_dump0/pg_restore0/psql0длявсехотказов; контрольныеservers/retention/sequence/speed послеотказовсовпали. Adminmm:settings:adminbackup200/478183bytes/PGDMP запустилровноодиннастоящийpg_dump. ЭтоусиливаетпрежниеHTTP-onlyPG-7 проверкинаблюдениемпроцессов.

Real browser restore: temporaryfrontend673e5ba/backend4c12c55,localhost3018черезотдельныйSSHтуннель, AUTHfalseдляbrowserсценария,выделеннаяБД. Передлюбойwriteмаркерserver3/192.0.2.250/disabled проверен. Перваяпроверкаотказала:Next.jsrewrites bakedприbuildигнорировалruntimeBACKEND_INTERNAL_URL ивременныйfrontendчиталосновнуюБД. Guard остановилсценарийдополученияархива/изменениянастроек/restore. Временныйfrontendотсоединёнотmmapp-test_default иподключёнкmmapp-browser-only,гдеaliasbackendуказывалтольковременныйbackend; повторныймаркерподтвердилвыделеннуюБД. Основнойfrontend/router configurationне менялись.

Backup478920bytesиспользовантольковпамятиNode/browser input,локальный.dumpнесохранён. Контрольretention14→19 сделанAPIввыделеннойБД. ЧерезнастоящийsettingsUI:выборфайла→Продолжить→подтверждение→restore200→подпись «База приложения восстановлена»; GETuptimesettings независимоподтвердилretention14. ЗатемPGDMP-invalid-fixture получил400:controlretention14сохранён,filenameвдиалогесохранён,unknowncaptionвиден,restoreкнопказаблокирована. Guardпережилreload, «Выбрать файл»disabled; послефактическойпроверкиcontrolнажато «Я проверил состояние — разрешить новый запрос»,кнопкавновьenabled. POSTstatusesровно[200,400],автоповторанет;0JSerrors,320px dialogfits. HTTP-моковнет. ЭтоbrowserPG-3/errorUX,неPortalSSO иневсеfailure/commit-lossварианты.

Temporaryfrontend/backend/самостоятельныйRBACcontainerудалены--rm, privateDocker networkудалена, временныйтуннель3018закрыт. Основнойтуннель3000/8000/стендсохранены;backend4c12c55healthy,основнаяБДserver1–2/retention14безизменений,AUTHfalseкакдоэтогоблока. Продуктовыйкодне менялся. PG-7 иbrowserrestoreпринятывуказанныхграницах; полный12.5 ещёоткрыт. Следующий12.5.19 — PG-8 speedpersistence/потеряcommitacknowledgement иостальныеROS/Q/integrationсценарии. Локальныйкоммитбезpush.

12.5.19 — speed persistence, ошибка INSERT и потерянное подтверждение commit (2026-10-08)

Выявленриск: общийcatch native run послеошибкиpersist запускалrecordSpeedTestFailure, хотяbandwidth-test ужезавершён. Послеcommitackloss это моглоподменитьsnapshot/log ложнымerror (особенноеслиrunId не былпередан). ДобавленSpeedRunPersistenceUnknown(actualrunId,cause) тольконаграничепубликацииуспешногоnativeрезультата. Routeвозвращает502/outcomeunknown/runId/просьбупроверитьисторию; failurewriterне вызывается. Плановыйrun тоже не записываетложныйfailedresult. Исходныйdrivercause сохранёнвError,публичныйreceipt не раскрываетSQL/credentials.

SchedulerSnapshotError раньшеигнорировалruns[].okfalse уuptime_speed, поэтому реальныйплановыйackloss помечалсяjobok. Теперьошибкиисполненияspeedrun попадаютвreceipt.statuserror/ограничение,безпереименованиядействительногосохранённогорезультатасетевоготеставerror. Корректные observedoffline/down ресурсы/ping по-прежнемунесчитаютсяисключениемоперации.

ОчищеннаяrealPG-8 матрица: image4c12c55 плюсcompiledworktreepatch, mmapp_acceptance_20261007, настоящиеCHR1→CHR2 TCPtransmit3s/afterping,RouterOSответынеподменены. SQLBEFOREINSERTtrigger отказалhistory:HTTP502unknown/actualrunId,baseline snapshot42 сохранился,history0,ровно1nativecall. Дляackloss node-pg boundary действительноисполнялCOMMIT,затемотклонялclientpromise:HTTP502unknown,независимыйPGread показал1historydone иsnapshotdone ссовпадающимTX1929.132904Mbps/RXnull. Плановыйackloss: HTTP200/okfalse receipt,1nativecall,историяdone/TX1729.056592/RXnull,snapshotнепереписанвerror. Этоинъекцияclientackfault послереальногосervercommit,нефизическийобрывTCP; универсальныйrollback длялюбогосетевогоотказанеутверждается.

Матрицапотребоваладиагностикиharness: первыйwrapperнеподдерживалPool.connectcallback иупалдонативныхтестов; перваяполнаяnativeматрицавыявилаschedulerok дефект; rerunполучил500 приcallback instrumentation. Добавленыcallbackbypass/BEGINreset,разовыеmanualrunIDs иdiagnosticerrorhandler; окончательнаяматрицапрошла,проверяемые502обработаныproductionroute,неdiagnostic handler. Выполнялисьручныеповторыпослеисправленияharness/classifier; это неавтоповторвнутриоперации. ФинальныеcompiledJSиpatchSHA совпалислокальными. Temporaryprobe/trigger/function удалены,count0; historicaltest runs сохраненывпроверочнойБД,probeassociationпослеcleanupFK=null. Temporarycontainer--rm/consumers/pool остановлены,mainhealth4c12c55ok/БДнеизменена,RouterOSconfigurationне менялась.

Локально18scheduler tests (включаяновыйunknownspeedreceipt),16speedpersistence tests,HTTPcommand/RBAC/unknownrunId-no-failure-write test иcontracts/backend build прошли; diff-check passed. Старыйосновнойruntime4c12c55 ещёбезэтогопatch. BrowserunknowncommitUX/физическийnetworkloss/deploymentpatch иостальной12.5 открыты. Остатокпятичасовоголимитапоследнейпроверки9%;новыйкрупныйблокненачат. Следующий12.5.20 — собрать/deploypatch иbrowserunknown-speed,затемROS/Q/integrationпротокол. Локальныйкоммитбезpush.

12.5.20 — сохранение подтверждённого speed snapshot при unknown receipt (2026-10-08)

Приостатке5%окнавыполненнебольшойлокальныйблокпередdeployment. Frontendcatch раньше ставилlastStatuserror/новыйlastRunAt любойошибкеPOSTspeed-test,включаяunknowncommit. Теперьподтверждённыйsnapshot пробысохраняется,еслиApiClientError502 содержитoutcomeunknown иrunId текущегозапроса. ЧужойrunId/неправильныйpayload/403/обычнаяошибка нераспознаютсякакэтотисход. Существующееservererrorсообщениепоказывается;новыекомпоненты/композицияReUIне менялись. Временнаястрокасамогозапросапо-прежнемуимеетstatuserror; полныйunknown-state/browserUX ещёнужнопроверить.

Добавленыlib/speed-persistence-outcome.ts и2meaningfultests;подключенguardвuptime/page.tsx. Обаunit tests passed. ПервыйroottscподхватилкопиистарогоCI contextвignoredtmp ивернулисходныеошибкиэтихкопий. Повторныйполныйfrontendtypecheckсвременнымconfig,которыйсохраняетrootoptions/исключения иисключаетtmp,passed; основнойtsconfigне менялся. Diff-check passed. ReUI skillпрочитан: адаптациясуществующегоэкрана,безновойregistryinstallation/редизайна. Browserunknownspeed/productionbuild/deploymentвэтомблокенезапускались.

Основнойruntimebackend4c12c55/frontend673e5ba сохраняется;backendpatchf408afb иfrontendguardещёнеразвёрнуты. Следующий12.5.21 — собратьобаобновлённыхобраза,проверитьbrowserunknownspeed/историю иразвернутьпослепроверок. Журналобновлён;локальныйкоммитбезpush.

12.5.21 — неопределённый исход speed-запуска и сверка с историей (2026-10-08)

В локальной строке запуска введён status unknown: «Сохранение не подтверждено», с видимым runId; это не новый статус серверного DTO (история API по-прежнему принимает только done/error). При обновлении истории незавершённая или неподтверждённая локальная строка сохраняется, если её идентификатора нет в ответе. Подтверждённая строка с тем же runId заменяет локальную, предупреждение снимается. Unknown не подменяет последний подтверждённый snapshot карточки пробы; предупреждение показано без destructive-оформления. Автоматического повторного сетевого теста нет. Ручной новый запуск остаётся доступен; предупреждение просит проверить историю перед повтором. Состояние локальной строки не сохраняется после перезагрузки страницы.

Проверки: 13/13 Playwright (uptime-speed-data и uptime-speed-unknown) за 27.7s, включая unknown → пустая история → done/error, сохранение TX42, один POST и адаптацию 320px. Это live-ветка UI с HTTP-моками, не real PG/browser proof. Scoped frontend typecheck (tmp/tsconfig-speed-check.json, исключён старый ignored tmp build context) и ESLint изменённых файлов прошли. Существующие null/zero, malformed DTO, свежесть, независимые источники и Ping-состояния сохранены.

Основной backend4c12c55/frontend673e5ba не изменён. Новые backend/frontend исправления ещё не развёрнуты. Полный 12.5 открыт. Следующий 12.5.22 — сборка обновлённых образов и приёмка на стенде перед deployment. Локальный коммит без push.

12.5.22 — новые Docker-образы и real browser speed unknown (2026-10-08)

Из зафиксированного source8782054078304f36cc611876af2d17f87b857f60 подготовлены отдельные frontend/backend contexts и последовательно собраны production-образы на Debian-стенде. Frontend production build и проверка TypeScript внутри Docker прошли; backend contracts/TypeScript build прошёл. Незакоммиченные изменения, .env, ключи и локальные node_modules в сборку не передавались. Образы не публиковались.

Real browser evidence: новый frontend/backend, отдельная БД mmapp_acceptance_20261007 и Docker network. Перед командой guard проверил имя БД. Реальный CHR1→CHR2 TCP transmit3s; после настоящего COMMIT введена ошибка подтверждения на границе node-pg. HTTP502/outcome unknown/runId speed-1791425187780. UI показал «Сохранение не подтверждено» и runId, сохранил прежний TX42. Независимый SQL подтвердил одну history done с TX2353.700072/RXnull. После «Обновить» строка стала done и предупреждение исчезло; POST ровно один, nativeCalls1, JSerrors0,320px fits. Снимок. Это fault injection после реального COMMIT, не физический обрыв TCP; throughput не является benchmark.

Deployment evidence: оба runtime теперь source8782054/version1.0.0-test.8782054, backend healthy. Backend image7862c9b4…; frontend image d22dd0f3…; full revision labels проверены. До обновления получен приватный backup1049796bytes/SHA826cad71… (только на сервере,0600). Контроль основной БД до/после совпал: servers1–2/enabledtrue, retention14, speedHistory5; migrations9. Restore основной БД не выполнялся. AUTHfalse/loopback порты сохранены. Предыдущие образы и приватная конфигурация доступны для отката на этом временном стенде.

После развёртывания dashboard/servers/uptime-speed/settings/filters200, ПК и320px,0JSerrors/0API>=400, HTTP-моков нет. Первая попытка чтения локального URL отказала из-за завершившегося прежнего SSH-туннеля; туннель3000/8000 восстановлен, повторная проверка прошла. Временные frontend/backend/network/3018-tunnel удалены; тестовая probe acceptance-browser-speed удалена, исторический результат остался только в выделенной БД. Основной туннель и тестовый сервер оставлены для продолжения.

PG-8 browser unknown/reconciliation принят в этих границах. PortalSSO, физический TCP fault, мультиэкземпляры и остальные ROS/Q/интеграции остаются открытыми. Следующий 12.5.23 — ROS-8/9: preflight409 и конкурентное изменение контекста speed-пробы на реальном PG/native. План, паспорт и протокол обновлены. Локальный коммит без push.

12.5.23 — реальный конфликт speed-контекста и конкурентные записи (2026-10-08)

Evidence ROS-8/9: актуальный backend image/source8782054, PostgreSQL18.6/mmapp_acceptance_20261007, реальные HTTP PUT/POST и CHR1→CHR2. HTTP/RouterOS ответы не подменялись; wrapper только считал bandwidth-команды и отмечал их начало/окончание. Перед fixture setup проверены имя выделенной БД и отсутствие проб.

Семь preflight конфликтов: смена пары, srcInterface, dstInterface, протокола, направления, длительности и удалённая до запуска проба. Каждый POST409, bandwidthCalls0; существующий snapshot не изменён. История содержит error для отклонённого запроса с probeIdnull, без привязки к новому контексту. PUT enable/reorder сохранил lastStatusdone и измеренный0; нулевой baseline был явно подготовлен как DB fixture, не выдан за результат RouterOS.

Три реальных коротких TCP transmit3s команды (по одной на case): объединённая смена пары/интерфейсов/протокола/направления/длительности; удаление пробы; конкуренция записи конфигурации и результата при внешнем SELECT FOR UPDATE. В первых двух изменение конфигурации через HTTP завершилось до получения native response. В третьем отдельный observer увидел двух writers с wait_event_type Lock до освобождения строки. Все POST200; одна history done с фактическими src1/dst2/TCP/transmit3 и probeIdnull. Новый snapshot остался lastStatus/lastTx/lastRunAtnull, удалённая проба не создана заново. TX2815.169992/2841.242408/3247.053056, RXnull — функциональные результаты, не benchmark.

Первый пробный прогон обнаружил помеху harness: PUT refreshScheduler запускает немедленный speed job, который изменил fixture snapshot. В принятой матрице production scheduler admission закрыт до fixture setup только внутри isolated test process; таймеры не подменялись, основной scheduler не трогали. Этот подготовительный прогон не объявлен passed. Длинный terminal input отклонён инструментом; сценарий передан отдельным файлом, без изменения разрешений.

После принятой матрицы удалены временные пробы, count0; контейнер завершён и удалён --rm, locks освобождены, scheduler/listener/background/pool штатно закрыты. Исторические результаты остались только в выделенной БД. Основной backend8782054healthy/version1.0.0-test.8782054 и пять записей основной speed-истории сохранены. Продуктовый код не менялся; повторная сборка не требовалась.

ROS-8/9 приняты в перечисленных API/SQL/native границах: отдельные поля проверены preflight, поздняя смена объединяет параметры, row lock — один backend. Browser race, каждый поздний параметр по отдельности и multi-instance не проверены. Следующий12.5.24 — browser-сценарий смены speed-контекста вторым клиентом во время теста. Полный12.5 открыт; план/паспорт/протокол обновлены, локальный коммит без push.

12.5.24 — browser speed при изменении контекста вторым клиентом (2026-10-08)

Real browser evidence: production backend/frontend8782054, выделенная БД mmapp_acceptance_20261007, изолированная Docker network и SSH3018. Guard до операции проверил имя БД. Первый browser context использовал настоящую кнопку «Запустить» в uptime speed; независимый второй context отправлял реальные HTTP PUT каталога. HTTP/RouterOS-моков нет. Scheduler admission закрыт только в isolated backend, чтобы сохранение каталога не запускало фоновый speed job.

Два принятых сценария: смена пары1→2 на2→1 и длительности3→4; удаление пробы. Второй клиент завершил изменение до получения native response (проверено счётчиком/finished в wrapper, который возвращает настоящий RouterOS ответ). В обоих случаях исходный CHR1→CHR2 TCP transmit3s завершилсяHTTP200; history done сохранила фактическую пару и длительность3, probeIdnull. После «Обновить» новая карточка показывала4s без прежнего значения Мбит/с; после удаления показано «Нет speed-проб», история остаётся. Reload сохранил оба результата,320px fits. Принятая матрица: nativeCalls2, POSTstatuses[200,200], JSerrors0, автоповтора нет.

Первый подготовительный прогон выполнил ещё одну короткую команду, затем тест отказал из-за неверного ожидания подписи «Последний запуск: —», которой в текущей карточке нет. Исправлено ожидание harness: отсутствие старого замера. Это ручной повтор валидации; всего на временном стенде три native commands, два в принятой матрице. Продуктовый код не менялся, новый build/deployment не требовался. Значения TX2938.274608/2769.82096 и RXnull — функциональная проверка, не benchmark.

Temporaryfrontend/backend/network удалены,3018туннель закрыт, fixtureprobe удалена; history сохранена только в выделенной БД. Основной backend healthy/version1.0.0-test.8782054, история5 без изменений, основной SSH-туннель сохранён. Browser ROS-8/9 принят в этих двух сценариях; второй клиент менял каталог через HTTP, не через форму редактирования. Полная матрица поздней смены каждого поля, PortalSSO и multi-instance остаются открытыми.

Следующий12.5.25 — ROS-2: реальный отказ bandwidth-аутентификации и проверка snapshot/error history в выделенной БД, без изменения учётных записей RouterOS. План, паспорт и протокол обновлены; локальный коммит без push.

12.5.25 — реальный отказ bandwidth-аутентификации (2026-10-08)

Real API/native/browser evidence: production8782054, выделенная БД mmapp_acceptance_20261007, изолированная Docker network/SSH3018. Только в app DB временно изменён username назначения2 на несуществующий тестовый; исходное значение сохранено в памяти и восстановлено при штатном завершении. Учётные записи и конфигурация RouterOS не менялись. Scheduler admission закрыт только внутри isolated backend. Guard подтвердил выделенную БД до команды; предыдущий TX42 был явно подготовлен как DB fixture.

Реальный POST /tool/bandwidth-test со стороны CHR1 вернул statuses connecting/connecting/authentication failed. Backend отказалHTTP502 с русской подписью «RouterOS отклонил авторизацию bandwidth-test»; это обычная ошибка native test, не persistence unknown. UI показал ту же ошибку, локальная строка error. Независимые API/SQL подтвердили одну history error для фактической пары1→2/TCP/transmit3, TX/RXnull; probe lastStatuserror, предыдущий lastTx42 сохранён/RXnull. Снимок ошибки320px.

После «Обновить» и reload история error сохранена; nativeCalls1/POST[502], автоповтора нет, JSerrors0/320px fits. HTTP/RouterOS-моков нет. Подготовительный запрос с чрезмерно длинным тестовым именем был отклонён RouterOSHTTP400 по длинеuser до целевого сценария; после исправления fixture выполнен отдельный принятый прогон. Это ручная валидация, не retry продукта.

Temporaryfrontend/backend/network удалены,3018туннель закрыт, fixtureprobe удалена. В выделенной БД username назначения восстановлен и проверен без вывода секрета; основная история5 сохранена, runtime8782054 исправен. Продуктовый код не менялся, build/deployment не выполнялся. ROS-2 authentication failure принят; unreachable/busy/disconnect/abort и PortalSSO остаются открытыми. Следующий12.5.26 — недоступное назначение bandwidth-test и проверка HTTP/UI/history. План/паспорт/протокол обновлены; локальный коммит без push.

12.5.26 — тайм-аут недоступного назначения и исправление Next proxy (2026-10-08)

Real failure evidence: source8782054, выделенная БД, назначение2 временно заменено в app DB на192.0.2.250. Реальный bandwidth POST от CHR1 не вернул native rows до30s. Backend записал history error/TXRXnull и сохранил предыдущий probeTX42; frontend rewrite оборвал запрос с socket hang up/ECONNRESET и вернулHTTP500 раньше структурированного ответа backend. Целевая UI-проверка отклонила500; она не объявлена passed. Это транспортный timeout, не подтверждённый native can not connect.

В установленном Next16.2.4 найден default proxyTimeout30000. В next.config.ts задан experimental.proxyTimeout180000, дольше120s ожидания speed-команды в UI. Добавлен tests/integration/next-proxy-timeout.mjs: загрузка реальной конфигурации проекта, настоящие loopback sockets и установленный Next proxy; delayed backend502JSON после31s доходит до caller. Регрессия, scoped frontend TypeScript и ESLint прошли. Сценарий использует fixture backend response для проверки proxy, не выдаётся за RouterOS proof. Backend/общие UI-компоненты не менялись.

Temporarycontainers/network/3018 закрыты; destinationhost восстановлен и проверен, testprobe удалена. Основной runtime8782054 прежний. Исправление требует нового frontend build: следующий12.5.27 — real browser timeout-проверка на новом образе и deployment после успеха. ROS-2 native can not connect/busy/disconnect/abort остаются открытыми. План и журнал обновлены, локальный коммит без push.

12.5.27 — приёмка и deployment исправленного Next proxy (2026-10-08)

Frontend production-образ sourceaa7dbdf608ca4da4986826fca956543f40922841 собран из чистого предыдущего context8782054 с зафиксированным next.config.ts; git diff подтвердил, что это единственное изменение runtime source frontend. Build/встроенный TypeScript passed; proxyTimeout180000 отражён в build config. Backend image8782054 не менялся.

Real browser/native timeout: новый frontend/старый backend в выделенной БД и Docker network. Длительный bandwidth REST запрос к назначению192.0.2.250 завершился транспортным timeout без native rows. Теперь UI получил структурированныйHTTP502 backend вместо proxy500/ECONNRESET. Probe lastStatuserror, previousTX42 сохранён; одна history error/TXRXnull, понятное обработанное предупреждение в UI. Refresh/reload/error state/320px passed, nativeCalls1/POST[502]/JS0, без автоповтора и HTTP/RouterOS-моков. Снимок. Это REST timeout; RouterOS can not connect не подтверждён, успешного native completion не заявляем. Техническая смешанная подпись timeout пока сохраняется как ограничение UX.

Deployment: MMAPP_IMAGE_TAG=ux-aa7dbdf, BACKEND_IMAGE_TAG=ux-8782054. Frontend imageSHAcd63b03b… и full revision label проверены. Backend8782054healthy/version1.0.0-test.8782054 не перезапускался. Контроль основной БД совпал: два enabled CHR,retention14,speedHistory5; restore не выполнялся. Приватная предыдущая env сохранена только на сервере, старый frontend image оставлен для отката. Новый frontend доступен через основной SSH localhost3000.

Пять основных экранов: dashboard/servers/uptime-speed/settings/filters200, ПК/320px fits,0JSerrors/0API>=400, HTTP-моков нет. Temporaryfrontend/backend/network/3018 закрыты, destinationhost восстановлен и проверен, testprobes0; основной стенд/туннель сохранены.

Локальная regression31s/TypeScript/ESLint12.5.26 и real production browser proof подтверждают исправление proxy. ROS-2 transport timeout принят в этих границах; native can not connect/busy/disconnect/abort и Portal/multi-instance остаются открытыми. Следующий12.5.28 — ROS-3: фактический адрес native bandwidth-test и интерфейс after-ping. План/паспорт/протокол обновлены; локальный коммит без push.

12.5.28 — интерфейс bandwidth-test и after-ping; уточнение формы (2026-10-08)

Real native/API/SQL evidence: backend8782054, выделенная mmapp_acceptance_20261007; реальные inventory и команды, HTTP/RouterOS-моков нет. На обоих CHR активны ether1/lo. НаCHR1 ether1 имеет dynamic194.226.121.150/24; наCHR2 dynamic104.165.244.7/24 иstatic195.195.195.195/32. Существующая конфигурация RouterOS не менялась. API каталога предпочитает static195 при явном выборе ether1 назначения. Это не тот же адрес, что host/API104.

Три попытки1→2 (дважды с выбранным ether1 назначения, один разauto) получили502/transport timeout и historyerror; никакая из них не объявлена успешной. Bandwidth-server enabledtrue/authenticatetrue/maxsessions100 наобоихCHR, Ping1→2 и2→1 поether1 подтвердил2/2/0%loss. Причина timeout1→2/auto не установлена. Нельзя заключать, что её вызвала ошибка приложения или исключительноstaticадрес.

Отдельная принятая команда2→1: srcInterfaceether1, dstInterfaceauto, TCPtransmit3s/HTTP200. Wrapper считал и записывал только несекретные параметры настоящих вызовов: bandwidth address194.226.121.150 без interface-параметра; after-ping addressтотже/count4/interfaceether1/interval1s. API/SQLhistorydone, TX3756.788128/RXnull, Ping53ms/0%loss. srcInterfaceAddress195 — metadata выбранного интерфейса, не доказательство фактического source IP bandwidth packets. Native routing определяет RouterOS; source-interface binding не реализован. В принятом прогоне native1, всего4 команды с учётом трёх непрошедшихforward-прогонов. Это функциональная проверка, не benchmark/multi-WAN proof.

В форме локально добавлено пояснение: интерфейс источника используется для Ping после теста, интерфейс назначения выбираетIP/staticfirst, маршрутbandwidth-test определяетRouterOS. Исправлена CLI-подсказка /ip address print where interface= вместоwhere name=; синтаксис RouterOS. Установленные ReUI/Frame-композиции сохранены, новый компонент не устанавливался.

Проверки локального UI: uptime-speed-interface.spec.ts1/1 сHTTP-фикстурами — открытие формы, приоритет адреса изAPI, корректныйCLI/Ping, пояснение и320px fits; scopedfrontend TypeScript/ESLint passed. Это локальная проверка формы, не realbrowserproof новых текстов. Runtimefrontendaa7dbdf прежний, новыеUIизменения ещё не развёрнуты.

Временные --rm containers закрыты, testprobes0; история тестов только в выделеннойБД, основнаяhistory5/backend8782054healthok сохранены. ROS-3 принят дляобратнойкоманды в перечисленных границах; forward2interface/auto не принят. Следующий12.5.29 — realbrowserform/deploymentподсказок; forward-native диагностика иполный12.5 остаются открытыми. План/паспорт/протокол обновлены, локальный коммит без push.

12.5.29 — real browser форма интерфейсов и deployment frontend (2026-10-08)

Production frontend sourcef194e7269b1e0276f257b3fda28413958907a503 собран из чистого contextaa7dbdf с зафиксированным app/(main)/uptime/page.tsx. Git diff подтвердил, что это единственное runtime-изменение frontend; Dockerfile/deps/контракт не менялись. Production build/TypeScript внутри Docker passed; proxyTimeout180s сохранён. Backend image8782054 прежний.

Real browser evidence: новый frontend, выделенная БД и Docker network/SSH3018. Guard подтвердил имя БД; fixtureprobe только в выделенной app DB. Настоящий RouterOS inventory вернул ether1 назначения2 с addresses195.195.195.195/104.165.244.7 (static first). В открытой форме редактирования CLI содержит /ip address print where interface="ether1", /ping address195… interfaceether1 и bandwidth-test address195…; where name отсутствует. Пояснение различает source Ping-интерфейс, destination IP и маршрутизацию RouterOS. ПК/320px fits,0JSerrors/0API>=400. HTTP/RouterOS-моков нет. ПК, телефон.

NativeCalls0/commandPOSTs[]: bandwidth-test в этом блоке не запускался. Это приёмка формы и read-only inventory, не новый throughput или source-interface binding proof. ROS-3 reverse proof12.5.28 сохраняется в своих границах; forward timeout остаётся открытым.

Deployment: MMAPP_IMAGE_TAG=ux-f194e72, BACKEND_IMAGE_TAG=ux-8782054. Running frontend imageSHAa210ebc2… и full source label проверены. Backend healthy/version1.0.0-test.8782054 не перезапускался. Контроль основной БД совпал: servers1–2/enabledtrue,retention14,speedHistory5; restore не выполнялся. Приватная предыдущая env/образ сохранены на сервере для отката; секреты не включены в Git/отчёты.

Пять основных экранов dashboard/servers/uptime-speed/settings/filters200,ПК/320fits,0JSerrors/0API>=400,без HTTP-моков. Временные frontend/backend/network/3018 удалены,fixtureprobe удалена/count0. Основной стенд и SSH3000/8000 сохранены. Обновлённая форма доступна через localhost3000 при создании/редактировании speed-пробы.

Следующий12.5.30 — read-only диагностика native bandwidth1→2 перед повторными командами; forward timeout/multi-WAN/прочие ROS/Q/интеграции и полный12.5 открыты. План/паспорт/протокол обновлены, локальный коммит без push.

12.5.30 — read-only диагностика направленного bandwidth timeout (2026-10-08)

RouterOS snapshot: реальные GET двух CHR через сохранённые app credentials, backend8782054, SQL-read только выделеннойБД. Bandwidth-server enabledtrue/authenticatetrue/maxsessions100, sessions0; local filter/NAT/mangle пусты, main default routes активны, CPU0/freeMemory около827MB, licensep-unlimited. IPv4/source-address конфигурация сохранена как очищенные поля; script contents/passwords/license IDs не выводились. NativeBandwidthCommands0/configurationChanges0. Не читались raw-table/routing rules и не снималась трасса во время failing run, поэтому этот снимок не исключает остальные причины.

TCP2000: Debian161.104.46.222 установил по одному короткому TCP connection к194.226.121.150:2000 и104.165.244.7:2000; sockets закрыты. Это доступность сDebian, не доказательство путиCHR1→CHR2. Служба bandwidth-test использует TCP2000 по документации MikroTik; меню server sessions описано в Bandwidth Test.

Job classification: позжеCHR1 вернул два текущихjob с metadata/keys, безстроковыхпризнаковbandwidth-test/192.0.2.250/195.195.195.195. Исходные trace/script values не сохранены. По этому чтению нельзя заявлять наличие зависших bandwidth jobs. Первый дополнительный прогон завершилсяREST401 безdevice ID в отчёте; повторныйCHR1 read прошёл, CHR2 read получил500. Это отдельная наблюдаемая нестабильность REST, а не доказательство смены пароля или найденной причины forwardtimeout. Эти обращения не повторялись в цикле и не меняли доступ/конфигурацию.

Все temporary --rm containers завершены; основной backend8782054healthy/frontendf194e72 сохранены, main speedHistory5. Продуктовый код не менялся, UI/deployment не выполнялись. Этот диагностический блок завершён; ROS forward success не принят, причина1→2 timeout не установлена.

Следующий12.5.31 — сопоставить короткий native CLI наCHR1 сREST и наблюдением TCP2000; предварительно дочитать raw/routing rules при стабильном доступе. Существующие адреса/маршруты/учётные записи сохраняются. План/паспорт/протокол обновлены, локальный коммит без push.

12.5.31 — сравнение native CLI/REST и отказ авторизации CHR2 (2026-10-08)

Sanitized evidence: Debiantesthost, sourceCHR1→destinationCHR2. Для SSH1 проверен ранее сохранённый host key. Учётные данные считаны из основной app DB только в память; строки паролей и CLI-команда не печатались/не сохранялись. На временный Debian установлен python3-paramiko для диагностического SSH-клиента; конфигурацияRouterOS не менялась.

Один native CLI TCPtransmit/duration3s завершился за3.5s со statuses connecting/authentication failed. Один непосредственный REST/tool/bandwidth-test с теми же параметрами завершился за3.0s,HTTP200/native connecting/authentication failed; HTTP200 не принят за success. Ни один тест не подтвердил native done. CLI имел15s предел канала, REST35s; автоповтора не было. Эти nativeкоманды не проходили через app speed-route, история app не изменялась.

Наблюдение TCP2000 наназначении не удалось: пять GETconnections вернули401, данныеpackets отсутствуют. Сравнениеmain/testБД без раскрытиязначений подтвердило равенство username/password для обоих устройств, fixture-prefix отсутствует. Отдельный SSH2 со сохранёнными данными получил AuthenticationException; его публичный hostkey впервые считан по указанномуIP и сохранён, независимая проверка ключа внеэтого соединения не выполнена. CLI/REST/SSH подтверждают текущую проблемуавторизации наCHR2; не доказывают, кто или что изменило доступ, и не объясняют предыдущийtransporttimeout.

У пользователя запрошены актуальные данные или проверка текущего admin-доступаCHR104.165.244.7. До ответа аутентифицированная приёмкаCHR2 не продолжается. Пароль в БД или наустройстве не изменялся/не сбрасывался. Остальные сценарии, не зависящие отCHR2, можно продолжать отдельно.

Временные диагностические процессы завершены; root SSH-сессия закрыта. Основнойbackend8782054healthok/frontendf194e72 сохранён, основнаяspeedHistory5 без изменений. Продуктовый код/UI/deployment не менялись. Следующий шаг после полученияданных — проверить доступ, затем native1→2/appreceipt/history без автоповтора. План/паспорт/протокол обновлены; локальный коммит без push.

12.5.32 — доступ CHR2 восстановлен пользователем; dashboard/native recovery (2026-10-08)

Пользователь подтвердил восстановление пароля104.165.244.7 и сообщил прежние учётные данные. Агент не менял/не сбрасывал пароль наRouterOS и не переписывал credentials приложения: сохранённые параметры уже подошли после восстановления устройства пользователем. Предыдущее ожидание данных31 снято.

Real API/native evidence: оба enabled CHRonline, BGP/GRE/WireGuard/VXLAN HTTP200/failures[]. Через обычный main speed-route выполнен один TCPtransmit3s1→2/runIdacceptance-restored-1791430842396. HTTP200 за10.3s; nativeconnecting/running/done testing, TX2717.731296/RXnull, after-ping53ms/0%loss. Независимый GET истории подтвердил ровно одну новуюhistorydone для фактической пары/направления; mainhistory5→6 намеренно, как запись этой пользовательской проверки. HTTP/RouterOS-моков нет. Это функциональная проверка, не benchmark.

Real browser dashboard: дождались ответов всех четырёх каталогов200/failures0, сообщения BGP/GRE/WireGuard/VXLAN «ошибка обновления» отсутствуют, JSerrors0. Новая headless browsercontext закрыта; основной пользовательский SSH-туннель/стенд сохранены.

Текущий отказ авторизации и текущийforward-native сценарий устранены восстановлением доступа пользователем. Это не доказывает источник изменения пароля и не позволяет объяснить все прежние transporttimeouts одной причиной. Static195.195.195.195/interface-specific/multi-WAN сценарии не переобъявлены успешными по этому auto-destination тесту.

Backend8782054/frontendf194e72 прежние; продуктовый код/образ/конфигурацияRouterOS агентом не менялись. Записи журнала о прежних401/500/тайм-аутах сохранены как история. Полный12.5 ещё открыт: busy/disconnect/abort, профильныесетевыеоперации/Q/интеграции. Следующий12.5.33 — оставшиесясценарии по протоколу сработающимдоступомCHR2. План/паспорт/протокол обновлены; локальный коммит без push.

12.5.33 — направления receive/both после восстановления CHR2 (2026-10-08)

Пятичасовой остаток перед блоком17%; выбран самостоятельный короткий блок без сборки/модификации компонентов. Real native/API evidence: текущий backend8782054/frontendf194e72, mainAPI, CHR1→CHR2, TCP/duration3s, последовательно receive иboth. HTTP/RouterOS-моков нет; по одной команде на направление, автоматических повторов нет.

Receive: HTTP200/10.3s/native done testing, RX4089.843456Mbps, TXnull. Both: HTTP200/10.3s/native done testing, TX1158.089056/RX983.244592Mbps. After-ping в обоих случаях53ms/0%loss. Независимый GET истории подтвердил уникальные runId/statusdone/направление и точное совпадениеTX/RX с receipt. Неизмеренный TX вreceive не подменён нулём. Значения — результаты короткой функциональной проверки, не benchmark устойчивой пропускной способности.

Mainhistory6→8 намеренно: ровно две записи этой приёмки. Probe snapshot не затрагивался (run безprobeId). Агентне менялRouterOSpassword/настройки/адреса; продуктовый код, образы иUI прежние. Это повторнаяпроверка направлений после восстановлениядоступа пользователем, не переобъявлениестарыхпрогонов.

Вместе сtransmit12.5.32 ROS-1TCP направления подтверждены на текущемдоступе. Native UDP/busy/disconnect/abort, multi-WAN/профильныеоперации/Q/интеграции ещёоткрыты. Следующий12.5.34 — ограниченный UDP native test с явными границами; полная12.5приёмка не закрыта. План/паспорт/протокол обновлены; локальный коммит без push.

12.5.34 — короткий UDP native test и реальная история UI (2026-10-08)

Пятичасовой остаток перед блоком13%; выполнен один самостоятельный тест без изменениякода/образов. Real native/API/browser evidence: основной стендbackend8782054/frontendf194e72, CHR1→CHR2, UDP/transmit/duration3s. HTTP/RouterOS-моков нет. Один POST, native connecting/running/done testing, HTTP200 за10.3s; TX3712.811856Mbps, RXnull, after-ping53ms/0%loss.

НезависимыйGEThistory подтвердил ровно одну строку с темжеrunId, protocolUDP/statusdone, точнымTX иRXnull; mainhistory8→9 намеренно. Реальный браузер uptime-speed показалUDP/done/TX3713Мбит/с и «Неизвестно» дляRX. 320pxfits,JSerrors0. Browsercontext закрыта, основнойстенд/туннель сохранены.

Это трёхсекундная функциональнаяпроверка; rate cap текущийAPI не задаёт, нагрузка ограничена длительностью. ЗначениеsenderTX и последующийPing не доказываютUDPpacket-deliveryratio приёмника или устойчивуюпропускнуюспособность. НовыеUDP directions/размерыpacket/длительнаянагрузка не проверялись. RouterOSконфигурация/пароли/сnapshotпроб (runбезprobeId) не менялись; продуктовыйкод иобразы прежние.

Следующий12.5.35 — Q-6: конкурентный enqueue с однимdedupekey в выделенномPostgreSQL, без фактическойотправки сообщений. ROS-2busy/disconnect/abort, профильныесетевыеоперации/Q/интеграции иполный12.5 остаютсяоткрытыми. План/паспорт/протокол обновлены; локальный коммит без push.

12.5.35 — PostgreSQL dedupe конкурентного enqueue (2026-10-08)

Q-6 real PG evidence: production function enqueueTelegramOutbox/source8782054, dedicatedmmapp_acceptance_20261007. Guard проверил имяБД. Scheduler admission закрыт внутри тестового процесса; dispatcher/Telegram sender не вызывались.

Две настоящие production INSERT сразнымиid/однимdedupekey одновременно ждали LOCK TABLEalert_outbox IN SHARE MODE: независимыйobserver увидел2Lockwaiters. ПослеCOMMIT holder обеоперации завершились, receipts[true,false]. SQL подтвердил однуpendingстроку/version0 сidпобедителя. Последующийenqueue стемжеключомвернулfalse, строкпо-прежнему1. Это реальная uniqueconstraint гонка/productionenqueue, не mockDB.

Fixture удалена, countoutbox совпал сbaseline, транзакция/соединения закрыты, container--rm удалён; основнойстенд/БД не затрагивались. Сообщений отправлено0. Q-6 принят в этих границах; claim/send/settlement/Q-1–5/7–8 отдельно не проверены. Продуктовыйкод/runtime прежний. Следующий12.5.36 — Q-4: конкурентныйunknownretry/expectedVersion без отправки сообщений. План/паспорт/протокол обновлены; локальный коммит без push.

12.5.36 — HTTP/PostgreSQL конкурентное разрешение unknown (2026-10-08)

Q-4 real HTTP/PG evidence: source8782054, dedicatedmmapp_acceptance_20261007/guardconfirmed, настоящийbuildApp/authfalse/startSchedulerfalse иproductionretryUnknownOutbox. Scheduleradmission закрыт, dispatcher не запускался; fixturepayload{} не отправлялся.

Два POSTalerts/outbox/id/retry сexpectedVersion0/acknowledgedDuplicateRisktrue одновременно ожидали внешнююSELECT FOR UPDATE блокировку: observerувидел2Lockwaiters. ПослеCOMMIT ответыполучены200/409. НезависимыйSQL подтвердилpending/version1, ровно одноувеличение. Следующийstaleversion0 запрос409, запись не изменилась. Послепереводаfixtureвprocessing запроссversion1 вернул409 безизменения; ackfalse получил400 такжебезизменения. Реальные транзакции/rowlock/HTTP, не mockDB.

Fixture удалена/countoutbox восстановленкbaseline; locks/app/poolзакрыты, temporarycontainer--rm удалён. ОсновнаяБД/runtimebackend8782054/frontendf194e72/mainhistory9 прежние. Сообщенийотправлено0; Telegram/Portal/RBAC не проверены этимauthfalse прогоном. Q-4 принят в этихграницах; Q-5 толькоprocessing-refusal, процедураповторанастоящегоunknown/рискдубликата ещёнепринята.

Следующий12.5.37 — Q-1конкурентныйclaim. РеальнуюTelegramдоставку/потерюreceipt проверятьтолько ссогласованнымтестовымчатом иразрешениемотправки; текущиеSQLfixturetests их не заменяют. Полный12.5открыт. План/паспорт/протокол обновлены; локальный коммит без push.

12.5.36.1 — rollback при некорректном retry receipt (2026-10-08)

Real HTTP/PG evidence: dedicatedmmapp_acceptance_20261007/backend8782054. Реальный BEFOREUPDATEtrigger только дляfixtureid добавляллишнююединицуversion: UPDATEreceiptвернул2 вместоожидаемой1. ProductionexecuteOutboxRetry отклонилreceipt, HTTP500; независимыйSQL подтвердилunknown/resolutionVersion0, ложнойpendingзаписи неосталось.

Тестовыеtrigger/function/rowудалены, countoutbox восстановленкbaseline; app/pool/containerзакрыты, dispatcherне запускался, сообщений0. Основнойbackend8782054/frontendf194e72 прежние. Это validation/transaction rollback, не полнаяQ-7/UI/RBAC/Telegramприёмка. Продуктовыйкод не менялся.

Блок выполнен изпоследнегорабочегорезервапослеQ-6/Q-4; новыхкрупныхблоковненачато. Следующий12.5.37 — Q-1конкурентныйclaim, сначала проверить остатокквоты. Журнал/план/паспорт/протокол обновлены; локальныйкоммитбезpush.

12.5.37 — конкурентный production claim с перехваченным отправителем (2026-10-08)

Q-1 real PG evidence: productiondispatchPendingOutbox/source8782054, dedicatedmmapp_acceptance_20261007. Guard проверил имяБД и отсутствиедругихготовыхpendingзаписей; scheduleradmission закрыт в isolatedprocess. Productionenqueue/claim/settle SQL использованы напрямую, queryкод не копировался в тест. Внешний fetch Telegram перехвачен только внутри процесса и вернулfixture oktrue; ниодногонастоящего сообщенияне отправлено.

Два dispatcher одновременновыбралиоднуpendingзапись и ожидалиSELECT FOR UPDATEholder: observerподтвердил2заблокированныхproductionUPDATE. ПослеCOMMIT оба завершились, но senderboundary былвызван1раз; results.sent суммарно1/failed0/held0/errors[]. IndependentSQL подтвердилоднуsentстроку иоднуhistorysent_oktrue. Повторныйdispatcher не сделалвторогоsendercall. Statussent иhistory — тестовыйрезультат принятогоfixtureHTTPresponse, не утверждениеореальнойдоставкеTelegram.

Fixtureoutbox/historyудалены, countoutbox восстановленкbaseline, временныеfakeTelegramsettings замененыисходными изпамяти безсохранениятокеноввфайлы/отчёт. Fetchзамена снята, locks/pool/containerзакрыты. Основнойстенд/БД не затрагивались, runtimeпрежний. Q-1claim/uniquesender принят в этихграницах, многопроцессныйdispatcher/реальнаяTelegramдоставка отдельнонепроверены.

Следующий12.5.38 — реальныйSQL settlement/history failure после принятого simulatedTelegramresponse, безреальныхсообщений. Q-2внешняядоставка не можетсчитатьсяпринятой поfixture. План/паспорт/протокол обновлены; локальныйкоммитбезpush.

12.5.38 — ошибки сохранения после принятого ответа отправителя (2026-10-08)

Отчёт PostgreSQL: production dispatchPendingOutbox из backend8782054, отдельная БД mmapp_acceptance_20261007. Telegram fetch перехвачен внутри изолированного процесса и возвращает ok=true; реальных сообщений не отправлено.

Реальный BEFORE INSERT trigger отклонил запись истории: транзакция settlement откатилась, outbox перешёл в unknown, история отсутствует. Повторный dispatcher не вызывает отправителя. После явно подтверждённого повторения синтетической записи проверена другая граница: PostgreSQL действительно выполнил COMMIT, затем обёртка node-pg ввела ошибку получения подтверждения. Outbox остался sent с resolution_version=1, история содержит ровно одну строку sent_ok=true; попытка hold не перезаписала подтверждённое состояние. Следующий dispatcher не повторил отправку. Поле result.sent=1 отражает принятый подменённый API-ответ и само по себе не подтверждает сохранение или реальную доставку.

Тестовые outbox/history/trigger/function удалены; исходные настройки Telegram восстановлены из памяти, fetch возвращён, pool и контейнер завершены. Основная БД и runtime не менялись. Это проверка SQL rollback и границы подтверждения COMMIT в одном процессе; физический разрыв соединения и реальная доставка Telegram не проверены.

Следующий блок 12.5.39 — неопределённый ответ отправителя и отказ записи unknown, без реальных сообщений. План, журнал этапа и протокол синхронизированы; локальный коммит без push.

12.5.39 — неопределённый ответ отправителя и отказ записи unknown (2026-10-08)

Отчёт PostgreSQL: production dispatchPendingOutbox из backend8782054, отдельная БД mmapp_acceptance_20261007. Fetch вместо внешнего запроса бросает исключение: это управляемая проверка отсутствия ответа, а не физический сетевой timeout и не доказательство доставки в Telegram.

В первом случае dispatcher вернул sent=0/failed=0/held=1, строка стала unknown без увеличения retry_count, история отсутствует. Повторный dispatcher не вызывает отправителя. Во втором случае реальный PostgreSQL trigger отклонил UPDATE unknown: строка осталась processing, API результата сообщает, что сохранение не подтверждено и автоматического повтора нет. После удаления триггера повторный dispatcher тоже не отправил сообщение. Два вызова перехваченного отправителя соответствуют двум явно подготовленным синтетическим сценариям; реальных сообщений — ноль.

Тестовые записи и объекты БД удалены, исходные настройки Telegram восстановлены из памяти с сохранением точного updated_at, fetch восстановлен, pool и контейнер закрыты. Отдельный SQL-запрос подтвердил ноль fixture-записей, ноль тестовых триггеров и функций для блоков 38–39. Основной стенд не затрагивался. Q-3 принят только на границе поведения production sender/PG; реальный чат, UI этого состояния и многопроцессное восстановление отдельно не проверены.

Следующий блок 12.5.40 — явный отказ отправителя, задержка повтора и исчерпание попыток, без реальных сообщений. Документы синхронизированы; локальный коммит без push.

12.5.40 — подтверждённый отказ и исчерпание попыток отправки (2026-10-08)

Отчёт PostgreSQL: production dispatchPendingOutbox из backend8782054, отдельная БД mmapp_acceptance_20261007. Внешний fetch возвращал явный Telegram отказ ok=false/error_code=400; реального запроса и сообщений не было.

Первая отклонённая попытка сохранила pending/retry_count=1, историю не создала и назначила next_attempt_at через 15 секунд. SQL timestamp проверен относительно времени до и после вызова; немедленный dispatcher не отправил повторный запрос. Чтобы не ждать таймер, только в fixture срок следующей попытки затем перенесён на now(). Вторая отклонённая попытка исчерпала maxRetries=2: failed/retry_count=2, одна история с sent_ok=false; последующий dispatcher больше не отправлял. Синтетический токен в description скрыт как [TOKEN] в сохранённой ошибке и ответе dispatcher.

Fixture outbox/history удалены, исходные настройки Telegram восстановлены из памяти с точным updated_at, fetch восстановлен, pool и контейнер завершены. Основной стенд не затрагивался. Это приёмка реального SQL и production-кода с перехваченным отказом; реальный Telegram отказ, нагрузка и многопроцессная работа не заявлены.

Следующий блок 12.5.41 — браузерная проверка unknown/processing через реальные HTTP и PostgreSQL, без отправки сообщений. Документы синхронизированы; локальный коммит без push.

12.5.41 — браузерная очередь через реальные HTTP и PostgreSQL (2026-10-08)

Отчёт браузера: production backend8782054/frontendf194e72, отдельная БД mmapp_acceptance_20261007. Пять синтетических SQL-состояний pending/processing/unknown/sent/failed, по одной строке; настоящий GET overview возвращает согласованные counts/items. HTTP-ответы в браузере не подменялись. Dispatcher не запускался, scheduler admission закрыт; внешний Telegram fetch дополнительно запрещён.

UI показывает понятные подписи и предупреждение об отсутствии автоматического повтора. Для unknown кнопка доступна, для processing отсутствует. Подтверждение риска требуется до постановки в очередь; отмена и Escape не отправляют POST и возвращают фокус. Управляемое исключение backend overview дало настоящий HTTP500: последний снимок сохранился, после восстановления ошибка исчезла. Reload сохранил SQL-состояния. Панель и диалог помещаются в 320px; итоговые снимки сделаны после завершения обновления и просмотрены: ПК, телефон, подтверждение. Queue HTTP statuses: 200/500/200/200; JS errors=0, retry POST=0, external sender calls=0.

Первый запуск остановлен проверкой маркера БД: Next rewrites закреплены во время сборки, runtime BACKEND_INTERNAL_URL не изменяет их. Для корректной изоляции frontend подключён только к отдельной Docker-сети с alias backend, разрешающим исключительно тестовый backend. Основной backend/БД не менялись. Временные контейнеры и сеть удалены; backend завершился с exitCode=0, журнал очистки подтвердил senderCalls=0/retryPosts=0, независимый SQL подтвердил ноль fixture-строк. Дополнительный SSH-туннель3018 закрыт; основной3000 сохранён.

Границы: AUTH_REQUIRED=false на изолированном loopback стенде; реальные Portal SSO, доставка Telegram, физический отказ PG и успешный UI retry не проверены этим блоком. Следующий 12.5.42 — настоящие JWT/RBAC чтения и повтора очереди на PostgreSQL. Локальный коммит без push.

12.5.42 — настоящие JWT/RBAC очереди на PostgreSQL (2026-10-08)

Отчёт JWT/RBAC: production buildApp/handlers/auth из backend8782054, AUTH_REQUIRED=true только внутри изолированного процесса, отдельная БД mmapp_acceptance_20261007. JWT HS256 подписаны серверным ключом в памяти; подпись, issuer и exp проверяет штатный middleware. Fastify inject проходит настоящий путь приложения и SQL, но не является браузерным запросом или удалённым сокетом.

GET outbox: anonymous, неверные issuer/signature, expired и malformed дают401; отсутствие разрешений, settings:admin без alerts и отсутствие доступа к приложению дают403; alerts:read/write/admin дают200 и реальные counts. Все GET сохраняют строки. Девять отказанных POST дают401/403, не меняют snapshot БД и не вызывают production retry boundary. Неподтверждённый риск даёт400 до boundary; неверная ожидаемая версия даёт409 без изменения. Разрешённые write и admin получают200, две fixture-строки становятся pending/retry_count=0/resolution_version=1. Дублирующий POST со старой версией даёт409 и сохраняет SQL snapshot. Ответы проверены на отсутствие JWT и ключа.

Первый запуск harness остановился до создания fixture: jose отсутствует в production-образе как тестовая зависимость. Для генерации стандартной HS256 подписи использован встроенный node:crypto, production middleware и настройки не менялись. Dispatcher не запускался, scheduler admission закрыт, сообщений не отправлено. App/pool/container завершены; fixture удалены, отдельный SQL подтвердил ноль тестовых строк; остались только три основные Compose-службы.

Границы: реальный Portal login/issuer endpoint не вызывался, браузерный RBAC и доставка не заявлены этим тестом. Q-7 подтверждён для API отказа до действия в этих границах. Следующий блок 12.5.43 — успешный UI retry и сохранение checkpoint при потере подтверждения HTTP в отдельной БД, с запретом внешней отправки. Локальный коммит без push.

12.5.43 — браузерный повтор и потеря подтверждения после COMMIT (2026-10-08)

Отчёт браузера: production backend8782054/frontendf194e72, отдельная БД mmapp_acceptance_20261007, два синтетических unknown-сообщения. Реальные браузерные HTTP запросы и production retry transaction; scheduler admission закрыт, dispatcher не запускается, внешний Telegram fetch запрещён. Изолированный frontend использует отдельную Docker-сеть и alias backend.

Первый POST200 подтверждает только постановку в pending/version1, подпись UI прямо сообщает, что отправка и доставка ещё не подтверждены. Во втором сценарии обёртка production retry бросает исключение после завершённой транзакции: настоящий HTTP500 при фактически сохранённом pending/version1. Диалог и checkbox риска остаются, повтор заблокирован. После отмены, refresh и reload предупреждение о неизвестном результате сохраняется; SQL подтверждает две pending-строки/version1/retry_count0 и ноль истории. Явная проверка результата снимает checkpoint без нового POST. Всего POST:200/500, lostReceipts1, senderCalls0, JS errors0; панель и диалог помещаются в320px.

Скриншоты просмотрены: предупреждение после перезагрузки, диалог после HTTP500. Первое тестовое ожидание внутреннего текста исключения исправлено на штатный production текст «Внутренняя ошибка сервера»; приложение не обязано раскрывать исключение. При пересоздании fixture первый прогон очищен с exitCode0. Итоговые контейнеры/сеть/туннель3018 удалены, backend exitCode0, независимый SQL подтвердил ноль fixture-строк. Основной стенд и RouterOS не менялись.

Границы: управляемый отказ получения receipt после фактического COMMIT, а не физический разрыв сети; AUTH_REQUIRED=false; реальных сообщений и проверки чата нет. Найдена UX-недоработка: внутри открытого диалога generic HTTP500 не объясняет неизвестный исход текущего повтора. Следующий блок 12.5.44 — явное пояснение и профильная проверка диалога. Локальный коммит без push.

12.5.44 — понятное пояснение неподтверждённого повтора в диалоге (2026-10-08)

По результатам реального теста12.5.43 уточнён catch в components/alerts-outbox-panel.tsx. При HTTP500, потере ответа или некорректном receipt ошибка прямо в открытом диалоге сообщает: «Результат повтора не подтверждён. Автоматический повтор заблокирован. Проверьте очередь и чат перед новой попыткой», затем показывает подробность ошибки. API400/401/403/409/422 остаются подтверждёнными отказами: checkpoint снимается, исходная ошибка сохраняется. Правила повторной отправки, права и API не менялись.

Профильный Playwright alerts-outbox.spec.ts:8/8, включая новый HTTP500 сценарий, сохранённый checkbox, disabled retry, reload guard и320px; прежние success, malformed receipt, reader, conflict и focus/cancel проходят. Eslint изменённых файлов и tsc --project tmp/tsconfig-speed-check.json --noEmit passed. Scoped config исключает старые копии исходников в tmp; это не утверждение о чистоте обычного полного tsc. Локальный диалог320px просмотрен. HTTP-ответы в этих локальных браузерных тестах подменены; реальные SQL/HTTP результаты43 сохраняются отдельно.

Применён skill ReUI и MCP get_audit_checklist: композиция, установленные primitives, base-nova и semantic tokens сохранены; новых API/стилей/компонентов нет. Ошибка объявляется существующим role=alert, реальные секреты не добавлены; подтверждение риска и управление фокусом покрыты профильными тестами. Изменение пока локальное, удалённый frontend остаётсяf194e72.

Следующий12.5.45 — production Docker build нового frontend, обновление тестового стенда и повтор сценария HTTP500 после COMMIT на отдельной БД. Локальный коммит без push.

12.5.45 — production frontend с пояснением неизвестного исхода (2026-10-08)

Развёртывание: чистый frontend Git archive из b55588f29b, SHA256 f18be60c1dc8c581e26040003d2c655ee2ae1da73044d761b166ac10dca71a7e совпал после передачи. Docker context повторяет frontend staging main workflow, workspaces ограничены packages; production build, полный TypeScript-check внутри образа и export завершились с exit0. Образ mmapp-test/frontend:ux-b55588f, imageId sha256:c3ce5aa8a3dbed7eaab23178cecbce2b2c1a27c31678590b54bc27db5820e5b1; исходный frontendf194e72 сохранён для отката. .env изменён только MMAPP_IMAGE_TAG, backend8782054 прежний и healthy, frontend опубликован исключительно127.0.0.1:3000. Git/image push не выполнялся.

Повтор реального browser retry: новый production frontend и прежний backend на отдельной PostgreSQL БД, без browser HTTP mocks. POST200/500, второй ответ потерян управляемым исключением после фактического COMMIT. Новый текст прямо в диалоге объясняет неподтверждённый исход и необходимость проверки; checkbox/форма/блокировка сохранены. Обе fixture pending/version1/retry_count0; история0, Telegram calls0. Refresh/reload сохраняют checkpoint, явная проверка снимает его без нового POST. Панель/диалог320px помещаются, JS errors0. Диалог и checkpoint просмотрены.

Smoke основной схемы: dashboard, servers, uptime speed, settings, filters, alerts возвращают200,320px fit, JS errors0/API errors0. Независимый контроль основной БД до/после совпадает: servers2/enabled2, speedHistory9, retention14, migrations9. Новые native тесты или сообщения не запускались. Тестовые контейнеры/сеть/туннель3018 удалены, backend fixture завершился exit0, независимый SQL подтвердил ноль его outbox-строк. Основной туннель3000 сохранён.

Границы: управляемый HTTP500 после COMMIT вместо физического сетевого разрыва; синтетические записи и AUTH_REQUIRED=false в изолированном browser стенде. Реальные Telegram доставка/чат, Portal SSO и multi-instance остаются отдельной приёмкой. Уточнены текущие версии и устаревшая сводка плана/паспорта, исторические записи сохранены. Следующий12.5.46 — браузерные права очереди с настоящими JWT. Локальный коммит без push.

12.5.46 — браузерные права очереди с подписанными JWT (2026-10-08)

Отчёт браузера: production frontendb55588f/backend8782054, отдельная PostgreSQL БД mmapp_acceptance_20261007. AUTH_REQUIRED=true только в тестовом процессе, отдельные синтетические HS256 key/issuer, два браузерных контекста read/write. Штатный backend проверяет подпись и разрешения; browser HTTP-ответы не подменялись. Основные настройки авторизации и ключи не изменялись, реальный Portal не вызывался.

Reader получает очередь и видит disabled retry. Прямой POST через browser fetch с reader JWT даёт403, SQL snapshot не меняется, mutation boundary не вызывается. JWT с теми же write claims, но неверной подписью, получает401 через настоящий HTTP API; строка и счётчик mutation сохраняются. Writer видит доступную кнопку, обязательное подтверждение риска, после него POST200 переводит fixture unknown/version0 в pending/version1/retry_count0. UI подтверждает только постановку в очередь; API принял0, история0. Reader после reload видит подтверждённое состояние.

Всего retry HTTP requests3 (403/401/200), mutation calls1, external sender calls0, JS errors0;320px fit. Читатель и после разрешённого повтора сохранены; экран читателя просмотрен. Тестовая запись синтетическая; scheduler admission закрыт, dispatcher не запускался, Telegram fetch дополнительно запрещён. Writer и reader имеют также необходимые read-права окружающей оболочки, но только writer имеет alerts:write.

Тестовые контейнеры/сеть/туннель3018 удалены; backend завершился exitCode0, cleanup подтвердил1mutation/3POST/0send, независимый SQL — ноль fixture-строк. Основной стенд/БД/RouterOS не менялись. Это подтверждение browser и API RBAC, не реального Portal login или Telegram доставки. Следующий12.5.47 — checkpoint и смена источника при незавершённом повторе. Локальный коммит без push.

12.5.47 — изоляция checkpoint при смене источника во время повтора (2026-10-08)

Отчёт браузера: текущий frontend sourceb55588f в Next dev с поддерживаемым NEXT_PUBLIC_BACKEND_URL=local, два настоящих backend8782054 и разные PostgreSQL БД: A mmapp_acceptance_20261007, B временная mmapp_acceptance_sourceb_20261008. Browser HTTP-ответы не подменялись. Production frontend остаётся same-origin с закреплённым источником; результат этого блока относится к конфигурации local, не к переключению в production.

Два синтетических сценария: нормальный поздний receipt и ошибка producer после реального retry COMMIT. Перед навигацией независимый SQL через контрольный endpoint подтверждает A pending/version1/retry_count0, ответ удержан. При A→B отображается только запись B unknown/version0, её кнопка доступна, checkpoint A и его подписи отсутствуют; БД B неизменна. При возврате в A предупреждение неизвестного результата сохраняется. Освобождение позднего producer outcome не снимает checkpoint и не показывает устаревший успех/ошибку; reload и refresh сохраняют защиту. Явная проверка результата снимает её без нового POST. По одному retry в A на сценарий, B retry0, Telegram calls0, JS errors0,320px fit.

Поздний receipt просмотрен; поздняя ошибка сохранена. Навигация штатно abort-ит старый клиентский запрос; управляемая задержка producer не является физическим разрывом сети или доказательством доставки сообщения. Scheduler admission закрыт, dispatcher не запускался, внешний Telegram fetch дополнительно запрещён. AUTH_REQUIRED=false на изолированных процессах; реальные Portal login и чат не проверены.

Оба backend завершились exitCode0, cleanup подтвердил A retry2/B retry0 и sender0. Независимые SQL-запросы подтвердили ноль fixture-записей в обеих БД. Контейнеры, локальный Next3101 и туннели8018/8019 удалены. Новая БД B удалена после проверки точного имени, владельца mmapp и отсутствия соединений; PostgreSQL подтвердил отсутствие БД. Основной стенд и БД не менялись. Следующий12.5.48 — профильная доступность очереди/диалога на production frontend. Локальный коммит без push.

12.5.48 — доступность production очереди и диалога (2026-10-08)

Отчёт доступности: production frontendb55588f/backend8782054, отдельная PostgreSQL БД, browser HTTP-ответы не подменялись. Axe4.11.3 с WCAG2A/AA,2.1A/AA,2.2AA tags: тёмная/светлая темы ×1280/320px, по четыре области/состояния — очередь, диалог без согласия, диалог с согласием, очередь при ошибке GET. Все16 scoped audits: violations0/incomplete0, passed rules14 для очереди и16 для диалога.

Клавиатура открывает диалог через Enter, Space переключает подтверждение риска и доступность submit. По шесть Tab/Shift+Tab проверок в каждом сочетании подтверждают завершённый перенос фокуса внутри modal; Escape закрывает и возвращает фокус trigger. Асинхронные состояния имеют role=status, ошибка GET — role=alert; после восстановления ошибка исчезает. Панель/диалог помещаются в320px. Светлая тема и тёмная тема сохранены и просмотрены.

Уточнены ожидания harness: сначала готовность доступной кнопки после основной загрузки, затем завершение CSS-анимации перед контрастным аудитом и завершение переноса фокуса через Base UI focus guards. Первый аудит поймал промежуточную прозрачность входной анимации; после её завершения контраст прошёл без изменения продукта. Это аудит устойчивых состояний, не проверка всех кадров перехода. HTTP500 создан управляемым backend overview exception; физический отказ БД не моделировался. Реальная screen reader сессия не проводилась, scoped axe/клавиатура не означают полную WCAG сертификацию приложения.

Retry POST0, Telegram calls0, JS errors0, SQL fixture counts сохранялись во всех сценариях. Dispatcher не запускался, scheduler admission закрыт. Временные контейнеры/сеть/туннель3018 удалены, backend exitCode0, отдельный SQL подтвердил ноль fixture-строк. Основной стенд и данные не менялись. Следующий12.5.49 — сводка Q-матрицы и точные оставшиеся условия реальной внешней приёмки. Локальный коммит без push.

12.5.49 — сводка очереди и оставшихся внешних условий (2026-10-08)

Сверены сохранённые JSON evidence блоков35–48: отчёты читаются, дата2026-10-08 и backend8782054 согласованы; актуальные browser отчёты используют frontendb55588f. Это сводка уже выполненных проверок, новых отправок или сетевых изменений нет.

ID Подтверждённый результат Что остаётся за пределами проверки
Q-1 Два production claim на PG дают один вызов перехваченного отправителя и одну историю: 37 Несколько процессов/экземпляров, настоящая Telegram доставка
Q-2 Реальный SQL отказ истории откатывает settlement; ошибка подтверждения после COMMIT не перезаписывает sent: 38 Принятый ответ настоящего Telegram API, независимая проверка тестового чата
Q-3 Неопределённый sender response удерживает unknown/processing без auto retry; browser checkpoint переживает HTTP500/reload: 39, 45 Физический timeout/disconnect после возможной реальной отправки и сверка с чатом
Q-4 Конкурентные retry дают200/409 и одно увеличение версии; старый повтор не меняет БД: 36, 46 Queue receipt не означает доставку
Q-5 Processing отвергается, обязательное подтверждение риска и блокировка неизвестного исхода работают: 36, 45 Операционная процедура остановки всех реальных senders, включая несколько экземпляров, перед осознанным повтором
Q-6 Два конкурентных enqueue создают одну строку, повтор возвращаетfalse: 35 Не отдельное доказательство Telegram delivery
Q-7 Malformed receipt откатывает реальную транзакцию; JWT/read/write защищают API и UI; ABA source isolation сохраняет checkpoint: 36.1, 46, 47 Настоящий Portal login; source switching проверен в поддерживаемой local-конфигурации, production закреплён same-origin
UX/a11y Dark/light1280/320,16 scoped axe audits, keyboard/focus/error states: 48 Ручная screen reader приёмка и полная WCAG оценка приложения

Готовность Telegram: штатный GET alerts на основном тестовом стенде, сохранены только признаки tokenConfigured=false/chatConfigured=false/threadConfigured=false. Токен, chat ID и исходный ответ не сохранялись. Telegram пока не настроен; real-message сценарии не могут быть приняты по подменённым ответам. Для этой ветки нужен отдельный тестовый бот/чат в приложении и явное разрешение на одно конкретное тестовое сообщение; до этого внешние сообщения не отправлять.

Этап12.5 остаётся открытым. Проверенные группы не заменяют остальные PG/ROS/Portal/интеграционные сценарии протокола. Следующий12.5.50 — read-only инвентаризация двух CHR для определения доступных VPN/маршрутизации/диагностики и подготовки оставшихся сетевых проверок; конфигурацию устройств этим шагом не менять. План/паспорт/протокол синхронизированы. Локальный коммит без push.

12.5.50 — инвентаризация двух CHR без изменения конфигурации (2026-10-08)

Отчёт CHR: штатный MikrotikClient из backend8782054, соединения из существующих записей основной тестовой БД, только enabled устройства194.226.121.150/id1 и104.165.244.7/id2. Использованы исключительно GET; post/put/patch/delete в тестовом процессе дополнительно запрещены. Не запускались Ping/bandwidth, scheduler или buildApp. Сырые VPN ответы, ключи и пароли оставались в памяти и не сохранялись/не выводились.

Оба устройства отвечают, RouterOS7.24.5 stable, CHR; оба имеют appType home-router. На каждом прочитаны19 разделов и повторно сверены выбранные конфигурационные поля; вместе с resource78 GET. Все разделы доступны, selectedConfigurationUnchanged=true. Сверка ограничена перечисленными в harness полями, не является полным export или доказательством отсутствия любых внешних изменений.

Раздел CHR1 / CHR2 Следствие для приёмки
Интерфейсы 2/2: ether и loopback Нет VPN-интерфейсов для действий над существующим туннелем
IPv4 адреса / маршруты 1/2 адреса,4/5 маршрутов Существующая адресация и маршруты сохранены; connectivity этим GET не доказана
WireGuard / peers, GRE, VXLAN 0/0 в каждом разделе Можно проверить истинное пустое состояние; ROS6 lifecycle/connectivity требует отдельного тестового объекта
IPsec Peers0,active-peers0; на каждом1policy/template Стандартный template не считать действующим VPN
BGP connections/sessions 0/0 Для реального сценария нужны тестовый peer и сессия
OSPF instances/templates/neighbors 0/0 Preview/apply/factual cost в ROS5 пока проверить не на чем
IPv4 Firewall filter/NAT/mangle, routing filters 0/0 Пустая конфигурация подтверждена; IPv6 и реальные изменения правил не приняты
Роли приложения home-router/home-router Home→JH и JH↔Exit в ROS4 не подтверждены текущей парой ролей

Контроль основной БД до/после совпадает: servers2, speedHistory9, retention14. Дополнительный SELECT подтвердил роли home-router. Эфемерный контейнер завершён/удалён, pool закрыт; остались только три основные Compose-службы. Пароли, адресация и правила устройств не менялись. Эта инвентаризация не закрывает ROS4/5/6 или остальные внешние ограничения.

Следующий12.5.51 — проверить реальные пустые состояния, выбор устройства/URL-контекст и доступность форм сетевых экранов на production frontend, без изменения RouterOS. После этого конкретный план создания изолированных тестовых объектов должен сохранять административный доступ и существующую конфигурацию. План/паспорт/протокол синхронизированы; локальный коммит без push.

12.5.51 — реальная GRE пара, связность и lifecycle (2026-10-08)

По прямому поручению пользователя VPN-приёмка продолжается с созданием реальных тестовых туннелей, особенно GRE. Lifecycle: production backend8782054, два CHR7.24.5, собственные имена mm-acceptance-gre-* и комментарий владения. Перед записью проверены локальные внешние адреса и отсутствие пересечения198.18.255.248/30 с существующей адресацией/недефолтными маршрутами. POST application API создал обе GRE стороны и /ip/address:201/201. Внешние endpoints194.226.121.150 ↔104.165.244.7, внутренние198.18.255.249/30 ↔198.18.255.250/30, MTU1400,keepalive2s/3. Дополнительных static/default routes и Firewall правил не создавалось.

После running=true независимый RouterOS Ping через указанный GRE интерфейс:3/3 в каждом направлении,0%loss,~54ms. Это реальная point-to-point связность, не benchmark и не шифрованный IPsec. PATCH MTU первого конца1360, disable и enable дали200 и подтверждены отдельным чтением RouterOS. Browser: настоящие созданные объекты, формы обоих устройств, local IP и server/tunnel URL-контекст/reload/320px, JS errors0; browser проход читает/отменяет формы, создание/изменение выполнял production API. ФормаCHR1 просмотрена, CHR2 сохранена.

Первый запуск Ping до готовности получил timeout; повтор после running подтвердил3/3. Первый harness остановил свою очистку на слишком строгом сравнении baseline, включавшем runtime IDs; причина конкретного несовпадения не была сохранена полностью. Независимая очистка удалила оставшуюся собственную сторону и подтвердила отсутствие интерфейсов/IP/connected route, исходные количества0GRE/1–2addresses/4–5routes. Harness исправлен: сначала очистить обе стороны, сравнивать конфигурационные поля без runtime IDs, сохранить evidence до assertion. Повторный полный lifecycle прошёл с exitCode0: DELETE200/200, все выбранные поля GRE/IP/route/IPv4 Firewall совпали с baseline. Прямое административное восстановление чужих объектов не выполнялось.

Обнаружен настоящий дефект: принятый remoteInnerIp возвращается пустым, затем теряется в форме редактирования. Связность обеспечивается настройкой обоих реальных /ip/address, но сохранение формы этим не считается исправленным. Следующий12.5.52 — исправить metadata persistence/restore peer IP и профильные тесты, затем развернуть и повторить настоящий GRE цикл. Ограничения ROS6 для остальных VPN/прав/частичных отказов остаются. Control main2servers/9speed/retention14 сохранён; application GRE revisions намеренно остаются журналом выполненных действий. Временный контейнер/туннель8018 удалены; RouterOS тестовые объекты очищены. Локальный коммит без push.

Официальная схема пары и keepalive: MikroTik GRE. Документация текущей версии проверена, реальные команды/ответы — RouterOS7.24.5.

12.5.52 — сохранение удалённого внутреннего IP GRE (2026-10-08)

Исправлен дефект, обнаруженный на настоящей GRE паре в12.5.51. Новый backend services/gre-comment.ts хранит remoteInnerIp в версионированном base64url JSON suffix комментария RouterOS. Это метаданные приложения, не маршруты и не /ip/address на удалённом устройстве. greInterfaceBody сохраняет peer, mapGreLive возвращает его и чистый пользовательский комментарий; snapshot содержит peer и исходный raw comment для корректного restore. PATCH без remoteInnerIp сохраняет текущий peer; явная пустая строка очищает. Форма теперь передаёт пустую строку при очистке вместо пропуска поля.

Старые gateway/network комментарии читаются и сохраняются при restore; непонятный/повреждённый suffix остаётся обычным пользовательским текстом. Явная очистка legacy peer записывает пустое metadata значение, чтобы прежняя подсказка комментария не возвращала удалённое поле. Метаданные не создают сетевые маршруты и не содержат PSK/паролей; GRE/IPsec secret logic не менялась. Raw metadata видна в прямом RouterOS comment, в API/UI служебный suffix отделён от пользовательского текста.

gre-comment.test.ts проверил create plan→native comment→map→snapshot→restore, Unicode/несколько строк, idempotence, legacy, invalid suffix и explicit clear; планы ограничены GRE/IP, без /ip/route. Прежний entity-snapshots.test.ts passed. Playwright gre-form+gre-toggle5/5: создание/DTO/edit, сохранённый ввод при отказе и неверном receipt, explicit empty remoteInnerIp, подтверждение переключения. Browser ответы локальных проверок подменены; новое metadata на реальном RouterOS этим блоком не принято. Backend tsc --noEmit и scoped frontend typecheck passed. Eslint без ошибок, одно прежнее unused bool предупреждение в entity-snapshots.ts:258; дифф не меняет этот helper.

Код и тесты готовы к сборке; удалённый runtime пока backend8782054/frontendb55588f, реальные GRE объекты из51 удалены. Следующий12.5.53 — production Docker build/deploy backend и frontend, новая собственная GRE пара с независимой проверкой peer read/MTU-toggle/clear/restore, реальный UI и двусторонний Ping, очистка по имени и decoded ownership comment. Пользовательское требование реальных VPN объектов сохраняется. Локальный коммит без push.

12.5.53 — развёртывание peer metadata и реальный GRE regression (2026-10-08)

Развёртывание: backend и frontend из bd3f996f55, чистый Git archive SHA256 c154aa8c706d083a791ed04f26bad433cb1ab9a5d9a6c6ec08b5751d7977d46f совпал после передачи. Docker staging повторяет main workflow; обе сборки exit0, Next production compile/full TypeScript passed. Backend imageId sha256:6bb78eaeb922de577d399633ed6fcc821a47ae8abbb947ce6971bb453bfcf6d8, frontend sha256:1f22f4a2900b13bb5b1202e4a98a4c679b57d6453599318b52cbc988a63cc4053. Только две image tag переменные .env обновлены, compose validation/health passed, version1.0.0-test.bd3f996. Прежние образы сохранены. Приватный PG backup1433491bytes/PGDMP/pg_restore --list passed остаётся только на сервере; дамп и секреты в Git не передавались. Push не выполнялся.

Настоящий GRE lifecycle: новая собственная пара на двух CHR, предварительно GRE разделы пусты и подсеть198.18.255.248/30 свободна. POST201/201 вернули запрошенный peer IP и чистый пользовательский комментарий. Независимое чтение native comment подтвердило metadata, MTU1360 и disable/enable сохранили peer; explicit clear и restore собственной первой apply-ревизии подтвердились. Snapshot проверен по имени, одному объекту и peer до restore, текущий GRE state ограничен собственным fixture. Двусторонний Ping после running:true —3/3,0%loss,~54ms. Это plain GRE/point-to-point ICMP, не IPsec или throughput benchmark.

Browser regression: production frontend/API без HTTP mocks, peer и local IP в формах обоих устройств, comment без служебного suffix, server/tunnel URL и reload сохранены,320px fits. НаCHR1 очистка и повторное сохранение peer через форму дали PATCH200/200, результат перечитан непосредственно с RouterOS. JS errors0. CHR1 просмотрен, CHR2 сохранён. Smoke: dashboard/servers/uptime/settings/filters/alerts200,320px fit, JS/API errors0.

Первые browser попытки остановились на меню, которое исчезало при перерисовке. Таймер первой пары удалил собственные объекты. Немедленная сверка /ip/route дала mismatch; финальный harness добавил ограниченное ожидание сходимости маршрутов, не меняя их вручную. Итоговый запуск exit0: DELETE200/200, все выбранные поля GRE/IP/routes/IPv4 Firewall совпали с baseline; CHR1 потребовал одно повторное чтение через250ms, CHR2 совпал сразу. Тестовое меню в успешном проходе пришлось открыть повторно1раз: это не исправленный UX, а отдельная выявленная недоработка для54. Проверка не является доказательством неизменности всех runtime параметров/полного export.

Own GRE интерфейсы, адреса и connected route удалены; эфемерный контейнер и туннель8018 закрыты, остались три основные Compose-службы. Main controls до/после: servers2/speedHistory9/retention14/migrations9 совпадают; GRE audit revisions намеренно сохранены. Следующий12.5.54 — сохранить устойчивость меню действий GRE при перерисовке и проверить профильный сценарий; затем продолжать настоящие VPN объекты. Права, частичные отказы остальных VPN, Portal/Telegram и прочие внешние ограничения остаются открытыми. Локальный коммит без push.

12.5.54 — устойчивость меню GRE при обновлении таблицы (2026-10-08)

При обновлении callbacks/прав пересоздавался inline renderer actions column; React монтировал ячейку заново и закрывал Base UI меню. В components/data-grids/gre-tunnels-data-grid.tsx вынесен стабильный GreActionsCell, текущие callbacks/permissions передаются через типизированный React context. ReUI composition, оформление, API таблицы и ключ строки serverId/id сохранены. Политика блокировки операций при загрузке и отсутствии доступа сохранена.

Проверки: новый tests/e2e/gre-menu-refresh.spec.ts открывает меню, запускает GET без outside pointer event, проверяет сохранение меню, disabled во время загрузки, восстановление enabled и свежий peer IP в форме. На прежнем HEAD тест падает именно из-за исчезнувшего menuitem; исправленный код проходит. Вместе с gre-toggle.spec.ts — 3/3 passed. Scoped TypeScript (tmp/tsconfig-speed-check.json) и ESLint изменённых файлов passed. Первую фикстуру скорректировали: инициализация источника допускает несколько GET, задержка включается только при проверяемом refresh. ReUI data-grid checklist проверен, общие компоненты не менялись.

Это локальное исправление. На тестовом сервере backend/frontend bd3f996; live CHR сценарий стабильности меню пока не проверен. Следующий12.5.55 — собрать и развернуть frontend, создать собственную реальную GRE пару, проверить меню при обновлении и форму, затем удалить только собственные интерфейсы/IP и проверить baseline. Реальные VPN объекты обязательны по указанию пользователя. Telegram/Portal/multi-instance и остальные внешние ограничения остаются открытыми. Локальный коммит без push.

12.5.55 — развёртывание устойчивого меню и повторная реальная GRE проверка (2026-10-08)

Развёртывание: frontend731803bade672e4e5bd58ffbc223563f3318d4a9/version1.0.0-test.731803b. Архив Git SHA256 b6ff604a03e65151b4f2fc1406885b97f40240646f651a371fd603c00e1e867b совпал после передачи. Staging предыдущей main-совместимой сборки обновлён единственным изменённым production input — gre-tunnels-data-grid.tsx; package-lock/Dockerfile совпали. Docker build exit0, Next production compile/full TypeScript passed. Обновлена только MMAPP_IMAGE_TAG, compose validation passed; перезапущен только frontend, прежний образ оставлен для rollback. Backendbd3f996 не менялся и healthy. Контрольные значения БД до/после: servers2/speedHistory9/retention14/migrations9 совпали. Push не выполнялся.

GRE native lifecycle: собственная новая пара mm-acceptance-gre-1791468767519, подсеть198.18.255.248/30 проверена на пересечение, оба GRE раздела исходно пусты. POST201/201, native peer metadata, snapshot/restore, MTU/disable/enable/clear подтверждены; Ping3/3 в обе стороны,0%loss. Production browser: никаких HTTP mocks, на каждом CHR меню открыто один раз и пережило live GET200 при1280 и320px; menuReopens0. Форма совпала с native local/remote inner IP и чистым пользовательским comment; URL/reload сохранён, JS/API errors0. Toolbar refresh вызван без outside pointer event: обычный клик вне меню должен его закрывать. Controlled pending permissions проверены локально в54, здесь подтверждено реальное обновление данных.

CHR1 mobile визуально просмотрен, CHR2 сохранён. Первое измерение ширины произошло во время анимации Sheet и остановило browser harness; повторный проход с ожиданием сходимости layout прошёл, продуктовый код не менялся. Выявлена отдельная UX-недоработка: два внутренних IP поля слишком узкие для чтения полной записи при320px. Это следующий56, а не заявленный исправленный результат55.

DELETE200/200, own интерфейсы/IP и connected routes удалены; выбранные GRE/IP/routes/IPv4 Firewall поля совпали с baseline (CHR1 — одно повторное чтение маршрутов через250ms). Эфемерный контейнер удалён, работают только три основные Compose-службы. GRE revisions намеренно остались как история операций. Smoke: dashboard/servers/uptime/settings/filters/alerts200,320px fit, JS/API errors0. Это plain GRE и point-to-point ICMP, не IPsec/throughput/остальные VPN. Telegram/Portal/multi-instance и другие внешние ограничения остаются открытыми. Следующий12.5.56 — мобильная форма GRE; пользовательское правило создавать и очищать реальные VPN объекты сохраняется. Локальный коммит без push.

12.5.56 — читаемые внутренние IP в мобильной форме GRE (2026-10-08)

В app/(main)/gre/page.tsx адаптирована только сетка существующих полей: grid-cols-1 gap-3 sm:grid-cols-2. До640px локальный и удалённый IP идут друг под другом; начиная соsm — рядом. Input/Sheet, подписи, значения и API сохранения не менялись, общие ReUI primitives и оформление сохранены. Доступные249px на320px позволяют показать полный255.255.255.254/32 (измеренная ширина текста≈173px); в двух колонках на640px доступно204px.

Локальная визуальная проверка через временный Playwright harness: светлая тема, тёмная тема. Два прохода/шесть комбинаций320/640/1280px passed: расположение полей, полный IPv4/CIDR в текущем шрифте, Tab локальный→удалённый, сохранение значения, доступность footer и отсутствие page overflow. Светлый320px и тёмный320px просмотрены. API в этих проверках подменён; это доказательство локального layout, а не внешняя CHR приёмка. Первые настройки временного harness исправлены: cwd для Next и фактический ключ темы rl-theme; продуктовых ошибок это не выявило.

Итоговая профильная регрессия gre-form.spec.ts + gre-menu-refresh.spec.ts —4/4 passed: create/DTO/edit, API ошибки и неподтверждённые ответы, сохранение ввода, защита от повторной отправки, открытое меню после refresh. Scoped TypeScript (tmp/tsconfig-speed-check.json), ESLint изменённого page и ReUI checklist passed. Общая регрессия не повторялась для одной адаптивной сетки.

Изменение локальное, удалённый runtime backendbd3f996/frontend731803b не менялся. Следующий12.5.57 — frontend production Docker build/deploy и мобильная форма на новой собственной реальной GRE паре/API/RouterOS, затем очистка и baseline. Пользовательское требование настоящих VPN объектов сохраняется. Telegram/Portal/multi-instance и остальные внешние ограничения остаются открытыми. Локальный коммит без push.

12.5.57 — развёртывание мобильной формы и реальная GRE приёмка (2026-10-08)

Развёртывание: frontendfd521f6ef892ff3f7e8bc25878d80fb13817dda8/version1.0.0-test.fd521f6, backendbd3f996 healthy. Архив Git SHA2563187feed4f9346045ccf5d878b2965093b4b115f305d1da183523d1b7988204a совпал после передачи. В main-совместимом staging предыдущей сборки обновлён единственный изменённый production input — app/(main)/gre/page.tsx; package-lock и Dockerfile совпали. Docker build exit0/production TypeScript passed. Изменена только MMAPP_IMAGE_TAG, compose validation passed; перезапущен только frontend, предыдущий731803b образ сохранён для rollback. Контрольные значения БД до/после: servers2/speedHistory9/retention14/migrations9 совпали. Push не выполнялся.

GRE lifecycle: новая собственная пара mm-acceptance-gre-1791469984747, исходные GRE разделы пусты,198.18.255.248/30 не пересекается с недефолтными маршрутами/адресами. POST201/201, native peer metadata, MTU/disable/enable/clear и snapshot restore подтверждены; Ping3/3 в обе стороны,0%loss. Это plain GRE и ICMP, не IPsec/throughput.

Production browser: оба CHR × две темы ×320/640/1280px —12 комбинаций без HTTP mocks. Native local/remote inner IP читаются полностью; на320px одна колонка, на640/1280 две; Tab local→remote и отсутствие page overflow подтверждены. Меню сохраняется после live GET200 при1280/320px, повторных открытий0. В тёмной теме формы обоих CHR сохранены с неизменёнными значениями: PATCH200/200, независимое native чтение подтвердило адреса, peer IP и comment. Светлая тема проверена без записи. Server URL context/reload сохранён. JS/API errors0. Browser refresh вызывается без outside pointer event; локальная проверка pending/прав остаётся доказательством54.

Скриншоты320px: CHR1 dark, CHR1 light, CHR2 dark, CHR2 light. CHR1 dark и CHR2 light визуально просмотрены: внутренние IP целиком видны. Smoke: dashboard/servers/uptime/settings/filters/alerts200,320px fit, JS/API errors0.

DELETE200/200, собственные GRE/IP/connected routes удалены; выбранные GRE/IP/routes/IPv4 Firewall поля совпали с baseline, CHR1 — одно повторное чтение маршрутов через250ms. Эфемерный контейнер удалён; остались три основные Compose-службы. GRE revisions намеренно сохранены как история операций. Следующий12.5.58 — реальная собственная WireGuard пара, API/native/UI, handshake/связность, очистка и baseline; private/preshared keys не включать в публичные отчёты. Требование пользователя о настоящих VPN объектах сохраняется. Telegram/Portal/multi-instance и другие внешние ограничения остаются открытыми. Локальный коммит без push.

12.5.58 — настоящая WireGuard пара, handshake и UI (2026-10-08)

Итоговый реальный lifecycle: собственная пара mm-acceptance-wg-1791470702451 на двух CHR, UDP51879 и198.18.255.240/30 проверены на коллизии/пересечения. POST interfaces201/201 создали интерфейсы и IP; native чтение подтвердило автоматические ключи и адреса, POST peers201/201 — связь с публичным ключом другого устройства. Ключи проверялись в памяти и не записывались в публичные артефакты. Allowed адреса ограничены IP другого конца /32, persistent keepalive5s. Default routes/Firewall не менялись. Параметры и смысл last-handshake сверены с официальной документацией MikroTik.

На обоих peers появился native handshake и RX>0; двусторонний Ping3/3,0%loss, около54–56ms. PATCH MTU1380 и возврат1420 подтверждены native чтением. Каталог приложения совпал с адресами/peers/handshake и не содержал privateKey по умолчанию. Это короткая проверка защищённой WireGuard связности; throughput, RBAC, interrupted mutation, экспорт и import не проверены.

Production browser: два CHR × две темы,1280/320px без HTTP mocks. В деталях видны own peer name, Allowed IPs, endpoint, handshake и известные RX/TX; server/interface URL и вкладка peers пережили reload, page overflow отсутствует. На320px длинные имя и CIDR переносятся; исходная таблица сохраняет собственный горизонтальный scroll. Создание/изменение/удаление через UI не проверялись. JS/API errors0. Скриншоты: CHR1 dark, CHR1 light, CHR2 dark, CHR2 light; итоговыйCHR2 light просмотрен. Первый browser locator одновременно находил sr-only и родительскую подпись handshake, уточнение локатора дало успешный проход без изменения продукта.

Первый проход подтвердил связность/UI, но cleanup harness получил DELETE400: Content-Type application/json был передан без тела. Это ошибка harness, не доказательство ошибки приложения. Восстановительная очистка через правильные DELETE проверила ownership comment/name и отсутствие own interfaces/peers/IP/routes. Baseline первого прохода был только в памяти и после выхода потерян; точная сверка первого baseline не заявляется. Harness исправлен, создана новая пара и повторён полный lifecycle/browser; итоговый exit0 и все выбранные baseline поля совпали.

В финальном cleanup собственные peers удалены API200/200, собственные IP явно удалены native API до удаления interfaces API200/200. Автоматическая очистка IP/peers при обычном удалении интерфейса НЕ проверена и остаётся следующим12.5.59. WireGuard/IP/routes/IPv4 Firewall выбранные настройки совпали с baseline; эфемерный контейнер удалён, работают только три основные Compose-службы. DB controls до/после servers2/speedHistory9/retention14/migrations9 совпали, backend healthy. WG revisions намеренно сохранены как история операций. Runtime backendbd3f996/frontendfd521f6 не менялся. Telegram/Portal/multi-instance и остальные внешние ограничения остаются открытыми. Локальный коммит без push.

12.5.59 — удаление WireGuard оставляло peer и IP; локальное исправление (2026-10-08)

Production UI: собственная новая пара mm-acceptance-wg-1791471219775, подтверждённые handshake/двусторонний Ping. Интерфейсы удалены через стандартные меню и AlertDialog приложения на обоих CHR (ПК/320px). DELETE200/200 закрыли диалоги, но независимое native чтение обнаружило на каждом устройстве оставшийся peer и собственный IPv4 адрес. Это подтверждённая ошибка backendbd3f996: route удалял только /interface/wireguard/id, RouterOS сохранил связанные записи.

Native проверка и восстановительная очистка: afterBrowserDelete содержит interface:null, peerCount1 и собственный адрес на каждом CHR. Harness сохранил исходные идентификаторы own peers/IP и удалил только эти остатки, даже после исчезновения интерфейса. Финальный exit0, выбранные WG/peers/IP/routes/IPv4 Firewall поля совпали с baseline; ephemeral контейнер удалён, остались три основные службы. Это очистка теста, а не успешная приёмка стандартного удаления. Ключи не включены в публичные отчёты; WG revisions намеренно сохранены.

Локально добавлен backend/src/services/wireguard-delete.ts и подключён к DELETE route: идентификация интерфейса по rosId, чтение peers и IPv4 адресов до первой записи, отбор только связанных с именем/rosId объектов, удаление peers→addresses→interface, независимое перечитывание и ошибка при оставшихся объектах. При read failure запись не начинается; при промежуточной ошибке дальнейшее удаление прекращается, ошибка возвращается вместо ok. Успех и apply revision происходят только после проверки отсутствия объектов. Это последовательные RouterOS операции, не транзакция: частичный сбой может оставить частично удалённые данные, потребуется повтор/обновление. Текст подтверждения в WireGuard page теперь указывает связанные пиры и IP-адреса.

Проверки backend/src/services/wireguard-delete.test.ts —9/9: чужие объекты сохранены, связи по имени/rosId, encoded ID, ошибки всех предварительных чтений, неизвестный интерфейс, частичная ошибка/повтор, неподтверждённое удаление каждой группы. Profile UI tests wireguard-links.spec.ts --grep deletion/удал —2/2: подтверждение удаления интерфейса/пира, запрет повторного нажатия и повтор после API ошибки. Backend TypeScript, scoped frontend TypeScript (tmp/tsconfig-speed-check.json), ESLint изменённых файлов и ReUI checklist passed. Примитивы/таблицы не менялись.

Исправление пока локальное: удалённый backendbd3f996/frontendfd521f6 остаётся прежним. Следующий12.5.60 — production Docker build/deploy обеих частей, новая собственная WireGuard пара и обычное UI/API удаление без предварительного удаления peer/IP, независимая проверка отсутствия остатков и baseline, очистка fallback только own объектов. IPv6 address lifecycle, concurrency/multi-instance, Telegram/Portal и другие внешние ограничения не проверены. Пользовательское правило настоящих VPN объектов сохраняется. Локальный коммит без push.

12.5.60 — развёртывание и реальное полное удаление WireGuard (2026-10-08)

Развёртывание: backend/frontend3722fad329a68a8721ebfda8e044ab6cb5830cca/version1.0.0-test.3722fad. Чистый Git archive SHA256ec8084a0acbd0f26886a4c54072b65943d835b42a6a314c28e58b1b2bed791c6 совпал после передачи. Main-совместимые staging contexts предыдущих сборок обновлены только изменившимися production inputs: WireGuard route/service backend и frontend page. Docker builds exit0, backend/full Next TypeScript passed. Только BACKEND_IMAGE_TAG и MMAPP_IMAGE_TAG обновлены, compose validation passed, перезапущены backend/frontend. Прежние backendbd3f996/frontendfd521f6 образы оставлены для rollback. Приватный pre-3722fad PG backup1771860bytes/0600 с проверкой pg_restore --list остаётся только на сервере; дамп и ключи не передавались. DB controls до/после servers2/speedHistory9/retention14/migrations9 совпали, backend healthy, версия API подтверждена. Push не выполнялся.

Настоящая пара и native проверка: новый own fixture mm-acceptance-wg-1791472117395, свободные UDP51879 и198.18.255.240/30. Создание interfaces/peers API201, native key association, handshake/RX, короткий двусторонний Ping3/3 и MTU подтверждены до удаления. Пиры и адреса оставались прикреплены к интерфейсам до действий пользователя в тесте; предварительного удаления peers/IP harness не делал.

Production UI delete: собственные интерфейсы удалены через стандартное меню и подтверждение на обоих CHR (ПК/320px), текст указывает связанные пиры и IP-адреса. DELETE200/200 закрыли диалоги; независимое native чтение сразу после каждого ответа показало interface:null, peers0, addresses[]. Проверка выполнена ДО finish/fallback cleanup. Это подтверждает исправление59 на живом RouterOS, а не маскирующую очистку harness. JS errors0; HTTP mocks отсутствуют.

Итоговый harness exit0: afterBrowserDelete пуст на обеих сторонах, выбранные WG/peers/IP/routes/IPv4 Firewall поля совпали с baseline. Fallback не понадобился для peers/IP/interfaces; ephemeral контейнер удалён, остались три основные Compose-службы. WireGuard revisions намеренно сохранены как история операций. Smoke: dashboard/servers/uptime/settings/filters/alerts200,320px fit, JS/API errors0.

Приняты успешное обычное удаление own интерфейса с IPv4 адресом и пиром и соответствующий UI результат. Partial failures/read errors/сохранение чужих WG объектов проверены локальными тестами59; на этом стенде такие отказы не инжектировались. IPv6 lifecycle, concurrency/multi-instance, throughput, Telegram/Portal и остальные внешние ограничения остаются открытыми. Следующий12.5.61 — реальные WireGuard действия через UI: создание интерфейса и пира, переключение и очистка собственной пары; ключи не публиковать. Пользовательское правило настоящих VPN объектов сохраняется. Локальный коммит без push.

12.5.61 — UI создание WireGuard и локальное исправление нестабильного меню (2026-10-08)

Первый native observer: собственная пара mm-acceptance-wg-ui-1791472667527, свободные UDP51879/198.18.255.240/30, интерфейсы и пиры созданы только через production формы приложения. Observer не создавал конфигурацию. Оба интерфейса/IP/native key generation и поля peers/endpoint/allowed/keepalive/comment подтвердились, native peer key association и первый двусторонний Ping3/3 прошли. Публичные ключи переданы в форму в памяти, ключи не включены в отчёты. Создание интерфейса наCHR1 выполнено наПК, наCHR2 при320px. Мобильная форма сохранена без ключей и визуально просмотрена; этот снимок второй попытки, не доказательство переключения.

Полный сценарий НЕ завершён: первая попытка не получила PATCH переключения; вторая, mm-acceptance-wg-ui-1791472879650, после создания интерфейсов остановилась на Добавить пира. Playwright зафиксировал unstable→detached DOM menuitem при перерисовке. Callback props пересоздавали columns/inline actions cell, React сбрасывал Base UI menu. Временные browser harness имеют эти ограничения; успешный финальный browser report не создавался и не заявляется.

Локально components/data-grids/wireguard-data-grid.tsx адаптирован по уже принятому GRE образцу: стабильный WireguardActionsCell и типизированный context передают свежие onExport/onAddPeer/onToggle/onDelete/toggleBusy. Данные строки остаются текущими; composition, styles, row key и installed ReUI APIs сохранены. Tests/e2e/wireguard-menu-refresh.spec.ts воспроизвёл исчезнувшее меню на прежнем коде; после исправления меню переживает pending refresh, показывает новое enabled state и вызывает PATCH с актуальным disabled=false. Вместе с wireguard-tables.spec.ts —6/6 passed. ESLint и scoped TypeScript passed. Первый TypeScript запуск совпал с генерацией .next/dev/types и получил временные syntax errors; повтор после остановки Next прошёл. ReUI checklist проверен, общие primitives не менялись.

Первая пара очищена observer, выбранный baseline полностью совпал. Во второй попытке observer получил401 на завершающем native чтении до cleanup; причина не установлена, пароли не менялись. Повторное чтение через приложение успешно. Штатный API cleanup проверил точные name/ownership comment и удалил оба own интерфейса DELETE200/200. Независимая native проверка подтвердила отсутствие own WG/peers/IP/routes на обоих CHR, total IPv4 addresses1/2 и routes4/5; WG interfaces/peers0. Второй baseline был только в памяти и потерян при выходе observer: точное равенство его baseline не заявляется. DB controls servers2/speedHistory9/retention14/migrations9 совпали. Эфемерные контейнеры завершены, остались три основные службы, backend healthy. Audit revisions намеренно сохранены.

Runtime backend/frontend3722fad, локальное меню ещё не развёрнуто. Следующий12.5.62 — frontend Docker deploy и полный UI create interface/peer→disable/enable→повторный handshake/Ping→delete на новой реальной паре, без повторных открытий меню. Перед повтором observer должен сохранить приватный baseline на сервере и продолжать независимую cleanup каждого устройства при ошибке финального state read; запуск browser только после подтверждения готовности нового observer. Переключение, экспорт/import, throughput/RBAC и прочие внешние ограничения остаются открытыми. Пользовательское правило настоящих VPN объектов сохраняется. Локальный коммит без push.

12.5.62 — развёртывание стабильного меню и полный WireGuard UI lifecycle (2026-10-08)

Развёртывание: frontend6a46fb1e40291024202455460dfc233f05e9e5d5/version1.0.0-test.6a46fb1, backend3722fad не перезапускался и healthy. Git archive SHA2560c25ec8215b25446d2a9ad1555244af94afff32194d2a0768ee727b1ca810db8 совпал после передачи. Main-совместимый staging обновлён единственным изменённым production input — WireGuard data grid; package-lock и Dockerfile совпали. Docker build exit0, Next full TypeScript passed. Изменена только MMAPP_IMAGE_TAG, compose validation прошла, предыдущий frontend3722fad образ сохранён. Push не выполнялся.

Production UI: новый fixture mm-acceptance-wg-ui-1791473944233, оба CHR, ПК/320px, HTTP mocks отсутствуют. Интерфейсы/IP созданы формами UI: POST201/201; peer формы дали201/201. Native проверка подтвердила поля, автоматическую генерацию ключей и соответствие публичного ключа другого конца (ключи только в памяти). Отключение/включение каждого устройства через меню дало PATCH200×4; disabled совпал с RouterOS, peer и IP сохранились. UI DELETE200/200 полностью удалили interfaces/peers/IP; native отсутствие остатков проверено до finish/fallback. Каждое меню открывалось один раз, menuReopens0. JS/API errors0. Это завершает незаконченный сценарий61 на исправленном production frontend.

Native observer: два раунда handshake/Ping — до и после переключения, каждый3/3 на обоих CHR,0%loss,≈55ms. Существующая конфигурация/коллизии UDP51879 и198.18.255.240/30 проверены до UI создания. Observer сохранил приватный baseline на сервере с0600, повторное чтение401 ограничено тремя попытками и отражается в readRetries; ошибка финального state read теперь перехватывается перед независимой cleanup каждого устройства. В этом проходе retries0/final state errors0; failure ветки не инжектировались. Browser запускался только после READY и сверял name fixture с зафиксированным новым observer.

Итоговый observer exit0, afterBrowser пуст на обеих сторонах; selected WG/peers/IP/routes/IPv4 Firewall baseline совпал. Fallback удаления не понадобился; эфемерный контейнер удалён, остались три основные Compose-службы. DB controls до/после servers2/speedHistory9/retention14/migrations9 совпали, audit revisions намеренно сохранены. Приватный baseline с возможными ключами чужой конфигурации не скачивался и не коммитился. Smoke: dashboard/servers/uptime/settings/filters/alerts200,320px fit, JS/API errors0.

Мобильная форма создания просмотрена, без ключей. Выявлена отдельная UX-недоработка: WireGuard create/peer/import используют обычный w-full, который не переопределяет data-side width общего Sheet; мобильная панель фактически240px при320px, footer сжат. Следующий12.5.63 — точные responsive width overrides по существующему GRE образцу, проверка полной ширины/кнопок в обеих темах и профильные UI проверки. Export/import, throughput, IPv6, внешние failures/RBAC/multi-instance, Telegram/Portal и остальные интеграционные ограничения остаются открытыми. Пользовательское правило настоящих VPN объектов сохраняется. Локальный коммит без push.

12.5.63 — полная ширина мобильных WireGuard Sheets (2026-10-08)

В components/wireguard/wg-create-sheet.tsx, wg-peer-sheet.tsx и wg-import-sheet.tsx заменены только width utilities на data-[side=right]:w-full и data-[side=right]:sm:max-w-md/lg. Это существующий GRE образец: одинаковые data-side modifiers корректно переопределяют default ширину установленного Sheet. Создание/пир наsm имеют448px, импорт512px; доsm панели занимают полную ширину экрана. Содержимое форм, API, footer composition и общие primitives не менялись.

Светлая тема, тёмная тема: временный локальный Playwright visual harness, три панели ×320/640/1280px × две темы —18 комбинаций passed. Actual bounding width равна320/448/512px; все footer buttons находятся внутри панели, scrollWidth не превышает clientWidth, page overflow отсутствует. Tab идёт по ожидаемым полям, Escape закрывает панель. HTTP API подменён, реальные RouterOS операции в этой проверке не выполнялись.

Мобильные скриншоты: создание dark, создание light, пир dark, пир light, импорт light, импорт dark. Create dark/peer dark/import light визуально просмотрены: текст действий читается полностью, IP/endpoint имеют достаточную ширину; ключи в снимках не заполнялись.

Profile wireguard-links.spec.ts --grep импорт/создание сохраняет форму —5/5 passed: interface,interface DTO,peer, импорт без подтверждённого результата и pending/retry. Сохранение ввода, API ошибки/неподтверждённые ответы и ожидание результата сохранились. Scoped TypeScript выполнен после остановки Next, ESLint трёх изменённых компонентов и ReUI checklist passed. Полная регрессия не повторялась для трёх responsive class overrides.

Изменение локальное: удалённый runtime backend3722fad/frontend6a46fb1 healthy остаётся прежним. Следующий12.5.64 — frontend production Docker deploy и live мобильные create/peer/import панели на новой собственной WG паре; real UI lifecycle/связность и очистка, baseline. Просмотр импортной формы не будет заявляться как проверенный настоящий import. Import/export, throughput/IPv6/внешние failures/RBAC/multi-instance/Telegram/Portal и другие внешние ограничения открыты. Правило пользователя создавать настоящие VPN объекты сохраняется. Локальный коммит без push.

12.5.64 — развёртывание и live приёмка мобильных WireGuard панелей (2026-10-08)

Развёртывание: frontendbf43263e43ae375651237e019fe1aae55e848308/version1.0.0-test.bf43263, backend3722fad healthy и не перезапускался. Чистый Git archive SHA256c42edf2983262b62bcc427f7e2922f1c6bf56754abe3b583be73fd71712bd074 совпал после передачи. Main-совместимый staging обновлён только тремя изменёнными WireGuard Sheets; lockfile/Dockerfile совпали. Docker build exit0, full Next TypeScript passed. Изменена только MMAPP_IMAGE_TAG, compose validation прошла, предыдущий frontend6a46fb1 образ оставлен для rollback. Push не выполнялся.

Production UI и формы: собственная новая пара mm-acceptance-wg-ui-1791475047653, оба CHR × две темы × три панели(create/peer/import) ×1280/320px —24 live сочетания без HTTP mocks. Ширина320px на телефоне, create/peer448px и import512px наПК, footer buttons внутри панели и без обрезания, page overflow отсутствует, Escape закрывает каждую форму. Формы просматривались на реально созданной собственной WG паре; в визуальных снимках ключи не вводились. Импортная форма только открывалась и закрывалась: применение/preview импорта не проверены.

Основной UI lifecycle выполнен отдельно от просмотров форм: создание interfaces201/201 и peers201/201 через реальные формы, native поля/key generation/peer association подтверждены; disable/enable каждого CHR PATCH200×4 сохранили peers/IP; Ping3/3 на обоих устройствах до и после переключения. DELETE200/200 удалили interfaces/peers/IP до finish/fallback. MenuReopens0, JS/API errors0. Native observer: приватный baseline0600 на сервере, два Ping раунда passed, retries0, final state без own объектов, выбранный WG/peers/IP/routes/IPv4 Firewall baseline совпал. Эфемерный контейнер удалён; остались три основные службы. Audit revisions намеренно сохранены, DB controls до/после servers2/speedHistory9/retention14/migrations9 совпали.

СкриншотыCHR2/320px: create dark, create light, peer dark, peer light, import dark, import light. Create dark/import light визуально просмотрены: панель и footer занимают доступную ширину, текст действий виден целиком. Smoke: dashboard/servers/uptime/settings/filters/alerts200,320px fit, JS/API errors0.

Следующий12.5.65 — настоящий экспорт WireGuard без private keys на новой собственной паре: RSC/CONF, выбранный interface/peer и независимое сравнение параметров; ключи/конфиги с секретами в публичные отчёты не включать. Настоящий import roundtrip — отдельный блок. Throughput, IPv6, внешние failures/RBAC/multi-instance, Telegram/Portal и другие протоколы/интеграции остаются открытыми. Пользовательское правило настоящих VPN объектов сохраняется. Локальный коммит без push.

12.5.65 — экспорт WireGuard без приватных ключей и ошибка client endpoint (2026-10-08)

Реальный API export/native: новая собственная пара mm-acceptance-wg-1791475605238 на двух CHR, свободные UDP51879/198.18.255.240/30. До export подтверждены API creation/native peer key association/handshake/Ping. Для каждого устройства POST /api/wireguard/export запрошены rsc/conf/peer-conf с includePrivateKey:false и явным собственным peerId —6 ответов200. Содержимое разобрано и сверено в памяти, реальные native private keys и активные private-key/PrivateKey assignments не обнаружены. Конфиги, публичные/приватные ключи и содержимое export в отчёты/файлы не записывались.

RSC/CONF совпали с native address/listenPort/MTU и выбранным peer(public-key association,allowed address,endpoint,keepalive). Это конфигурационные снимки без приватного ключа, не заявленные готовые импортируемые туннели. Peer-conf подтвердил выбранный interface public key и peer selection, однако клиентская конфигурация не принята: endpoint равен адресу удалённого пира, а не экспортирующего устройства, client Address отсутствует без client metadata. В fixture A→B клиентский шаблон дляB использует keyA, но endpointB — разные стороны соединения. В официальной документации client-endpoint обозначает адрес/порт WireGuard устройства, к которому подключается клиент; клиентские metadata нужно отличать от серверного peer endpoint/allowed-address.

Кодовая причина подтверждена чтением backend WireGuard export route и frontend wg-export-sheet.tsx: fallback peer.clientEndpoint || peer.endpoint. API и локальный preview требуют согласованного исправления; отсутствие client Address/явных client маршрутов нельзя скрывать готовым конфигом. Следующий12.5.66 — корректный client endpoint/defaults, явные поля/состояние шаблона, сохранение client metadata overrides, профильная регрессия. Точное правило client routes/address определить из имеющихся metadata; не выводить клиентские маршруты автоматически из server allowed-address.

UI live export не запускался: его текущий handler запрашивает includePrivateKey:true дляRSC/CONF. Этот блок доказывает API false redaction и выбранные параметры, не безопасность всех UI/export режимов. Native/API snapshot GET, plaintext memory сравнения и отсутствие чувствительных полей в публичном JSON проверены. Product source не менялся, общая регрессия не запускалась для внешней read-only проверки.

Финальный fixture cleanup exit0, selected WG/peers/IP/routes/IPv4 Firewall baseline совпал. Own peers/IP явно удалялись harness перед интерфейсом; полное обычное UI удаление уже отдельно подтверждено в60/62/64. Эфемерный контейнер удалён, остались три основные службы, backend healthy. DB controls до/после servers2/speedHistory9/retention14/migrations9 совпали, audit revisions намеренно сохранены. Runtime backend3722fad/frontendbf43263 не менялся. Настоящий import roundtrip, export private-key modes/UI download, throughput/IPv6/RBAC/внешние failures/multi-instance/Telegram/Portal и остальные протоколы/интеграции остаются открытыми. Пользовательское правило настоящих VPN объектов сохраняется. Локальный коммит без push.

12.5.66 — правильный client endpoint и явный шаблон Peer .conf (2026-10-08)

Ошибка65 исправлена локально в backend и preview. Общий resolveWgClientEndpoint в packages/contracts/src/wireguard.ts приоритетно использует явный client-endpoint, добавляет listenPort для hostname/IPv4 без порта и brackets для IPv6; иначе берёт host/listenPort экспортирующего устройства. Неизвестный host/неподходящий формат оставляют Endpoint placeholder. Backend export route больше не использует peer.endpoint; frontend WgExportSheet получает host выбранного устройства из текущего каталога серверов и использует тот же resolver.

Server allowed-address не обозначает клиентские маршруты: API/preview больше не передают его в Peer .conf. Оба codec generatePeerClientConf сохраняют явно переданные client параметры, но без client Address/AllowedIPs/Endpoint выводят комментарии-подсказки вместо активных выдуманных значений; default0.0.0.0/0 не создаётся. PrivateKey клиента остаётся placeholder. Существующие client-address/client-dns/client-endpoint overrides сохраняются. UI сообщает, что Peer .conf — шаблон: заполнить собственный ключ/адрес/сети и проверить endpoint заNAT. Политика поддерживаемых client routes не расширена новыми RouterOS полями; ready client config без этих данных не обещается.

Схема после исправления: экспорт интерфейсаA для клиентаB → PublicKey интерфейсаA + Endpoint устройстваA:listenPort; Address клиентаB и его AllowedIPs задаются явно. Backend/frontend изменения согласованы через общий contracts helper, Zod wire format и HTTP response shape не менялись. Общие ReUI primitives не менялись; beforeCode — существующий slot CodeExportSheet.

Проверки lib/wg-client-template.test.ts —5/5: endpoint exporting server/явный override/hostname/IPv6/неизвестные значения, одинаковые backend/frontend placeholders, отсутствие активного Address/AllowedIPs и default route без явных данных, сохранение явно заданных client параметров. Existing backend wireguard-config.test.ts passed; contracts build, backend TypeScript, scoped frontend TypeScript и ESLint всех изменённых файлов passed. Profile wireguard-links.spec.ts --grep экспорт —4/4: late response isolation/error, неправильный формат, выбор второго peer/ROS ID, его client-address/client-endpoint и отсутствие remote endpoint/server allowed-address в preview. Первый запуск старого теста ожидал ошибочно скопированные peer.allowedIps; fixture и assertions заменены на отличающиеся client metadata, защита выбора второго пира сохранена. ReUI checklist checked.

Исправление локальное: runtime backend3722fad/frontendbf43263 не менялся. Следующий12.5.67 — production Docker build/deploy backend и frontend с обновлённым contracts source, новая собственная WG пара, native/API export false redaction и правильный endpoint/шаблон, browser preview соответствие, cleanup/baseline. Поддержка client-allowed-address, настоящий client import/connectivity, import roundtrip/private-key modes, throughput/IPv6/RBAC/внешние failures/multi-instance/Telegram/Portal и другие протоколы/интеграции остаются открытыми. Пользовательское правило настоящих VPN объектов сохраняется. Локальный коммит без push.

12.5.67 — Docker deploy и реальный экспорт клиентского шаблона WireGuard (2026-10-09)

Обе production Docker сборки c16fc0c завершились успешно. Межслойный unit test перенесён из lib в tests/unit/wg-client-template.test.ts отдельным локальным коммитом c16fc0c: frontend Docker context не содержит backend source. Предварительный frontend staging c82e8fa не включал этот новый тест и не используется как доказательство чистой сборки исходного c82e8fa. Окончательные staging lib/backend src/contracts совпали с архивом c16fc0c; финальные образы обеих частей имеют OCI revision c16fc0c5b5. Network-none assertion backend образа проверил общий resolver и отсутствие активных клиентских Address/AllowedIPs без явных данных.

Перед обновлением сохранён приватный PG dump pre-c16fc0c.dump,2314923bytes,mode0600; pg_restore --list passed. Backend/frontend обновлены до1.0.0-test.c16fc0c, backend healthy, frontend /wireguard HTTP200. Образы: backend sha256:fb9f9279df07481d960f5799338e15a0fc9162a8baca3be7789a89f28a5f56dc, frontend sha256:bc70ee3203b4fd3f269ab6554493f0fb1ec2e60ef515ced2dcd6c6c7428064bc. Резервная .env хранится только на сервере. SSH161.104.46.222 и RouterOS REST194.226.121.150/104.165.244.7 доступны с прежними учётными данными; пароли не изменялись.

Создана собственная временная WG пара с адресами198.18.255.241/30 и198.18.255.242/30,port51879,MTU1420,уникальными name/comment. Native key generation/peer association проверены в памяти, handshake и Ping3/3 в обе стороны passed. Шесть настоящих API export запросов (rsc/conf/peer-conf на обоих устройствах) вернули200 с includePrivateKey=false. RSC/CONF параметры совпали с native; ключи и конфигурации не сохранялись. Peer .conf содержит PublicKey экспортирующего интерфейса и Endpoint экспортирующего устройства:51879; client Address/AllowedIPs остаются comment placeholders, активного default route нет. Это шаблон, готовность к импорту клиента не заявлена.

Native/API evidence, browser evidence, deploy/DB controls. Четыре настоящих browser сценария без HTTP mocks: оба CHR ×1280/320px. Local preview и live Peer export совпали по server endpoint/client placeholders; POST включает выбранный ROS peer ID и includePrivateKey=false. Нет page errors/API errors/page overflow. Export содержимое и ключи не попали в отчёты/скриншоты; UI download не выполнялся.

Fixture завершён exit0 и удалён. Проверенные WG interfaces/peers/IP/routes/IPv4 filter/nat/mangle совпали с baseline на обоих CHR. Очистка только собственных объектов; audit revisions намеренно сохранены. DB controls до/после совпали:servers2,speedHistory9,retentionDays14,migrations9. Дополнительно сохранён ранее полученный screenshot создания на CHR2 в12.5.64 с исходной датой2026-10-08. Product code в этом блоке не менялся после уже проверенного c16fc0c; общая регрессия не повторялась.

Следующий12.5.68 — import roundtrip собственного конфигурационного файла с независимой проверкой параметров и очисткой. Client-allowed-address/готовый client import, private-key export modes/UI download,throughput/IPv6/RBAC/внешние failures/multi-instance/Telegram/Portal и остальные протоколы/интеграции остаются открытыми. Локальный коммит без push.

12.5.68 — реальный .rsc roundtrip WireGuard через UI (2026-10-09)

Runtime backend/frontend c16fc0c не менялся. На обоих CHR создана собственная временная WG пара с уникальными name/comment,port51879,MTU1420 и198.18.255.241/30↔198.18.255.242/30. Исходный handshake/Ping3/3 подтверждены. POST export rsc с includePrivateKey=true получен только в памяти; исходные native keys и содержимое конфигураций не записывались в файлы, screenshots, traces или Git. Это собственные ключи тестовой пары, доступы серверов не менялись.

На обоих устройствах POST import dryRun=true вернул200; native интерфейс/пир/IP остались прежними. Затем обычный API DELETE удалил собственный исходный интерфейс и связанные объекты без остатков. Реальный UI импорт восстановил RSC на CHR1 при1280px и CHR2 при320px без HTTP mocks: server context изURL сохранился, локальный preview распознал собственное имя и одного пира, POST import dryRun=false вернул200 с applied.interfaceName и peersCreated=1, Sheet закрылся после подтверждения, интерфейс появился в таблице. Page errors/API errors/горизонтального page overflow нет.

Native проверка после UI восстановила name/comment,listen-port,MTU,один IPv4 address,одного peer,allowed-address,configured endpoint/port,keepalive и peer comment. Публичные ключи интерфейсов/пиров совпали с исходными. На CHR2 текстовая private-key запись после импорта отличается; нормализованные32байтные Curve25519 scalar совпали, а public identity сохранилась. Приёмка сравнивает эквивалентность scalar и public key, не обещает byte-for-byte неизменность raw encoding. Правило clamping проверено по официальному исходнику WireGuard: изменения затрагивают предусмотренные биты. После восстановления настоящий handshake и Ping3/3 в обе стороны passed.

Final native report, browser report, предыдущая диагностика raw-key, DB controls. Первый browser запуск не завершил import; следующая native проверка отклонила raw private-key equality наCHR2. Каждая попытка очищена с совпавшим baseline; диагностическая проверка не объявлена успешной. В окончательном запуске поэлементные native checks passed на обоих устройствах и fixture exit0. Readiness ожидание наблюдателя добавлено в тестовый harness, данные конфигов не выводились при ошибках.

Own interfaces/peers/IP/connected routes удалены; WG/peers/IP/routes/IPv4 filter/nat/mangle совпали с исходным baseline на обоих CHR. Остались три основные службы, backend healthy. Business DB controls совпадают с контрольной точкой67:servers2,speedHistory9,retentionDays14,migrations9; audit revisions намеренно сохранены. Публичные JSON проверены на отсутствие ключей/конфигураций/паролей. Общие ReUI компоненты и product source не менялись; общая регрессия не повторялась для внешней приёмки.

Граница результата: правильный RSC собственного туннеля, preview и успешное применение с независимой связностью. Импорт .conf не принят: exporter не сохраняет имя/комментарии, parser использует wg0 по умолчанию; incomplete Peer .conf template требует отдельной проверки до применения. Partial failure/rollback, повторный import/коллизии, private-key UI download,IPv6/throughput/RBAC/внешние failures/multi-instance/Telegram/Portal и остальные протоколы/интеграции остаются открытыми. Следующий12.5.69 — preflight/ошибки .conf и затем безопасный собственный roundtrip. Локальный коммит без push.

12.5.69 — preflight импорта WireGuard без выдуманных маршрутов (2026-10-09)

Обнаружено локально: parse/apply могли принять клиентский шаблон без PrivateKey и подставить0.0.0.0/0 вместо отсутствующих allowed-address. Добавлен backend/src/services/wireguard-import.ts; route использует его до dry-run, поиска сервера и любых RouterOS mutations. .conf должен содержать ровно одну Interface секцию и PrivateKey; каждый объявленный Peer должен иметь PublicKey и явные корректные AllowedIPs. Проверяются32байтные base64 ключи, IPv4/IPv6 CIDR, порты, положительный MTU и неотрицательный keepalive. Неподдерживаемые несколько Address и PresharedKey отклоняются явно вместо потери данных. Ошибки ключей не выводят их значения.

Backend/frontend RSC parsers больше не подставляют default route и требуют interface command; applyParsedConfig использует только проверенные явные сети. Явно заданный0.0.0.0/0 остаётся допустимым. Числа сохраняются для проверки вместо parseInt/undefined defaults, включая0 иNaN. Перед обычным apply route читает список интерфейсов и возвращает409 при занятом имени; это предварительная проверка, не блокировка конкурентных запросов. Dry-run проверяет формат, но не обещает доступность сервера или отсутствие конфликтов на момент применения.

В существующем WgImportSheet добавлено короткое пояснение: .conf безName использует wg0; ключ/сети надо заполнить, совпадение имени остановит import. Структура Sheet/base-nova, формы, aria labels/status/alert и управление busy не менялись. Локальный preview остаётся разбором формата; обязательная preflight проверка выполняется backend. Новых API полей/зависимостей нет. Полный протокол .conf или поддержку PSK этот блок не добавляет.

Проверки: wireguard-import unit22/22 (готовый conf и explicit default route, template, Interface/Peer/key errors, CIDR, отсутствие маршрутов, несколькоAddress/PSK, числовые ошибки и RSC); настоящий Fastify inject4 invalid apply/dryRun случая →400, PUT mutations0. Backend test:wireguard теперь включает новые service/route tests; исходный codec passed. Client-template cross-layer5/5 passed. Browser3/3: доступ/неподтверждённый receipt, ожидание/повтор,400 incomplete conf с сохранением текста и выбранного сервера2. Последний test не попал в первый grep импорт; отдельно запущен и прошёл. Backend/scoped frontend TypeScript, ESLint и diff check passed. ReUI checklist checked; installed primitives не менялись.

Исправление локальное, стенд по-прежнему c16fc0c. Реальные preflight400/409, отсутствие native изменений при отказе, production build и новый .conf roundtrip ещё не приняты. Проверка коллизии409 добавлена в code, отдельно не доказана RouterOS fixture в этом блоке. Следующий12.5.70 — собрать/развернуть, проверить отказы и собственную пару на обоих CHR, native параметры/идентичность/связность, затем cleanup/baseline. Конкуренция, повторный import/partial failure/rollback, неизвестные/повторные поля .conf и остальные внешние ограничения остаются открытыми. Пароли и RouterOS настройки в этом блоке не менялись. Локальный коммит без push.

12.5.70 — deploy preflight и собственный .conf roundtrip WireGuard (2026-10-09)

Production Docker backend/frontend479f2ad успешно собраны и развёрнуты. Зафиксированный source commit479f2adc78b162d7694d9897d201704b51082968 передан Git archive, SHA25661e1dfeb413d80ee3b463f14abf539739203f31b886a1e248fce869fa4e9aba1. Backend src и frontend lib/components/app/contracts в staging совпали с source. OCI revision labels479f2ad,version1.0.0-test.479f2ad; backend image inspect IDsha256:48f85bf9863fcec8f3a1df39e2e9e06835b7a7aaf1c59a5e73f00e0181ab3eff7,frontend sha256:346c0df48cc49314045f54e3e6e6efe826524e279bb3652a515c2d37c7295678. Новый backend-образ без сети отклонил неполный conf/peers-only RSC; backend healthy, frontend HTTP200.

Перед обновлением сохранён private PG dump pre-479f2ad.dump,2343134bytes,mode0600; pg_restore --list passed. Предыдущая .env сохранена только на сервере, прежние c16fc0c images доступны для отката. SSH161.104.46.222 и RouterOS REST обоих CHR доступны с прежними доступами. Пароли устройств не менялись.

На каждом CHR настоящий API отклонил неполный conf шаблон с400 для dryRun=false иtrue: всего4 запроса, выбранные WG/peers/IP/routes/IPv4 Firewall ресурсы native не изменились. Затем создана собственная WG пара с уникальным name/comment,51879/1420 и198.18.255.241/30↔198.18.255.242/30; native handshake/Ping3/3 подтверждены. Private .conf exports получены только в памяти; в каждый добавлен явный Name для приложения. Валидный dry-run200 не изменил интерфейс/пир/IP, попытка применить конфиг поверх занятого собственного имени вернула409 на обоих CHR без native изменений. Остальные отрицательные варианты69 проверены локально, не объявлены всеми выполненными на RouterOS в70.

Обычный DELETE удалил исходную пару с peers/IP. UI восстановил conf наCHR1 при1280px иCHR2 при320px без HTTP mocks. Перед успешным import каждому серверу отправлен неполный шаблон → ожидаемый400; Sheet остался открыт, textarea и server selection сохранены, на выбранном устройстве не появились native объекты. Затем local preview показал CONF/явное имя/одного пира, apply200 подтвердил applied.interfaceName/peersCreated=1, Sheet закрылся и объект появился в таблице. В этих browser сценариях2 ожидаемых400 и0 неожиданных API/page errors, page overflow нет.

Native checks подтверждают name,ключевую идентичность,listen-port,MTU,адрес,peer public identity,allowed-address,configured endpoint/port/keepalive. Как в68, raw private encoding наCHR2 нормализован при импорте: Curve25519 scalar equivalent и public key unchanged; raw byte equality не требуется. Настоящий handshake иPing3/3 восстановленной пары прошли в обе стороны. Conf не сохраняет interface/peer comments и peer names; Name здесь расширение parser приложения, не стандартная директива wg-quick. Поэтому результат — network/key roundtrip с явно заданным именем, не побайтовое восстановление исходной RouterOS конфигурации. Для metadata-preserving восстановления ранее принят RSC68. Ключи и конфиги не сохранялись в отчёты/файлы/screenshots/traces.

Native/API, browser, smoke6 страниц, deploy/DB controls. Первый browser run остановлен ошибочной проверкой harness: после importCHR1 она ожидала отсутствие объектов на обоих CHR перед отказомCHR2. Ошибка исправлена на проверку выбранного устройства; product source не менялся. Прерванная попытка не объявлена принятой; её cleanup/baseline также passed. Финальный fixture exit0.

Все собственные объекты удалены; выбранные WG/peers/IP/routes/IPv4 filter/nat/mangle совпали с baseline на обоих CHR. Для imported conf без comment ownership подтверждалась уникальным fixture name и ожидаемой native public identity, используемой только в памяти. Остались3 основные службы, backend healthy. DB controls до/после:servers2,speedHistory9,retentionDays14,migrations9. Audit revisions намеренно сохранены. Production smoke /dashboard,/servers,/uptime?tab=speed,/settings,/filters,/wireguard →HTTP200,320px fits,0 page/API errors. Публичные JSON проверены на отсутствие ключей/конфигов/паролей. Дополнительная общая локальная регрессия не повторялась после уже проверенного69; production build/typecheck и реальные scoped сценарии выполнены.

Следующий12.5.71 — partial apply failures/компенсация и повторный import. Concurrent collision races, rollback/interrupted mutation, неизвестные/повторные поляconf,PSK/multi-address поддержка, ready Peer client template import,private-key UI download,IPv6/throughput/RBAC/multi-instance/Telegram/Portal и остальные внешние протоколы/интеграции остаются открытыми. Локальный коммит без push.

12.5.71 — подтверждённая очистка частичного импорта WireGuard (2026-10-09)

Локально обнаружено по code: прежний последовательный apply оставлял интерфейс/IP, если поздний peer PUT отклонялся. Добавлен backend/src/services/wireguard-import-apply.ts; route использует сервис вместо встроенного applyParsedConfig. До mutations читаются interface/IP/peer baseline; занятое имя возвращает409. Каждый успешный create должен дать один строковый ROS .id, отсутствовавший в baseline; identity записывается в памяти. Native GET после всех PUT подтверждает созданные ID и name/interface/public-key/address association перед success receipt. Полное сравнение всех настроек/связности остаётся внешней проверкой, не подменяется этим identity check.

При подтверждённом RouterOS rejection (явные400/401/403/404/405/409/422) сервис читает текущее состояние, проверяет принадлежность всех receipt-owned объектов и отсутствие чужих связанных объектов. Только затем удаляет собственные peers →IP →interface в обратном порядке и перечитывает ресурсы. Подтверждённое отсутствие объектов →502,state rolled-back с понятным сообщением и возможностью исправить/повторить. Удаление существующих baseline IDs, чужих child rows и cleanup только по имени запрещены. Это компенсация текущего запроса, не RouterOS транзакция.

Потеря ответа после commit,HTTP408/500,неполный create receipt или несовпадение native identity →needs-review; автоматическое удаление не выполняется при неподтверждённом create outcome. Ошибка cleanup/read/изменённая identity/чужой concurrent child →needs-review, успешный rollback не обещается. Если DELETE оборвался после части удалений, состояние надо проверить вручную. Ответы не пересказывают native body с потенциальными ключами. Между ownership GET и DELETE нет распределённой блокировки; конкурентные изменения и потеря процесса требуют отдельной приёмки.

Route отдельно обрабатывает audit revision failure после успешного apply:502,state applied и сообщение, что конфигурация уже применена, но ревизия не сохранена; сеть не объявляется неприменённой и автоматический rollback уже подтверждённых изменений не запускается. Этот backend audit branch реализован, но отказ реальной БД после apply в71 не воспроизведён. Success HTTP shape прежний; error state добавлен как уточнение, текущий UI показывает message и сохраняет форму.

Проверки apply unit16/16: native receipt успех, baseline read failure0writes, несовпавшая native identity, повтор после успеха409 без mutations, отказ второго peer/адреса с восстановлением baseline, успешный повтор после rollback, lost reply после iface/IP/peer commit,HTTP408/500,missing/foreign receipt,concurrent чужой peer,изменённая identity,отказ/неподтверждённый DELETE. Исходные preflight22/22 и codec/HTTP4 invalid cases passed; новые apply tests включены в backend test:wireguard. Browser6/6: прежние import сценарии и три новых502 состояния rolled-back/needs-review/applied сохраняют текст/server/error; автоматического повторного POST нет; ручной retry после rolled-back принят успешным receipt. HTTP ответы browser подменены, это не real RouterOS cleanup. Backend и scoped frontend TypeScript, ESLint и diff check passed. UI primitives/ReUI composition не менялись.

Исправление локальное: runtime backend/frontend479f2ad из70 не обновлялся; production frontend source не менялся. Следующий12.5.72 — production build/deploy только backend, реальная проверка ROS PUT receipts, поздний native rejection на собственных объектах,cleanup/baseline и исправленный повтор с связностью. Прерванный HTTP/процесс,подлинный audit DB failure,конкуренция/multi-instance,IPv6/throughput/RBAC,PSK/multi-address/unknown-conf поля,интеграции и остальные внешние протоколы остаются открытыми. Пароли/RouterOS конфигурация в этом локальном блоке не менялись. Локальный коммит без push.

12.5.72 — реальная компенсация позднего отказа импорта WireGuard (2026-10-09)

Backend e01454b720 production build/deploy passed; frontend479f2ad оставлен, его container ID до/после совпал. Git archive SHA2566cffbd73c05cf28fded3c80d9c8965a3c22f8f698e33f499fb87f5d21fc2effc; backend src staging совпал с source. Новый image inspect IDsha256:b6d5d7f68a8529ead68d8a676a0def5edfdd6aa9ad485be4b0158c0241ecae46,OCI revision полныйe01454b,version1.0.0-test.e01454b. Module import/state assertion без сети passed, backend healthy,/health HTTP200. Private backup pre-e01454b.dump2364848bytes,0600,pg_restore --list passed; предыдущая.env и образы сохранены только на сервере для отката. SSH161.104.46.222 и RouterOS REST обоих CHR доступны с прежними доступами.

Создана собственная WG пара с уникальным name/comment,51879/1420 и198.18.255.241/30↔198.18.255.242/30; исходные native keys/association/handshake/Ping3/3 подтверждены. Private conf exports с явным Name использованы только в памяти, исходная пара обычным DELETE удалена. Для позднего отказа к каждому conf добавлен повтор того же Peer. Это настоящий native rejection, не fake HTTP response или transport injection.

Supplemental native service run на каждом CHR использовал новый applyWireguardImport и настоящий MikrotikClient. Adapter только записывал method/path/наличие receipt .id/завершение DELETE и делегировал реальные операции; GET retries наследуют harness, mutations не повторяются. Native trace: iface PUT receipt →IP PUT receipt →первый peer PUT receipt →второй peer HTTP400 →DELETE peer/IP/iface. State rolled-back и полный выбранный baseline restored на обоих CHR. Успешные native HTTP-коды не выдумывались: client возвращает body/void, отчёт отмечает completed и receiptIdPresent; status400 получен из реального MikrotikError. Наличие receipt/native identities на этой RouterOS версии подтверждено.

Отдельно реальный production UI/API наCHR1 при1280px иCHR2 при320px: неполный template400 сохраняет форму/server selection, duplicate-peer conf502,state rolled-back сохраняет введённый конфиг и показывает подтверждённую очистку; native observer не нашёл iface/peer/IP на выбранном устройстве. После исправления textarea повтор200 подтвердил applied name/peersCreated=1, Sheet закрылся, интерфейс появился в таблице. Применённая пара прошла native parameter/public identity/private scalar checks, handshake иPing3/3 в обе стороны. Expected UI errors:2×400 и2×502; unexpected API/page errors0,page overflow0. Comments/peer names не переносятся conf, явный Name — расширение parser приложения; byte-for-byte metadata restore не обещается.

Native service/API evidence, production browser failure/retry, deploy/DB controls, smoke6 страниц. Финальный fixture exit0, собственные WG/peers/IP/connected routes удалены; выбранные WG/peers/IP/routes/IPv4 filter/nat/mangle совпали с baseline на обоих CHR. Остались3 основные службы, backend healthy. DB controls до/после servers2,speedHistory9,retentionDays14,migrations9; audit revisions намеренно сохранены. Smoke /dashboard,/servers,/uptime?tab=speed,/settings,/filters,/wireguard →200,320px fits,0 page/API errors. Ключи/конфигурации не включались в отчёты/скриншоты/traces/файлы; public JSON проверены. Product source после71 не менялся, общая локальная регрессия не повторялась; выполнены production build и реальные scoped сценарии.

Граница результата: подтверждённый native validation failure после трёх создающих операций, компенсация и ручной успешный retry в production HTTP/UI. Потерянный ответ/HTTP408/500 после commit,потеря процесса,unconfirmed cleanup,concurrent changes и audit DB failure остаются внешними ограничениями; unit71 их не заменяет. Следующий12.5.73 — изолированный audit failure после настоящего apply и truthful состояние applied с собственной WG парой/cleanup. RBAC/IPv6/throughput/multi-instance/PSK/multi-address/unknown-conf поля и остальные протоколы/интеграции остаются открытыми. Доступы и чужая RouterOS конфигурация не менялись. Локальный коммит без push.

12.5.73 — отсутствие audit receipt не означает полный успех импорта (2026-10-09)

При подготовке внешнего fault scenario найдено: captureAndAppendRevision перехватывает capture/persistence errors и возвращает null, а recordWireguard раньше игнорировал return value. Поэтому catch из71 не срабатывал при обычном сбое сохранения и route мог вернуть200. Внешний тест перенесён до исправления обнаруженной причины; реальный DB fault в73 не заявлен принятым.

recordWireguard теперь возвращает результат helper. Новый confirmWireguardImportRevision проверяет null/undefined и exception; созданная или уже существующая неизменённая ревизия считается подтверждением. Импорт после успешного native apply при отсутствующем receipt возвращает502,state applied: «Конфигурация применена, но сохранение ревизии не подтверждено. Обновите данные перед повтором». Формулировка не утверждает отсутствие строки БД: error может случиться после INSERT при prune/read. Подтверждённые изменения RouterOS не откатываются из-за audit error. Другие consumers recordWireguard продолжают игнорировать nullable receipt, их поведение не расширялось этим блоком.

Новый wireguard-import-revision.test.ts4/4: created/unchanged receipt, null/undefined, exception и настоящий captureAndAppendRevision с падающим capture callback. Последний воспроизводит именно контракт swallowing→null, DB запрос не выполняется; это не реальный отказ PostgreSQL. Новые tests включены в backend test:wireguard:42/42 (22 preflight+16 apply+4 revision), codec и Fastify4 invalid cases passed. Backend TypeScript/ESLint passed. Browser applied1/1 с подменённым502/точным новым message сохраняет textarea/server/error и не повторяет POST автоматически; это UI boundary, не native/DB интеграция. Diff check passed. Production UI/ReUI primitives не менялись.

Исправление локальное, runtime backend e01454b/frontend479f2ad не менялся; RouterOS объекты/пароли и DB schema в73 не менялись. Следующий12.5.74 — production build/deploy backend и изолированный реальный audit persistence failure после настоящего apply на собственных WG объектах: подтвердить applied/native/связность, предупреждение HTTP/UI, отсутствие повторной мутации и cleanup/baseline. Нельзя считать73 доказательством сбоев DB/процесса/transport/concurrency/RBAC/IPv6/интеграций; они и прочие внешние ограничения остаются открытыми. Локальный коммит без push.

12.5.74 — настоящий PostgreSQL audit отказ после успешного WireGuard apply (2026-10-09)

Backend source8eaf78b68631d774bf18ae049d0e11f90fe098d8 production build/deploy passed; frontend479f2ad иего container сохранены. Archive SHA256a685c56eff695beb8d30eaaf49c6ca03d97011e9a306679e2173d7485df7540a; backend src staging совпал с source. Image inspect IDsha256:2f94d4d52f8c2a23806ac7795af3d2346f9dd3114e2fcda4237b3be3c6513f69,OCI revision8eaf78b,version1.0.0-test.8eaf78b. Network-none revision helper: null false,unchanged receipt true. Backend healthy. Private backup pre-8eaf78b.dump2382377bytes,0600,pg_restore --list passed; previous.env/images сохранены на сервере. SSH и RouterOS REST обоих CHR доступны, пароли не менялись.

Подготовлена собственная WG пара с уникальным name/comment,51879/1420 и198.18.255.241/30↔198.18.255.242/30. Seed handshake/Ping/export private conf только в памяти/explicit Name и обычный DELETE выполнены. Изолированный контейнер из нового backend образа поднял настоящий Fastify HTTP endpoint с production wireguardRoutes на8082 (host127.0.0.1:8020). Scheduler/обычный main backend не запускались в worker. Endpoint ограничен POST import и точным content/serverId собственной fixture.

В PostgreSQL создана уникальная temporary NOLOGIN/NOSUPERUSER роль с USAGE schema иSELECT; write privileges не выдавались. Только worker pool запросы выполнялись через SET ROLE на выделенном соединении с обязательным RESET ROLE/release; queries делегировались настоящему pg driver, ответ SQL не подменялся. Production main pool/его права не менялись. Native RouterOS apply выполнился, snapshot успешно дошёл до БД, INSERT config_revisions получил настоящий SQLSTATE42501 на обоих устройствах. Counter реальных denied revision writes2; captureAndAppendRevision вернулnull, новый helper не объявил audit success.

Production frontend наCHR1 при1280px/CHR2 при320px направил POST на реальный изолированный HTTP endpoint через Playwright route.continue URL override; response fulfillment/HTTP fixtures/SQL/RouterOS mocks не использовались. Это отдельный backend process/HTTP port, не fault основного backend. Оба запроса вернули502,state applied; UI показал «Конфигурация применена, но сохранение ревизии не подтверждено», сохранил textarea/server selection, автоматического повторного POST нет. Native observer подтвердил interface/IP/peer после warning. Пара сохранила network parameters/public identity/private scalar и выполнила handshake/Ping3/3 в обе стороны; audit error не откатил рабочую конфигурацию. Keys/configs не сохранялись в отчёты/screenshots/traces/файлы.

Native/PG evidence, реальный HTTP/UI, deploy/DB controls, smoke6 страниц. Fixture exit0. Fault HTTP listener закрыт, pool восстановлен, DROP OWNED/DROP ROLE применены только к подтверждённо созданной NOLOGIN роли без owned business objects; temporaryAuditRoles0. Все собственные WG/peer/IP/connected routes удалены, selected WG/peers/IP/routes/IPv4 filter/nat/mangle baseline совпал на обоих CHR. Остались3 основные службы, backend healthy; frontend не перезапускался. Business DB controls servers2/speedHistory9/retentionDays14/migrations9 до/после совпали; штатные seed/cleanup audit revisions намеренно сохранены. Smoke /dashboard,/servers,/uptime?tab=speed,/settings,/filters,/wireguard200,320px fits,0 page/API errors. Публичные JSON проверены на отсутствие keys/config/password values.

Граница результата — изолированный реальный permission denial при INSERT после настоящего apply и truthful HTTP/UI. Не проверены физический DB disconnect,ошибка после COMMIT/prune/read,потеря процесса/transport/concurrency/multi-instance/RBAC/IPv6/throughput; warning73 остаётся осторожным и не утверждает отсутствие строки БД. Остаточные WireGuard ограничения открыты. Следующий12.5.75 — перейти к VXLAN: сверить route/model/context, создать только собственные реальные интерфейсы на двух CHR, проверить native/API/связность и cleanup с сохранением baseline. Product source после73 не менялся, общая локальная регрессия не повторялась; production build и scoped реальные сценарии выполнены. Локальный коммит без push.

12.5.75 — собственная VXLAN пара и реальный каталог/экспорт (2026-10-09)

Карта возможностей: backend GET /api/vxlan и /api/servers/:id/vxlan читают интерфейсы/статические VTEP; create/delete API отсутствует. UI — каталог, URL server/tunnel context и экспорт interface/VTEP fragment. Реальные fixture create/delete выполнены RouterOS REST напрямую, не объявляются операциями приложения. Схема статических VTEP сверена с документацией MikroTik. Production source/runtime не менялся: backend8eaf78b/frontend479f2ad.

На194.226.121.150 и104.165.244.7 созданы собственные уникальные VXLAN interface/name/comment сVNI160075,UDP51880,MTU1400,local-address своего CHR,remote VTEP второго CHR иIP198.18.255.245/30↔198.18.255.246/30. Перед созданием проверены name/VNI/port/benchmark subnet collisions и selected native baseline. Existing bridge/ports/firewall/default routes не менялись. Native receipt IDs сохранялись только для собственной очистки. Short ICMP3/3 в обе стороны passed. GET /api/vxlan безfailures совпал по server/id/VNI/dstPort/local-address/remoteVTEP/l2mtu/enabled/up; это real API, не mocks. Interface running дополнен настоящим Ping, не используется как единственное доказательство связности.

Native/API/Ping/cleanup, browser4/4. Browser выбрал точный tunnel id/server черезURL, увидел ровно свою строку, открыл экспорт и подтвердилVNI160075/port51880/статический remote VTEP на обоих CHR при1280/320px; page errors/overflow нет. Экспорт — fragment, его reapply не выполнялся; bridge/FDB/IP/MTU recreation не подтверждена. Первый browser run не завершился, native часть иcleanup exit0; повтор с диагностикой passed4/4. Причина первого сбоя не установлена и не объявлена исправленной product bug. Во всех попытках own объекты удалены.

Финальный fixture exit0, own IP→VTEP→interface удалены по receipt IDs с проверкой собственного comment. VXLAN/VTEP/IP/routes/IPv4 filter/nat/mangle/bridge/bridge-port selected projections совпали с baseline на обоих CHR. Динамические ARP/FDB не входили в baseline projection; полнота их очистки этим блоком не заявлена. Backend healthy,3 основные службы, business DB controls2servers/9speedHistory/14retentionDays/9migrations сохранены. Контрольные данные. Ключей/паролей в JSON нет. Доступность обоих CHR подтверждена native операциями; тестовый серверSSH работает. Product changes/build не выполнялись, локальная общая регрессия не повторялась для read-only UI приёмки.

По code прямой /servers/:id/vxlan пока получает server без enabled guard; отключённый сервер здесь может опрашиваться, вопреки ранее принятому правилу пользователя. Следующий12.5.76 — исправить этот endpoint и проверить disabled/no native calls. Реальное отключение устройств в75 не выполнялось. VXLAN create/delete UX,bridge/FDB export/reapply,IPv6/throughput/RBAC/частичные сбои и остальные внешние ограничения открыты. Локальный коммит без push.

12.5.76 — VXLAN: достоверность, экспорт и полная профильная приёмка (2026-10-09)

По поручению пользователя работа укрупнена по разделам. В одном блоке выполнены code/API/UI, профильные проверки, production Docker build обеих частей, deploy, реальная приёмка и очистка; один локальный коммит в конце, без push.

Прямой GET /api/servers/:id/vxlan теперь возвращает409 для выключенного сервера до обращения к RouterOS. Защита есть также в native reader и агрегаторе, для home-router и exit-node. Неполные/некорректные параметры интерфейса, повторные ID/имена и неизвестные/некорректные статические VTEP считаются ошибкой устройства вместо выдуманных VNI/port/L2MTU/флагов. Сохранение последних успешных данных и частичная ошибка остаются прежними. VTEP сопоставляется с именем или RouterOS ID интерфейса.

Реальный MTU передаётся в модель, виден в таблице и экспортируется; для старого снимка без MTU показывается «—», параметр не придумывается, экспорт просит проверить его отдельно. CodeExportSheet прямо описывает fragment: interface/известный MTU/static VTEP, без IP/bridge/FDB. Стабильная actions cell получает callback через контекст, поэтому открытое меню сохраняется при refresh и экспорт использует последние данные. Frame/base-nova и установленные ReUI primitives сохранены; registry migration не выполнялась.

Проверки: backend mapping/HTTP route/export tests, backend и scoped frontend TypeScript, ESLint изменённых файлов и diff check passed. Профильный browser набор23/23 (VXLAN и два связанных layout cases), context-race4/4. В тесте1000 строк отображаются50 строк; измерено2245 DOM nodes, payload227787 bytes и829ms до ready в данном локальном запуске — это наблюдение, не универсальный performance SLA. Общая регрессия проекта не повторялась.

На161.104.46.222 развёрнуты backend/frontend mmapp-test/*:ux-vxlan76, version1.0.0-test.vxlan76. Сборочный source — git archive базового HEAD6b068ac с явными13 working-file overrides, а не отдельный уже закоммиченный revision. SHA256 архива b69f8eb8b5830e85930aca0974cd83a94940e2e162101b8798208720ccf3e1ae; manifest позволяет сверить каждый изменённый файл. Production builds passed; Compose3 services running, backend/PostgreSQL healthy; frontend healthcheck отсутствует, HTTP/browser passed. Backup2441206 bytes/0600, pg_restore --list passed, .env сохранён приватно на сервере, прежние образы доступны для rollback.

Реальная собственная VXLAN пара на194.226.121.150 и104.165.244.7: VNI160075, UDP51880, MTU1400, публичные local/static remote VTEP, IP198.18.255.245/30↔198.18.255.246/30. Native параметры совпали с каталогом приложения; Ping3/3 в обе стороны. Browser4/4 подтвердил URL выбранного устройства/туннеля, экспорт и отсутствие page overflow на1280/320px. Экспорт каждой стороны заново применён через строго ограниченный native REST adapter к собственным интерфейсам: только interface/VTEP команды, IP добавлены отдельно; MTU1400 и Ping3/3 повторно подтверждены. Это проверка параметров fragment, не запуск произвольного .rsc скрипта в терминале.

Две временные выключенные записи home-router/exit-node указывали на отдельный HTTP probe. Прямые GET вернули409, nativeProbeCalls0; временные записи удалены. Native protocol: cleanup сравнил исходные VXLAN/VTEP/IP/routes/IPv4 firewall/bridge/bridge-port на обоих устройствах, все проверки true. DB controls после: servers2/speedHistory9/retention14/migrations9. Пароли не менялись, SSH и оба CHR доступны. Smoke шести страниц: HTTP200, mobile fits, JS errors0/API errors0.

Референс Схема применённого решения
ReUI Data Grid / Filtering2 Контекст устройства → достоверная таблица/MTU → устойчивое меню
Sheet8 Актуальный снимок → границы fragment → код → независимая native проверка
flowchart LR
    A[Устройство] --> B{Включено?}
    B -->|Нет| C[409: без опроса]
    B -->|Да| D{Снимок достоверен?}
    D -->|Нет| E[Ошибка и последние данные]
    D -->|Да| F[Таблица с MTU]
    F --> G[Экспорт interface и VTEP]
    G --> H[Повторное применение и Ping]

Границы: app VXLAN API read-only, create/delete выполнены native REST только на собственных объектах. IPv6/bridge/FDB/throughput/RBAC/concurrency и произвольный терминальный .rsc import не приняты; динамический ARP/FDB baseline не сравнивался. Первый запуск Edge в sandbox завершился до страницы; повторный разрешённый запуск прошёл. Этап12.5 целиком не закрыт. Следующий раздел12.5.77 — IPsec; остаточные VXLAN/WireGuard ограничения остаются в протоколе.

12.5.77 — IPsec: основной раздел, RouterOS7 и реальная профильная приёмка (2026-10-09)

Укрупнённый блок включает backend/API/UI, тесты, production Docker build/deploy, собственные реальные объекты на обоих CHR и очистку. Один локальный коммит после блока, без push. Установленные ReUI/Frame/base-nova компоненты сохранены.

Достоверность и операции. Чтение восьми коллекций IPsec больше не скрывает отказ RouterOS или некорректный контейнер/строки/ID пустым успешным списком. Агрегатор сохраняет успешные устройства и сообщает ошибку конкретного устройства; observed history не запускается для неудачного среза. Выключенный сервер исключён из чтения и операций, ID разбирается целиком. Init/User/Peer формы сохраняют поля при отказах по существующим шаблонам. Статический IPv4 проверяется до изменений; отсутствующий явный peer и дубликат клиента отклоняются. Зарезервированные имена mode-config учитываются в истории и очистке, поскольку RouterOS7.24.5 отклонил comment.

Совместимость RouterOS7. Мастер создаёт сертификатную identity с digital-signature, certificate находится в identity; неподдерживаемые certificate/send-cert убраны из peer и restore body. Исправлены responder=yes для mode-config, доверие CA, неподдерживаемые profile/mode-config comment и identity place-before. Из генерации убраны DH1024/1536 и SHA1. Сертификатная роль учитывает identity references. Plain PSK remote ID при создании превращается в key-id. Отображаемое имя сертификатного клиента хранится в identity, подписанный CN/ключ/имя сертификата сохраняются.

Выбор объекта и удаление. Клиенты используют явные rosId namespace identity:/cert:; совпадение ID разных RouterOS меню больше не выбирает чужой объект. Неоднозначный legacy ID даёт409 с предложением обновить список; CA не является клиентом. Удаление сервера заранее читает весь объём, сохраняет стандартный/чужой policy template, не скрывает ошибки и удаляет CA после leaf сертификатов. Чужие identity/policy и сертификат, подписанный управляемым CA, блокируют удаление до первой записи. Общий/чужой mode-config сохраняется при удалении клиента. Это проверки перечисленных ссылок, не гарантия учёта всех внешних потребителей PKI.

Контекст и интерфейс. URL сохраняет server и tab при reload; неизвестное устройство остаётся отдельным срезом с ошибкой и заблокированным созданием клиента. Сохранена цель мастера при переключении контекста. Форма peer больше не предлагает сертификат, относящийся к identity. Реальный browser выявил возврат вкладки после закрытия Sheet; локальные query-state обновления переведены на History API без отдельного RSC перехода. Next.js API. Тестовые PNG сохраняются в каталог конкретного запуска после ошибки записи общего файла Windows.

Проверки. npm backend test:ipsec:67 новых проверок + config tests, entity-snapshots passed; backend/scoped frontend TypeScript и ESLint passed. Итоговый профильный набор30/30 (включает связанные GRE cases), context-race6/6. Реальный browser4/4: оба CHR ×1280/320px, готовность, peer/client формы, URL/tab/reload и отсутствие page overflow; без HTTP mocks. Browser protocol. Полная регрессия проекта не повторялась.

Реальная схема. На194.226.121.150 и104.165.244.7 выполнены HTTP init без NAT, создание/disable/enable/duplicate PSK клиента,400 на неверный IP,404 на отсутствующий peer, выпуск сертификатов, проверка .p12 через OpenSSL и сохранение CN при переименовании. Для сетевой проверки native REST создал собственные profile/proposal/peer/identity/policy/GRE и198.18.255.249/30↔.250/30; IPsec encrypt/require защищал GRE между публичными /32, без изменения firewall/default route. PSK, затем digital-signature с реальным экспортированным клиентским ключом: Ping3/3 в обе стороны, ph2-state established и ненулевые SA bytes. В импортированной цепочке CA/leaf получили одинаковое имя от RouterOS; тест назначает им уникальные имена по ID. Сертификатная роль задана явно: CHR1 responder, CHR2 initiator. Это native site-to-site проверка криптографии/экспорта; выдача road-warrior lease и импорт через приложение не объявляются проверенными.

Ошибки чтения и выключенные устройства. Две собственные временные DB записи home-router/exit-node указывали на HTTP probe. Выключенные GET сообщали disabled, операции404, native calls0. Включение только fake endpoint вернуло настоящий upstream401: не было ложной успешной пустой сводки, два исправных CHR сохранились в частичном результате;16 probe calls на два чтения. Все fake записи удалены. Native protocol.

Развёртывание и состояние. Образы backend/frontend ux-ipsec77/version1.0.0-test.ipsec77 собраны и развёрнуты;3 services running, backend/PG healthy, frontend проверен HTTP/browser. Source: архив базового HEAD e2d81f9 +14 явных working-file overrides, SHA256 e0a034a855eb2d07696a1849c9baed738890e7c84108d5a3d6dbe652188bee9e; manifest. Это не архив одного уже закоммиченного revision. Приватный pre-deploy PG backup2510309 bytes/0600, pg_restore --list passed; .env/прежние VXLAN образы сохранены на сервере. DB после: servers2/speedHistory9/retention14/migrations9. Пароли не менялись; оба CHR/SSH доступны, единичный401 CHR2 при контрольном чтении не повторился. Deployment, smoke8 страниц.

Очистка последнего цикла сравнила IPsec/PKI/GRE/IP/routes/IPv4 firewall/file metadata на обоих CHR: все проверки true. При восстановлении раннего цикла широкий отбор отклонила автоматическая проверка: выполнены инвентаризация и preflight17 точных ID/атрибутов собственного запуска, затем их разрешённая очистка. Удаление каталога flash наCHR2 отклонено отдельно: системное имя/пустота не доказывают ownership; каталог сохранён. Приватные .p12/.pass/.pem теста удалены, ключи не включены в отчёт/Git.

Референс Схема и реальные экраны
Data Grid Filtering2 Устройство/URL → достоверный срез → клиент; ПК, телефон
Sheet8, Tabs API/preview Peer/клиент → сохранение ввода → подтверждение API → возврат в тот же срез
flowchart LR
    A[Устройство и вкладка в URL] --> B{Достоверный срез?}
    B -->|Нет| C[Ошибка и последние данные]
    B -->|Да| D[Peer или клиент с явным ID]
    D --> E[Форма и подтверждение API]
    E --> F[Native проверка и возврат]

Остаточные границы: online/active-peer корреляция, настоящая выдача mode-config, NAT/интернет, IPv6, Windows/macOS/iOS/Android подключения, late failure receipts/DB/transport, history restore, многопроцессность, IPsec-specific live JWT/RBAC и throughput не приняты этим блоком. Основной раздел внедрён и принят в перечисленных сценариях; этап12.5 и эти профильные ограничения остаются открытыми.

12.5.78 — IPsec: реальный online и адрес mode-config (2026-10-09)

Результат. Установленный PSK IKEv2 клиент отображался offline: RouterOS7 возвращает active-peers.id без префикса key-id:, а старый mapper ожидал remote-id; address/established также не соответствовали реальному ответу. Теперь используются id, state=established, dynamic-address (при наличии), remote-address и uptime. Для настроенного remote-id распознаются только известные префиксы key-id/fqdn/user-fqdn/address; starting/dying/отсутствующее состояние не подтверждают online. Изменены только ipsec-live.ts и профильный тест; UI-компоненты сохранены.

Реальное подтверждение. Собственный responder на194.226.121.150 и initiator на104.165.244.7: PSK, IKEv2, SHA256/AES256/modp2048, отдельные profile/proposal/group/template/mode-config/pool/peer/identity. На responder RouterOS и развёрнутый GET /api/ipsec?serverId=1 подтвердили established, online=true, activeAddress=198.18.78.10, activeSince=0s. Это проверка выдачи адреса и корреляции PSK, не NAT/интернет/throughput. На initiator remote-id=auto не связывается с персональным клиентом, его online=false не считается принятой корреляцией. Сертификатный/DN вариант остаётся открытым. Очищенный отчёт.

Проверки и очистка. npm --prefix backend run test:ipsec: config passed +77 state checks; backend TypeScript, scoped ESLint, diff check passed. Native/API сценарий прошёл на новом backend. До удаления проверены точные ID и атрибуты всех собственных объектов; после — исходные ID восьми коллекций совпали на обоих CHR. Пароли не менялись; flash не затрагивался. Первые три попытки настройки fixture завершились authentication failure; чтение IPsec logs показало identity not found. Удаление избыточных явных responder my-id / initiator remote-id восстановило переговоры; это настройка тестовой пары, приложение не меняет my-id этим блоком.

Runtime и происхождение. Единственная backend production сборка/deploy: mmapp-test/backend:ux-ipsec78, version1.0.0-test.ipsec78, image sha256:d25bb95996e7b917c8829a40e5d90cdcd75a4909e4a4654fcfc818f617262d81, healthy. Frontend остаётся ux-ipsec77; его сборка и общая UI-регрессия не повторялись, поскольку frontend не изменён. Backend context основан на предыдущем проверенном ipsec77 (production соответствует f80d9b7), с заменой ipsec-live.ts; SHA256 runtime исходника29b6843f9b6c80cc83af61ec44f3fdc99759ea656ba126722be3eb5f03501b0b совпал локально/удалённо. Архив двух backend-файлов3bf89cbefc57c3d0002da7285abaa300544700eb3ebeb9e5a83ad4622396ac3a; в нём тест на73 checks, ещё4 проверки префиксов добавлены локально после старта сборки и прошли — это не изменение production кода. Образ не заявляется сборкой из итогового Git SHA; label revision=ipsec78. Backup .env сохранён приватно на сервере; миграций БД нет.

Организация. По замечанию пользователя о длительности предыдущего блока: одна подтверждённая проблема, профильные проверки, одна backend сборка, без повторной frontend сборки и полного набора E2E. Расход пятичасового окна на контрольной точке8%; это квота, не длительность работы. Один локальный коммит без push. Следующий шаг12.5.79: проверить сертификатный active-peer/DN и mode-config, затем late failure receipts/DB/transport и history restore. Остальные ограничения12.5.77 сохраняются.

Референс: RouterOS IPsec — Active Peers, поля state/dynamic-address/remote-address/uptime. Приёмка подтверждена собственным native ответом и API, а не одной документацией.

12.5.79 — IPsec: сертификатный online и поздняя ошибка истории (2026-10-09)

Результат. Реальный сертификатный клиент получал198.18.79.250, но отображался offline: active-peers.id возвращается как CN=имя. Mapper сопоставляет полный одноатрибутный DN с единственным CN сертификата; не извлекает CN из составного DN и не угадывает дубликаты/экранированные значения. Статус/адрес/uptime подтверждены через production API. Native match-by=certificate корректно выбрал персональный mode-config несмотря на общую listener identity; менять порядок identities не понадобилось.

Поздний сбой истории. captureAndAppendRevision может вернуть null при отказе capture/БД. Все IPsec apply/rollback теперь проверяют результат и отвечают502 со state=applied, historyRecorded=false и пояснением: операция уже выполнена, обновить данные перед повтором. Observed capture остаётся best effort для чтения. Добавлен createIpsecRoutes с узкими зависимостями для проверок реального HTTP-маршрута. Это не подтверждение транспортного разрыва или частичного применения до recordIpsec: эти границы открыты.

Проверки. config tests +80 state checks, HTTP PATCH: успешная запись истории/отказ после подтверждённого native изменения/отказ до записи; backend tsc, scoped ESLint, diff check. Реальный сертификат выпущен через API и экспортирован вPKCS12, импортирован наCHR2 с уникальными именами CA/leaf; private material оставался в0700 каталоге стенда и удалён. IKEv2 established на обоих CHR; responder native и API: staticIp/activeAddress198.18.79.250, online=true, uptime1s. Управляемая инъекция recordRevision=null в изолированном Fastify с тем же compiled route дала502/applied после настоящего выключения собственного peer; production PATCH вернул peer обратно. Это контракт сбоя записи, не реальная авария PostgreSQL. Отчёт.

Очистка. До удаления проверены точные ID/name/comment всех собственных объектов; после совпали исходные ID10 коллекций на обоих CHR. CA удалялся после leaf; системные каталоги/исходные файлы сохранены. Пароли не менялись. Первоначальный запуск после deploy столкнулся с readiness race до первого API write; повтор выполнен после docker compose --wait. Далее всегда ждать healthy до native сценария.

Runtime. Одна backend production сборка: mmapp-test/backend:ux-ipsec79/version1.0.0-test.ipsec79, image sha256:26b5b05122b7b55aa83b1f80b880d1aee6eaf33caa225afe09327b02a219c5dc1. Frontend ux-ipsec77 сохранён. Context предыдущего ipsec78 + пять backend-файлов из рабочего состояния перед коммитом; archiveSHA50cdacc0016810bd8c87c0bf2eaedbe9ddd4e1d6134a960f6ca11207c4faaff6. SHA runtime исходников совпали локально/удалённо: ipsec-live.ts676b51c9ed7edd9bc5d0cf5a455409b445c46235a55e2bedeff9e07208401bb6, routes/ipsec.ts192a3a7c5628c5e68c5cb20c26b55ce97c9a4c2cce8effea8ed1a26c79ee442d. Label revision=ipsec79, не итоговый Git SHA. .env backup приватный; миграций нет.

Следующий12.5.80: исправить restore mode-config без неподдерживаемого comment, порядок зависимостей и проверить реальный откат изменений. Обнаружен воспроизводимый локальный отказ: существующие reserved mode-config планируются как новые PUT; новая профильная проверка для следующего блока пока красная. Остальные ограничения12.5.77, составные/экранированные DN, NAT/интернет/IPv6/клиентские ОС/RBAC/throughput открыты. Один локальный коммит без push.

12.5.80 — IPsec: восстановление истории и зависимости (2026-10-09)

Исправления. Restore распознаёт reserved mode-config по имени без неподдерживаемого RouterOS comment; существующий объект обновляется вместо повторного PUT. Пул создаётся до mode-config; restored responder=yes и персональный address-prefix-length=32. Лишние mode-config/peer/pool удаляются после переключения identities. Для проверки ссылок restore state содержит полный live набор, а план изменяет managed объекты. Чужие identity/static policy/пул mode-config и конфликт имени блокируют разрушительный план до записей; HTTP409 с объяснением отсутствия изменений. Отсутствующие сертификаты/profile ревизии также проверяются до исполнения; история не содержит ключи PKI и не может создать их.

Проверки. config +80 state checks, IPsec HTTP history test, новый ipsec-restore test (reserved objects, pool dependency, responder/32, переключение перед удалением, foreign identity/policy/name conflict), entity-snapshots tests, backend TypeScript/ESLint/diff check. Сохраняется исходное предупреждение entity-snapshots.ts unused bool; новых ESLint ошибок нет.

Реальная приёмка. Собственные profile/peer/pool/mode-config/PSK identity наCHR1. Production API сохранил observed ревизию, PATCH изменил198.18.80.250→249 и disabled=true; restore вернул250/disabled=false, native responder=true. Повторный restore200 не создал дубликат. Собственная дополнительная identity без managed marker, ссылающаяся на test peer/mode-config, заблокировала возврат пустой ревизии409; native peer и identity сохранились. Очистка по точным ID/name/comment; исходные ID пяти коллекций совпали. PKI/profile missing guards добавлены, но их отдельная native fault injection не заявляется. Отчёт.

Docker и инцидент. Установка системных пакетов runner перенесена до COPY приложения/APP_VERSION для повторного использования кэша. Первая правка ошибочно выбрала apt block deps и сократила Dockerfile: build формально прошёл, backend не стартовал. Health gate остановил тест до RouterOS/БД mutations; возвращён healthy ux-ipsec79. Dockerfile восстановлен из HEAD, перемещён только runner apt block, diff проверен. Перед повторным deploy проверены entry file/node --check и pg_restore18.6 внутри образа; compose --wait подтвердил healthy. Это две сборки80, включая исправление собственной ошибки; не считать первую успешной приёмкой. Повторное использование apt слоя будет проверено на следующем изменении.

Runtime. mmapp-test/backend:ux-ipsec80/version1.0.0-test.ipsec80, image sha256:c28600a85fb609c910a030594ff4ea2fea91d87415744935c5e49e24b013f578, healthy; frontend ux-ipsec77. Context ipsec79 + шесть backend-файлов рабочего состояния до коммита; corrected archive SHA680f90b1f88119702aa5761a5d71e77bb6c512b4a67aea4f606993606f1e586b; label revision=ipsec80, не Git SHA. Приватный .env backup; миграций нет. Один локальный коммит без push.

Границы. Принят откат управляемых peer/identity/mode-config/pool/nat в проверенном срезе. Политики и profile/proposal/CA/key материал не пересоздаются; удалённый сертификат/profile требует ручного восстановления перед restore. Частичные write failures и транспортная неопределённость остаются12.5.81; NAT/интернет/IPv6/клиентские ОС/RBAC/throughput и сложные DN открыты.

12.5.81 — IPsec: частичные операции, потерянное подтверждение и права (2026-10-09)

Результат. Request-local tracker учитывает подтверждённые PUT/PATCH/DELETE/POST, включая вложенные методы клиента. Ответы отказа: partial — подтверждённые записи до явного4xx; unknown — неподтверждённая запись при сетевой/5xx ошибке; applied — весь mutation завершён, но финальный ответ не получен. Поля confirmedWrites/needsReview и текст требуют обновить данные перед повтором. Tracker не делает автоматический откат и не является durable/idempotency receipt: потеря соединения клиент↔backend и повтор после рестарта требуют отдельного разбора. Отказ до первой записи не называется applied. История после apply/rollback продолжает явно сообщать о null capture/record согласно79.

Preflight и консистентность. Конфликты имени/staticIP/Remote ID проверяются до переименования. Create и PATCH нормализуют обычный PSK Remote ID в key-id: одинаково; duplicate Remote ID одного peer отклоняется. После rename + смены staticIP identity переключается на новый mode-config, старый owned и неиспользуемый удаляется по существующему guarded helper. Поздний отказ такого удаления теперь возвращает корректный частичный результат.

Проверки. npm test:ipsec: config +80 state checks, HTTP history/restore, progress evidence (4xx/partial/transport/5xx/nested/completed) и HTTP mutations. Backend TypeScript/scoped ESLint/diff check прошли. Playwright7/7: три новых320px сценария partial/unknown/applied сохраняют ввод, показывают ошибку и не повторяют запрос автоматически; существующие формы peer/cert/PSK/edit также прошли. UI-код не изменён, frontend не пересобирался.

Реальная приёмка. Собственная PSK конфигурация наCHR1. Production409 при занятом IP сохранил native comment. Изолированный compiled route: первый native patch подтверждён, следующий искусственно403 → partial/confirmedWrites1; настоящий native patch применён, затем injected exception вместо ACK → unknown/confirmedWrites0. Независимый GET подтвердил оба изменения имени. Это управляемая инъекция после реального применения, не физический TCP disconnect. Production PATCH обычного Remote ID подтвердил typed key-id; rename/staticIP подтвердили новый адрес и отсутствие старого mode-config.

JWT/RBAC. В изолированном worker env AUTH_REQUIRED=true и случайный JWT secret только в памяти; тот же auth plugin/requireAuth + compiled IPsec routes. No token/invalid token401, reader PATCH/DELETE/restore/export403, reader GET200, writer native peer disable/enable200. Native объекты при запрете сохранены. Рабочий backend остаётся AUTH_REQUIRED=false, Portal SSO и live browser authenticated flow не заявляются. Отчёт.

Очистка и runtime. До удаления сверены точные ID и ожидаемые имена/comments; свои objects удалены, baseline IDs четырёх коллекций совпали. Один backend build/deploy: mmapp-test/backend:ux-ipsec81/version1.0.0-test.ipsec81, image sha256:2a7d8ab317867f2df4826b7c477659eeba689b7e9d8806676ca030fc4f099abac, healthy; frontend ux-ipsec77. Entry file/node --check/pg_restore18.6 и compose --wait прошли. Runner apt layer #18 CACHED: оптимизация80 подтверждена на изменённом коде/версии. Context ipsec80 + восемь backend-файлов до коммита, archive SHA111eb30a5621eb85e2f7e421a25c22ab70f8073093a83cf0a0f67663163004ec; label ipsec81, не Git SHA. .env backup приватный; миграций нет. Один локальный коммит без push.

Следующий12.5.82: реальная NAT/связность сертификатного клиента. Открыты физические transport disconnect/durable retry, multi-instance, Portal SSO/browser auth, IPv6/клиентские ОС/throughput, сложные DN и полный PKI/policy/profile/proposal restore. Не расширять эти границы по результатам fault injection.

12.5.82 — IPsec: NAT, policy group, реальная передача и полный цикл (2026-10-09)

Исправления по native доказательствам. Master NAT ссылался на несуществующий WAN list чистого CHR и получал400 после остальных записей. Теперь до изменений читаются маршруты/interfaces, выбирается единственный egress активных IPv4 defaults main; PPP/direct interface и дубликаты одного egress поддержаны, отсутствие/неоднозначность даёт409 без CA/других записей. Srcnat ограничен VPN-подсетью, конкретным out-interface и ipsec-policy=out,none. Повторный init обновляет одно owned правило; прежнее дополнительное interface-list ограничение не очищается вслепую.

Группа default выбирала несовместимый proposal: phase1 established/lease/online были успешны, data plane Ping0/3 и native log no proposal chosen. Изолированная группа в fixture доказала причину. Master теперь создаёт mmapp-ipsec-vpn, привязывает owned template/listener и новые персональные identities; legacy default/пустая группа owned identities на app peer мигрирует, чужие объекты/default policy сохраняются. Reuse reserved group требует managed template, foreign consumers блокируются до изменений. Delete server удаляет только reserved group со ссылкой managed template и без foreign refs.

История. Capture/canonical/body сохраняют policy-template-group и NAT out-interface/out-interface-list/ipsec-policy. Restore проверяет наличие группы и не теряет egress. Старый masquerade snapshot без egress отклоняется409. RouterOS также отклонил пустую out-interface-list как ambiguous: body больше не отправляет пустые ограничения, несовместимое снятие существующего дополнительного фильтра блокируется до записи с инструкцией ручной проверки. PKI/profile/proposal/policy definitions по-прежнему не пересоздаются историей.

Контроль Исходная проблема Подтверждённый результат
NAT master WAN отсутствует,400 после partial init ether1/out,none; repeat init одно правило
Data plane default proposal, Ping0/3 owned policy group; Ping3/3 в обе стороны
Интернет До группы не проверен CHR2 assigned198.18.82.250→8.8.8.8 Ping3/3, srcnat=true/seen-reply=true
Restore/delete Пустое interface-list400 группа/egress/disabled восстановлены; group удалена API, default policy сохранена
Cleanup Преждевременная проверка route IDs контроль после удаления обоих peer и короткого bounded ожидания: все14 коллекций ×2 совпали

Приёмка. Собственный сертификатный клиент API, PKCS12 import наCHR2; dynamic assigned address применяется RouterOS, отдельный дублирующий IP наCHR2 больше не добавляется. НаCHR1 собственный bridge198.18.82.1/32; отдельные маршруты только между своими IP с pref-src через неизменённые public gateways. Production init/client/GET/restore/DELETE server прошли без ручной модификации группы в финальном сценарии. Capped UDP bandwidth3s,1,000,000bps в каждую сторону: tx-total-average955040/rx970080bps, lost-packets0; encrypted SA byte delta816906. Это smoke передачи, не максимальная пропускная способность/SLA. NAT reply destination194.226.121.150 подтвердил masquerade. Очищенный отчёт с baseline/recheck.

Проверки. test:ipsec: config/80 state checks/history/restore/progress/mutation/NAT/group, entity-snapshots tests, backend TypeScript/ESLint/diff check. Новые HTTP/unit проверки: no-write missing/ambiguous/VRF NAT, shared group inheritance, foreign refs/namespace guard, default group retained, scoped/legacy NAT restore. Исходный unused bool warning сохраняется. Frontend не изменён;7 E2E81 остаются актуальным profile evidence, полная регрессия не повторялась.

Ошибки тестовой оснастки и очистка. После ручного proof динамическая policy была ошибочно принята за новый чужой объект; cleanup остановился. Read-only ownership audit подтвердил точные29 собственных ID/атрибутов на двух CHR; они удалены после полного preflight, dynamic policy/assignedIP исчезли с peer, приватные файлы удалены. Receipt теперь пропускает auto policy/address, а статические конфигурации удаляет по точным проверенным ID. Один финальный run имел только transient route mismatch; независимый post-control подтвердил исходные4/5 маршрутов, повторный окончательный run сохранил baseline и recheck: CHR1 initialMatch=false/finalMatch=true, CHR2true/true. Не подменять этот переход утверждением о постоянном изменении ID. Flash/system files,195.195.195.195/32, default routes сохранены; пароли прежние.

Runtime/происхождение. Backend mmapp-test/backend:ux-ipsec82c/version1.0.0-test.ipsec82c, image sha256:57fdd7dbbf66091fd0710154ed7c47f284047505977e7b06d0b15bfbfd5fa57d3, healthy; frontend ux-ipsec77. Три builds82/82b/82c по новым подтверждённым отказам: NAT/WAN, proposal group, empty list restore. Финальный context82b +11 backend файлов рабочего состояния, archive d7b0ad10c248ca6c1525266d67b4953f2752f5d046d46b63262e3dc93421e280, label ipsec82c не итоговый Git SHA. Entry/node --check/pg_restore18.6 и compose --wait passed; apt cached. Приватные .env backups, миграций нет. Один локальный коммит без push.

Основной реальный цикл IPsec принят в перечисленных границах. Открыты сложные/экранированные DN, реальные клиентские ОС/IPv6, Portal SSO/browser auth, физические disconnect/durable retry/multi-instance, maximum throughput и полный PKI/policy/profile/proposal restore. Следующий83 — маршрутизация. Референсы интерфейса сохраняются: List9/Sheet8 из общего плана; настройки полей подтверждены RouterOS IPsec и Bandwidth Test.

12.5.83 — маршрутизация: выключенные устройства и реальная eBGP-пара (2026-10-09)

Изменения. BGP raw debug использует общую lookup зависимость и отклоняет enabled=false до создания клиента. Selected BGP sessions и selected OSPF также возвращают409 без опроса, независимо от типа Home Router/Exit Node. BGP debug журнал содержит число сессий вместо дублирования полного raw payload. Selected OSPF использует strict readOspfCatalogRaw: отказ BFD/routes или неправильный контейнер больше не подменяется успешными пустыми массивами; dependency failure503. Legacy aggregate paths не менялись этим блоком.

Проверки. BGP/OSPF catalog tests с новыми selected/raw disabled/unknown/invalid/enabled сценариями, OSPF BFD failure503; backend TypeScript, scoped ESLint/diff check passed. Сохраняются исходные OSPF unused and/measurePingByInterface warnings, новых ошибок нет. UI/контракты не менялись, frontend build и полная регрессия не повторялись.

Real API. Две собственные disabled DB записи с HTTP probe на приватном Docker DNS: Home Router/Exit Node × BGP raw/selected/OSPF selected409, probeRequests0. Записи удалены по id/name/host. Selected OSPF двух настоящих enabled CHR возвращает корректные массивы; это чтение исходно пустой OSPF конфигурации, не приёмка adjacency.

eBGP. Собственные RouterOS7.24 instances с private ASN65083/65084 и конкретными remote/local public IP, multihop eBGP connections и input/output reject-all chains. Native established=true на обоих CHR, production selected и catalog State Established/type eBGP/ASNs корректны; received prefixes0, catalog transmitted prefixes null как ненаблюдаемое значение. Инстансы/соединения/filter rules удалены по точным ID/name/chain/comment после полного preflight. Исходные ID connection/instance/filter/IPv4 route коллекций совпали на обоих CHR, default/management routes не участвовали в обмене. Это Establishment/read-only UI data contract, не route policy propagation, failover или maximum scale. Отчёт.

Runtime. Одна backend Docker сборка, entry/node --check/pg_restore18.6 и compose --wait passed. mmapp-test/backend:ux-routing83/version1.0.0-test.routing83, image sha256:b68c326b8ee601eb2c490e7517c49614abd8cdfccc9d2af2ec44fb5d3dc5aded7, healthy. Frontend ux-ipsec77 сохранён. Context ipsec82c +четыре routing backend файла рабочего состояния до коммита, archive eaaca441a3eae1c95396abaca4a09fa4a38e4a769adaff276fc4bbcadac18244; label routing83, не итоговый Git SHA. .env backup приватный; миграций нет. Один локальный коммит без push.

Следующий84 — OSPF Full adjacency и обучение только собственного частного prefix через собственный GRE; исходные public interfaces/default routes сохранить. BGP failover/route propagation/BFD optimizer/recursive diagnostics и внешние границы IPsec82 остаются открытыми. Версия RouterOS7.20+ с явными instance подтверждена MikroTik BGP и настоящим API7.24.5; схема таблиц/деталей сохраняет референсы Data Grid Filtering2/List9 общего плана.

12.5.84 — OSPF: Full adjacency, GRE и реальная таблица (2026-10-09)

Сценарий. На двух CHR созданы собственные GRE,198.18.84.1/30↔2/30, bridge loopbacks198.18.184.1/32↔2/32, OSPFv2 instances/router IDs, backbone area и templates: ptp GRE/cost10/hello1s/dead4s; passive loopback/cost1. Originate-default=never, redistribution не включалась, public interfaces не включены в OSPF. Baseline instance пустой проверен до создания.

Native/API. Оба соседа Full; только собственные частные remote prefixes выучены и active. Ping loopback3/3 в обе стороны. Production /ospf/catalog и /servers/:id/ospf подтвердили neighbor/route/device context. Raw route имеет distance110 без ospf-metric/оспf-type; main catalog сохраняет cost=null/type Unknown, не выдаёт110 за измеренный cost. Legacy selected route representation сохраняет старую совместимость — не считать её полем фактической метрики. Native/API отчёт.

Браузер. Headless Edge, настоящий deployed frontend/backend, без interception/mock: два устройства×1280/320 =4/4. DOM содержит нужного соседа/выученный prefix, selected button aria-pressed, server/tab URL восстанавливается после reload, document не расширяется, pageerror0. Скриншоты показывают сводку/топологию верхнего экрана; таблица доступна ниже во внутренней прокрутке Frame. Browser отчёт, экраны ospf-real-neighbors-server1/2-1280/320-2026-10-09.png. UI/source/dependencies не менялись.

Оснастка. Первая native попытка проверила route сразу при Full до завершения SPF и отказалась; cleanup прошёл. Ожидание исправлено на Full плюс active learned route. Первая browser попытка ожидала role=tab, тогда как существующий UI использует button/aria-pressed; тест поправлен по прочитанному коду, продукт не менялся ради локатора. Финальные native и browser runs прошли; промежуточные попытки не считаются UI acceptance.

Очистка. Exact receipt ID/name/comment/address/interface проверены до удаления. Templates→areas→instances, свои IP/bridge/GRE удалены; контроль обеих сторон после удаления всей пары и bounded route convergence. Исходные ID7 коллекций×2 совпали, адрес195.195.195.195/32 и public/default routes сохранены. Credentials не менялись. Сборок/миграций/смены runtime не было; backend ux-routing83/version1.0.0-test.routing83 healthy, frontend ux-ipsec77. Один локальный commit без push, только evidence/docs.

Следующий85 — разрешение BFD только на своих GRE/private peers и Up/control-plane checks. Не приняты BFD/failover/optimizer/масштаб/IPv6 и остальные внешние границы. Механика instance/area/template подтверждена MikroTik OSPF; таблицы/Frame сохраняют общие референсы плана.

12.5.85 — BFD: реальные Up, потеря GRE и восстановление (2026-10-09)

Конфигурация. Собственная GRE/OSPFv2 пара по шаблону84, link198.18.85.1/30↔2/30, loopback198.18.185.1/32↔2/32. Свои BFD configurations только для точного GRE и private subnet, min-rx/min-tx200ms/multiplier3; OSPF GRE template use-bfd=yes. Public/default routes/interfaces и foreign BFD config не менялись, default originate/redistribution не включались.

Native/API. BFD state up, multihop=false, multiplier3 и packets-rx/tx растут на обоих CHR. Main catalog Up, интервалы/hold поля200/200/600ms и counters корректны; RX minimum — требуемый minimum, не измерение межпакетного времени. OSPF Full, own loopback route active, Ping3/3 в обе стороны. Up отчёт.

Браузер. Настоящий backend/frontend, Headless Edge, два устройства×1280/320:4/4 без pageerror. BFD/private peer DOM и selected button/URL, learned route и reload context проверены, document fits. Для BFD table screenshot выполнена внутренняя прокрутка к peer; просмотр mobile подтвердил видимую таблицу/Up и объяснение TX fact/RX minimum. Browser отчёт, экраны ospf-real-bfd-server1/2-1280/320-2026-10-09.png.

Loss/recovery. Повторная собственная пара без browser wait: временно отключён только свой GRE наCHR1. НаCHR2 нет BFD Up/OSPF Full, remote private route больше не active; API согласован. Включение GRE восстановило Full и active route. Первая проверка требовала постоянную строку Down и отказалась: dynamic session удаляется после потери OSPF пользователя. Критерий исправлен на отсутствие Up + отсутствие Full + withdrawal, исчезновение записи не выдаётся за наблюдённый Down. Loss/recovery отчёт.

HTTP sampling показал withdrawal за5245ms при OSPF dead interval4000ms; beforeDeadInterval=false. Это включает RPC/SPF/convergence и не подтверждает sub-second detection или преимущество перед Hello/Dead. Причину/latency требуется разбирать отдельно по событиям и SPF timing, не обещать BFD performance по nominal600ms hold. Alternate-path failover не тестировался.

Очистка и фиксация. На каждом run exact returned ID и name/comment/address/interface/interfaces сверены до удаления. OSPF templates/areas/instances, own BFD config/IP/bridge/GRE удалены; затем bounded route convergence и исходные IDs8 коллекций×2 совпали. Loss run тоже cleanup passed/error=null. Credentials прежние;195.195.195.195/32/default routes сохранены. Production backend routing83/PG healthy, frontend ipsec77 Up; временных контейнеров/fixture DB записей не осталось. UI/source/dependencies не менялись, сборки/миграции не запускались. Один локальный commit без push.

Продолжение86: проверить раздельно BFD event и SPF withdrawal timing, затем профильные optimizer/recursive diagnostics, routing failover/масштаб в согласованных границах. Сохраняются Portal SSO/browser auth, multi-instance/physical disconnect/durable retry, client OS/IPv6/сложные DN/maximum throughput/полный PKI-policy restore ограничения82. Контрольная квота96%, дальнейшие mutations в этом окне не начинать. MikroTik BFD подтверждает отдельную configuration и use-bfd; acceptance основана на настоящем API и native состояниях.

12.5.86 — BFD/OSPF: раздельные наблюдения реакции и маршрута (2026-10-09)

Проверка. Собственная OSPFv2/GRE пара, link198.18.86.0/30 и loopbacks198.18.186.1/32↔2/32. BFD200ms×3, OSPF hello1s/dead20s. Два временных firewall filter правила блокировали только UDP3784 в input/output на своём GRE CHR2 и адресе private peer. Hello не блокировались. Временные memory logging rules bfd/ospf debug без packet; исходные правила не редактировались. Другие интерфейсы, default/public routes и пароли сохранены.

Сценарий Первый BFD не Up Первый сосед не Full Первый маршрут не active
Только BFD UDP, окончательный run 629ms 630ms 1845ms
Полная административная потеря своего GRE 622ms 622ms 2842ms

Измерение начинается перед первой записью fault и включает RPC. Каждое GET имеет start/end в отчёте, три коллекции читаются одновременно, между раундами100ms. Это верхние границы первого наблюдения; точное время внутренних BFD/SPF событий и SLA не установлены. Native log подтверждает bfd down → state change to Down, но его timestamps имеют секундную точность. Удаление маршрута наблюдалось отдельно, позже потери соседа; прежние5245ms блока85 нельзя называть временем детектора BFD.

Существенное ограничение. Первый BFD-only run обнаружил BFD Down за736ms и потерю Full за736ms, но к концу8,78s сосед снова Full, маршрут active; strict withdrawal assertion отказалась. Cleanup прошёл. При сохранённых Hello RouterOS может заново поднять adjacency даже с BFD Down: устойчивую блокировку маршрута и alternate-path failover эта проверка не доказывает. Окончательный run фиксирует первый transient withdrawal и не выдаётся за постоянную потерю маршрута. После снятия firewall fault и после включения GRE отдельно подтверждены BFD Up, OSPF Full и active route.

Результат. Очищенный отчёт: HTTP samples, scoped native logs, initial-attempt summary, recovery и baseline. Все свои firewall/logging/OSPF/BFD/IP/bridge/GRE объекты удалены после exact-ID/атрибутов preflight. Исходные ID10 коллекций×2 совпали; оба CHR доступны. Продукт/зависимости/runtime не менялись, сборки/широкие регрессии не повторялись. Локальный коммит без push. Квота5% использовано после завершения.

Настройки протокола подтверждены MikroTik BFD, механика memory logging — MikroTik Log. Продолжение87: собственные OSPF templates через production optimizer preview/apply, неизвестные/модельные метрики и частичный отказ без заявления полного успеха; далее recursive diagnostics. Этап12.5 остаётся открытым.

12.5.87 — OSPF optimizer: права, реальные costs и частичный результат (2026-10-09)

Изменения. Три проверки разрешения в OSPF UI приведены к backend mm:network:write. Роль только mm:servers:write не запускает оптимизацию, network writer может её выполнить. Существующие Frame/компоненты/композиция ReUI сохранены; skill ReUI применён для минимальной правки поведения.

POST optimize при отказе записи возвращает502 и request-local receipt: state partial для подтверждённых шагов перед RouterOS4xx; unknown при потерянном ACK/transport/5xx; rejected при первом явном4xx. applied содержит только подтверждённые interfaces/from/to, confirmedWrites, failedInterface и needsReview. После первого отказа следующие записи не выполняются. Preflight/plan ошибки остаются500 без заявления о записи. Автоматического rollback/retry, durable receipt или межпроцессной блокировки не добавлено. UI сохраняет прежнее сообщение о неподтверждённой операции и повторный опрос.

RouterOS7.24.5. GET может опустить disabled при unset и у interface-template, и у instance/area. GET disabled=false/proplist не раскрывает effective default: отдельный native POST /get с .id/value-name=disabled возвращает ret=false; при disable ret=true; при явно false GET уже содержит false. Добавлено чтение эффективного значения только для пропущенного disabled, до4 одновременно. Значение не угадывается по отсутствию или inactive. Неправильный ответ/отказ/повтор ID блокирует чтение. Явные значения сохраняются, исходный payload не мутируется. Большой набор unset потребует дополнительных RPC; maximum scale/performance этого пути не принят.

Проверка До После / доказательство
Права кнопки OSPF servers:write расходится с API network:write; обе роли проверены на320px
Неявный disabled strict preview500 native /get подтверждает состояние templates/instances/areas
Частичный отказ обычный500 без шагов partial/unknown/rejected и подтверждённые изменения
Production preview/apply Не принято на устройстве preview без записи, два costs применены на каждом CHR, повтор0

Схема: устройство → достоверные flags/costs → preview → последовательная запись → receipt → повторный опрос. Референс сохранён: Data Grid Filtering2. Экран ПК, 320px; mobile просмотрен, кнопки/cur-opt помещаются в документе.

Реальная приёмка. Свои GRE/link198.18.87.0/30/loopbacks198.18.187.1/32↔2/32, OSPF instances/area, templates с начальными costs50/60. Public interfaces не включались в OSPF, originate-default=never. Production preview сохранил native costs, apply изменил два собственных шаблона на10/20 согласно плану, repeat optimizedCount0. DTO observed остаётся отдельным от модельных ping/speeds; fallback не объявляется измерением. OSPF Full, private route active, Ping3/3 по первоначальной проверке пары.

Изолированный экземпляр тех же compiled routes с настоящими PATCH собственных шаблонов: reject второго шага до передачи → partial/confirmed1, второй cost неизменён; исключение после подтверждённого native PATCH, вместо ACK вызывающему коду → unknown/confirmed1, отдельный GET подтверждает оба фактических изменения. Это инъекция ответа, не физический TCP disconnect. После тестов production API привёл costs к текущему плану. Native/API/flags протокол.

Браузер и локальные проверки. Настоящий deployed frontend/backend без HTTP interception: два устройства×1280/320 =4/4, apply повтор0, receipt/server context, кнопка после опроса, reload URL, document fits/pageerror0. Browser отчёт. Профильные E2E OSPF operations/optimizer apply16/16; optimizer identity/metrics/plan/effective disabled/HTTP, catalog tests и signed JWT RBAC passed. Backend build и scoped frontend tsc passed, Docker frontend production build прошёл. Обычный root tsc захватывает старые ignored tmp build copies и имеет исходные ошибки; scoped config исключает tmp. ESLint новых helper/test/UI прошёл; OSPF прежние2 unused warnings, mikrotik.ts прежние2 prefer-const errors подтверждены на HEAD, новых ошибок нет. Полная регрессия не повторялась.

Оснастка/очистка. Первые два native runs отказались на отсутствующем disabled template, затем instance; оба exact cleanup7 коллекций×2 passed. Read-only discovery проверила proplist/filter/get; numbers оказался неподдерживаемым аргументом, рабочий .id проверен. Отдельная flags fixture cleaned baseline5 коллекций. Финальный run native/browser прошёл, own templates/areas/instances/IP/bridge/GRE удалены по точным ID/атрибутам, исходные IDs7 коллекций×2 совпали. 195.195.195.195/32/default/management routes сохранены. Оба CHR доступны, credentials не менялись, fixture контейнеров/DB записей не осталось.

Runtime. Backend ux-optimizer87c/version1.0.0-test.optimizer87c, image sha256:22cc9a09a89038e58c15dfd6224191d1fab7ad63f7af6f80ecc9e7577483d390; frontend ux-optimizer87/version1.0.0-test.optimizer87, image sha256:22f05c341a7dc0e40e04f23b0da61ba5cfbf31d741d4e22b0c9bcd71c85e0c49. Backend/PG healthy, frontend served/browser passed. Backend entry/node --check/pg_restore18.6, frontend entry/node --check и compose --wait passed. Три backend builds87/87b/87c по двум реальным flag incompatibilities; frontend build один, apt cache сохранён. Context backend routing83 +2 routes, затем4 файлов final-c; override SHA c04289ab57294d57cc9aed292e247e144c171ade3d1101f6ebb84129e41b065be; frontend ipsec77 +OSPF page, override dab57aad2cb248553b0fee9da73069f7a31cb627b26c414f03320315a299756db. Labels не Git SHA; это рабочие файлы до локального коммита. .env backup приватный, миграций нет. Один локальный commit без push.

Продолжение88 — recursive routes, затем диагностика. BFD sustained/alternate-path failover, IPv6/scale/maximum throughput, Portal SSO/browser auth и другие внешние ограничения сохраняются; lab AUTH_REQUIRED=false, RBAC checked отдельно. API /get и .proplist/query подтверждены RouterOS REST API и реальным устройством. Квота23% использовано, этап12.5 открыт.

12.5.88 — рекурсивные маршруты: реальные операции и история (2026-10-09)

Исправления. Все6 путей catalog/gateways/catalog/legacy reads/PUT/restore проверяют enabled=false и возвращают409 до опроса/применения любого типа устройства. История остаётся доступным чтением БД. Создание RouterOS route исправлено с POST без add на PUT. Весь управляемый набор проходит strict parse до записей: неподдерживаемая owned row не исключается молча перед удалением. IPv4 destination/gateway и check-gateway проверяются до native writes. Замена кэша выполняется в транзакции вместо независимых delete/insert.

Request-local receipt сохраняет подтверждённые createdIds/deletedIds и число записей. RouterOS4xx после успешных шагов → partial; первый4xx → rejected; потерянный ACK/неправильный ответ/transport → unknown; ошибка кэша/истории после native completion → applied/metadataRecorded=false. После успешного apply, но отказа заключительного чтения кэша → applied/metadataRecorded=true. Ошибки операций возвращают502, последующие записи не выполняются, automatic retry/rollback не добавлены. Старые/default/foreign routes не удаляются при отказе создания новых; полная distributed transaction/idempotency не заявляется.

Проверка Подтверждённый результат
Disabled Home Router и Exit Node По6 запросов409; контрольный HTTP probe0
Native PUT + strict catalog Формат/ID/flags подтверждены на двух CHR отдельным малым probe
Recursive resolution gateway198.18.189.peer → resolver host route → immediate-gw198.18.88.peer%ownGRE
Data plane Own loopback Ping3/3 в обе стороны в окончательном run
API/history Apply, изменение distance/disabled, restore своей версии; invalid CIDR400 без записи
Fault injection partial1/unknown1/applied2 подтверждённых записей; независимый native GET
Browser 4/4 ПК/320px, две реальные формы добавления; reload context, pageerror0

Стенд. Свои GRE и link198.18.88.0/30, bridge loopbacks198.18.188.1/32↔2/32 и probe IP198.18.189.1/32↔2/32. Неуправляемый собственный resolver /32 имеет scope10; управляемый remote loopback /32, gateway probe IP, scope30/target-scope11/distance150/check-gateway none. Native immediate-gw доказал двухступенчатое разрешение через GRE, Ping подтвердил передачу. Это проверка recursion/data plane, не loss-based failover или SLA. Default/public/metadata routes и195.195.195.195/32 сохранены.

Доказательства. Native/API/DB отчёт. Production API применил конфигурацию обоих устройств, прочитал каталог, изменил distance/disabled и восстановил только созданную в этом run версию. Revisions baseline≤35 проверен, чтобы тестовые записи не вызвали pruning старой истории. HTTP409 проверены на двух собственных disabled DB rows с probe на private Docker DNS; fake rows и их revisions удалены каскадно.

Ошибки инъецированы в тот же native executor: второй PUT отклонён до передачи → partial и сохранён старый маршрут; второй PUT выполнен, ACK заменён исключением → unknown, фактические3 owned rows прочитаны отдельно; persist callback отказал после replace → applied, новый набор уже на RouterOS. API-обёртка этих receipts и поздний getRoutes отказ проверены HTTP/unit. Реальный отказ PostgreSQL/физический TCP disconnect не создавался.

Браузер. Настоящий backend/frontend без mocks: два устройства×1280/320. Раскрытый endpoint и URL/reload, document fits, затем на320px заполнена и отправлена форма: gateway probe IP/scope30/target11/none/distance152, новый private prefix198.18.188.250/32. API подтвердил два маршрута, sheet закрылась, две группы видны. Browser отчёт, ПК, 320px форма просмотрена. Общие Data Grid Filtering2/Sheet8/Frame из плана сохранены, frontend source не менялся.

Проверки/оснастка. 29 профильных E2E data/values/links passed. Backend recursive HTTP/catalog/executor tests, TypeScript, scoped ESLint/diff passed. Проверены invalid before writes, foreign retention, create/delete ordering, unsupported owned preflight, malformed ACK, rejected/partial/unknown/applied, поздняя ошибка чтения и disabled обоих типов. Первый native run Ping0/3: обратный маршрут ещё не создан; порядок исправлен на предварительное применение обеих сторон. Второй начальный Ping2/3: ограниченное ожидание готовности пути добавлено, до3 коротких попыток с сохранением результатов. Финальный run получил3/3 с первой попытки на обоих CHR. Ошибки оснастки не считаются приёмкой; оба cleanup passed.

Очистка. Native managed routes сверены по уникальному name-prefix, остальные свои GRE/bridge/IP/resolver по exact ID/атрибутам. Свои объекты удалены, baseline IDs4 коллекций×2 совпали. Исходно пустой recursive cache восстановлен; удалены только новые собственные revisions после проверки payload/comment и ID, прежние revision IDs сохранены. Последовательности PG увеличились из-за тестовых insert; это не побитовый restore БД. Оба CHR доступны, credentials неизменны, fixture containers удалены.

Runtime/фиксация. Одна backend сборка ux-recursive88/version1.0.0-test.recursive88, image sha256:d358ec1d6ea87ea7f29a12cc4fd3c1a6a7929b854bcdc732d956c702fe4dc587. Backend/PG healthy, frontend ux-optimizer87 сохранён и принят браузером. Context optimizer87 final-c +6 backend файлов, override SHA de4caf2aced38ba7e490f6a459a19d359cc92cb5b098564b799c05bc86be1365; label не Git SHA, рабочее состояние до коммита. Entry/node --check/pg_restore18.6, compose --wait passed, apt cached. .env backup приватный, миграций нет. Один локальный commit без push. REST метод подтверждён RouterOS REST API.

Следующий89 — диагностика/терминал: реальный запуск, ограниченные команды, ошибки, права и контекст. Routing alternate-path/BFD sustained failover, IPv6/scale/physical disconnect/durable retry/Portal SSO и остальные внешние границы остаются открытыми. Квота38% использовано после блока; этап12.5 открыт.

12.5.89 — диагностика и терминал: реальные ответы и JWT-права (2026-10-09)

Изменения. Exec отклоняет enabled=false до создания клиента, включая локальную help-команду. Средний Ping RTT больше не берётся из time последнего пакета: используется подтверждённый native avg-rtt при received>0. Отсутствующий/неверный average или отсутствие полученных пакетов → ?, явный0ms при полученном ответе сохраняется. RosPingResult дополнен avg-rtt. Allowlist/сетевые правила/GUI не менялись.

Проверка Доказательство
Два disabled типа Exec и все6 probe tools:16 ответов409, probeRequests0
Native терминал Identity/resource/routes/OSPF/BFD, Ping3/3, ограниченный log read; неизвестная команда400
Native диагностика Ping3/3, traceroute≤3 hops/1 probe/1s timeout, active route lookup, DF MTU probe
DNS приложения example.com A; .invalid502 без ложного output
Средний RTT Compiled exec formatter сверён с avg-rtt того же native Ping запроса
JWT API 401 none/invalid,403 reader/network writer,200 server writer/admin; native factory0 до разрешения
Реальный UI 8/8: две страницы×два CHR×1280/320, Ping5/5, ошибочный command сохранён

Приёмка. Native/API/RBAC отчёт. Read-only allowlist применяется обычным production API. Текст log print limit=1 не сохранён в Git, записана только длина. DNS выполняется на backend, что явно подписано в UI; не выдаётся за RouterOS DNS. Traceroute ограничен тремя хопами и не считается полным путём. MTU — первая успешная DF проба из существующего набора до1500, не доказательство максимального MTU/jumbo/SLA. Uncapped bandwidth endpoint не запускался: capped native smoke82 остаётся отдельным доказательством.

JWT тест использовал изолированный экземпляр compiled exec/probes routes, реальные credentials/native reads, временный локальный secret/issuer и настоящие подписи HS256. Проверены обе API группы и отсутствие native client до разрешения. В production AUTH_REQUIRED=false сохранён, Portal SSO/browser login этой проверкой не принят. Native configuration/пароли не изменялись.

Браузер. Настоящие deployed frontend/backend, без interception/mocks. Terminal400 сохраняет ввод; следующий resource request подтверждён, вывод содержит7.24.5, поле очищено и фокус возвращён. Probes Ping5/5 с правильным source/target, reload server context, document fits/pageerror0. Browser отчёт, терминал320, диагностика320. Последний снимок просмотрен; значения не подменены моками. Frame/ReUI композиция прежняя.

**Проверки и оснастка.**58 профильных E2E terminal data/layout и probes data/source passed; exec/probes HTTP, signed JWT unit, backend TypeScript/ESLint/diff passed. Probes.cancel локальный HTTP тест сначала получил sandbox EACCES, повторён только он с разрешённым loopback: passed, включая abort настоящего MikrotikClient POST к локальной HTTP-фикстуре. Это не доказательство остановки процесса на CHR; UI сохраняет соответствующее пояснение.

Production image не содержит dev-only jose: первый fixture import завершился до native requests, подписи заменены native crypto. Следующая RBAC попытка меняла process.env после загрузки env объекта и получила200 вместо ожидаемого401 в изолированном приложении с выключенной авторизацией. Исправлен только fixture: snapshot/config authRequired/secret/issuer и восстановление finally. Успешные phase1 native проверки не повторялись; report объединяет их с исправленным RBAC и browser phase.

Контроль. Собственные disabled DB rows удалены по id/name/host, fixture containers завершены. IDs7 native коллекций×2 совпали до/после: interfaces/addresses/routes/OSPF instances/BGP connections/BFD config/IPsec peers. Оба CHR доступны, пароли прежние; public/default routes и195.195.195.195/32 сохранены. Никаких VPN объектов в этом read-only блоке не создавалось.

Runtime. Один backend build ux-diagnostics89/version1.0.0-test.diagnostics89, image sha256:97c1cff01efd5055d3811b742e293180d5999ff1e326e42242e5c975b5f70349. Backend/PG healthy, frontend ux-optimizer87 сохранён/принят. Context recursive88 +3 exec/type files, override SHA2ca8c80d13a2dcce8b09c905f2b65d7467892ee6918cc102caad2d15d90bacbf7; label не Git SHA. Entry/node --check/pg_restore18.6/compose --wait passed, dependencies/apt cached. .env backup приватный, миграций и frontend rebuild нет. Один локальный commit без push.

Продолжение90 — два собственных GRE пути OSPF/BFD, потеря primary, переход на alternate, packet observations и возврат. Сохраняются sustained BFD-only/физическая WAN failure/IPv6/масштаб/максимальная производительность/Portal SSO и другие внешние границы. Квота56% использовано после блока; этап12.5 открыт.

12.5.90 — OSPF/BFD: переход на резервный GRE и возврат (2026-10-09)

Топология. Свои primary GRE public↔public/link198.18.90.0/30/cost10/MTU1400 и alternate GRE/link198.18.91.0/30/cost100/MTU1380. Резервный GRE имеет отдельные outer endpoints198.18.92.1↔2 внутри собственного WireGuard/UDP59990/MTU1420. WireGuard ограничен peer /32, ключи созданы RouterOS; private keys не сохранены в отчёте. OSPFv2 private instances/area/loopbacks198.18.190.1/32↔2, hello1s/dead20s; BFD200ms×3 только на двух своих GRE. Originate-default=never, public interfaces не включались в OSPF. Два пути используют один public WAN; физическое резервирование не доказано.

Control/data plane. На обоих CHR сначала2 Full и2 BFD Up, loopback через primary. Отключён только собственный primary GRE наCHR1; alternate остаётся Full/Up, native immediate-gw и API via показывают резервный интерфейс. Включение primary возвращает preferred path. Steady Ping3/3 в обе стороны во всех трёх фазах, в финальном control run с первой попытки. Исходная конфигурация восстановлена.

Наблюдение Результат / граница
Primary BFD не Up / OSPF не Full Первое HTTP-наблюдение797,7ms при dead20s
Active loopback через alternate Первое HTTP-наблюдение4250,4ms
Ping во время переключения Отдельная фаза18/40,55% loss; бесшовность не принята
Steady/возврат 3/3×2 primary, alternate, recovered primary
UI во время alternate 4/4 PC/320px, route peer/via DOM, BFD peer, reload URL, pageerror0

Объединённый отчёт сохраняет packet/browser phase и отдельную control phase с их именами/timestamps. В packet phase долгий native REST Ping задержал получение status batch:7648ms не является измерением BFD detection. В control phase длинного Ping во время sampling не было; времена включают RPC и остаются верхними границами первого наблюдения, не event timestamps/SLA. Потери не скрыты успешным steady Ping.

Оснастка. Первая пара с одинаковыми outer public endpoints не достигла готовности; cleanup8 коллекций×2 прошёл. Для дальнейшего теста outer endpoints разграничены через свой WireGuard. Packet/browser phase подтвердила alternate path и4 UI cases, но первый Ping после возврата дал2/3. Cleanup10×2 прошёл. Затем выполнен только профильный control/recovery run без повторной UI-приёмки; bounded3 попытки сохраняют каждый результат, финальные steady probes прошли с первой. Product/source/dependencies не менялись, сборок/полной регрессии не было.

Визуальная приёмка. Browser отчёт, ПК, 320px. На PC снимке подтверждён next-hop198.18.91.2 и alternate via. Тип/Cost неизвестны и не заменены distance110. При просмотре найдено, что первый столбец слишком узок: CIDR198.18.190.2/32 визуально обрезан; это следующий самостоятельный UI блок91. Mobile проверяет document fit и наличие значений в DOM, а не одновременную видимость всех столбцов в горизонтальной прокрутке.

Очистка. Exact ID/name/comment/address/interface/interfaces/addresses/public key preflight; удалены только свои templates/area/instance/BFD/IP/bridge/GRE/WG peers/interfaces. Исходные IDs10 коллекций×2 совпали, public/default routes и195.195.195.195/32 сохранены. WG secret fields не включены в report. Оба CHR доступны, passwords неизменны; временных контейнеров не осталось. Backend diagnostics89/PG healthy, frontend optimizer87 сохранён. Один локальный commit без push.

Схема: primary → BFD/adjacency loss → alternate GRE over WG → проверка data plane → восстановленный primary. Транспорт подтверждён GRE и WireGuard; таблицы сохраняют референсы общего плана. Продолжение91 — обрезка CIDR, затем BGP propagation/остальные внешние границы. BFD-only устойчивый запрет/physical WAN/IPv6/scale/maximum throughput/Portal SSO остаются открыты. Квота66% использовано; этап12.5 открыт.

12.5.91 — OSPF Data Grid: целый IPv4 CIDR (2026-10-09)

Уточнена визуальная проблема90: это не потеря API-данных, а перенос последней цифры /32 на вторую строку; первый ряд выглядел как /3. Столбец назначения расширен150→180px, span использует whitespace-nowrap и title полного значения. Установленные Data Grid/Table/ScrollArea, pinned column, theme и структура сохранены. ReUI inline API и audit checklist прочитаны; API, превью.

Проверки. Новый browser test ждёт document.fonts.ready и проверяет Range rectangles: ровно одна строка, текст внутри ячейки. До исправления1280px failed: /3 и2 дали два rect. Первоначальная проверка только границ проходила и была уточнена, чтобы не пропустить разрыв CIDR. После изменения4 размера320/390/1280/1440 и IPv4 CIDR15/18 символов проходят; сортировка/количество строк/document fit/no writes сохранены. С OSPF unknown cost/disabled/inactive —7/7. Scoped TypeScript, ESLint/diff passed. Это meaningful visual regression, не проверка буквального size в исходнике.

Live. Backend diagnostics89 и обновлённый frontend ospf91, без mocks: два CHR×1280/320 =4/4. Свои GRE/OSPF private link198.18.93.0/30/loopbacks198.18.193.1/32↔2/32; Full/active learned route/Ping3/3. Целый /32 виден в одной строке после загрузки шрифтов; title, границы ячейки, URL/reload, document fit/pageerror0 подтверждены. Browser отчёт, native/cleanup, ПК после, 320px после. PC снимок просмотрен:198.18.193.2/32 полностью читается. Проверка не обещает одновременную видимость всех колонок на телефоне: сохраняется внутренняя горизонтальная прокрутка.

Контроль/runtime. Свои objects удалены по exact IDs/атрибутам, baseline7 коллекций×2 совпал, оба CHR доступны, default/public/195.195.195.195/32 и credentials сохранены. Нормализованные SHA source/deployed DataGrid renderer и OSPF consumer совпадали до изменения, поэтому проблема не была вызвана отставшим компонентом стенда. Один frontend Docker build, production TypeScript/build, entry/node --check/compose --wait passed. mmapp-test/frontend:ux-ospf91/version1.0.0-test.ospf91, image sha256:b4bade515234115b3cad257ceb87ef7beb347e754ca92d6a97a25adc2199fd33. Context optimizer87 frontend +один consumer file, override SHA27a27569335c377bf8662fb5b39d200ce98d52925cafdf51dee165464c1532078, label не Git SHA. .env backup приватный, backend/migrations не менялись, полная регрессия/failover не повторялись. Один локальный commit без push.

Следующий92 — BGP propagation собственных private prefixes, withdrawal/re-advertisement и UI counters; только собственные GRE/instances/filter chains. Квота84% использовано после блока, этап12.5 и внешние границы остаются открытыми.

12.5.92 — BGP: собственный префикс, отзыв и повторное объявление (2026-10-09)

Сценарий. Свой GRE/link198.18.92.0/30 и bridge loopbacks198.18.192.1/32↔2/32, private AS65092/65093, explicit BGP instances/router IDs и direct eBGP connections. Address list output.network содержит только собственный loopback /32. Отдельные input/output chains принимают только соответствующий exact /32 по dst/dst-len и отклоняют остальное. Default-originate=never, network-blackhole=no, public/default/metadata prefixes не экспортировались.

Проверка Результат
Established / маршрут Обе сессии Established; ровно1 learned BGP route на узле, active
Data plane Собственные loopbacks Ping3/3 в обе стороны
Production API Selected/catalog Established, prefixesRx1; неизвестные counters не заменены нулём
Отзыв Отключение своей connection наCHR1 убрало active private route наCHR2
Повторное объявление Включение connection вернуло Established/active own prefix/API Rx1
UI 4/4 два CHR×1280/320: received1, Router ID, details/reload, document fits/pageerror0

Доказательства. Native/API протокол. Withdrawal впервые наблюдался340,8ms после acknowledgement административного disable. Это не hold-timer/BFD detection или loss-based failover/SLA. Public routing не менялся; peer TCP179 проходит только через собственный GRE. Input принимает только remote loopback, output только local loopback, что проверено также отсутствием других BGP routes.

Browser отчёт, ПК, 320px просмотрен: received1, Router ID198.18.192.2, unknown transmitted/active counters не выдуманы. Настоящие deployed API, без mocks. В URL сохранены server/state=Established/q собственного имени/session. RouterOS readonly session cache может сохранять старые строки, поэтому UI fixture отфильтрована по текущему имени и Established.

Оснастка/границы. Native lifecycle прошёл с первой попытки. Observer90s завершился до начала browser; первая браузерная попытка получила ECONNRESET до страницы. Уже принятые native операции не повторялись: для UI создана отдельная такая же пара, ожидание180s, после4 cases cleanup. Это две отдельно обозначенные фазы, не один общий snapshot. Правила подтверждены BGP и Routing Filters.

Контроль/фиксация. На каждой фазе exact ID/name/comment/chain/list/address/interface preflight; свои connections→instances→filter rules→address list/IP/bridge/GRE удалены. Исходные IDs8 коллекций×2 совпали, default/public/195.195.195.195/32 сохранены, оба CHR доступны, пароли не менялись. Product/source/dependencies не менялись, build/миграций/широких регрессий нет. Runtime backend diagnostics89/PG healthy, frontend ospf91; временных контейнеров не осталось. Один локальный commit без push.

Квота95% использовано после блока. Следующий93 — отдельный BGP loss/alternate-path сценарий и сведение остаточных внешних ограничений; начать со свежего лимита. Не приняты multi-peer/WAN policy failover, IPv6/scale/maximum throughput/Portal SSO/physical disconnect/durable retry и ранее перечисленные внешние границы IPsec. Этап12.5 целиком не закрыт.

12.5.93 — BGP/BFD: потеря основного GRE и резервный путь (2026-10-10)

Два собственных eBGP пути между CHR: primary GRE поверх public WAN и alternate GRE поверх собственного WireGuard. Различные GRE outer endpoints исключают неоднозначность демультиплексирования. Link198.18.94.0/30 и95.0/30, WG96.0/30/UDP59993, loopbacks198.18.194.1/32↔2/32, AS65094/65095. Каждая input/output chain принимает только соответствующий exact /32; output.network содержит один собственный адрес, default-originate=never/network-blackhole=no. Local preference200/100 задаёт основной и резервный путь; BGP use-bfd=yes, BFD200ms×3.

Проверка Результат
Начальное состояние 4 Established, 4 BFD Up, по2 BGP route одного собственного /32; active через primary
Потеря пути Отключён только собственный primary GRE наCHR1; BFD primary неUp, BGP primary неEstablished, active через alternate на обоих CHR
Production API Alternate Established/prefixesRx1×2; после возврата4 Established/prefixesRx1
Связность Финальный Ping3/3 в обе стороны в primary/alternate/recovered-primary
Возврат Primary восстановлен и снова выбран по local preference
Очистка Собственные exact IDs/атрибуты удалены; исходные11 коллекций×2 совпали

Native/API/cleanup отчёт. Первый initial Ping наCHR2 дал2/3, следующий3/3; отказавшая попытка сохранена, бесшовность не заявлена. В остальных пяти steady-state направлениях3/3 с первой попытки. Непрерывный Ping во время отказа не запускался, чтобы длинный native REST RPC не искажал control observations. ACK отключения30,6ms; первый завершённый snapshot BFD неUp/primary неEstablished/alternate active —641,8ms от начала PATCH. Это верхняя граница наблюдения с задержкой REST, не точное событие/гарантия600ms/SLA. При деградации API оставляет primary state=Unknown, когда RouterOS не сообщает конкретное состояние; Idle не выдуман.

Сценарий прошёл с первой попытки, без browser повторения уже принятого92 UI; product/source/build/миграции не менялись. Runtime backend diagnostics89/frontend ospf91, backend/PG healthy, только3 compose containers, compose config passed. Default/public/metadata/195.195.195.195/32 и credentials сохранены, оба CHR доступны. Нативные private keys не записывались; проверка заданных sensitive JSON keys прошла. Свои connection→instance→filters/address-list/BFD→IP/bridge/GRE→WG peers/interface удалены, после обоих устройств дождались route convergence.

Правила подтверждены MikroTik BFD, BGP selection и Routing Filters. Один public WAN у каждого CHR: это failover двух логических путей, не независимых физических каналов. Hold-timer безBFD, потеря пакетов в переходе, IPv6, scale, WAN policy, sustained BFD-only gate и ранее перечисленные внешние ограничения остаются открытыми.

Следующий94 — свести актуальную матрицу внешних ограничений и согласовать текущие указатели документов. Пятичасовая квота4% использовано после native блока; этап12.5 открыт. Один локальный коммит без push.

12.5.94 — актуальная матрица и согласование документов (2026-10-10)

Сведены доказательства PG/speed/outbox/VPN/routing/diagnostics после93 в матрицу оставшейся приёмки. Разделены достигнутый результат, непроверенные конфигурации и необходимые внешние зависимости. Указаны известные потери OSPF90, первая потеря Ping BGP93, sustained BFD-only86, AUTH_REQUIRED=false и границы isolated JWT. Принятые тесты не повторялись, native writes/сообщений/build0.

Текущие верхние указатели плана/протокола и таблица runtime паспорта исправлены: они ранее ещё ссылались на IPsec77/routing83. Исторические датированные записи сохранены. Следующий95 — полный source/build-context drift audit до новой общей регрессии; затем timezone/ограниченный disconnect speed96. Telegram/Portal/OS/WAN/multi-instance остаются отдельными внешними условиями. Локальные ссылки новой матрицы и датированные заголовки проверены; один локальный коммит без push.

12.5.95 — полнота Docker contexts и compiled backend (2026-10-10)

Отчёт сверки, local HEAD9d6cd00. Проверены902 unique tracked application/build inputs с учётом Docker COPY. Frontend515 совпавших файлов, backend405; common contracts/lockfile проверены в обоих contexts. Производственные TS/TSX/JS/CSS/public/config/migrations не отстают от текущих файлов. Исключения явно разобраны: frontend package workspaces безbackend; backend stripped root dependencies/scripts; отсутствующий .dockerignore в очищенном frontend context; recursive-routes.test.ts без позднего as const (тест исключён backend tsconfig). Эти исключения не требуют нового deployment.

Локальный contracts/backend production build passed. Дополнительно SHA980 emitted backend/contracts files сверены с реальным запущенным контейнером: missing0; после явной CRLF→LF нормализации different0. При raw byte сравнении10 JS файлов отличались переносами внутри multiline strings; байтовая идентичность не заявлена. Image IDs подтверждены docker inspect: backend97c1cff01efd…/frontendb4bade515234…, labels diagnostics89/ospf91 — названия блока, не Git SHA.

Для frontend подтверждён сохранённый build context/lockfile/config и текущий image ID; compiled frontend не пересобирался и не заявлен independently reproducible. Ранее принятые build/live proofs91 остаются основанием его поведения. Secrets/env не копировались, native writes/fixture/сообщений/deploy0. Повторный frontend build и широкая регрессия при отсутствии source drift не нужны. Следующий96 — remaining speed timezone/контракт времени, затем ограниченный transport disconnect при возможности безопасного окончания native test. Локальный коммит без push; этап12.5 открыт.

12.5.96 — speed history: одинаковый instant в трёх часовых поясах (2026-10-10)

Native/SQL/API, live browser. Настоящий compiled production speed route/service/MikrotikClient и PG, один accepted TCP transmit3s1→2 с cap10Mbit/s на обоих native tx limits. Только cap добавлен тестовой оснасткой в команду, HTTP/native responses не подменялись. Production API cap не добавлялся; это функциональная проверка времени, неbenchmark. ProbeId отсутствует, существующие snapshots не изменялись.

POST result.createdAt, SQL created_at и production GET истории совпадают до миллисекунды. Instant фиксируется перед after-ping, после ответа bandwidth и3s ожидания; это не время начала bandwidth. Backend UTC; live browser UTC/AsiaNovosibirsk/AmericaLosAngeles×1280/320 =6/6: один instant, соответствующее местное время, корректная смена календарной даты, reload/document fits/pageerror0; UI native POST0. Миллисекунды не показываются в ячейке, но API не теряет их.

Две предварительные попытки завершили native тест, но остановились в fixture: лишнее требование Ping0% при фактических25% и Date.parse(Date) с потерей ms. Исправлены только тестовые условия/getTime; реальные timestamp продукта не менялись. Три коротких capped native команды всего, принятый итоговый Ping сохранён в отчёте; успешные browser/native checks повторно не выполнялись. Все три own history IDs удалены, исходный список истории сохранён; процессов/fixtures не осталось, аккаунты/RouterOS конфигурация не менялись.

ROS-10 принят для текущей версии POST/GET и перечисленных timezone; legacy receipt безcreatedAt сохраняет прежний отдельный fallback. Source/build/deploy0. Следующий97 — реальный обрыв HTTP receipt bandwidth-test через локальный relay, без изменения устройств и с независимым наблюдением короткого native завершения; не заявлять это physical WAN loss или auto cancellation. Квота15% использовано, этап12.5 открыт. Один локальный коммит без push.

12.5.97 — реальный обрыв HTTP receipt bandwidth-test (2026-10-10)

Native/SQL/cleanup, live browser. Собственная disabled speed-проба с явно синтетическим прежним snapshot42/17Mbit/s/Ping15ms/0% для проверки сохранения. Actual compiled speed route/service/MikrotikClient/PG; source client направлен через локальный HTTP relay, destination/account/RouterOS не менялись. Relay передал настоящую TCP transmit3s команду с native cap10Mbit/s и через100ms после отправки закрыл receipt socket. Independent upstream продолжил читать ответ и подтвердил done testing; это реальный HTTP socket disconnect после отправки, не подмена ответа/throw вместо сети.

API502, history error/TXRX/Pingnull, probe error с прежними42/17/15/0; nativeCount1/noauto retry. App не получила доказательство завершения и не записала done, хотя relay независимо видел успешный native конец. UI2/2 на1280/320: error history/reload/document fits/pageerror0, API сохраняет старые snapshots; UI command POST0. Визуальное отображение card metrics отдельно не утверждается этим read-only сценарием.

Свои history/probe exact IDs удалены, исходные списки совпали, только3 compose containers/backend/PG healthy. Один короткий capped native запуск с первой попытки, без RouterOS configuration/account changes/build/deploy. Native команда не отменялась; physical WAN failure/abort/multi-instance locks не приняты. Lab AUTH_REQUIRED=false, rights не проверялись повторно. HTTP ошибка приложения не доказывает failure native команды.

Обнаружено оставшееся UX ограничение: timeout/socket message техническая и не объясняет неопределённость native результата. Следующий98 — единый понятный transport error для HTTP/history, профильные tests и один backend build/live повтор только изменённого message path; затем общая регрессия на согласованном runtime. Этап12.5 открыт. Один локальный коммит без push.

12.5.98 — понятный неизвестный результат теста скорости (2026-10-10)

После реального lost receipt97 техническое сообщение заменено единым speedRunErrorMessage для HTTP и сохраняемой истории: «Результат теста скорости неизвестен: ответ устройства не получен. Проверьте его состояние перед повторным запуском». Timeout/socket hang up/ECONNRESET не означают доказанный native failure. Известный отказ авторизации и остальные конкретные ошибки сохраняются; неизвестное сохранение PG остаётся отдельным outcome=unknown/runId. HTTP502/history error означают ошибку получения результата приложением; schema/status/автоматический retry не расширялись.

Проверки. Speed-test HTTP validation/persistence/RBAC и дополнительные3 transport cases/известная auth error passed; локальный contracts/backend production build и scoped ESLint passed. Service иroute используют один formatter. Deployment: одна Docker backend сборка из context diagnostics89 +3 working-tree files, package/lockfile неизменны, production tsc/entry/node --check/pg_restore18.6/compose --wait passed. Runtime backend ux-speed98/version1.0.0-test.speed98/image779b0fc010c9…; frontend ux-ospf91 прежний. Label speed98 — блок, не Git SHA. Приватный .env backup сохранён; обновлён только BACKEND_IMAGE_TAG.

Native/API/PG и browser: повторён только изменённый receipt path, одна capped10Mbit/s TCP3s команда, реальное закрытие socket после передачи, native independently done, API/history содержат новое сообщение; прежние синтетические42/17/15/0 сохранены, native1/noauto retry. Live1280/3202/2, сообщение видно в probe card, reload/document fits/pageerror0/UI command POST0. Свои disabled probe/history удалены, исходные IDs совпали, только3 compose containers/backend/PG healthy; RouterOS/credentials не менялись.

При согласовании указателей94–97 обнаружено, что массовая замена также затронула исторический абзац77 в плане/протоколе. Восстановлен точный абзац из40f730b, история/дата2026-10-09 сохранены; следующие обновления ограничены текущими указателями. Следующий99 — одна общая backend/main/context регрессия на текущем source, с восстановлением исходных доказательств, затем итоговая сводка. General backend/main runs уже запущены, их результат этим блоком не заявлен. Квота23% использовано; этап12.5 открыт. Один локальный commit без push.

12.5.99 — общая регрессия и live обзор (2026-10-10)

Сводный отчёт. Main1207 passed/1 failed/0flaky/0skipped,39min: единственный сбой large-ospf-routes.spec.ts44 — backbone перекрывается pinned CIDR180px при320px/max horizontal scroll. Полныйmain выполнен один раз на неизменённом frontend до101; исходный failure сохранён. Исправление101 выравнивает последнюю область вправо, сохраняя широкий/целый CIDR. Delta5/5: failed large scenario +4 CIDR sizes; весьmain не повторялся и не переобозначен1208 passed.

Context221/221/0flaky/0skipped,7,6min на frontend101 working source/local switching config. Backend после общей transport правки100:24 npm groups/171 node:test cases плюс console assertion scripts/exit0; недоступный fixture DB URL гарантировал отсутствие внешних DB writes. Main/context используют API mocks, port3100/3101 и недоступный upstream; это не native/Portal приёмка. JSON hashes и точные границы в отчёте.

Live обзор до101:30 routes×1280/320=60, HTTP200/route errors0/pageerror0/document overflow0. Два automatic read-only OSPF preview POST; apply/mutations0. Scoped default-dark axe выявил10 нарушений; светлая тема дополнительно выявила sidebar subtitles/HR badge. Исправление и отдельная live20 приёмка101 следуют отдельно; общий обзор не назван полной WCAG сертификацией.

493 исходных evidence files защищены,120 перегенерированных main/mock files возвращены к исходным bytes; прежние чужие GRE/VXLAN screenshot changes сохранены, новые live proof/screens имеют отдельные имена. Удалён один exact duplicate12.5.21 изтрёх журналов, первая запись/дата2026-10-08 сохранены. Numbered records имеют даты, пропусков до100 нет. Source/context/compiler checks101 и поздние API bounds описываются отдельно. Один локальный commit без push; внешняя12.5 остаётся открытой.

12.5.100 — RouterOS: обрыв тела HTTP ответа больше не зависает (2026-10-10)

У ClientRequest и IncomingMessage разные error events. После получения headers частичный ответ не вызывал request error/end; запрос оставался pending даже после500ms timeout. Изолированная проверка воспроизвела6 failures по deadline1200ms для GET/POST/PUT/PATCH/DELETE/raw file reading; полныйsuccess/401 проходил. Добавлен общий watchRosResponseFailure на aborted/error во всех6 paths, очистка timer и существующий settle/AbortSignal cleanup дляPOST. Partial response отклоняется как ECONNRESET, без выдуманного ACK и повторных writes. Две прежние read-only file compatibility стратегии сохранены.

Протокол: после изменения7/7 включая complete success/401, probes.cancel/actual HTTP AbortSignal и byte file parser passed. Тест включён в test:ros-file. Локальный production build, новый test ESLint и Docker build прошли. Исходные2 prefer-const errors mikrotik.ts сохраняются, новые ошибки не добавлены; whole-file lint clean не заявлен. Общая backend регрессия повторена именно из-за изменения общей основы:24 npm groups/171 node:test cases/exit0. Console assertion scripts дополнительно входят в npm suite,171 не заявляется числом всех их assertions.

Live. Native/API/PG, browser. Relay сначала получил actual RouterOS done testing, затем передал headers/первые16 bytes настоящего JSON и оборвал body. Теперь API502/понятный неизвестный результат вместо pending, история/прежний synthetic snapshot42/17/15/0 согласованы. Один capped10Mbit/s TCP3s test, native1/noauto retry, PC/3202/2/new message/reload/document fits/pageerror0. Свои disabled probe/history удалены, original IDs совпали, credentials/configuration RouterOS не менялись. Это controlled HTTP socket loss после headers, не independent WAN failure/cancelled native command.

Runtime. Backend ux-response100/version1.0.0-test.response100/image797979da82d6…; одна сборка изspeed98 +client/test/package-script files, source archive SHA в отчёте. Entry/node --check/pg_restore18.6/compose --wait passed, приватный .env backup; обновлён только BACKEND_IMAGE_TAG, frontend ux-ospf91/dependencies/migrations прежние. Label response100 — имя блока, не Git SHA. Backend/PG healthy,3 compose containers. Одна локальная фиксация без push; main UI99 всё ещё выполняется на неизменённом frontend source, его итог не заявлен. Квота37% использовано. Следующий101 — подтверждённые нарушения контраста/keyboard code после main99, затем context/финальная сводка.

12.5.101 — доступность общей оболочки, текста и OSPF-колонки (2026-10-10)

Поверхность / референс До Доработка
Sidebar / App Shell12 Light muted token на тёмной rail:3,55:1 Subtitle AppSwitcher/NavUser использует sidebar foreground/70, popup style сохранён
Информация / Settings16 Alerts empty text opacity40; enabled badge3,62:1; containers/uptime hints<4,5 Семантические foreground tokens без лишней прозрачности; локальный override badge, общий theme/vendor не менялись
Справка CLI / Settings16 Horizontal pre нельзя достичь клавиатурой 3 named regions/tabIndex0/visible focus; Tab/Shift+Tab/ArrowRight проверены
Filters HR light badge3,28:1; initial API error4,4:1 Existing status-online/offline foreground для этих конкретных элементов
OSPF / Data Grid Filtering2 Last area/backbone за pinned180px CIDR на320px Last-column alignment вправо иtitle полной области; цельный CIDR/пиннинг/сортировка сохранены

Схема: общий context → читаемый status/empty text → таблица с pinned CIDR и доступной последней областью → named code region с keyboard scroll. Структура Frame/base-nova/ReUI Data Grid/Badge сохранена; не установлены новые компоненты, не изменены vendor internals/shared theme. ReUI adapting/quality и MCP Data Grid audit checklist проверены, props/types взяты из установленного API.

Протокол.24 unique accessibility cases:5 sections +Filters503×dark/light×1280/320; violations0/document fit/no writes. Первые4 alerts failures были неверным fixture endpoint(/api/alerts/overview вместо/api/alerts),2 light Filters выявили реальный contrast initial error. Исправлены fixture/локальный error foreground; повторены только alerts/filters12 cases, остальные12 accepted cases не повторялись. Geometry5/5: исправленный failed main OSPF scenario +4 CIDR sizes. Context221/221 из99 работает на101 source, без регрессии source/permissions/checkpoints.

Scoped TypeScript/новые components+test lint passed; старый NavUser set-state-in-effect error подтверждён наHEAD, whole-file clean не заявлен. Одна remote frontend Docker production build/full TypeScript/entry/node --check/compose passed, backend/lockfile/миграции прежние. Frontend ux-a11y101/version1.0.0-test.a11y101/image52b50784b914…; clean context ospf91 +9 source overrides, archive SHA в отчёте, label неGitSHA. Приватный .env backup, изменён толькоMMAPP_IMAGE_TAG.

Live20/20 настоящего frontend/backend безHTTP mocks:5 routes×2 themes×2 widths, axe0/pageerror0/overflow0/API writes0. Сертификатные3 blocks во всех4 combinations доступны Shift+Tab/Tab иArrowRight. Светлая CLI/фокус320, тёмные Filters320 просмотрены; остальные dark certificate/light filters snapshots сохранены. Code screenshot показывает горизонтально прокрученный focused block, его содержимое не обрезано в данных.

Это scoped accessibility delta, не полная WCAG/все состояния/повтор всегоmain. Два CHR/credentials/configuration не менялись, только3 compose containers/backend/PG healthy. Следующий102 — клиент PATCH сейчас принимает nonempty malformed JSON как{}, что может выглядеть ACK; проверить/исправить его без изменения правила empty successful response, затем ограниченная профильная фиксация. Один локальный коммит без push; этап12.5 остаётся открытым.

12.5.102 — malformed PATCH JSON не подтверждает изменение (2026-10-10)

Раньше rosPatch превращал непустой невалидный JSON в{} и мог выглядеть успешным ACK. Теперь возвращает error «Некорректное JSON-подтверждение RouterOS: результат изменения неизвестен» без эха тела ответа. Empty2xx compatibility, нормальный JSON, explicit401, команды/права/метаданные/автоматические retries не менялись. MikroTik REST PATCH описывает updated object как результат успешного изменения; ошибки не следует заменять пустым объектом.

Отчёт: before8 tests/7pass/1fail (PATCH falsely resolved); after8/8. GET/POST/PUT rejection иexplicit empty PATCH сохранены, partial-response6/complete success/401 прежние. IPsec иOSPF optimizer profile suites/локальный backend production build/new test lint passed. Консольные assertion scripts этих suites не переобозначаются произвольным числом node:test cases. Whole backend/main/context не повторялись после одного parser branch; общая100/99 и профили сохраняют свои границы.

Native. Своя GRE pair/private198.18.102.0/30 на двух CHR. Normal PATCH comment вернул actual updated.id/comment. Relay следующего PATCH сначала получил настоящий native200/updated comment, затем отдал downstream malformed JSON200. SDK rejected unknown; независимый GET подтвердил фактически изменённыйcomment. PatchCalls1/noauto retry дляfault path. Это HTTP response fault injection после real write, не реальное повреждение WAN; не заявлена приёмка каждого API mutation handler. До любых writes проверены оба устройства/subnet/отсутствие GRE с такими же outer endpoints. Exact own IDs/name/comment/address/interface cleanup, original3 collections×2 совпали, public/default/metadata/195.195.195.195/32 иcredentials сохранены.

Связность/оснастка. Первый fixture остановился доPATCH на требовании Ping3/3, фактически2/3; cleanup accepted. ACK scenario не требует нулевых потерь: повтор использовал по одному paced Ping3/1s, сохранил фактические1/3/66% наCHR1→2 и3/3/0% обратно; zero-loss GRE не принят. Сетевые потери не скрыты успешным ACK. Следующий103 — read-only native packet rows/public versus own GRE diagnostics, чтобы отличить actual packet loss от неверной интерпретации статистики; BGP hold-timer безBFD отложен до понимания пути.

Deployment. Одна backend Docker production build изresponse100 +client/test, без dependency/миграций; entry/node --check/pg_restore18.6/compose --wait passed. Backend ux-patch102/version1.0.0-test.patch102/image34fca84b8721…; frontend ux-a11y101 прежний. Приватный .env backup, изменён только BACKEND_IMAGE_TAG, labelpatch102 неGitSHA. Только3 compose containers/backend/PG healthy. Один локальный commit без push; этап12.5 открыт.

12.5.103 — native Ping: public и собственный GRE (2026-10-10)

Сырые packet rows/cleanup. Своя GRE pair198.18.103.0/30, доwrites обаenabled CHR доступны/нетконфликтов prefix/outer endpoints.8 bounded native Ping команды по10 пакетов/interval0,5s: initial/settled×оба направления×public/GRE;80 packets всего. После первой серии2s пауза. Сохранены seq/time/status/sent/received/loss/avg-rtt без credential fields, resource version/CPU. Source/runtime не менялся: backend patch102/frontend a11y101.

Путь Initial Settled
Public CHR1→CHR2 10/10 10/10
Public CHR2→CHR1 10/10 10/10
GRE CHR1→CHR2 9/10,1 timeout 10/10
GRE CHR2→CHR1 10/10 10/10

Во всех8 ответах final sent/received соответствуют числу raw reply/timeout rows. В этой серии статистика согласована; счётчики нельзя «исправить», скрыв timeout. Наблюдения102 с1/3 и2/3 не переписаны. Здесь steady sample не выявил устойчивых потерь, но причиной начальных потерь и долгосрочной zero-loss/SLA это не является; startup/transient explanation остаётся гипотезой. Нет packet capture/физическогоWAN теста/максимальной нагрузки.

Exact own GRE/IP IDs/name/comment/address/interface удалены, baseline3 коллекций×2 совпал; public/default/metadata/195.195.195.195/32 иcredentials сохранены. ОбаCHR доступны, native fixtures/extra containers0, build/DB writes/messages0. Следующий104 — собственная BGP пара безBFD, negotiated hold3s/keepalive1s, scoped TCP loss при работающем GRE/ICMP, withdrawal/recovery. Проверка отличает hold expiry от административного connection/interface disable; не обещает точный timing/physical WAN redundancy. Один локальный commit без push; этап12.5 открыт.

12.5.104 — BGP hold expiry без BFD (2026-10-10)

Native/API/cleanup. Собственная GRE198.18.104.0/30/loopbacks198.18.204.1/32↔2/32, AS65104/65105; input/output chains принимают только соответствующий exact own /32, output.network single own loopback/default-originate never. Обаnative connection use-bfd=false, hold3s/keepalive1s; session local/remote hold-time3s иkeepalive1s подтверждены, BFD configurations не создавались.

Две собственные firewall rules только наCHR1: input/output TCP между own GRE link IPs с exact in/out-interface; baseline firewall empty проверен. НиGRE, ниBGPconnection не отключались. Полный underlay остаётся активным, после protocol loss direct GRE ICMP3/3×2/running=true. BGP initially Established/own route/Ping3/3×2; после scoped TCP loss обе сессии перестали быть Established/active own route отсутствует. Снятие двух own rules восстановило Established/own /32/catalog Rx1×2.

ACK добавления двухdrops41,3ms; первое notEstablished наблюдение2667,3ms, обе active routes отсутствуют3690,5ms от начала fault. last-keepalive instant не зафиксирован, samples включаютREST/планирование: это upper observation bounds, не точное hold duration/SLA. Различие с92 административнымdisable/93BFD-path loss сохранено. В этой конфигурации отказ TCP проявился при работающем GRE/ICMP; physical WAN redundancy/разные peers/IPv6/scale не приняты.

Определение hold/keepalive подтверждено официальным BGP connection reference; текущая online docs7.26, наличие свойств/поведение непосредственно проверено на lab7.24.5. Source/UI/build/DB writes/messages0, первая попытка passed. Ownership preflight exact IDs/name/comment/chain/list/address/interface/protocol/src/dst, drops сначала удалены дляrecovery, потом own BGP/filter/address-list/IP/bridge/GRE. Baseline10 коллекций×2 совпал, public/default/metadata/195.195.195.195/32/credentials сохранены, обаCHR доступны. Runtime backend patch102/frontend a11y101, extra fixtures/containers0. Один локальный commit без push.

Следующий105 — заключительный source/context/runtime/evidence контроль окна и точная матрица оставшихся внешних условий. Принятые network tests не повторять без изменения/ошибки. Этап12.5 остаётся открытым.

12.5.105 — source/runtime/evidence: заключительный контроль окна (2026-10-10)

Финальная source сверка, HEADbeb72ce.904 unique tracked application/config inputs: frontend515/backend406 matched; production source drift0. Root package preprocessing/workspaces/clean-context dockerignore идве исключённые backend tests(recursive as const/speed98 assertions) разобраны. Backend984 compiled files actual container совпадают с local build после явнойLF normalisation; byte identity не заявлена. Frontend identified by source context/lockfile/image/build101/live20, independent binary reproducibility не заявлена.

Read-only stand: обаenabled CHR отвечают/RouterOS7.24.5,14 native collections×2 не содержат prefixes объектов этого окна. Own speed history/probes0, servers2/migrations9. Это выборочная GET/SELECT сверка по своим namespace, не full export/universal ownership scanner. Нативные session caches не удалялись.3 compose services running/backend/PG healthy/compose config passed; дополнительных fixture containers нет. Credentials/RouterOS defaults/public/195.195.195.195/32 сохранены в профильных baseline проверках.

Runtime backend ux-patch102/version1.0.0-test.patch102/image34fca84b8721…; frontend ux-a11y101/version1.0.0-test.a11y101/image52b50784b914….13 контрольных блоков93–105; каждый фактический результат сохранён локально безpush. Whole main1207/1208 с исходным failure иdelta5/5, context221/221, backend100 groups24/node171 +parser1028/8/IPsec/OSPF profiles, accessibility24local/20live; это точные границы, не суммарная выдуманная «полная production приёмка». Принятые unchanged tests повторно не запускались.

Все numbered records датированы, no duplicate12.5.21 после exact dedup, progress/stage12 согласованы.120 перегенерированных canonical/mock evidence files восстановлены из493 protected originals, прежние чужие skills/AGENTS/8GRE-VXLANscreens/tsbuildinfo/.codex/.codegraph изменения сохранены.20 новых JSON reports разобраны и проверены по заданным sensitive keys(password/secret/private-key/privateKey/token/authorization/tcp-md5-key): непустых strings0. Это конкретный recursive key scan, не универсальная гарантия secret-free всех артефактов.

Внешняя12.5 открыта: настоящие PortalSSO/Telegram/clientOS/IPv6/WAN policy/scale/multi-instance/durable retry/physical loss идругие условия матрицы не заменяются лабораторными two-CHR proofs. По Telegram отправки0; для real delivery нужны отдельный тестовый бот/чат иявное разрешение на конкретное сообщение. Запрошено наличие Portal/Telegram, зависимые действия не выполнялись. Следующий106 — подготовка внешних интеграций при наличии доступов, иначе отдельные согласованные network/scale bounds. Квота89% использовано при заключительной сверке; новые крупные блоки не начинать без возможностей закончить checks/cleanup/commit. Один локальный commit без push.

12.5.106 — готовность Portal/Telegram без внешних сообщений (2026-10-10)

Read-only отчёт: actual lab authRequired=false, issuerConfigured=true/jwtConfigured=true (только booleans), portalHostname=localhost. Это не настоящий Portal login/проверка ролей/отзыва; JWT value/issuer string не сохранены. Telegram DB tokenConfigured=false/chatConfigured=false, activeRules0. Секреты/chat ID не выводились, API доставки/getMe/login не вызывались, конфигурация/таблицы не менялись, messagesSent0. Helper/pool/container закрыты, основной runtime/3 compose services прежние.

Вопрос о наличии тестовых Portal/Telegram задан пользователю; ответа/разрешения на сообщение пока нет. Реальная приёмка этих веток не заменяется локальными fake sender/JWT checks35–49/89. Следующий107 требует тестовую Portal-конфигурацию/аккаунт и отдельный bot/chat; перед отправкой подготовить конкретное сообщение и получить прямое разрешение. Доступы кCHR/SSH этого разрешения не дают. Остальные clientOS/IPv6/WAN policy/scale/multi-instance/physical failure/durable retry bounds остаются в матрице.

За окно сохранены14 local commits93–106, push0. Backend patch102/frontend a11y101, source904/compiled984 matches, main1207/1208+geometry delta5/5/context221/221/backend171+parser8 profiles/accessibility24local20live вточных границах99–105. ОбаCHR доступны, свои конфиги/DB fixtures очищены, credentials не менялись. Квота94% использовано перед записью; этап12.5 целиком открыт. Один локальный commit без push.

12.5.107 — VXLAN: мост, обучение MAC и восстановление bridge-порта (2026-10-10)

Native отчёт. На обоих CHR7.24.5 создана собственная пара VXLAN VNI160107/UDP51907/MTU1400 с отдельными bridge, фиксированными locally administered MAC и IP198.18.107.1/30↔198.18.107.2/30. Публичный ether1 не добавлялся в мост, исходные routes/firewall не менялись. Все collision/preflight reads завершены на двух устройствах перед записью. Каталог production GET /api/vxlan совпал с native VNI/port/learning/VTEP и без failures.

Initial Ping3/3 и steady Ping10/10 в обе стороны; сохранены реальные packet rows. Удалённый bridge MAC изучен на собственном VXLAN-порту, VXLAN FDB связывает его с правильным удалённым публичным VTEP на каждой стороне. После native PATCH disabled=yes только собственного bridge-порта CHR1 Ping0/3 в обе стороны; интерфейс VXLAN и каталог остаются UP. Это операционный флаг интерфейса, который не доказывает end-to-end связность через bridge. После disabled=no и2s паузы Ping10/10 в обе стороны и FDB подтверждены снова. Нет утверждения о физической аварии, SLA или бесшовности перехода.

Перед удалением сверены exact IDs, comment/name и interface/bridge/address/remote-ip всех собственных объектов. После удаления обеих сторон baseline projection9 коллекций×2 совпала, own bridge hosts/VXLAN FDB отсутствуют. Пароли не менялись, оба CHR доступны. Исходники продукта, DB, Docker runtime и UI не менялись; build/общая регрессия не повторялись. App API остаётся read-only; bridge/FDB/IP не входят в экспорт fragment. Client OS, IPv6 outer, scale, throughput и hardware offload ещё не приняты. Следующий108 — отдельный собственный IPv6 inner сценарий. Квота после проверки: использовано4% пятичасового и62% недельного.

Референс семантики FDB: официальная документация MikroTik VXLAN. Доказательством данного сценария служат независимые native таблицы и Ping, а не только статус каталога.

12.5.108 — VXLAN: IPv6 внутри собственного моста по IPv4-транспорту (2026-10-10)

Native отчёт. Read-only preflight подтвердил IPv6 уже включён на обоих CHR; глобальные настройки не менялись. Собственная пара VXLAN VNI160108/UDP51908/MTU1400 с отдельными мостами и MAC, только IPv6 ULA fd00:108:1::1/64↔fd00:108:1::2/64 на мостах, advertise=no. IPv4 outer VTEP — исходные публичные адреса; IPv6 WAN/outer не тестировался. Никаких новых адресов/bridge-port на ether1, ND/firewall/default routes не менялись.

Initial IPv6 Ping дал0/3 и1/3; packet rows сохранены, причина потерь не установлена. После3s паузы steady Ping10/10 в обе стороны. Native адреса valid/advertise=false, bridge host и VXLAN FDB изучили MAC противоположного моста с правильным remote VTEP. Каталог приложения показывает правильные интерфейсы/VNI/port/learning/remoteVteps без failures. После отключения собственного bridge-порта CHR1 Ping0/3 в обе стороны, интерфейсы остаются UP; после включения и2s паузы Ping10/10 и FDB подтверждены. Initial loss не скрыт повтором и не заменён утверждением о zero-loss startup/SLA.

Exact-ID/marker cleanup вернул baseline projection13 коллекций×2, собственные bridge hosts/FDB отсутствуют; disable-ipv6/forward/accept-router-advertisements совпали с исходными. Пароли прежние, оба устройства доступны. Исходники/DB/runtime не менялись, build/общая UI регрессия не повторялись. Результат подтверждает native IPv6 inner в данной паре; не добавляет IPv6 IP/bridge/FDB в fragment экспорт, не доказывает SLAAC, клиентские ОС, масштаб, IPv6 outer или максимальную скорость. Следующий109 — GRE/WireGuard IPv6 inner по существующему IPv4 outer.

12.5.109 — GRE/WireGuard: IPv6 inner и раздельное восстановление (2026-10-10)

Native отчёт. На обоих CHR создана отдельная GRE пара MTU1400 и WireGuard пара UDP59909/MTU1420. IPv6 ULA fd00:109:1::1/64↔::2/64 на GRE и fd00:109:2::1/64↔::2/64 на WG; advertise=no. GRE outer и WG endpoints остаются исходными публичными IPv4. Ключи сгенерировал RouterOS на собственных WG-интерфейсах; private keys не сохранялись в отчёт/репозиторий. Peer allowed-address ограничен удалённым собственным IPv6 /128, keepalive5s. До записей collision/baseline/IPv6 preflight завершён на обоих устройствах; ether1/глобальные настройки/ND/firewall/routes не изменялись вручную.

Initial результаты: gre/CHR1=0/3, gre/CHR2=1/3, wireguard/CHR1=3/3, wireguard/CHR2=3/3. Все реальные packet rows сохранены. После3s паузы steady IPv6 Ping10/10 в обе стороны каждого типа, valid native адреса и WG handshake/rx/tx>0 подтверждены. Последовательно отключены только собственный GRE интерфейс CHR1 и собственный WG peer CHR1: соответствующий Ping0/3 в обе стороны, второй туннель в каждой фазе продолжает передавать3/3. После включения и3s паузы recovery Ping10/10 в обе стороны каждого типа. Измерение переходного loss/SLA/максимальной скорости не выполнялось.

Production aggregate GET /api/gre/tunnels и /api/wireguard вернули собственные интерфейсы без failures; WG allowedIps сохранил native IPv6 /128, privateKey не возвращён. Ограничение обнаружено и зафиксировано: CHR1: GRE localInnerIp="", WG address=null; CHR2: GRE localInnerIp="", WG address=null. Текущие GRE/WG readers получают interface addresses из /ip/address, поэтому native IPv6 адрес не попадает в это поле. Эти проверки не принимают IPv6 создание/restore/history/export через приложение и не расширяют его API. Поддержка полного IPv6 управления требует отдельной согласованной модели адресов и миграции snapshots.

Перед очисткой exact IDs/markers и immutable reference fields сверены; собственные peers/IPv6 addresses/interfaces удалены. Baseline projection13 коллекций×2 и7 исходных параметров IPv6 settings совпали. Пароли прежние, оба CHR доступны. DB/runtime/исходники продукта не менялись, повтор build/общей UI регрессии не требовался. Открыты IPv6 outer/client OS/scale, application IPv6 address lifecycle и остальные пункты матрицы. Следующий110 — IPsec complex/escaped DN с собственной сертификатной парой и контролем online identity; внешние Portal/Telegram требуют настоящей настройки.

12.5.110 — IPsec: полный DN сертификата и достоверный online (2026-10-10)

Исправлена реальная ошибка: собственная IKEv2 certificate сессия на двух CHR7.24.5 established/получила198.18.110.250, но production каталог показывал клиента online=false. Сначала воспроизведён DN с country/organization/unit и comma/plus/equals вCN; затем полный subject с state/locality/кавычками/обратным слешем. RouterOS печатает строку без экранирования: C=US, S=New York, L=Albany, O=Example, Ltd, OU=QA+Operations, CN=... Поэтому не используется CN substring или общий RFC4514 parser. Новый ipsec-certificate-dn.ts строит точную полную строку из известных метаданных; ipsec-live.ts сравнивает весь subject, считает collisions по rendered string, не выбирает одну из одинаковых active IDs и требует уникальный CN для прежнего bare-CN fallback. Подсчёт subject/CN выполняется один раз на снимок. Выбор matched identity, сетевые операции, PKI, секреты, API DTO и UI-компоненты не менялись.

Проверки: профильный test:ipsec (8 скриптов) passed; финальный state набор89/89, включая иной organization, одинаковые сертификаты, разные attribute tuples с одинаковой неэкранированной строкой, duplicate active ID и control characters. Backend/contracts production TypeScript build, ESLint трёх изменённых файлов и diff check passed. Source manifest: base audited build-patch102 context +3 working-file overrides отHEAD1d61b50; context hashes3/3 и runtime compiled byte hashes2/2 совпали. Это не полный повтор audit всех production inputs. Docker backend ux-dn110/version1.0.0-test.dn110, imagesha256:f0cd7afc7391ac463c8b3c7d183b0c294f01ffca6beda3d240d26bec59c06d72, label dn110 — stage marker, неGitSHA. Entrypoint/node check и pg_restore18.6 passed; приватный pre-dn110.env сохранён, прежний backend image остаётся для rollback. Backend/PG healthy; frontend ux-a11y101 unchanged/HTTP browser passed.

Полный протокол сохраняет7 preliminary native failures: два неподдерживаемых параметра fixture (comment вprofile и address-prefix), затем auth failures сложного/простого control. Причина тестовой конфигурации выявлена по my auth size0: import присвоил client иCA одинаковое имя. Их переименование по exactIDs в разные имена восстановило handshake; исправление trust собственногоCA/source address само по себе не устраняло дублирование. Все preliminary cleanups passed. Эти отказы не приписаны продукту и не заменены успешным итогом. Два успешных native before-fix воспроизведения доказывают именно ошибку online. После deploy полныйDN established, native lease и application online/activeAddress совпали.

Live UI4/4:1280/320px×dark/light, URL выбранногоCHR, правильный online address, reload, page overflow0/JS errors0/application writes0. Первый помощник неверно использовал storage key theme; его4 cases не принимаются как две темы. В повторе возник detached read-only locator при refresh; helper ограниченно заново находит элемент, никакие mutations не повторяет. Финальный запуск использует rl-theme и проверяет root class; скриншоты actual dark/light сохранены, два размера/темы просмотрены. Frontend/shared ReUI/Frame/base-nova не менялись, общая UI регрессия не повторялась.

Собственные CA/server/client certificates, импортированные сертификаты, peer/identity/profile/proposal/group/template/mode-config, export/upload files и временные logging rules удалены после exact-ID/name/comment/prefix preflight. Baseline13 коллекций×2 совпал, включая logging/certificates/files/IP/routes/NAT; default/metadata/public routes и исходный195.195.195.195/32CHR2 сохранялись. Private P12/PEM/pass files удалены из helper-каталога, private keys/пароли не записаны в репозиторий. В приложении использовался aggregate GET /api/ipsec без observed revision write; tests DB не меняли. ОбаCHR и SSH доступны, пароли не менялись.

Границы: это сопоставление подтверждённой native сессии для данного формата RouterOS7.24.5, не общая DN/ASN.1 библиотека и не новая проверка encrypted data plane (77–82 остаются источником). Custom OIDs/другие форматы и IKE ID namespaces, клиентские ОС, полнаяPKI/policy-profile-proposal restore/IPv6/scale открыты. При неоднозначном rendered subject адрес не приписывается одному из клиентов. Следующий111 — нестандартные IKE ID и границы сопоставления сертификатных сессий; внешние интеграции всё ещё требуют настройки. Квота после live-блока: использовано33% пятичасового/67% недельного (значение до финальной записи).

Референс семантики certificate ID: официальная документация MikroTik IPsec; фактический формат S/порядок/символы подтверждён native отчётом выше.

12.5.111 — IPsec: буквальный CN, чужой DN и явно настроенный FQDN ID (2026-10-10)

Исправлены две ошибки атрибуции. При одном native active-peers.id=CN=alice приложение могло пометить online также сертификат с буквальным common-name=CN=alice. Bare-CN fallback теперь не используется, если эта строка совпадает с полным subject другого сертификата; full-DN match имеет приоритет. Для common-name=key-id:alice прежний findActive удалял type prefix и приписывал ему сессию alice. Буквальный CN теперь сравнивается буквально через exact lookup; нормализация key-id/fqdn/user-fqdn/address сохраняется только для явно настроенного identity.remote-id. Сетевые операции, certificate auth/PKI, DTO, UI и ReUI компоненты не менялись.

Red-before state test остановился на ложном online; после исправления state96/96. Семь новых assertions проверяют DN-looking CN, typed-looking CN, сохранение literal exact match, нормализацию explicit fqdn и отказ unsupported prefix. Полный test:ipsec (8 скриптов), backend/contracts production TypeScript build, ESLint двух изменённых файлов и diff check passed. Дополнительно actual compiled mapper ux-dn110 на synthetic alice/key-id:alice показывал обоих online; compiled ux-id111 показывает только alice. Это проверка mapper с подставленным снимком, не native допуск данного typed-looking CN как IKE ID.

Native before/after: на собственных CHR7.24.5 созданы CA/server/client сертификаты и второй signed client certificate с common-name=CN=<имя первого>. Второй сертификат не экспортировался/не использовался инициатором; server identity строго ссылается на первый remote-certificate. На ux-dn110 native одна established сессия/адрес198.18.111.250, каталог давал online=true/тот же адрес обоим сертификатам. Эта red-attempt и её successful cleanup сохранены. После deploy ux-id111 тот же сценарий даёт только original online и decoy offline/без activeAddress.

В той же собственной паре отдельно подтверждён explicit certificate FQDN ID: подписанный original cert имеет SAN DNS:<имя>.example; initiator my-id=fqdn:<имя>.example, responder remote-id=fqdn:<имя>.example. Отключён/включён только собственный client peer для нового handshake. Native established id содержит bare DNS value, lease198.18.111.250, production catalog originalOnline=true/decoyOnline=false. Это reserved test name в сертификате/ID, внешние DNS endpoints не использовались. Не утверждается независимый data-plane/throughput/SLA тест.

Live UI4/4:1280/320×dark/light с проверкой actual root class; original online address, decoy offline/без чужого адреса, reload, no page overflow, pageErrors0/applicationWrites0. Свежие скриншоты сохранены; desktop light просмотрен. Helper повторно находит только read-only locator при refresh, mutations не повторяет. Frontend ux-a11y101 прежний, общая UI регрессия не повторялась.

Source/runtime manifest: build-id111 из audited build-dn110 +2 working overrides отHEAD2aa93ad, context byte hashes2/2 и changed compiled mapper byte hash совпали. Backend mmapp-test/backend:ux-id111/version1.0.0-test.id111/imagesha256:e9a5cf65433ed77b8c67991a556f3863a0e9609411a0e3e58d39463323c65414; labelid111 — stage marker, неGitSHA. Одна backend build, entrypoint/node check/pg_restore18.6/Compose wait passed; приватный pre-id111.env сохранён, прежний image доступен для rollback. Backend/PG healthy, frontend unchanged/HTTP/browser passed; миграции и DB test rows не создавались.

Обе native attempts сравнили baseline13 коллекций×2 после удаления собственных сертификатов, imported chain с уникальными именами, peer/identity/profile/proposal/group/template/mode-config/files. Cleanup passed, logging/default/public/metadata routes и исходный195.195.195.195/32CHR2 сохранены; passwords прежние, SSH/обаCHR доступны. Private P12/PEM/pass files удалены, приватные ключи/секреты не сохранены в evidence. Native helpers используют aggregate GET /api/ipsec, не selected observed-revision write.

Границы: shared configured Remote IDs, aliases нескольких identity/PSK с одинаковым bare value, arbitrary IKE ID types, custom DN/OIDs/client OS/full PKI/restore/IPv6 остаются открытыми. Этот блок принимает два конкретных CN fallback нарушения и одну real explicit-FQDN certificate сессию; не закрывает всю12.5. Следующий112 — коллизии configured Remote IDs между identity/PSK и безопасная атрибуция в этих случаях.

12.5.112 — IPsec: неоднозначные certificate/PSK Remote ID и понятный статус (2026-10-10)

Исправлена подтверждённая ошибка: одна реальная established сессия с bare FQDN ID и адресом198.18.112.250 учитывалась как два online-клиента — certificate с remote-id=fqdn:<имя>.example и PSK identity с remote-id=key-id:<имя>.example. В native снимке, используемом reader, нет подтверждения отдельной связи этой сессии с одним из этих двух catalog rows. Backend теперь собирает claims на каждый observed session object и при нескольких видимых владельцах не выбирает пользователя: online=false как «не подтверждено», sessionAmbiguous=true, activeAddress/activeSince удалены. Конфигурационные staticIp/Remote ID/IDs сохраняются; сетевые операции и допустимые конфигурации не запрещаются.

В @mmapp/contracts добавлены optional sessionAmbiguous и summary clientsSessionAmbiguous. Старые DTO остаются совместимыми; contradictory ambiguous+online/activeAddress/activeSince отвергается вместо ложного успеха. Summary clientsOnline — число подтверждённых строк, которое сопровождается ambiguous count. UI показывает «Не определено», пояснение Remote ID и «—» в KPI онлайн; карточка сервера подписывает число подтверждённых клиентов и неопределённых статусов. Это не offline и не ноль фактических сессий. Skill ReUI применён reuse-first: существующие Frame/KpiStatGrid/grid/Alert/semantic tokens, без vendor/theme/registry изменений. Source consumers изменены только для достоверного состояния данных.

Проверки: state102/102, test:ipsec8 scripts, backend/contracts TypeScript build и ESLint7 изменённых файлов passed. Первый локальный E2E startup не уложился120s, параллельный tsc увидел незавершённые generated .next route types. Старый dev cache перемещён в проверенный workspace tmp backup, пользовательские процессы/файлы не удалялись. Повтор E2E14/14 (data/freshness/layout,38.7s) passed; после добавления проверки server card только2 изменённых cases повторены (8.6s). Это14 unique accepted, не16 разных сценариев. Scoped source TypeScript passed с исключением generated cache; обе production builds отдельно прошли full build type-check. E2E проверяет unknown без offline/чужого IP, recovery и сохранение last-good при противоречивом DTO. Общая регрессия не повторялась.

Native before/after/recovery: собственная certificate FQDN/SAN пара, неиспользованный DN-looking CN certificate и дополнительная собственная PSK identity с другим typed prefix/тем же bare ID и отдельным mode-config198.18.112.251. На ux-id111 каталог присваивал одному native ID адрес198.18.112.250 обеим configured rows/clientsOnline2. Red-attempt и successful cleanup сохранены. На ux-alias112 две строки ambiguous, без active address/since; total3/confirmedOnline0/ambiguous2, third unused certificate остаётся offline. Native сессия established сохранялась. После exact-owner удаления только PSK identity/mode-config original снова online/198.18.112.250, sessionAmbiguous отсутствует; никаких автоматических network retries/rollback не добавлено.

Live4/4:1280/320×dark/light, actual root theme, unknown two rows/online KPI, unused certificate offline, reload, pageErrors0/no page overflow/applicationWrites0. Сначала functional4 cases прошли, но визуальная проверка обнаружила frontend vdev: APP_VERSION не тот build arg. Frontend пересобран с NEXT_PUBLIC_APP_VERSION=1.0.0-test.alias112, tag ux-alias112-version. Финальные4 cases повторены на этом image, desktop header version явно проверен; mobile header скрывает версию, отдельный version check там не заявлен. Скриншоты обновлены, light desktop/dark320 просмотрены. Preliminary functional/native result и ошибка версии не скрыты.

Source/runtime manifest: backend context build-id111 +3 overrides, frontend build-a11y101 +4 overrides, общий contracts source;7 context byte hashes совпали, compiled backend mapper/contracts hashes2/2 совпали с контейнером. BaseHEAD7815e00 +working changes, labelalias112 неGitSHA; полный905-input audit/reproducible frontend binary не заявлены. Backend imagesha256:03e110dd414b575ad9a8f13f7b0302f241dbd3e439418c8ad1bbca7dc1c6fc9c, final frontend imagesha256:4bf4cad8b3c990a7259f84cf27fd6bb9ee34e3db904223b559c0559dbbe094a2; обе app versions1.0.0-test.alias112, backend/PG healthy, frontend running/HTTP/UI passed. Entry/node checks/pg_restore18.6 passed, приватный pre-alias112.env и старые images оставлены для rollback. Frontend построен дважды из-за исправления version arg; backend — один раз. DB migration/schema changes отсутствуют.

После обеих accepted runs удалены exact own IDs всех certificates/imported chain, peer/identity/profile/proposal/group/template/mode-config/export/upload files; private P12/PEM/pass файлы удалены. Baseline13 коллекций×2 совпал; logging/default/metadata/public routes/195.195.195.195/32 сохранены. Helpers используют aggregate GET /api/ipsec без observed revision writes, secrets не записывались в Git. ОбаCHR/SSH доступны, пароли прежние.

Границы: новое состояние относится к нескольким видимым clients, претендующим на одну observed сессию. Несколько native sessions с одинаковым ID, один certificate с несколькими identity refs, arbitrary ID types/custom OIDs/полнаяPKI/restore/client OS/IPv6 остаются отдельными пунктами. Следующий113 — эти две границы атрибуции одним профильным блоком;12.5 целиком открыт. Квота перед финальным блоком: использовано68% пятичасового/72% недельного.

Референс Применённая схема
ReUI Stats12 Native ID → claims → подтверждено либо «—»
ReUI Filtering2 Контекст устройства → статус «Не определено» → пояснение → проверка Remote ID

12.5.113 — IPsec: несколько сессий одного клиента без ложного офлайн (2026-10-10)

Исправлен mapper: ранее повторяющиеся established active-peers.id удалялись из индекса целиком, и даже единственный соответствующий клиент выглядел офлайн. Теперь индекс сохраняет группу сессий. Единственный клиент с совпадающим ID получает online=true; activeAddress/activeSince выдаются только при одной established сессии. При нескольких сессиях reader не выбирает произвольный lease/uptime. Claims считаются на группу: если её разделяют разные catalog clients, у них sessionAmbiguous и нет подтверждённого online/адреса, как в112. Начальные/завершающиеся сессии не подтверждают online.

Изменены backend/src/services/ipsec-live.ts, ipsec-state.test.ts и tests/e2e/ipsec-data.spec.ts. Контракт и существующие компоненты ReUI не менялись: таблица уже показывает «онлайн» без адреса. Проверены certificate/PSK, перестановка native rows, конфликт aliases, переход несколько→одна→нет established сессий. State108/108; все8 профильных скриптов, backend build, ESLint прошли. E2E16 unique passed33.6s: два новых сценария1280/320 и прежняя профильная регрессия IPsec.

На стенд собран/развёрнут только backend ux-sessions113/version1.0.0-test.sessions113. Source base cb6ec09/context build-alias112 плюс один явный override; source и compiled ipsec-live.js SHA256 совпали с локальными байтами. Label sessions113 не является Git SHA. Frontend ux-alias112-version/version1.0.0-test.alias112 сохранён, backend/PG healthy; у frontend нет healthcheck, подтверждены HTTP/browser. Rollback .env сохранён privately как pre-sessions113.env, прежний образ оставлен.

Оба CHR прошли реальный fetchIpsecState, aggregate GET /api/ipsec вернул200 без failures. В собранном reader проверены контролируемые snapshots с повторяющимися ID и aliases на базе прочитанных состояний; это НЕ создание нескольких реальных IKE подключений. Каталог live пустой: browser smoke1280/320 проверил API, пустое состояние, отсутствие ошибки и overflow; pageerrors0/APIwrites0. Первый browser запуск получил ECONNREFUSED: прежний localhost туннель отсутствовал; восстановлен согласованный SSH forward3000/8000, повтор passed. RouterOS writes0, acceptance DBwrites0, тестовых сетевых объектов не создавалось; пароли прежние.

Протокол: ipsec-multiple-sessions. Следующий114 — один сертификат с несколькими identity refs: текущий last-reference-wins ещё не исправлен, нужно проверить представление строк и выбор target для мутаций. Одновременные реальные подключения с одним ID, внешние интеграции, client OS, полнаяPKI и итоговая общая регрессия остаются отдельной приёмкой.

Референс Схема
ReUI Filtering2 ID → группа established → один клиент «онлайн» / разные клиенты «Не определено»
ReUI Stats12 Несколько сессий → один подтверждённый клиент → сводка без двойного счёта

12.5.114 — IPsec: общий сертификат, разные identity и безопасный target (2026-10-10)

Устранён last-reference-wins: mapper хранит все ссылки на remote-certificate и выдаёт отдельную строку для каждой identity. У каждой строки свой identity:, имя, peer, Remote ID, mode-config/static IP. Сертификат без ссылок сохраняет cert:. Общая observed сессия не присваивается двум строкам: sessionAmbiguous и «Не определено»; независимые explicit ID проверены отдельно. Перестановка native identity rows не меняет состав/поля каталога.

Resolver помечает запрос по certificate target как неоднозначный при нескольких refs, поэтому PATCH/DELETE не выбирают первую identity. DELETE identity с removeCertificate=true проверяет другие identity/peer refs до первого удаления и возвращает409. Явный removeCertificate=false допускает удаление выбранной identity с сохранением сертификата; локальный HTTP тест подтверждает один delete/историю и отсутствие других writes. Интерфейс пока не предлагает этот отдельный вариант — следующий115 должен сделать его понятным. Прямой endpoint принудительного удаления сертификатов не менялся.

Изменены backend services/ipsec-live.ts, routes/ipsec.ts, state/mutation tests и UI HTTP fixture. Контракт и компоненты ReUI/base-nova не менялись; существующая таблица принимает отдельные DTO rows. State114/114, все8 профильных скриптов, backend build и scoped ESLint passed. E2E18 unique/35.9s: две новые проверки общего сертификата1280/320 плюс профильная регрессия.

Before на backend113: native established с адресом198.18.114.250, две certificate identities, но каталог сохранил только вторую и присвоил ей адрес; первая отсутствовала. After на ux-refs114 обе строки присутствуют и unknown без активного адреса, конфигурационные250/251 сохраняются. Certificate PATCH/DELETE и identity DELETE с общим сертификатом вернули409. PATCH выбранной identity при одинаковых match-by=certificate условиях вернул502 с native400 «a matching identity already exists»; обе identity остались неизменными. Это ограничение RouterOS, успешное редактирование одновременно существующих идентичных match rules НЕ принято. После удаления собственного дубля исходная identity восстановила online/250; её API PATCH имени и возврат исходного имени дали200, native readback совпал. Два успешных PATCH вызывают запись истории с dedupe; число вставленных revisions отдельно не заявляется.

Live browser4/4 без HTTP mocks: dark/light1280/320, обе реальные строки, unknown alert/сводка, decoy offline, reload, overflow0, pageerrors0/APIwrites0. Desktop light и mobile dark снимки просмотрены. Первичные helper ошибки сохранены: syntax до вызовов; DELETE с Content-Type без тела дал400 до guard; затем native matching conflict потребовал правильного критерия приёмки. Каждый запуск с сетевыми объектами завершил cleanup13 коллекций×2; предварительные отказы не выданы за passed.

Backend только: ux-refs114/version1.0.0-test.refs114, base60b2e09/context build-sessions113 плюс два overrides; source и compiled bytehashes совпали. Frontend ux-alias112-version/version1.0.0-test.alias112 сохранён. Backend/PG healthy; frontend подтверждён браузером, собственного healthcheck нет. Rollback .env pre-refs114.env сохранён privately, старый образ оставлен. Собственные certificates/keys/imports/peers/identities/mode-config/profile/proposal/groups/templates/files удалены; исходные13 коллекций×2 совпали, default/public/metadata/195.195.195.195/32/logging сохранены. Оба CHR доступны; пароли прежние.

Протокол: shared certificate, live UI. Следующий115 — UI для удаления только выбранной identity с сохранением общего сертификата; затем согласовать оставшиеся native/внешние ограничения и итоговую регрессию. Множественные реальные сессии одного ID, клиентские ОС, полнаяPKI, интеграции и multi-WAN не закрыты этим блоком.

Референс Схема
ReUI Filtering2 Сертификат → все identity → отдельные строки/настройки → выбор по identity ID
ReUI Sheet8 Выбранная identity → проверка ссылок → API409 без записи либо подтверждённая операция

12.5.115 — IPsec: удалить identity и сохранить общий сертификат через UI (2026-10-10)

В существующий AlertDialog добавлен Checkbox «Удалить также клиентский сертификат» только для certificate identity с явным identity:. По умолчанию выбран для единственной привязки; при других rows того же certName на том же serverId выключен/disabled. Сертификаты с одинаковым именем на другом сервере не считаются общими. Подтверждение объясняет сохранение сертификата и остальных identity; запрос передаёт removeCertificate=false. При API ошибке диалог/выбор/данные сохраняются, блокировки повторного нажатия прежние. Для cert-only row без identity нет ложной возможности «удалить клиента, сохранив единственный объект».

Изменены app/(main)/ipsec/page.tsx и tests/e2e/ipsec-delete.spec.ts. ReUI/base-nova, установленный AlertDialog и Checkbox переиспользованы; vendor/theme не менялись. Scoped ESLint и source TypeScript passed; production frontend build passed. Приняты26 unique E2E: первая профильная серия22 passed/4 failed из-за проверки getByRole фона при открытом модальном диалоге; corrected includeHidden проверка сохранности DOM rows дала4/4 rerun9.8s. Это26 уникальных, не30 сценариев.

Frontend ux-keepcert115/version1.0.0-test.keepcert115 развёрнут; backend ux-refs114/version1.0.0-test.refs114 сохранён. Source base58f5c48/context build-alias112-front плюс один page override, bytehash совпал. Label keepcert115 — метка этапа, неGitSHA; compiled frontend reproducibility не заявлена. Backend/PG healthy, frontend HTTP/browser passed, healthcheck у frontend отсутствует. Private rollback pre-keepcert115.env и прежний образ сохранены.

На собственном signed-certificate IKE fixture проверены4 live диалога (dark/light1280/320) без mocks; первые3 отменены, в light320 выполнен ровно один DELETE identity с removeCertificate=false. Native readback подтвердил отсутствие выбранной identity и сохранение точного certificate ID и другой identity. Исходный клиент восстановил online/198.18.115.250, unknown alert исчез. Последующие PATCH имени/возврат200 подтвердили восстановление. Чужой для приложения mode-config API не удалял: helper очистил только собственный fixture объект. История вызывается API с dedupe; точное число вставленных revisions не заявляется.

Собственные native объекты и private exports/imports очищены, исходные13 коллекций×2 совпали; маршруты/default/logging сохранены. Оба CHR/SSH доступны, пароли прежние. Screens4, просмотрен light320. Протоколы: native/deployment, live UI.

Следующий116: default user DELETE ещё угадывает имя сертификата для identity без remote-certificate; проверить/исключить случай PSK + отдельный cert с совпавшим именем. После последнего исправления — единая общая регрессия. Внешние Portal/Telegram/client OS/multi-WAN/scale и множественные native IKE sessions остаются в матрице.

Референс Схема
ReUI Sheet8 Выбранная identity → прямой объём удаления → сохранить общий сертификат → подтверждённый API результат

12.5.116 — IPsec: не удалять сертификат, угаданный по имени PSK (2026-10-10)

Устранена подтверждённая ошибка default DELETE: при пустом remote-certificate managed display name преобразовывалось в ipsec-user-, и несвязанный сертификат мог удаляться вместе с PSK identity. Теперь имя клиента не является доказательством связи: certificate deletion/preflight используют только явный remote-certificate либо выбранный cert target. Прямая одиночная certificate привязка по-прежнему допускает удаление; shared refs блокируются до записи как114. PSK диалог объясняет сохранение сертификатов; описания mode-config уточняют, что удаляются только неиспользуемые объекты приложения.

Изменены routes/ipsec.ts, mutation test, IPsec page и delete E2E. Все8 backend scripts, state114, backend build/source TypeScript/scoped ESLint passed. HTTP тест подтвердил PSK name collision: один identity DELETE, removeCertificate0; positive explicit binding: identity+certificate writes2. E2E28 unique passed39.6s, включая PSK описание/сохранение отдельной строки1280/320 и профильную регрессию. Vendor/ReUI/base-nova не менялись.

Before на backend114: создана собственная PSK identity с managed name, совпадающим со slug собственного unused signed decoy certificate. DELETE200 удалил оба объекта, хотя remote-certificate пуст. After на bound116: четыре live PSK диалога (dark/light1280/320), один DELETE через light320 UI, PSK удалён, тот же native ID/имя несвязанного сертификата сохранены. Browser не использовал mocks; APIwrites1, pageerrors0. Исходная certificate IKE сессия/online/198.18.116.250 сохранялись. Это не тест новой PSK сессии/throughput. Просмотрен light320 screenshot.

Обе части собраны последовательно и развёрнуты как ux-bound116/version1.0.0-test.bound116. Base d52c48e/context backend build-refs114, frontend build-keepcert115-front; по одному override для route/page, два source bytehash и compiled backend route bytehash совпали. Frontend compiled reproducibility не заявлена, label bound116 неGitSHA. Private rollback pre-bound116.env и прежние образы оставлены. Backend/PG healthy; frontend browser/HTTP подтверждён, healthcheck отсутствует. На VM25GB после сборок3.6GB свободно/86% занято; ресурсов достаточно для текущих проверок, production performance не оценивалась.

Оба native запуска очистили собственные fixtures, baseline13 коллекций×2 совпал; сохранены logging/default/public/metadata/195.195.195.195/32. Пароли прежние, оба CHR/SSH доступны. API DELETE вызывает history recording с dedupe; число новых revisions отдельно не заявляется. Протоколы: binding, live UI.

Следующий117 уже запущен: единая основная UI-регрессия1244 сценария на текущем frontend source, затем контекстный набор и сверка source/build/runtime. Внешние аккаунты/Portal/Telegram/client OS/scale/multi-WAN и одновременные native IKE sessions остаются в матрице.

Референс Схема
ReUI Sheet8 Выбранная identity → явная certificate связь → preflight → удаление выбранных объектов / сохранение несвязанных

12.5.117 — общая UI-регрессия и сверка действующего source/runtime (2026-10-10)

Основной набор1244:1243 passed/1 failed за28.8m; контекстный221/221 за7.2m. Failed large-backups.spec.ts измерял кнопки сразу после изменения1440→320 viewport: размер43.796875px во время CSS-transition, после двух animation frames ровно44×44, границы viewport/pinned соблюдены. Исправлен только тест: expect.poll ждёт прежние44px/координаты без снижения порога. Scoped rerun1/1 за10.2s, полноценный поиск/refresh/error/page/file/focus/grid axe сценарий завершился. Итог1465 unique accepted (1243+1+221); основной первоначальный exit1/failure сохранён,1244 fresh whole-main pass НЕ заявляется. Production UI менять/пересобирать не требовалось, scoped ESLint passed.

Source audit базируется на057b530:905 tracked application/config inputs, frontend515 raw matched + preprocessing package + отсутствующий clean-context .dockerignore; backend405 raw matched + подготовленный root package + четыре test-source differences. Содержимое frontend package проверено: только исключён backend workspace; backend package: scripts omitted, dependencies/devDependencies empty, остальные поля совпадают. Production source drift0; различия ipsec-state/ipsec-mutation/recursive-routes/speed-test tests явно исключены из этого утверждения. Контексты не содержат non-example .env inputs. Git label bound116 — метка, неSHA.

Все984 emitted production backend/contracts outputs, построенные по текущим tracked non-test TS paths, совпали с actual backend container после CRLF→LF. Старые вложенные local dist/backend/src outputs не включались: они не текущие outputs и отсутствуют в контейнере. Это normalized equivalence, не обещание byte identity; отдельная frontend binary reproducibility не доказана. Runtime source contexts build-bound116/build-bound116-front, обе версии1.0.0-test.bound116; backend/PG healthy, frontend HTTP/browser принят116, собственного healthcheck нет.

Read-only stand: оба enabled CHR reachable/RouterOS7.24.5 stable;27 коллекций×2 не содержат собственных prefixes (критерии/пути сохранены в JSON), own speed runs/probes0, servers2/migrations9. Это scoped namespace scanner, не full export и не универсальное определение ownership; native session caches не удалялись. Проверка не меняла RouterOS/пароли. Отдельный118-before fixture после этого подтвердил legacy export bug и очистился по13 коллекциям×2; archive/passphrase остались в памяти и не попали в Git.

Автоматически переснятые120 ранее чистых PNG сохранены в ignored tmp/regression117-generated-screens и убраны из diff; восемь исходных dirty GRE/VXLAN снимков восстановлены из сохранённой копии с проверенными исходными размерами. В этот блок включён только relevant large-backups-320 screenshot; unrelated skills/AGENTS не коммитились. Протокол: regression/source/runtime.

Следующий118 — удалить name inference из legacy POST /ipsec/users/:serverId/:rosId/cert, отказать PSK до export и проверить прямую certificate binding. Before200 с архивом отдельного своего сертификата уже воспроизведён, не принят как верное поведение. UI fixtures не заменяют native/Portal/Telegram/client OS/multi-WAN/scale приёмку.12.5 остаётся открыт.

Референс Схема
ReUI Filtering2 Viewport → окончание анимации → прежний touch target44px → keyboard/file/axe

12.5.118 — IPsec: legacy экспорт только по явной certificate привязке (2026-10-10)

Исправлен POST /ipsec/users/:serverId/:rosId/cert: managed display name больше не преобразуется в clientCertName как fallback. PSK либо отсутствие remote-certificate возвращают409 до вызова exporter, без contentB64/passphrase. Для отдельного сертификата остаётся явный export-by-name endpoint. Direct certificate binding поддерживается после смены display label: имя сертификата/ключ не меняются, bundle.user соответствует актуальной подписи.

Изменены routes/ipsec.ts и mutation test. Все8 backend scripts/state114, backend build и scoped ESLint passed. HTTP test подтвердил PSK409/exportCalls0, positive200/exportedName ровно explicit ref при другом display label. Первый positive mock упал502 из-за отсутствующего getCertificates у заглушки; fixture дополнен и повтор принят. Последняя перестановка независимых HTTP кейсов проверена focused script повторно. UI/source не менялись, full1244/context221 не повторялись после локального изменения одного backend endpoint; границы117 сохранены.

Native before на backend116: создана своя PSK identity без remote-certificate с именем, совпадающим со slug собственного unused signed decoy cert. Legacy POST200 вернул его P12 archive. After на118: этот запрос409 без archive/passphrase. Для primary certificate identity временно установлен другой managed display label; POST200 вернул archive её прямого remote-certificate, исходный comment восстановлен. Архив/passphrase/instructions использовались только в памяти, не записывались в report/Git. Existing certificate IKE session/CN/FQDN/catalog оставались корректны; это не новая PSK session или клиентская OS приёмка.

Backend ux-export118/version1.0.0-test.export118 собран из build-bound116/base9da5e55 с одним route override; source/compiled route bytehash совпал. Frontend ux-bound116/version1.0.0-test.bound116 сохранён. Backend/PG healthy; rollback .env pre-export118.env и прежний образ оставлены, label export118 неGitSHA. Оба native запуска очистили собственные certificates/imports/peers/identity/groups/templates/mode-config/profile/proposal/files, baseline13×2 совпал. Native certificate IDs сохранялись до собственного cleanup; logging/default/public/metadata/195.195.195.195/32 сохранены, оба CHR/SSH доступны, пароли прежние. Протокол: export binding.

Следующий119 — закрыть controlled-only границу113: несколько реальных established IKE sessions с одним ID и одним certificate principal. Подготовка отдельного official Debian/strongSwan image начата; клиенты будут в собственных Docker namespaces, private credentials временные/свои, host network и приложение не перенастраиваются. До native подтверждения этот пункт остаётся открытым. Конфигурация сверена с strongSwan, каталогом credentials и RouterOS. Внешние Portal/Telegram/Windows/macOS/mobile/multi-WAN/scale остаются отдельно.

Референс Схема
ReUI Sheet8 Выбранный клиент → явная certificate binding → PKI export либо409 без архива

12.5.119 — две реальные IKE-сессии одного certificate principal (2026-10-10)

Контролируемая граница113 дополнена реальными сессиями: два Docker Linux клиента, official Debian trixie/strongSwan6.0.1-6+deb13u7, собственные namespace/bridge, NET_ADMIN только внутри clients. Один свой RSA2048 клиентский сертификат/ключ, свой CA и явно закреплённый server certificate. IKE/ESP AES256/SHA256/MODP2048, unique=never; чужие сетевые объекты/host networking приложения не перенастраивались. Docker создал и затем удалил собственную временную bridge/NAT сеть.

В принятой конфигурации local ID получен непосредственно из сертификата. RouterOS подтвердил две established с одинаковым ID CN=<имя>-client и разными198.18.119.249/248. Каждый клиент выполнил Ping3/3 до собственного encrypted endpoint198.18.119.1. Это short data-plane proof, не throughput/rekey/SLA. API: clientsTotal1/clientsOnline1, activeAddress/activeSince/sessionAmbiguous отсутствуют. Два live UI1280/320 без mocks: один зелёный «онлайн», VIP не присвоен произвольно, unknown alert отсутствует; writes0/pageerrors0. Mobile screenshot просмотрен. Application source не менялся, backend118/frontend116 сохранены.

Первый cleanup остановился: helper ошибочно ожидал comment у cert, который SDK/RouterOS не сохранил. До повторения scoped recovery проверил имя/CN/CA references/native IDs, удалил только свои объекты/credential files; Docker cleanup уже был завершён. Последующие retries сохранили baseline16×2. Первые FQDN/ADDR4, ручной DN и pinned server+ручной DN получили AUTH_FAILED; RouterOS сообщил identity not found/peer ID does not match certificate. Certificate-derived ID с тем же ключом/CA/server pin прошёл. Точная причина различий encoding не доказана; эти варианты не переименованы в success и остаются следующей120 приёмкой.

Final cleanup: labelled clients/network удалены после owner проверки, свои native logging/peer/identity/policy/group/profile/proposal/mode-config/pool/bridge/address/certificates удалены по ID;16 исходных коллекций×2 совпали, default/public/metadata/195.195.195.195/32 сохранены. Private P12/pass/PEM/config files удалены, пустые свои directories закрыты без recursive delete. Архивы/ключи не попали в Git. Оба CHR доступны, пароли прежние. Инструментальный image сохранён для повторения; приложение не пересобиралось. Протоколы: native/отказы/cleanup, live UI.

References: strongSwan configuration, credentials, RouterOS. Два контейнера используют один public WAN/NAT, не являются независимыми площадками и не закрывают Windows/macOS/iOS/Android. Следующий120 — ID interop/encoding; остальные внешние зависимости сохранены в матрице.12.5 открыт.

Референс Схема
ReUI Filtering2 Две подтверждённые сессии → один клиент онлайн → без произвольно выбранного VIP

12.5.120 — кодирование DN и FQDN SAN в реальном IKE (2026-10-11)

На том же strongSwan6.0.1-6+deb13u7 последовательно проверены шесть вариантов с собственными CA/server/client certs, server certificate pin, RSA/AES256/SHA256/MODP2048. Certificate-derived DN, явный asn1dn с точными DER-байтами, FQDN из DNS SAN и FQDN с явным RouterOS remote-id установили tunnel и дали Ping3/3 каждый. Ручной текстовый DN и точный DER с единственным изменением тега CN 0x0c→0x13 отклонены AUTH_FAILED. Сертификат содержит UTF8String; парсер strongSwan6.0.1 выбирает PrintableString для этого ASCII CN. Это доказанная граница данной пары версий, не утверждение обо всех DN/PKI.

Обнаружено: FQDN SAN без явно заданного remote-id успешно аутентифицируется, но catalog API показывает offline. С remote-id=fqdn:… online=true. Первый helper остановился на ошибочном ожидании online; finally полностью очистил стенд. Уточнённый сценарий сохранил этот дефект отдельным результатом и завершил шесть вариантов. Он требует исправления в121, а не считается успешной приёмкой отображения. Ранее119 отказ FQDN включал requested IDr; новая конфигурация закрепляет точный server cert и не запрашивает IDr. Проверка сертификатов не отключалась.

Все свои containers/network/credentials и native objects удалены после проверки ownership. Baseline16 коллекций×2 совпал; оба CHR доступны, пароли и исходная конфигурация сохранены. Application source/runtime не менялись, UI заново не тестировался. Протокол. Следующий121 — SAN matching с защитой неоднозначности и нескольких ID одного principal. Windows/macOS/mobile, независимые WAN, scale/rekey и интеграции остаются открыты.

References: Identity parsing6.0, парсер6.0.1.

Референс Схема
ReUI Filtering2 Native established → точный ID/сертификат → подтверждённый online; неоднозначность → неизвестно

12.5.121 — подтверждённый онлайн по DNS SAN и нескольким IKE ID (2026-10-11)

Исправлен обнаруженный120 дефект: RouterOS принимает FQDN SAN, но API сопоставлял только DN/CN/явный remote-id. Теперь точный DNS SAN учитывается при прямой привязке сертификата к identity и отсутствующем/auto remote-id. SAN должен быть уникален среди всех native certificates; DNS wildcard/IP/email/чужие namespaces и конфликты DN/CN не угадываются. Явный иной remote-id не подменяется SAN. Общие claims проверяются по каждой native session, поэтому пересечение с PSK или другой identity остаётся sessionAmbiguous, без присвоения её адреса.

Все наблюдаемые DN/CN/explicit ID/SAN сессии одного principal объединяются: online подтверждён, но при нескольких сессиях не выбираются произвольные VIP/uptime. Добавлены13 state scenarios: unique/duplicate SAN, explicit/auto, DN+SAN с перестановкой, PSK collision, неподдерживаемые SAN, CN shadow и отсутствие привязки. Прошли127 state checks и8 профильных scripts, backend production build и scoped ESLint. Общая регрессия117 не повторялась; DTO/frontend/vendor не менялись.

Backend ux-san121/version1.0.0-test.san121 собран из контекста118 с одним source override. Локальный и серверный SHA256 source/compiled ipsec-live совпали. Frontend116 сохранён; backup pre-san121.env/предыдущий image оставлены. Backend healthy. Первый native helper остановился на regex старого диапазона VIP; finally восстановил baseline, затем regex исправлен. Повторение: один certificate-derived DN и один FQDN SAN одного cert одновременно established, Ping3/3 каждый. Catalog online1, activeAddress/activeSince отсутствуют. Два live UI1280/320 без mocks/write/pageerrors, mobile screenshot просмотрен.

Все свои Docker clients/network/credentials/native configs удалены после ownership preflight; baseline16 коллекций×2 совпал, default/public/metadata/195.195.195.195/32 сохранены. Оба CHR доступны, пароли прежние. Native/build/проверки, live UI. Следующий122 — IKE/CHILD rekey/reconnect; клиентские ОС/длительные нагрузки/физические WAN/integrations остаются открыты.

Референс Схема
ReUI Filtering2 Native DN+SAN → один клиент online → несколько сессий без случайного VIP

12.5.122 — реальный rekey CHILD/IKE и повторное подключение (2026-10-11)

На собственном Linux strongSwan→CHR certificate tunnel приняты пять состояний: initial, CHILD rekey, IKE rekey, terminated, reconnected. CHILD rekey подтверждён новой парой native ESP SPI после ухода старых SA; IKE rekey — новым strongSwan IKE unique ID после ухода прежнего. В четырёх connected фазах native established1/API online и Ping3/3 с первой попытки; после terminate established0/API offline без activeAddress/uptime. Повторное подключение вернуло online/Ping. RSA/private CA/exact server certificate pin/AES256/SHA256/MODP2048 сохранены.

Первый прогон принял обе смены ключей/офлайн, но reconnect Ping failed. Сценарий не сохранил достаточно данных для доказательства причины. Повторение использовало именно выданный native VIP, записало все client addresses и ограниченные Ping attempts; каждая рабочая фаза прошла с первого Ping3/3. Это не превращает первый отказ в успех и не доказывает мгновенное/бесшовное восстановление. Оба протокола сохранены. Длительное обновление, packet loss в переходе, reauth и физический WAN/SLA ещё не приняты.

Application source/image не менялись, общая регрессия и UI повторно не запускались. Все собственные Docker clients/network, private P12/PEM/pass/config и native configs/certs/logging удалены с ownership preflight. Baseline16×2 совпал, оба CHR доступны/пароли прежние. Native installed-sa сохранялись только по whitelist public SPI/state/адресов, ключи не записывались. Протокол с первоначальным отказом. Следующий123 — неправильный server pin и непривязанный клиентский certificate.

Reference: strongSwan rekey6.0.

Референс Схема
ReUI Filtering2 Новые SA → подтверждённый online → terminate/offline → reconnect/online

12.5.123 — server pin и привязка клиентского сертификата (2026-10-11)

Три реальные Linux strongSwan→CHR попытки без ослабления проверки сертификатов. Контрольный клиент с private CA/точным server pin/привязанным remote-certificate установил туннель и дал Ping3/3. Замена server pin на другой собственный certificate привела к отказу на клиенте. Второй RSA client certificate, подписанный тем же CA, но не указанный в remote-certificate identity, отвергнут RouterOS. Общий доверенный CA не подменяет точную native привязку. Отказы проверялись как ожидаемые, а не success tunnel.

После каждой попытки native established0 и catalog online0; неподключённые клиенты не получили active session. Все собственные Docker clients/network/private credentials и native objects удалены;16 исходных коллекций×2 совпали, пароли/default/public/metadata/195.195.195.195/32 сохранены. Оба CHR доступны. Source/runtime не менялись, профильная общая регрессия и UI не повторялись. Протокол.

Это ограниченная certificate authentication приёмка, не полная PKI: revocation/expiry, прочие client OS/custom OIDs/ID namespaces остаются открыты. Следующий124 — полноценный reauth и наблюдаемая граница IKE online при отсутствии CHILD SA.

Референс Схема
ReUI Filtering2 Сертификат и привязка подтверждены → online; ошибка pin/привязки → отказ без ложного online

12.5.124 — reauth и честная граница IKE онлайн (2026-10-11)

Реальный strongSwan certificate reauth завершился новой IKE SA и уходом старой; после initial/reauth/CHILD restore Ping3/3 каждый с первой попытки. При terminate только CHILD SA RouterOS сохранил established IKE1, installed-sa0; API продолжал online=true, Ping2/2 потерян. После нового CHILD SA Ping восстановился. Это подтверждает семантику текущего online: установленная IKE-сессия, не измерение передачи данных.

На странице добавлено краткое пояснение «Онлайн означает установленную IKE-сессию. Передачу данных проверяйте Ping». ReUI/Frame/base-nova и существующие компоненты сохранены. Production frontend build/typecheck и scoped ESLint прошли; source hash страницы совпал с Docker context. Frontend ux-ike124/version1.0.0-test.ike124 развёрнут, backend ux-san121 сохранён. Backup pre-ike124.env/прежний image оставлены. Два live UI1280/320 без writes/pageerrors/overflow: дождались API receipt и стабильного положения текста, screenshot mobile просмотрен. Empty catalog UI проверяет пояснение; активные DN/SAN строки уже приняты121.

Native objects/private credentials/Docker clients/network очищены с ownership preflight, baseline16×2 совпал. Оба CHR доступны, пароли/default/public/metadata/195.195.195.195/32 сохранены. Полная регрессия117 не повторялась для этой текстовой правки. Native/build, браузер. Длительный reauth/rekey, transition loss, физические WAN и клиентские ОС остаются открыты; следующий125 — отзыв/CRL.

Референс Схема
ReUI Stats12 IKE online → пояснение значения → отдельная проверка Ping

12.5.125 — фактическая граница локального отзыва сертификата (2026-10-11)

Контрольный собственный certificate tunnel установился/Ping3/3. Первая попытка использовала неверный /certificate/revoke и получила400 no such command; finally очистил fixtures. По официальному CLI reference уточнена /certificate/issued-revoke. Повторение подтвердило native revoked=true у собственного leaf certificate. Уже установленная IKE-сессия осталась established. После terminate повторное подключение тем же отозванным certificate также установилось. Ожидание отказа не прошло; это сохранённое наблюдение, не успешная приёмка revocation blocking.

После cleanup чтение certificate/settings подтвердило на обоих CHR crl-use=false/crl-download=false; certificates0/crls0. Глобальные settings в этом блоке не изменялись. Документация описывает CRL проверку отдельной настройкой, поэтому native revoked flag не считается доказательством блокировки при нынешней конфигурации. Application source/API не менялись; вывод об API online после reconnect не делается — helper остановился раньше его чтения.

Все свои configs/certificates/logging/private credentials/Docker clients/network удалены. Baseline17 коллекций×2, включая certificate/crl, совпал; default/public/metadata/195.195.195.195/32 и пароли сохранены. Протокол наблюдения и непройденное ожидание. Следующий126 — контроль валидного клиента и отказ отозванного при собственной CRL цепочке/временном crl-use, с обязательным возвратом исходных settings. Полная CRL/expiry/PKI приёмка остаётся открытой.

References: issued-revoke, CRL settings.

Референс Схема
ReUI List9 Метка revoked → отдельная CRL policy → реальная попытка соединения → подтверждённый результат

12.5.126 — CRL-enabled отзыв и проверенная очистка цепочки (2026-10-11)

Создана собственная CA/серверная/клиентская цепочка с CRL URL. До control IKE временно включены crl-use/crl-download на CHR1, после проверки certificates0/CRLs0 baseline. Валидный клиент установился/Ping3/3. После issued-revoke подтверждён revoked=true; действующая IKE могла остаться established. После явного terminate новый IKE тем же cert отвергнут AUTH_FAILED, native established0/API offline. Это закрывает отличие от125 для данной local CA конфигурации, не полную PKI и не мгновенный разрыв существующих SA.

Все certificate/settings возвращены к точной исходной записи. Initial sign потребовал точный .id — добавлен по ответу REST. Первый cleanup остановился на удалении issued server leaf: RouterOS требует revoke для сертификата CA с CRL. Settings/Docker/network/configs к этому моменту уже восстановлены/удалены. Recovery проверил ровно три собственных имени/CN/issuer, отсутствие своих configs, исходные settings и удалил точный собственный CA ID с каскадом только этих проверенных детей. CRL/private files очищены. Повторение использовало preflight всех дочерних cert IDs/ссылок перед own CA cascade и прошло целиком; baseline17 коллекций×2, private credentials/Docker/settings restored.

Наблюдение показывает риск API удаления: identity может быть удалена до native отказа удаления CRL-issued certificate. Следующий127 —409 до любых writes для защищённого leaf и CA с issued children; сохранение cert при identity-only остаётся доступным. Production source/runtime в126 не менялись. Оба CHR доступны, пароли/default/public/metadata/195.195.195.195/32 сохранены. Все результаты/отказ cleanup/recovery.

Reference: Certificates/CRL. Expiry, внешняя CRL загрузка/timeout, intermediate/custom PKI, клиентские ОС и долговременные нагрузки остаются открыты.

Референс Схема
ReUI List9 CA/CRL policy → валидный клиент → отзыв → reconnect отказ → возврат исходных settings

12.5.127 — удаление CRL-issued сертификатов без частичных изменений (2026-10-11)

Исправлена выявленная126 последовательность: перед удалением identity API проверяет явно привязанный cert/issuer. Локально issued либо revoked certificate CA с crl=true получает409 до любых writes. Пользователь может удалить только identity с removeCertificate=false. В /ipsec/certs дополнительно запрещено отдельное удаление CA с дочерними certs: RouterOS каскадно удаляет цепочку, поэтому force=true это ограничение не обходит. Автоматический отзыв/удаление чужой цепочки не добавлялся. Imported non-issued/non-revoked leaf сохраняет прежний сценарий удаления.

Добавлены13 профильных HTTP cases с нулевыми writes/history при отказе, сохранением cert при identity-only, обеими issued/revoked формами native metadata, CA force guard и положительным imported случаем. Прошли8 IPsec scripts (state127), backend production build/scoped ESLint. Backend ux-crl127/version1.0.0-test.crl127 собран из121 с одним route override; локальные и серверные source/compiled SHA256 совпали. Frontend ux-ike124 сохранён, backup pre-crl127.env/прежний image оставлены. DTO/vendor не менялись.

Native собственная CRL chain: семь409 (user/cert targets, direct leaf/CA с/безforce и revoked leaf) сохранили certs; до identity-only identity также оставалась. Identity-only200 удалил выбранную identity, сохранил все3 certs. Первый control остановился на Ping3/3 без достаточной диагностики; cleanup прошёл, отказ сохранён. Повторение проверяло выданный native VIP и записывало bounded Ping attempts, затем завершило API-сценарии. Мгновенная связность/SLA не заявляется.

Settings восстановлены точно, own CA cascade после проверки всех детей/ссылок очистил только собственную цепочку; baseline17×2/Docker/private credentials restored. Оба CHR доступны, пароли/default/public/metadata/195.195.195.195/32 сохранены. UI и общая регрессия117 повторно не запускались: guards/backend-only, сохранение modal при API error уже принято предыдущими UI блоками. Протокол. Следующий128 — expired/not-yet-valid certs без изменения часов.

Референс Схема
ReUI Sheet8 Проверка cert/CA →409 без изменений → выбор сохранить cert → подтверждённое identity-only удаление

12.5.128 — сроки сертификатов и неподтверждённая причина отказа (2026-10-11)

На OpenSSL3.5.7 созданы собственные same-key/same-CA сертификаты с явно заданными датами. Часы VM/CHR не менялись. Действующий original cert и перевыпущенный valid cert установили IKE/Ping3/3 каждый. Для renewed/invalid сертификатов временная собственная identity проверяла доверенный CA (remote-certificate=none/match-by=remote-id/auto), сохраняя pubkey auth/crypto и точный server certificate pin. Положительный renewed control доказывает работоспособность этой конфигурации с новым certificate DER.

Expired и not-yet-valid certificate не установили сессию за30s: IKE_INIT отвечал, затем IKE_AUTH retransmits, без явного AUTH_FAILED. Native established0/API online0. Это наблюдение тайм-аута, а не доказанный RouterOS expiry отказ. Журнал прочитан после cleanup, audit boundary уже не сохранился; точная причина остаётся открытой. Следующий129 должен захватить scoped auth logs сразу в каждой фазе.

Первый подход пытался импортировать expired cert: новых native rows оказалось0, точная причина импорта не записана. Cleanup остановился на принадлежности файла/ID. Scoped recovery проверил собственный namespace/CN/issuer/возраст, удалил только свои configs/certificate chain и точное имя созданного CRT (flash directory не удалялся), private files/CA key. Повторение не импортировало invalid certificates, держало их только в собственном client filesystem; cleanup baseline17×2/Docker/credentials passed. Оба CHR доступны/пароли/default/public/metadata/195.195.195.195/32 сохранены.

Протокол и все ограничения. Полный первоначальный Ping failure127 дополнительно перенесён в репозиторий. Source/runtime не менялись, UI/общая регрессия не повторялись. Expiry reason и внешняя CRL/PKI приёмка не закрыты.

Reference: OpenSSL x509 dates.

Референс Схема
ReUI List9 Valid control → encoded dates → native establishment/API → тайм-аут без выдуманной причины

12.5.129 — непройденный положительный контроль и изоляция диагностики (2026-10-11)

Повторение с чтением журнала во время фаз остановилось на valid-renewal control: original cert/Ping3/3 прошли, действующий новый cert получил IKE_AUTH timeout. Expired/future случаи не запускались. Поэтому предыдущие128 тайм-ауты не считаются доказанной expiry причиной. Phase authLogs оказались пусты; точная транспортная/сертификатная причина пока не определена.

Readonly clock проверка: VM20:13:44Z, CHR1 23:13:44/+03:00 (Moscow), CHR2 22:13:44/+02:00 (Warsaw), в пределах точности секунд совпали. Часы и timezone не менялись. Default memory:1000 entries/stop-on-full=false; CHR1 журнал содержит273 сообщения namespace129. Гипотеза о повторном использовании container IP/UDP tuple не выдаётся за установленную причину. Следующий130 использует отдельный netns/IP на вариант и собственный memory logging action с чтением только своего буфера; default logs не очищаются.

Final cleanup baseline17 коллекций×2/Docker/private files (включая собственный CA key) passed. Оба CHR доступны, passwords/default/public/metadata/195.195.195.195/32 сохранены. Source/runtime не менялись, UI/регрессия не повторялись. Failure/control/clocks/log metadata.12.5 и time-validity diagnosis открыты.

Референс Схема
ReUI List9 Положительный контроль не прошёл → не принимать отрицательные случаи → изолировать транспорт/журнал

12.5.130 — изолированная проверка сроков и исправление остатка cleanup (2026-10-11)

Каждый renewed/expired/future вариант получил отдельный Docker client namespace/IP (.3/.4/.5); прежние контейнеры удерживали адреса до общего cleanup. Original и renewed valid client установили IKE/Ping3/3. Expired и not-yet-valid client получили явный AUTHENTICATION_FAILED от CHR, native established0/API online0. Own key/CA/server pin/pubkey auth/crypto сохранены, часы не менялись. Это принимает local same-key/CA time-boundary после положительного renewed control; точная причина прежних128/129 тайм-аутов не доказана.

Созданы и затем удалены собственные memory action/rule без очистки штатного memory. Collector GET buffer query сохранил также исторические сообщения, поэтому строгая атрибуция этих логов не считается принятой; proof отрицательных случаев — прямой IKE AUTH_FAILED и состояние API/native. Полный диагностический buffer selector требует отдельной проверки через print query.

Обнаружено дополнительно: recovery128 удалял объекты по name/comment и пропустил logging rule, имеющее только prefix. Оно входило в последующие baseline128/129/130; их равенство не доказывало отсутствие этого остатка. Проверено точное имя namespace из recovery128, единственная rule с этим prefix, topics и action=memory; удалён только её native ID. Все остальные logging rows остались точно прежними, default журнал не очищался. Артефакты128/129 дополнены исправлением, исторические ограничения сохранены.

Итоговое повторение18 коллекций×2 прошло; после него отдельно удалён доказанный остаток128. Own custom logging action/clients/network/private files/CA key очищены, certificates/CRLs0, оба CHR доступны/пароли/default/public/metadata/195.195.195.195/32 сохранены. Source/runtime/UI не менялись. Протокол и correction. Следующий131 — ECDSA P-256 chain/Ping/экспорт. Full intermediate/custom PKI/external CRL/OS/scale остаются открыты.

Референс Схема
ReUI List9 Раздельные клиенты → valid control → explicit AUTH_FAILED → API offline → полная ownership очистка

12.5.131 — ECDSA P-256 и итоговая очистка блока IPsec (2026-10-11)

Создана собственная ECDSA P-256 CA/server/client chain (prime256v1), без изменения existing certificates/passwords. strongSwan6.0.1 установил certificate-authenticated IKE/ESP tunnel с точным server certificate pin/private CA и AES256/SHA256/MODP2048; Ping3/3. Public client key проверен Node X509: ec/prime256v1. API online1 и конкретный VIP этой единственной сессии. Экспорт client cert через /api/ipsec/certs/1/export вернул200/archive; архив и passphrase не сохранены в evidence/Git.

Own logging/peer/identity/policy/group/profile/proposal/mode-config/pool/bridge/address/certificates/private files/Docker client/network удалены по ownership preflight; baseline16×2 совпал. Дополнительная итоговая readonly inventory18 коллекций на каждом CHR проверила все namespaces120–131: residue0, established0, crl-use/download=false, private directories0. Labelled Docker acceptance containers/networks0; backend ux-crl127 и PostgreSQL healthy, frontend ux-ike124 running/HTTP+UI уже подтверждены124. Source/runtime/UI в131 не менялись, тесты и регрессия не повторялись. Оба CHR доступны, пароли/default/public/metadata/195.195.195.195/32/flash directory сохранены.

За эту серию исправлены implicit DNS SAN online121, смысл подписи IKE online124 и no-write CRL certificate/CA deletion guards127. Native interop/rekey/reauth/authentication/CRL/time validity/ECDSA приняты только в описанных границах. Все initial failures/recovery сохранены; тайм-ауты128/129 не переименованы в success и не используются как proof expiry. ECDSA/экспорт/final inventory.

Следующий132 — проверить scoped logger через POST print query (GET buffer collector130 содержит исторические сообщения), затем external CRL download/failure и оставшуюся матрицу. Windows/macOS/mobile, intermediate/custom PKI, независимые WAN/scale/долговременные нагрузки/реальные интеграции ещё не приняты. Этап12.5 открыт; новые native проверки начинать только с доступным бюджетом для cleanup и сохранения.

Референс Схема
ReUI Filtering2 EC cert/CA → native IKE/Ping → API online/VIP → подтверждённый экспорт → ownership cleanup

12.5.132 — изоляция диагностических буферов RouterOS (2026-10-11)

На обоих CHR RouterOS7.24.5 созданы по два собственных RAM action/rule с разными prefix. Один script/info marker попал в оба буфера. POST /log/print с .query=[buffer=ownAction] и .proplist вернул только нужный prefix: один маркер, foreignRows0. Контроль другого буфера вернул другой prefix; несуществующий буфер —0 строк. Обычный POST параметр buffer отклонён400; это ожидаемый отрицательный контроль. В проекции поле buffer отсутствует, поэтому изоляция подтверждена независимыми маркерами/контролями, а не выдуманным значением поля.

GET /log?buffer=ownAction тоже изолирует корректно. Повторное чтение helper130 показало, что после initial scoped read его collector обращался к общему GET /log. Поэтому предыдущая формулировка о ненадёжности GET buffer уточнена: дефект был в диагностическом сборщике. Исторические записи130 остаются смешанными и не становятся доказательством конкретной причины отказа сертификата.

Все четыре собственных logger/action на каждом CHR удалены по exact-ID/name/prefix/action/topics preflight. Полные существующие logging/action rows до/после совпали на обоих устройствах; default buffer не очищался. Пароли и VPN-конфигурация не менялись. Протокол и точный selector. Документация: REST query, раздельные memory buffers.

Source/runtime/UI не менялись; build и регрессия не повторялись. Следующий133 — оставшиеся реальные сценарии и проверка расхождений API; external CRL distribution failures, другие ОС и независимые WAN остаются открыты.12.5 не завершён.

12.5.133 — реальные журналы в REST-терминале (2026-10-11)

Диагностика132 выявила продуктовый баг getLogs: GET /log?limit=N использовал limit как REST property filter. На обоих CHR default memory содержал1000 строк, но SDK возвращал0, а API log print limit=3 —200/(no log entries). Исправлен SDK: чтение default memory с проекцией полей, последние N строк в native chronological order, максимум200. Невалидный limit отклоняется до опроса. Это лимит вывода: native buffer читается целиком перед slice; лимит сетевой передачи не обещается.

Проверены реальные API limits3/50/500→3/50/200 на каждом CHR, own marker виден, latest native IDs совпадают; limit0→400. Live терминал1280/320 получил по3 реальные строки, очистил поле команды после успеха и не имеет document overflow. Уточнена исходная подпись: «REST: каждая команда — отдельный запрос. Результат появится после ответа API.»; постоянная фраза о непроверенном соединении больше не противоречит успешному результату. ReUI Frame/Button/Input и base-nova сохраняются, vendor/layout не менялись.

Профильный HTTP SDK test (tail/default50/cap200/short/empty/invalid limits/401) passed, включён в npm test:exec. HTTP route/empty-versus-error и signed JWT/RBAC passed; backend build passed; source-only TypeScript и frontend production build passed. Scoped ESLint страницы/тестов passed; SDK lint имеет две исходные prefer-const ошибки125/899, проверка с отключением только этой rule passed. Обычный root tsc захватил ignored historical tmp и failed; существующий source-only config passed. Initial SDK test sandbox EACCES исправлен разрешённым loopback запуском. Первый UI assertion сравнивал newline string с отдельными div и failed; исправлен только способ проверки, final2/2 passed. Эти initial failures не скрыты и не прибавлены к уникальным сценариям.

Развёрнуты production backend/frontend ux-log133; backend/PostgreSQL healthy, frontend running/live UI. SDK source и compiled output SHA256 совпали с Docker; source страницы совпал с build context. Сохранены private rollback env и предыдущие образы. Только script/info markers добавлены в default logs; журнал не очищался, новых конфигурационных/VPN fixtures нет, оба CHR доступны, пароли не менялись. До/после и проверки, live UI.

Следующий134 — external CRL distribution/failure и оставшаяся матрица. Полная итоговая регрессия после последнего product изменения ещё требуется;12.5 открыт.

Референс Схема
ReUI App Shell12 Устройство → log print limit=N → default memory tail → ответ API → реальные строки

12.5.134 — внешняя загрузка CRL и отказ HTTP endpoint (2026-10-11)

Первый CHR выпустил собственные CA/client certificates с CDP; второй импортировал только public PEM, private-keys-imported0. Публичный DER CRL успешно разобран OpenSSL. Временный HTTP endpoint на Debian161.104.46.222:18084 отдавал только точный CRL path с Content-Length/Connection close. Фактические downloader GET от104.165.244.7 зафиксированы; dynamic CRL для CA и client в итоговом snapshot оба invalid=false/expired=false/revoked0.

Для независимого static CRL URL с отсутствующим path сервер вернул404 фактическому downloader. Строка осталась invalid=true/cert=none; ранее загруженные валидные CA/client CRL сохранились. Это принятие HTTP download/404/cache preservation, а не доказательство IKE refusal для сертификата с недоступным собственным CDP. Новый VPN tunnel здесь не создавался: проверяется инфраструктура распространения CRL. Отказ IKE, истёкший/повреждённый CRL, часовой refresh и немедленное завершение existing IKE остаются открыты.

Initial attempts сохранены полностью.1: manual download400/in progress и cleanup preflight failed, поскольку RouterOS потребил публичные файлы после импорта; exact scoped recovery убрал own chain/files/cache, остальные файлы сохранены.2: direct CHR-to-CHR CRL не загрузился за20s, cleanup10×2 passed.3: receiver /tool/fetch к direct CHR URL получил remote disconnected while in HTTP exchange, хотя Debian GET200; точная причина неизвестна, настройки HTTP/Firewall не менялись.4: временный endpoint дал valid CRL control, но повторный manual download во время automatic job вернул400/in progress; cleanup passed.5: busy receipt учтён отдельно, ожидается actual downloader request/status; valid+404/cache control и cleanup passed. Эти отказы не переименованы в success; direct distribution между CHR не принята.

CRL-use/download второго CHR восстановлены точным сравнением исходного settings object. Own logger/action, issuer chain, imported certificates, exports/uploads и CRL cache удалены после exact ownership preflight. Набор IDs10 коллекций на каждом CHR совпал с baseline итогового запуска; endpoint closed, порт18084 больше не слушается, Compose one-off завершён. Default buffer не очищался; flash directory/default/public/metadata/195.195.195.195/32 сохранены; пароли не менялись. Backend/PG healthy, frontend ux-log133 running; source/runtime/UI не менялись, build и регрессия не повторялись. Все попытки и итоговый протокол.

Следующий135 — certificate-bound missing/expired/malformed CRL и IKE enforcement с новым успешным контролем.12.5 открыт.

Референс Схема
ReUI List9 Own CA → public certificate/CDP → HTTP200 CRL → valid cache → own404 → invalid row → scoped cleanup

12.5.135 — недоступный CRL привязанного сертификата и реальный IKE (2026-10-11)

Создан собственный certificate-authenticated tunnel на CHR2; client CA/certificate выпущены CHR1 и импортированы в responder только публично. Собственный responder CA/server key создан native на CHR2. Linux strongSwan использовал собственный client key/private CA и точный public server certificate pin. CRL-use/download=yes; distinct Linux containers/addresses сохранены для трёх фаз.

  1. Валидный external CRL для CA/client загружен: IKE/ESP established, Ping3/3, API online=true.
  2. Тот же certificate CDP endpoint отвечает404; own CRL cache сброшен только после проверки ownership всех сертификатов/URL, invalid caches подтверждены. Native RouterOS ответил AUTHENTICATION_FAILED в обоих запусках; scoped log первого запуска — «failed to validate path: CRL not found» для собственного client certificate. Established0/API online=false. Это явный PKI отказ, не inference по timeout.
  3. Endpoint снова отдаёт signed valid CRL, оба cache valid; новый Linux container: IKE/Ping3/3/API online=true.

Первый запуск прошёл1–2, но recovered control получил IKE_INIT timeout без ответа и не был принят как восстановление. Его полный протокол сохранён, exact transport cause неизвестен. Повторный полный запуск прошёл три фазы; возможный bounded transport retry записывается отдельно, не увеличивает число уникальных сценариев. Оба запуска и итог.

CRL settings восстановлены точным сравнением. Own endpoint/logger/CA/certificates/private exports/credentials/Linux clients/network/IPsec identity/peer/policy/group/profile/proposal/mode-config/pool/bridge/address удалены по ownership checks.18 наборов IDs на каждом CHR совпали с baseline; private files removed, Docker cleanup, порт18084 закрыт. Existing/default/public/metadata/195.195.195.195/32/flash directory и пароли сохранены. Crypto dumps в evidence не включены, сохранены только выбранные auth/CRL сообщения.

Source/runtime/UI не менялись; действующий backend/frontend ux-log133. Следующий136 — повреждённый и подписанный истёкший CRL. Общая UI-регрессия после133 запущена отдельным процессом, её результат пока не заявляется. Немедленное завершение существующего IKE при отзыве, другие ОС и SLA ещё не приняты;12.5 открыт.

12.5.136 — повреждённый и подписанный истёкший CRL в IKE (2026-10-11)

В собственном external-CA tunnel проверены четыре payload на одном certificate-bound CDP: valid DER → HTTP200 malformed text → signed expired DER → original valid DER. Между фазами own cache сбрасывался после certificate/URL ownership preflight, CRL-use/download=yes. Private CA key использован только в0700/0600 временных файлах для подписания CRL, затем удалён. OpenSSL проверил подпись expired DER точным собственным CA; lastUpdate=now−2h, nextUpdate=now−1h. Часы CHR/Debian не менялись.

Оба positive controls установили IKE/ESP, Ping3/3 и API online=true. Malformed payload дал invalid=true caches, AUTHENTICATION_FAILED/established0/API offline. Signed expired payload был распознан RouterOS как invalid=false/expired=true, но новое IKE тоже получило явный AUTHENTICATION_FAILED/established0/API offline. Это четыре уникальные фазы без retry в итоговом запуске; отказ не выводится из сетевого timeout. Per-phase log сохраняет выбранную auth metadata; список expired может содержать earlier malformed reason и не выдаётся за отдельный точный текст причины expiry.

Own certificates/CA/exports/imports/private credentials/Linux containers/network/endpoint/loggers/tunnel config/pool/bridge/address удалены.18 наборов IDs×2 совпали с baseline, CRL settings restored exact, endpoint closed/порт18084 не слушается. Default/public/metadata/195.195.195.195/32/flash directory и пароли сохранены. Четыре фазы, подпись и cleanup; OpenSSL CRL date options.

Source/runtime/UI не менялись, действуют backend/frontend ux-log133. Следующий137 — external revocation при existing IKE и новый handshake. Уже запущенная общая UI-регрессия после133 продолжается; её итог будет отдельным последующим блоком, без объявления успеха заранее. Другие ОС/SLA/часовой refresh/immediate active-session revocation остаются открыты;12.5 открыт.

12.5.137 — внешний отзыв сертификата и существующая IKE-сессия (2026-10-11)

Собственный external-CA tunnel подтвердил IKE/Ping3/3. Затем CHR1 отозвал собственный client certificate. Свежий CRL содержит его точный serial, подпись проверена собственным public CA; CHR2 загрузил CA/client cache valid с revoked count1. Новый Linux client получил AUTHENTICATION_FAILED; scoped RouterOS log — «revoked by CRL cert is revoked by crl».

Уже установленная IKE-сессия в коротком наблюдении сохранилась и продолжила Ping3/3. API online=true корректно отражал именно эту старую сессию, а не успех нового handshake. После явного terminate только собственного старого IKE API стал offline; ещё один новый revoked client также получил AUTHENTICATION_FAILED/established0/API offline. Поэтому отзыв/обновление CRL не выдаётся за гарантированное немедленное завершение уже установленного туннеля. Подпись/serial, старый IKE, два отказа и cleanup.

Own logger/certificate chains/exports/imports/private credentials/Linux containers/network/tunnel config/pool/bridge/address/HTTP endpoint удалены.18 наборов IDs×2 restored, CRL settings object восстановлен точно, port18084 closed. Default/public/metadata/195.195.195.195/32/flash и пароли сохранены. Source/runtime/UI не менялись; действуют backend/frontend ux-log133. Ключи и crypto dumps в evidence не сохранялись.

Следующий138 — intermediate CA certificate chain. Общая UI-регрессия после133 продолжается и будет принята только по итоговому протоколу. Другие ОС, долгие нагрузки, periodic refresh и немедленное завершение existing sessions ещё не приняты как гарантии;12.5 открыт.

12.5.138 — промежуточный CA и повторная аутентификация (2026-10-11)

CHR1 выпустил собственную RSA2048 chain Root CA → Intermediate CA → client. Root/intermediate имеют CA BasicConstraints, leaf — CA=false; обе подписи проверены Node X509, полная цепочка/сроки/constraints прошли OpenSSL verify. CHR2 импортировал три public certificates и загрузил три valid/nonexpired CRL cache через два собственных CDP path. Отдельные native responder CA/server key созданы на CHR2.

Linux strongSwan с собственной client private key, explicit public Root/intermediate trust и точным server certificate pin установил IKE/ESP: Ping3/3/API online=true/конкретный VIP. Reauth завершился успешно, IKE id изменился1→2; новый IKE/ESP снова Ping3/3/API online/VIP. Профиль не менял auth algorithms/правила существующих сетевых операций. Полная цепочка, CRL, IKE/reauth и cleanup.

Own issuer chain удалена только после доказательства ownership всех descendants/отсутствия references. Own responder/imports/exports/private credentials/Docker client/network/endpoint/loggers/cache/tunnel objects/pool/bridge/address удалены;18 наборов IDs×2 restored, CRL settings restored exact, порт18084 закрыт. Default/public/metadata/195.195.195.195/32/flash directory и пароли сохранены. Source/runtime/UI не менялись; backend/frontend ux-log133.

Принята именно описанная native RSA chain и один Linux client. Arbitrary custom OIDs/policies/path length/missing chain/intermediate revocation/прочие ОС и полная production PKI не приняты. Следующий139 — дождаться итогов текущей общей UI-регрессии, выполнить context/source series и сохранить точный итог с сохранением исходных evidence/screens.12.5 открыт.

12.5.139 — общая регрессия, сверка Docker и реальный RIPE (2026-10-11)

После последнего продуктового изменения133 выполнена полная main UI-серия:1244/1244 passed, затем последовательно context/source/backend switch:221/221 passed. Итого1465 уникальных сценариев, оба exit0, без retries/delta rerun. Это production UI code с HTTP mocks/изолированными источниками, а не1465 живых RouterOS операций. Source не менялся во время обеих серий; production build/live UI133 и native135–138 остаются отдельными доказательствами.

С текущих tracked non-test backend/contracts source inputs построен manifest984 emitted outputs. Все984 совпали с actual Docker backend ux-log133 после CRLF→LF; missing0/different0. Старые вложенные local dist/backend/src outputs исключены. Создан input manifest906 файлов, но equality всех raw inputs/воспроизводимость frontend binary этим не заявляются. Нового build не требовалось: runtime source не менялся.

Реальный production RIPE service в отдельном процессе, без чтения/записи рабочего кеша, обогатил194.226.121.150 и104.165.244.7: network-info/maxmind-geo-lite/as-overview200, prefix/ASN/holder/country/coordinates получены. Это provider metadata, не гарантия физического положения хоста и не complete NetFlow pipeline. Дополнительный no-fetch контроль с198.18.139.1 failed: benchmark IPv4 ошибочно отправлен upstream. Private192.168/loopback контроль не вызвал запросов; public cache hits проверяются отдельно в следующем блоке. Этот отказ сохранён, весь RIPE test не объявлен success. Регрессия, compiled hashes и partial RIPE.

Перед регрессией сохранены586 existing evidence files.125 автоматически изменённых файлов восстановлены; все исходные SHA256 совпали, включая восемь pre-existing dirty GRE/VXLAN PNG. Новые135–138 evidence не затёрты. Подробные временные logs/snapshots в ignored tmp; побочные generated screenshots не включены в коммит. Source/runtime не менялись; backend/frontend ux-log133. Следующий140 — исправление фильтра специальных IPv4 согласно IANA, профильные backend/flow проверки, build/deploy и повторный live RIPE.12.5 открыт.

12.5.140 — специальные IPv4, RIPE и изолированная SQL-приёмка (2026-10-11)

Исправлен isNonPublicIp: benchmark198.18/15, TEST-NET ranges, reserved240/4 и non-global IETF assignments исключены из внешнего RIPE lookup. Глобальные PCP/TURN anycast192.0.0.9/10 сохранены eligible. Фиксированные CIDR masks вычисляются один раз; hot flow predicate больше не разбирает строки CIDR/адреса для каждого range. IPFIX tuples, NAT, network config и DB schema не менялись.31 boundary/exception checks и stale public-cache bypass/no-fetch тесты passed; IANA.

Local test:traffic-flow (20 scripts) exit0, но шесть SQL modules включали PG skips — не объявлены pass. Все шесть затем проверены against production candidate в четырёх собственных temporary PostgreSQL DBs. Parent создаёт exact own DB, child проверяет current_database до test import, DATABASE_PATH/GEOIP_DIR вынесены в ephemeral container; original DB/legacy SQLite не использовались fixtures. Все четыре DB удалены с owner/prefix check, включая failed runs.

Initial failures сохранены и исправлены в tests: analytics зависел от чужого hardcoded server7 (FK); теперь создаётся own server, все SQL scoped, finally cleanup. Map-hops использовал TEST-NET как вымышленные публичные сервисы; fixtures получили eligible synthetic IPv4, assertions не ослаблены. Statistics не создавал historical server_snapshots partition; теперь создаёт exact fixed-date partition. Ingest/analytics/map-hops/purge/facts-rebuild/statistics SQL modules passed across bounded runs; прошедшие modules без необходимости не повторялись. Mock upstream failure fixture перенесён с TEST-NET на eligible address и явно подтверждает реальный вызов stub.

Changed-file ESLint, backend production build, RIPE/IP profile tests passed. Реальный production RIPE service снова обогатил два публичных IP; повторный public cache hit и special/private controls дают0 дополнительных requests. Действует backend ux-ripe140/frontend ux-log133; backend/PG healthy. Все984 emitted outputs совпали с candidate Docker, actual deployed IP service SHA256 совпал; private rollback env/old image сохранены. Полные попытки/проверки/границы.

Readonly live traffic/statistics smoke320: rendering200/no overflow/pageerror0. При этом traffic отправил initial requests /api/traffic/servers/srv1 и /interfaces, оба400/id is required; это existing mock-id hydration/catalog gate defect, не часть IPv4 fix и не скрытый success. Smoke. Следующий141 — gate live fetch до подтверждённого numeric server id/catalog. IPv6 special ranges — отдельно. Full UI1465 accepted139 до backend-only140; backend/SQL/live delta проверены отдельно, frontend не менялся.12.5 открыт.

12.5.141 — подтверждённый каталог перед запросами трафика (2026-10-11)

Исправлен обнаруженный140 initial live defect: details/interfaces requests отправлялись с demo ID srv1 до загрузки реального каталога и получали400. Теперь details, interfaces и SSE ждут positive safe numeric ID, присутствующий в подтверждённом каталоге текущего backend. Смена источника данных лишает старый каталог права запускать запросы; смена периода не сбрасывает выбранный интерфейс. Demo-режим и backend API не менялись.

17 профильных E2E passed: два новых сценария удерживают запрос каталога и проверяют отсутствие любых individual requests до подтверждения, затем успех numeric ID или503 без запросов к серверу; остальные проверяют историю/ошибки/гонки периода/интерфейсов и SSE. Changed-file ESLint и source-only TypeScript passed; production Docker frontend build passed. Runtime frontend ux-traffic141, backend ux-ripe140 сохранён. Private rollback env и предыдущий образ оставлены.

Readonly live /traffic1440 и320: каталог и numeric interfaces200, initial srv1/400 отсутствуют, pageerror0, horizontal overflow нет. Протокол. Это приёмка начальной загрузки с реальным текущим каталогом, а не полной цепочки NetFlow ingestion/throughput. Сетевые объекты и пароли не менялись. Следующий отдельный блок — IPv6 special registry guard; оставшаяся внешняя приёмка перечислена в матрице.12.5 открыт.

12.5.142 — специальные IPv6 и рабочий кеш RIPE (2026-10-11)

Исправлены две причины недостоверного обогащения IPv6: неполная проверка служебных адресов и отсутствие IPv6-поиска в RIPE-кеше. Теперь документальные/benchmark/discard/dummy/SRv6/local/multicast адреса и некорректные записи не запрашивают RIPE, даже при старом seeded metadata. Более конкретные глобальные назначения внутри2001::/23 сохранены; Teredo/6to4 со статусом N/A не объявлены non-global. Правила сверены с IANA, eligibility не гарантирует маршрутизацию.

Добавлены validated128-bit parser, /48 buckets и отдельные широкие IPv6-префиксы. Lookup выбирает самый точный свежий CIDR, учитывает замену/просрочку/инвалидацию. Отрицательный кеш использует /128 и не затрагивает соседний адрес. Expanded и compressed записи дают одинаковый результат; IPv4-mapped hex/dotted/expanded формы нормализуются к одной IPv4 host identity. Host /128 удаляется перед RIPE resource request. Тест с3000 unrelated /48 подтверждает, что lookup не сканирует их все. Фиксированные special CIDR вычисляются один раз.

Changed-file ESLint, backend production build и IP/RIPE profile tests прошли локально и в candidate. Потребители classification/destination/GeoIP passed. Первый local aggregate остановился на GeoIP из-за ограниченного доступа к temporary files; разрешённый отдельный rerun passed, причина и неуспешный запуск не скрыты. Шесть PG skips локального запуска не считаются успешными: все шесть SQL-модулей затем прошли одним запуском в собственной temporary DB, удалённой с owner check. Working DB и legacy SQLite не использовались fixtures.

Первый Docker запуск указал отсутствующий Dockerfile.backend; исправлен путь backend/Dockerfile, build passed. Все984 emitted production outputs candidate совпали с local build. Реальный RIPE API дал6 HTTP200 для Google и Cloudflare IPv6; cached sibling/expanded address и special/invalid controls дали0 новых requests. Service process отдельный, persistence выключена. Backend ux-ipv6142 развёрнут, /health и Docker health healthy; frontend ux-traffic141 сохранён. Live /traffic1440/320 passed без srv1/400/pageerror/overflow. Rollback env/image сохранены, сетевые настройки и пароли не менялись.

SQL/live RIPE и границы, browser smoke. Это не доказывает IPv6 WAN connectivity или полный exporter→ingest→SQL→UI pipeline. При live RIPE выявлены координаты0/0 для Cloudflare; следующий143 — проверить, не подменяются ли отсутствующие значения нулями. Далее — IPv6 flow pipeline.12.5 открыт.

12.5.143 — неизвестные координаты RIPE без ложной точки на карте (2026-10-11)

При real RIPE IPv6 acceptance142 Cloudflare получил координаты0/0 после ответа upstream с country=? и latitude/longitude=0. Эти данные не подтверждают положение узла. Исправлен pickGeo: принимается только полная пара finite numeric coordinates в диапазонах±90/±180; empty strings, boolean, numeric strings, missing/partial/out-of-range coordinates дают null pair. Unknown-country0/0 также даёт null. Действительный ноль на экваторе/меридиане и явно заданный known-country0/0 сохраняются. ASN country fallback не превращает неизвестную точку в подтверждённые координаты.

16 новых end-to-end service cases в RIPE profile прошли локально и в production candidate. ESLint, backend build,984 compiled outputs comparison passed. Три затронутых SQL-потребителя (analytics, map-hops, facts-rebuild) прошли в собственной temporary PostgreSQL DB; она удалена с owner check, working DB не использовалась fixtures. Real RIPE снова дал6 HTTP200 для Google/Cloudflare IPv6. Upstream unknown-country0/0 сохранён в протоколе вместе с service lat/lng=null, ASN/country retained. Cache controls не сделали новых queries.

Backend ux-geo143 развёрнут, health healthy, frontend ux-traffic141 сохранён; read-only traffic PC/mobile smoke выполнен отдельно. Rollback env/image сохранены. Полный протокол, browser smoke, RIPE API.

Unknown0/0 policy основана на наблюдённом live ответе, а не на заявлении о поведении всех providers. Старые persisted entries с уже потерянной raw provenance не переписываются: исправлены новые fetches, прошлый cache живёт по прежнему TTL. Изменений schema/UI/theme или настроек CHR нет, пароли не менялись. Полная физическая точность геолокации и licensed GeoLite2 file acceptance не заявляются. Следующий144 — реальный IPv6 IPFIX UDP→collector worker→SQL в изолированной БД.12.5 открыт.

12.5.144 — IPv6 IPFIX через UDP, production worker и PostgreSQL (2026-10-11)

Новый controlled dual-stack IPFIX fixture воспроизвёл реальный parser defect: zero IPv4 placeholders заменяли уже прочитанный IPv6 или блокировали последующее IPv6 field. Исправлены source/destination поля в обоих порядках: usable IPv4 сохраняет прежний приоритет, zero IPv4 не подменяет usable IPv6. Expanded unspecified IPv6 теперь распознаётся так же, как ::, включая NAT fallback. Новая проверка добавлена в test:traffic-flow; parser assertions исполняются всегда, UDP/SQL часть требует exact own MMAPP_OWN_TEST_DB/current_database before migrations, иначе явно skip.

21 local traffic-flow scripts exit0; existing6 PG modules и UDP own-DB часть имели явные skips и не объявляются pass. Changed-file ESLint и backend production build passed. Candidate984 emitted outputs matched. Затем в own temporary PostgreSQL DB запущен настоящий production collector worker с UDP loopback socket: отправлены template и data datagrams, приняты6 IPv6 flows с forward/reverse public peers и documentation/benchmark/multicast controls. Проверены каждый src/dst, bytes/packets; raw/minute сохраняют все25200B/42 packets. Hour/day Internet facts по существующим правилам включают только три public flows:7200B/12 packets. Worker dropped0/error0, graceful shutdown acknowledged; SQL totals проверены после flush.

Две initial fixture failures сохранены: в первом запросе использовались неверные SQL column names src_ip/dst_ip (actual src/dst); во втором ожидалось равенство all traffic и Internet facts, что противоречит существующим правилам. Исправлены только ожидания/запрос теста, assertions каждого адреса/объёма не ослаблены, production aggregation/filter/schema не менялись. Third attempt passed. Все3 own temporary DBs удалены с owner check; working DB и legacy SQLite fixtures не использовались.

Backend ux-ipfix144 развёрнут, health healthy; frontend ux-traffic141 сохранён. Live traffic1440/320 passed без initial srv1/400, page errors/overflow. Rollback env/image оставлены. Все попытки и границы, browser smoke.

Это real UDP/worker/SQL path с синтетическим exporter через IPv4 loopback transport, не native RouterOS IPv6 export/outer transport и не maximum throughput. CHR configuration/passwords не менялись. Следующий145 — проверить возможность native RouterOS IPv6 exporter и populated API/UI на собственных objects/DB.12.5 открыт.

12.5.145 — настоящий RouterOS IPv6 IPFIX и заполненный интерфейс (2026-10-11)

Оба CHR доступны с прежними credentials, RouterOS7.24.5. Исходно Traffic Flow disabled/targets empty. Созданы собственные GRE-пара с allow-fast-path=false и fd00:145:1::1/2/64, advertise=no. CHR1 временно экспортирует IPFIX только своего GRE, с short timeouts/one owned target. Native Ping прошёл5/5 в обе стороны; CPU/input-output path и IPv6 support сверены с официальным Traffic Flow manual, версия manual7.26, фактическая проверка7.24.5.

На Debian запущен отдельный application/production collector worker в own temporary PostgreSQL DB. Скопирована конфигурация только CHR1 без публикации credentials; worker слушает UDP48145, HTTP API доступен только через localhost18145/SSH. Native RouterOS sender, не synthetic fixture, передал IPv6 IPFIX records: production API содержит реальные ULA source/destination и positive bytes/packets. Deployed frontend ux-traffic141 проверен через явный relay реальных ответов отдельного backend: Sessions DOM содержит IPv6, PC1440/mobile320 API200/pageerror0/no document overflow. Screenshots сохраняют frame/current scroll position, не все строки одновременно. Initial UI attempts искали адрес на Applications summary и ошибочно выбирали button вместо actual tab; исправлено только обращение к существующей вкладке.

Тест не использовал main DB для seeded fixtures; обычный background polling главного приложения оставался активным, поэтому абсолютное отсутствие background writes не заявляется. IPsec/WireGuard keys, пароли, исходные public/default/metadata routes не менялись. Native objects/GRE/IPv6 inputs принадлежат одному unique tag.

Автоматическая очистка восстановила Traffic Flow и удалила objects CHR1, но GET собственного GRE по ID на CHR2 вернул401. Child drain прошёл, own DB удалена. Read-only resource и полный каталог обоих CHR снова доступны с теми же credentials; причина одиночного GET401 не установлена, пароль не менялся. Recovery по свежему полному каталогу проверил exact comment/name/local-remote/address и отсутствие IDs в baseline; удалены только два оставшихся objects CHR2 обычным DELETE. Все12 collection projections×2 и Traffic Flow/IPFIX fields/IPv6 settings совпали с исходными. Initial failure и recovery сохранены, не заменены гладким success.

Own container удалён после проверки exact container ID; UDP48145/HTTP18145 и отдельный SSH tunnel закрыты, основной стенд backend ux-ipfix144/frontend ux-traffic141 healthy. Начальный неверный host port81245 был отвергнут до запуска/изменений, исправлен18145. Native/API/cleanup receipt, UI receipt, PC screenshot, mobile screenshot.

Доказан IPv6 ULA inner/native IPFIX поверх IPv4 GRE/export transport, не public IPv6 WAN/outer или throughput/произвольные clients. На live UI ICMPv6 подписан numeric58, IPv6 endpoints с портом требуют однозначного bracket format; следующий146 — улучшить эти подписи, сохранив ReUI/Frame/base-nova.12.5 открыт.

12.5.146 — понятные подписи ICMPv6 и адресов IPv6 с портами (2026-10-11)

После native145 устранены две неоднозначные подписи. protoName/applicationName protocol58 теперь ICMPv6 вместо numeric58 или58/—. Existing ICMP, TCP/UDP, unknown numeric fallback сохранены. В существующей ReUI Sessions table IPv6 с портом выводится [IP]:port, включая packet-tuple tooltip; IPv4:port и IPv6 без порта не изменились. Frame/base-nova/vendor компоненты и порядок колонок сохранены.

Parser/interface/classifier profiles прошли локально и в production candidate; последние выполнены без подключения к working PostgreSQL. Changed-file ESLint, source-only TypeScript, backend/frontend production Docker builds и984 emitted backend output comparison passed. Existing28 flow E2E прошли первым запуском. Два новых1440/320 tests сначала получили неверный fixture (sessions вместо conversationsList), что выявило отсутствие HTTP DTO guard; corrected fixture повторён отдельно,2 passed. Проверены visible IPv6 TCP/UDP endpoints, tooltip, portless ICMPv6, IPv4 compatibility и отсутствие document overflow. Итого30 принятых сценариев across attempts; первый failure не скрыт и прошедшие28 не повторялись.

Backend/frontend ux-labels146 развёрнуты; backend/PG healthy, deployed traffic PC/mobile loading passed. Label/check receipt, readonly smoke. Это live rendering/catalog smoke после label delta, а не повтор populated native145. Raw protocol integer сохранён в DB; talker/analytics response отображает его через новый protoName, schema/migration не требовались. Rollback env/images оставлены, device settings/passwords не менялись.

Следующий147 — применить существующие contract schemas к HTTP analytics/monthly, как уже сделано для SSE/settings, чтобы malformed200 response давал existing error/retry state без ложных нулей или page crash.12.5 открыт.

12.5.147 — подтверждённые HTTP данные аналитики и месяца (2026-10-11)

HTTP analytics/monthly раньше принимались как typed JSON без runtime schema check: malformed200 с отсутствующей conversationsList мог упасть при render. Теперь reused existing contract schemas и flowConfirmed error state, как в SSE/settings. Неверные required fields и negative RX/TX series отклоняются; monthly.month обязан совпадать с requested month. Existing Alert/Повторить аналитику показывает понятную ошибку, retry сохраняет server/range/month. Никаких false zero defaults для отсутствующих обязательных данных.

Необязательные overlay/wire measurements могут быть неизвестны отдельно от основных счётчиков. Invalid optional numbers (missing/null/string/negative/nonfinite) нормализуются в undefined, UI сохраняет Нет данных; legitimate numeric0 и valid core остаются. Это сохраняет partial-data UX и прежнюю проверку, вместо объявления всего DTO недоступным. Contract schemas/backend response shapes не менялись.

34 профильных E2E приняты across attempts:31 passed в первом запуске; strict optional metric rejection и два monthly fixtures без server catalog дали3 failures. Исправлены partial metric handling и fixtures, повторены только эти3, все passed. Covered incomplete analytics/monthly, negative series, different month, no pageerror/no false speed, retry with identical scope, existing flow races/SSE/metrics/month/table and IPv6 labels. ESLint/source-only TypeScript/frontend Docker build passed. Receipt.

Frontend ux-http147 развёрнут, backend ux-labels146 сохранён. Настоящие analytics/monthly HTTP200 текущего backend прошли схемы; month2026-10 совпал с запросом. Live PC/mobile smoke. Это contract compatibility/read-only smoke с текущими lab data, не новый populated WAN test. Rollback image/env сохранены, device/password changes нет.

Следующий148 — не запускать scoped flow HTTP/SSE до подтверждённого выбранного элемента каталога и не превращать malformed serverId в aggregate request.12.5 открыт.

12.5.148 — подтверждённый срез потоков без агрегатной подмены (2026-10-11)

Исправлено продолжение initial srv1 defect для flow mode. Scoped analytics/SSE теперь ждут выбранный элемент current provider/range/scope catalog. Server ID обязан быть positive safe numeric и присутствовать в exporters/monthly catalog, user ID — в confirmed clients. Catalog pending/error не запускает запрос для guessed/old selection; analytics loading не висит после catalog failure. Monthly history сохраняет supported non-exporting/disabled catalog entries, device polling не добавлено.

Backend больше не извлекает numeric prefix из1suffix и не превращает srv1/invalid/unsafe IDs в omitted filter/all-servers aggregate. Возвращается400 Некорректный идентификатор сервера. Missing/empty optional filter сохраняет aggregate semantics. Query validation выполняется до acquisition MAX4 SSE slots, поэтому malformed requests не съедают live quota.

21 invalid query cases (7 IDs×analytics/monthly/live) прошли source/candidate; full4 slots остались доступны. Новый тест сначала импортировал несуществующий non-scoped package; исправлен на existing @fastify/type-provider-zod без установки dependencies, проверки затем passed. Backend test включён в обычную traffic-flow series.36 E2E одним запуском passed: delayed/error catalog без any scoped request, затем only confirmed id1; existing flow/SSE/races/month/DTO/IPv6 labels. ESLint/source-only types/both production builds и984 emitted backend outputs comparison passed.

Backend/frontend ux-scope148 развёрнуты, health healthy. Real API9 malformed cases400 и2 valid scoped cases200; receipt, PC/mobile readonly smoke. No native changes/password changes/schema/theme changes; rollback env/images сохранены. Populated native145 не повторялся без необходимости.

Следующий149 — строгий month input и calendar bounds: invalid month не должен подменяться текущим или выдаваться за подтверждённый zero report.12.5 открыт.

12.5.149 — календарный месяц без тихой подмены и ложных нулей (2026-10-11)

Supplied malformed month раньше подменялся current UTC month на route; impossible month мог вернуться из service как zero report. Теперь непустой параметр передаётся для strict YYYY-MM/month1..12/year!=0000 validation, invalid получает400 Некорректный месяц отчёта до SQL. Missing/empty optional month сохраняет прежний current UTC default. Runtime non-string тоже отклоняется.

Calendar bounds больше не используют Date.UTC дляyear1..99 (он превращает их в1901..1999) и не режут extended ISO date at year10000. Integer year/month arithmetic даёт exact next-month day1, average bps используют Gregorian month length/leap rule. Source tests проверяют нормальный month/year rollover,1/99/9999, invalid input rejection before SQL. Normalized labels/DB schema не менялись.

В candidate Docker5 SQL intervals прошли в own temporary PostgreSQL DB:0001 January,0099 December,1900 February28days,2000 February29days,9999 December/end10000. In-month1200B retained, next-month12000B excluded, average country bps matches exact month length. Fixture DDL выполняется только после exact own DB/current_database check, DB удалена с owner check; working DB/legacy SQLite не использовались fixtures. Both month and scoped-query tests добавлены в normal traffic-flow series. ESLint/backend build/984 output comparison и6 frontend scoped/context tests passed; frontend не пересобирался.

Backend ux-month149 развёрнут, frontend ux-scope148 сохранён, health healthy. Real API6 invalid months400 иcorrect2026-10→200/same month; initial smoke helper Fetch.status method typo исправлен только в harness, сохранён как setup error. Full SQL/live receipt, PC/mobile smoke. Device/password changes нет, rollback retained. Это не расширяет UI на future month selection.

Следующий небольшой150 — понятные подписи Sessions columns вместо App/Proto/Iface/JH/EN, сохраняя ReUI grid/Frame/base-nova/data semantics.12.5 открыт.

12.5.150 — понятные названия колонок сессий (2026-10-11)

Существующая ReUI Sessions grid получила ясные подписи вместо внутренних сокращений:

Было Стало
JH Экспортёр
EN Выходной узел
App Приложение
Proto Протокол
Iface Интерфейс
Напр. Направление
Download / Upload (tooltip) Получение / Отправка

Column IDs, accessors, sorting/filtering, row values, direction meanings, grid layout/Frame/base-nova/vendor не менялись. Экспортёр описывает serverName корректнее, чем JH: данные могут поступать с разных типов устройств. IPv6 bracket/ICMPv6 labels146 сохранены.

Existing viewport1440/320 cases passed: endpoint/tooltip/IPv4/ICMPv6 behaviour иno document overflow. ESLint passed. Первый types check совпал с Next dev записью generated routes.d.ts и прочитал незавершённый файл; после окончания E2E/webserver TypeScript повторён последовательно и passed без изменения source. Production frontend build passed. Frontend ux-sessions150 развёрнут, backend ux-month149/PG healthy; receipt, readonly PC/mobile smoke. Rollback image/env сохранены. Network/password/device/schema changes нет; populated native145 не повторялся для copy-only delta.

Окно завершает coherent группу IPv6/NetFlow142–150. Следующий151 — application GRE IPv6 address lifecycle. Native inner proof109/145 уже есть, но gre-live читает только /ip/address, а entity-snapshots create/restore/delete всегда используют IPv4 resource. Нельзя просто объединить IPv6 catalog без family-safe write/delete paths: одинаковые ROS IDs в разных namespaces и dynamic link-local требуют отдельной обработки. План151: static IPv6 catalog, family-aware paths, create/update/restore/delete+legacy snapshot compatibility, запрет неоднозначной смены primary при multiple addresses, profile/native own tunnel cleanup иUI metadata. Сначала проверить лимит; не выпускать partial family migration.12.5 открыт, public IPv6 WAN/outer и внешние integrations остаются в матрице.

12.5.151 — управление статическими IPv6-адресами GRE (2026-10-11)

GRE читает IPv4 и IPv6 адреса; динамические адреса исключены из управления. Ошибка любого address catalog или неверный формат ответа останавливает чтение/запись, неполный ответ не становится пустым снимком. Выбранный выключенный сервер также исключён из опроса.

Create/PATCH/restore/delete выбирают /ip/address или /ipv6/address по проверенному CIDR; одинаковый RouterOS ID в разных семействах безопасен. Новые снимки содержат все статические адреса, disabled/advertise/comment/no-dad. PATCH меняет только целевой GRE, сохраняет дополнительные адреса; очистка поля передаёт явную пустую строку. Восстановление старой ревизии при нескольких текущих адресах возвращает409 до записи. Неоднозначные ID/name и переименование также409. Expanded/compressed IPv6 сравниваются по одному ключу. Применение from-pool/EUI-64 остановлено с объяснением: их выделение не принимается за обычный literal static address.

Существующие ReUI/Frame/base-nova сохранены, добавлена подсказка IPv4/IPv6 с префиксом. Проверки: config-sync4 scripts (включая14 invalid POST/PATCH до DB/REST), gre-comment и selected-context tests; backend/source-only types/ESLint;15 GRE E2E; backend/frontend production builds;984 emitted outputs совпали. Первый E2E запуск не стартовал из-за sandbox Windows/SWC canonicalize access; разрешённый повтор прошёл.

Настоящие production Fastify handlers + выделенная PG база + оба CHR:18 API requests включая создание IPv6 пары, PATCH IPv6, сохранение дополнительных IPv4/disabled IPv6, history restore многoадресного снимка, legacy409 и ID/name409, смену IPv6→IPv4, очистку, восстановление и DELETE. Ping3/3 в обе стороны после running=true и address invalid=false. Первоначальный короткий Ping получил0 вместо ожидаемых3 и остановил первый сценарий; причина не доказана. Его результат и очистка сохранены отдельно, повтор не скрывает начальный отказ. Это короткий dataplane, не доказательство бесшовности/throughput.

Оба запуска: собственные объекты удалены,8 static collections×2 совпали с baseline, отдельные базы удалены. Пароли не менялись, public/default routes не трогались. Native parent читает исходные enabled server credentials; background polling главного приложения продолжался, отсутствие всех background SQL writes не заявляется. Runtime backend/frontend ux-gre151 healthy, live read-only PC/mobile catalog/form smoke прошёл после cleanup; native mutation принята через изолированную базу, deployed browser mutation не выполнялась.

Протоколы: native/cleanup, API/history, первый запуск, compiled parity, live UI.

Границы: IPv6 ULA inner по IPv4 GRE outer; IPv6 outer/public WAN, scale, длительное восстановление и from-pool/EUI-64 не приняты. Полная регрессия после139 не повторялась: выполнен профиль изменённых областей. Следующий152 — WireGuard IPv6 lifecycle;12.5 остаётся открытым.

12.5.152 — IPv6 lifecycle WireGuard и общий допуск выключенных серверов (2026-10-11)

WireGuard читает оба address catalogs; ошибки/не-массивы не превращаются в пустые данные. Catalog показывает активный статический адрес, новые snapshots сохраняют все статические адреса с disabled/advertise/comment/no-dad. Dynamic link-local исключён из управления. Create и PATCH address, history restore и delete выбирают семейство по CIDR; дополнительные адреса сохранены, legacy snapshot с несколькими текущими адресами409. Общий адресный planner переиспользован GRE/WireGuard; constructor alias GreRestoreConflict совместим. PATCH не переименовывает одновременно интерфейс и адрес.

Import подтверждает receipts в /ip/address и /ipv6/address раздельно, normalized IPv6 identities принимаются, automatic link-local не считается чужим static child. Lost/unconfirmed receipt не разрешает удаление по одному имени; rollback не удаляет IPv4 с совпавшим IPv6 ID. IPv6 RSC export использует /ipv6 address add +advertise=no, parser распознаёт IPv6 address line. Multiple/special address import и export явно отклоняются вместо тихой потери данных. Это single-address literal import/export, не произвольный RouterOS configuration codec. Существующий ReUI create sheet получил подсказку IPv4/IPv6; структура/Frame/base-nova сохранены.

При native приёмке обнаружено: getEnabledServerById ранее проверял только ID. Теперь общий getter допускает только enabled=true и полный корректный DB ID; WireGuard selected catalog также исключает disabled. Это влияет на использующих getter GRE/WireGuard/firewall/containers/traffic/overlay. Постоянный opt-in test network-disabled-server.test.ts делает33 API/SQL cases: три типа Home Router/Jump Host/Exit Node ×11 calls, factory любого ROS client запрещена, contacts=0, enabled positive control проходит.8 malformed IDs проверяются до SQL, включая unsafe/выход за integer DB range. Без MMAPP_OWN_TEST_DB SQL часть честно skipped; в собственном PG стенде выполнена и база удалена.

Проверки:56 node:test cases import/rollback/revision/delete, service/config/HTTP scripts, GRE config-sync и14 invalid GRE requests, containers/live-maps profiles;10 E2E (WireGuard IPv6/error-retained input PC/mobile, tables/menus и GRE smoke после общего planner), source types/ESLint; обе production сборки,984 emitted outputs совпали с окончательным backend.

Native изолированная PG + production handlers + оба CHR:29 API cases, native handshake0s и Ping3/3 в обе стороны после IPv6 invalid=false; create/PATCH/IPv6→IPv4/clear, multiple-address history restore, legacy409, export multiple409, RSC/conf single IPv6 export и реальный import/delete, disabled GET empty/PATCH404 с forbidden factory. После каждого запуска9 static collections×2 совпали, собственные интерфейсы/peers/адреса и PG базы удалены. Native source/cleanup не меняли пароли/public/default routes. Background polling главного приложения продолжался; отсутствие всех background SQL writes не заявляется.

Первый сценарий остановился из-за ошибки теста: ожидал200 от POST peer, фактический корректный201. После исправления сценарий прошёл весь native lifecycle, но завершающий disabled PATCH вернул500 из-за реального дефекта общего getter. Оба отрицательных протокола сохранены; getter исправлен,33 isolated API/SQL cases и полный native сценарий на финальном образе прошли. Frontend повторно не собирался из-за backend-only gate delta.

Runtime backend/frontend ux-wg152 healthy; deployed live read-only catalog/create-sheet на1440/320 passed после cleanup. Browser mutations покрыты controlled E2E, реальные RouterOS mutations — production handlers в выделенной базе. IPv6 ULA inner по IPv4 WireGuard outer, не IPv6 public WAN/client OS/throughput/scale/lost ACK physical acceptance. From-pool/EUI-64/multiple-address import/export остаются явными ограничениями; full regression после139 не повторялась.

Протоколы: native/cleanup, API/history/import/export, 33 SQL/API gates, до исправления getter, compiled, live UI.

Следующий153 — sustained OSPF/BFD-only gate и recovery на собственных GRE;12.5 остаётся открытым.

12.5.153 — граница OSPF/BFD и предупреждение конфликта состояний (2026-10-11)

В существующей OSPF странице ReUI/Frame/base-nova добавлено предупреждение последнего опроса: OSPF Full при наблюдаемом BFD Down/AdminDown. Correlation требует точный server/interface/neighbor IP, explicit active/useBfd=true, одну direct multihop=false BFD session и свежие данные; чужое устройство/интерфейс/peer, duplicate sessions, unknown/multihop/inactive/non-BFD template не создают вывод. Native Full/route states и правила RouterOS не меняются. Переход Проверить BFD сохраняет server/node context и атомарно снимает search, чтобы найденная сессия была видна. Референс остаётся существующий ReUI Data Grid/Frame, новые vendor components не устанавливались.

На обоих CHR собственные GRE198.18.153.0/30 и OSPFv2 loopbacks198.18.253.1/32↔2/32, hello1s/dead20s, BFD200ms×3. Два own firewall правила на CHR2 блокировали только UDP3784 input/output на own GRE с exact private src/dst. Protocol89/ICMP не блокировались; OSPF Hello отдельным packet capture не измерялся.51 native rounds около30s: BFD Down наблюдался, в поздних samples после20s оба OSPF neighbors Full и own route active. Это подтверждает отсутствие гарантированного постоянного route gate при BFD-only ACL loss; непрерывность каждого пакета/мгновенного состояния не заявляется. Data plane initial/fault/recovery Ping3/3×2. После удаления fault — BFD Up/Full/active, затем собственные firewall/OSPF/BFD/IP/bridge/GRE objects удалены.10 static collections×2 совпали с baseline; filter/BFD config order также сравнивался. Default/public routes и пароли сохранены.

UI native positive проверена в source Next dev3133 с настоящим backend8000, без JSON mocks и browser mutations:1440/320 показывают alert+native Full; переход ведёт к реальному Down, сохраняет server и очищает q. Скриншоты 1440, 320; мобильный экран визуально проверен.3 unit cases,9 controlled E2E с recovery/foreign/non-BFD/unknown и previous data-cache scenarios, source types/ESLint passed. Read-only deployed PC/mobile smoke после cleanup подтвердил отсутствие ложного alert.

Frontend production build прошёл с окончательным source context; frontend ux-ospf153 развёрнут, backend ux-wg152/PG healthy. Первоначальная SCP сессия истекла в ожидании пароля; первый frontend candidate был собран без delta и не развёртывался. Context пересинхронизирован/хеш проверен, финальная сборка повторена и принята. Backend code/build не менялись, broad regression не повторялась. Только собственный завершённый container6a521d… удалён после exact-ID/state check; background main polling продолжался, собственная SQL база не создавалась.

Правила конфигурации сверены с MikroTik BFD. Протоколы: native51 samples/recovery/cleanup, real source UI, deployed smoke.

Границы: sustained BFD-only gate не гарантирован на RouterOS7.24.5; программа показывает реально наблюдаемый конфликт и не навязывает новые network rules. IPv6/scale/independent WAN/continuous packet loss/SLA не приняты этим блоком. Следующий154 — OSPFv3 IPv6 routes; существующий catalog читает только /ip/route, требуется family-safe /ipv6/route.12.5 открыт.

12.5.154 — IPv6 маршруты OSPFv3 в API и интерфейсе (2026-10-11)

Каталог и selected/all OSPF reads получают /ip/route и /ipv6/route. Обе коллекции обязательны: ошибка/не-массив не становятся успешным пустым ответом. IPv6 rows имеют namespace ipv6: для native ID: одинаковые IPv4/IPv6 IDs не конфликтуют. IPv4 IDs сохранены, операция только чтения. Gateway parser предпочитает фактический nonblank immediate-gw, затем configured gateway; это сохраняет наблюдаемый интерфейс после %. Существующие ReUI tables/Frame/base-nova не менялись.

Backend build, config-sync, live-maps profiles (dual family ID collision, IPv6 read failure/malformed payload, link-local gateway/via, existing disabled/partial/unknown),9 OSPF data/cache/BFD E2E и984 compiled parity passed. Backend ux-ospf154 развёрнут с rollback copy; frontend ux-ospf153 сохранён, PG/backend healthy. Native проверка выполнена после profile/parity deployment на disposable lab; frontend/backend неподтверждённый candidate не публиковался.

На обоих CHR собственный GRE IPv4 outer, IPv6 link fd00:154:1::1/64↔2/64, loopbacks fd00:154:ff::1/128↔2/128, OSPFv3 router IDs198.18.254.1↔2. Interface templates принадлежат только own GRE/loopback, originate-default=never, use-bfd=no; public/default paths не менялись. Native neighbors Full и own learned IPv6 route active, Ping3/3×2. Catalog/selected API содержат ровно соответствующие remote loopbacks с ipv6: ID и actual link-local nextHop +own GRE via.4 production UI cases: оба устройства на1440/320, IPv6 prefix/family row ID/gateway/interface присутствуют в DOM, document overflow/page errors0. На mobile отдельные columns могут находиться в горизонтальном table scroll; все columns одновременно viewport-visible не заявляются.

Координационный harness ожидал ui.done180s и завершился exit1 до позднего сигнала. Исходный passed=false/timeout сохранён: не переписан на успех и не скрыт повтором. Это не API/OSPF/Ping отказ: соответствующие assertions и4 независимых реальные UI cases прошли. finally удалил own OSPF/GRE/bridge/IPv6 objects,13 static collections×2 совпали с baseline, включая IPv4/IPv6 routes/filter/ND. Background main polling продолжался; собственная SQL fixture база не создавалась. Пароли сохранены, оба CHR доступны. Остановленный own container удаляется только по точному ID/state, не по широкому filter.

Протоколы: native и timeout/cleanup, 4 real UI, compiled984. Конфигурация сверена с официальным OSPF.

Границы: IPv6 ULA inner по IPv4 GRE outer, single area/single path, BFDv6 выключен, IPv6 public WAN/outer, scale/interop/throughput/physical redundancy не приняты. Full orchestration script success не заявляется; production behavior/profile и независимые native/UI/cleanup proofs отделены от timeout. Следующий155 — BGP IPv6 session/NLRI;12.5 открыт.

12.5.155 — IPv6 BGP session и обмен NLRI (2026-10-11)

Без изменения production source/dependencies/build: на двух CHR созданы собственные GRE с IPv6 link fd00:155:1::1/64↔2/64, loopbacks fd00:155:ff::1/128↔2/128, private AS64555↔64556, afi=ipv6. Output.network использует own /ipv6/firewall/address-list. Input/output filters принимают только точный own/remote /128, default-originate=never и network-blackhole=no. Native sessions Established, каждый узел получил ровно1 собственный remote IPv6 prefix; initial/recovery Ping3/3 в обе стороны.

Catalog и selected API подтвердили Established и IPv6 peerIp. Administrative disable одной own connection снял own active IPv6 route на другом узле, первое наблюдение144ms после PATCH — не hold-timer/SLA. Enable вернул sessions/routes/Ping. Read-only production UI1440/320 показал обе IPv6 сессии/Established в DOM, document overflow/page errors0; горизонтально скрытые mobile columns не выдаются за одновременно видимые. Live UI, native/withdrawal/recovery.

Первый harness проверял отсутствующее поле remoteAddress, тогда как public API контракт использует peerIp. Он остановился после успешных native route/Ping assertions;11 baseline collections×2 восстановлены. Failure сохранён отдельно. Исправлен только ignored test helper; полный второй сценарий exit0. Own BGP/filter/address-list/IPv6/bridge/GRE objects удалены,11 static collections×2 совпали, filter order также сохранён. Обе завершённые собственные container identities проверены и удалены; пароли/public/default routes не менялись. Background main polling продолжался, SQL fixture база не создавалась.

Конфигурация сверена с официальным BGP connection/AFI и IPv6 address lists. Границы: IPv6 BGP transport/NLRI внутри GRE по IPv4 public outer, два собственных peers/single path. Это не IPv6 public WAN/outer, independent WAN, external peer interoperability, BFDv6, continuous packet loss/maximum throughput/scale acceptance. ReUI/Frame/base-nova и runtime backend ux-ospf154/frontend ux-ospf153 сохранены.

Следующий156 — общая UI/context regression после151–154, один проход с сохранением исходных изображений;12.5 открыт.

12.5.156 — bigint идентификаторы серверов и начало общей регрессии (2026-10-11)

Audit actual schema обнаружил, что servers.id и references — PG bigint с Drizzle mode:number. В152 ошибочно введён верхний предел2147483647; это не диапазон данной DB схемы. Ограничение удалено, общая parseDbServerId требует positive safe integer и полную decimal строку. IDs2147483648 и Number.MAX_SAFE_INTEGER сохраняются точно;9007199254740992/3 и прочие unsafe/malformed не округляются в другой сервер. Историческая запись152 отражает прежнюю ошибочную границу; этот блок её исправляет.

Permanent server-id.test.ts проверяет25 valid/invalid forms без SQL. Dedicated PG test сохранил33 API checks disabled Home/Jump/Exit с forbidden ROS factory/contacts0, enabled control и2 реальные positive bigint rows. Guards MMAPP_OWN_TEST_DB152/156/current_database выполнены до bootstrap; собственная база удалена. Локальные config-sync/live-maps profiles и production backend build passed;984 emitted files совпали. Backend ux-id156 развёрнут, frontend ux-ospf153 сохранён. Native devices не изменялись этим блоком.

Протоколы: SQL/33 guards/2 bigint controls, compiled984. ReUI/Frame/base-nova/контракты UI сохранены, frontend build без source delta не повторялся.

Однократная общая UI regression запущена:1260 main cases.348 текущих tracked screen files, включая8 preexisting user-dirty GRE/VXLAN изображений, сохранены с SHA256 в ignored tmp/regression156-originals. На checkpoint774 cases ошибок не наблюдалось; это не завершённая приёмка всего прогона. Source screenshots могут временно меняться тестами и должны быть восстановлены исходными bytes после main/context. В157 дождаться основного процесса, выполнить221 context cases одним sequential server session, восстановить348 файлов, выполнить types/checks и записать точные exits/failures. Не выдавать running/skipped за pass.12.5 открыт.

12.5.157 — общая регрессия после IPv6 и bigint исправлений (2026-10-12)

Однократный основной прогон завершён: 1260 UI-сценариев прошли, exit0. Затем в отдельной последовательной frontend-сессии прошли 221 проверка контекста, exit0; всего 1481 сценарий, без сложения повторных профильных прогонов. Полная команда backend test завершилась exit0: все 24 профиля, входящие в эту команду, прошли. Это не число отдельных assertions. Первоначальный sandbox-запуск остановился в probes.cancel из-за EACCES на локальном HTTP listener; исходный лог сохранён, полный повтор с разрешённым доступом прошёл. Проверки собственной PostgreSQL базы и bigint rows относятся к156, этим общим прогоном повторно не заявляются.

Source TypeScript прошёл после остановки тестового Next dev. Все348 tracked изображения восстановлены из сохранённых перед прогоном текущих bytes, каждое сверено по SHA256; сохранены в том числе8 пользовательских GRE/VXLAN изменений. Сгенерированные тестами изображения не заменяют согласованные референсы. Production source не менялся, образы ux-id156/ux-ospf153 повторно не собирались и не развёртывались. RouterOS конфигурация и пароли этим блоком не изменялись.

Протокол: регрессия157. Это локальная контролируемая регрессия интерфейса/контекста/backend, а не повтор native сценариев или приёмка внешних сервисов, клиентских ОС, масштаба и физических WAN. Исторический timeout orchestration154 остаётся в исходном протоколе. Этап12.5 открыт; следующий158 — проверка эквивалентных IPv6 адресов в сопоставлении OSPF/BFD.

12.5.158 — корректное сопоставление IPv6 OSPF и BFD (2026-10-12)

Строковое сравнение не связывало эквивалентные IPv6 адреса: например FE80:0000:0000:0000:0000:0000:0000:0002 и fe80::2. Теперь IPv6 приводится к канонической записи, optional zone должна совпадать с наблюдаемым интерфейсом. Hostnames, malformed IPv4/IPv6, пустая/чужая/повторная zone не создают совпадение. Stale duplicate с тем же точным device/interface/peer не исключается до проверки уникальности: наличие такой неоднозначности подавляет предупреждение. Single stale session также не доказывает конфликт. Это только корреляция наблюдений; состояния RouterOS и правила сети не менялись.

5 unit tests,11 E2E, source TypeScript и ESLint прошли. E2E включает IPv4/IPv6 на1440/320, предупреждение/переход к BFD с сохранением устройства и очисткой поиска, recovery/foreign/not-used/unknown; остальные7 проверяют состояния данных OSPF. Полную1481 UI/context регрессию157 повторно не запускали: она принята на предыдущем source, эта delta проверена отдельно.

Переданный production source SHA256 совпал локально/на сервере. Frontend production build exit0; ux-bfd158 развёрнут с сохранённой private rollback env, backend ux-id156/PG сохранены. Немедленный curl после старта получил000 до готовности frontend; последующие две browser проверки1440/320 получили200, реальные catalog/server API200, page errors/overflow0 и отсутствие ложного предупреждения после очистки native fixtures. Позитивная native BFDv6 сессия этим блоком не заявляется. Пароли и RouterOS конфигурация не менялись; прежний закрытый SSH-туннель localhost3000/8000 восстановлен.

Протоколы: профильные проверки и сборка, реальный развёрнутый интерфейс. Установленные ReUI/Frame/base-nova переиспользованы без изменения primitives.

Референс Схема доработки
ReUI Data Grid Filtering2 Устройство → точный IPv6 peer/интерфейс → достоверное предупреждение → соответствующая BFD сессия

Следующий159 — native OSPFv3/BFDv6 на собственной GRE паре, short loss/recovery и независимая сверка cleanup. Официальный BFD manual описывает IPv4/IPv6 и use-bfd, но текущая страница версии7.26 не заменяет эксперимент на стенде7.24.5. Sustained route gate, scale/IPv6 public WAN/outer и физическая резервность остаются непроверенными;12.5 открыт.

12.5.159 — native OSPFv3 и BFDv6 с потерей и восстановлением (2026-10-12)

Два CHR7.24.5, собственные GRE с IPv4 outer, ULA fd00:159:1::1/64↔2 и loopbacks fd00:159:ff::1/128↔2/128. OSPFv3 single area/private router IDs, originate-default=never; BFD разрешён только на собственном GRE для fe80::/10,200ms×3, use-bfd=yes только own template. Начальные состояния: BFD Up, OSPF Full, собственный удалённый IPv6 маршрут active; Ping3/3 в обе стороны. Catalog и selected API подтвердили own маршруты/ipv6:IDs/link-local nextHop/via.

Два собственных /ipv6/firewall/filter правила блокировали только UDP3784 input/output на CHR2, exact own GRE и соответствующие link-local src/dst /128. OSPF89/ICMPv6 не блокировались; отдельный packet capture Hello не выполнялся.44 samples за25s показали BFD Down и поздние OSPF Full/own route active после20s. Это наблюдаемая граница, не доказательство постоянного route gate/непрерывной доставки/SLA. На production frontend ux-bfd158 с реальным backend ux-id156 два readonly UI случая1440/320 показали предупреждение, IPv6 BFD Down и переход с сохранением server context; page errors/overflow0. ПК, телефон; mobile просмотрен, скрытые горизонтально table columns не считаются одновременно видимыми.

После снятия own UDP fault: BFD Up/Full/route active и recovery Ping3/3×2. Затем own rules/templates/area/instance/BFD config/IPv6/bridge/GRE удалены;13 static collections×2 сравнивались по выбранным конфигурационным полям, dynamic rows/volatile counters исключены. Порядок IPv4/IPv6 filters и BFD configuration сохранён. Это не побайтное сравнение полного runtime export. Helper exit0; container удалён после сравнения exact full ID с own cidfile и состояния exited0. Собственная SQL fixture база не создавалась, helper только читал server config из main DB, background polling продолжался. Пароли/public/default routes не менялись; оба CHR доступны при cleanup.

Протоколы: native44/recovery/cleanup, 2 реальные UI. Source/dependencies/build не менялись после158, повторная общая регрессия не требовалась. Официальный BFD использован как справка; фактический результат относится к установленной7.24.5, не текущей версии страницы7.26.

Принят basic native IPv6 BFD в OSPFv3, scoped loss/recovery/API/UI; IPv6 public outer/WAN, scale, физическая резервность/interop/continuous loss остаются открыты. Следующий160 — BGP IPv6+BFD own pair;12.5 открыт.

12.5.160 — IPv6 BGP с BFD: снятие маршрута и восстановление (2026-10-12)

На двух CHR7.24.5 собственная GRE пара по IPv4 outer, ULA fd00:160:1::1↔2/64 и loopbacks fd00:160:ff::1↔2/128, private AS64555/64556. BGP afi=ipv6/use-bfd=yes; BFD разрешён только own GRE/ULA subnet200ms×3. Input/output routing filters принимают только точные own/remote /128, default-originate=never, network-blackhole=no. Initial BFD Up/Established/ровно1 own remote NLRI и Ping3/3×2, catalog/selected sessions API подтверждены.2 real UI1440/320 показали IPv6 peers/Established, no overflow/page errors; собственные native мутации выполнялись helper, browser только читал.

На CHR2 два own IPv6 filter rules блокировали только UDP3784 input/output, exact own GRE/ULA src/dst /128. TCP179/ICMPv6/публичные пути не блокировались.44 samples за25s подтвердили BFD Down и отсутствие обоих own active IPv6 routes; первое такое REST наблюдение636ms после установки fault, это не SLA/packet capture/continuous packet loss. Во время перехода native established flag некоторое время ещё присутствовал на одном узле; промежуточные состояния сохранены полностью. Fault catalog показал Unknown для обеих session rows с отсутствующим установленным FSM state, не догадку Idle/Down. UI во время самого fault отдельным сценарием не проверялся.

Удаление own fault вернуло BFD Up/Established/NLRI и Ping3/3×2. Все созданные connection/instance/filter/address-list/BFD/IPv6/bridge/GRE удалены;12 static collections×2 совпали по выбранным конфигурационным полям (dynamic/volatile исключены), routing/IPv6 filter/BFD configuration order сохранён. Helper exit0, container удалён по exact full ID из cidfile только после exited0. Основная DB только читалась helper; background polling продолжался, отдельная SQL база не создавалась. Пароли и default/public routes не менялись; оба CHR доступны при cleanup.

Протоколы: native44/withdrawal/recovery/cleanup, 2 live UI, ПК, телефон. Source/dependencies/build не менялись; runtime ux-id156/ux-bfd158 сохранён, без повторной общей регрессии.

Basic single-path BGP IPv6/BFD withdrawal/recovery принят, не IPv6 public WAN/outer/scale/interop/physical redundancy/бесшовность. BFD с BGP — справочный документ; результат фактически проверен на7.24.5. Следующий161 — audit legacy selected BGP/alert parser: общий catalog сохраняет Unknown, но старый detectState угадывает Active из uptime и Idle при отсутствующем native FSM.12.5 открыт.

12.5.161 — неизвестные состояния BGP без ложных оповещений (2026-10-12)

Общий legacy/selected parser больше не угадывает Active из uptime и Idle при отсутствии native FSM. Established=true сохраняет подтверждённое Established; остальные известные FSM распознаются точным match, malformed/future-prefix/blank/missing сохраняют Unknown. Catalog и selected state согласованы; legacy числовые counters/timers этим блоком не мигрировались. BGP alert evaluation рассматривает только известные FSM: Unknown/blank/future state не подтверждают проблему и не становятся подтверждённым previous down при recovery.

Из collector выделена чистая корреляция BGP signals: newest current Unknown остаётся Unknown, previous baseline ищет ближайшее известное состояние среди сохранённых runs. Так Idle→Unknown→Established подтверждает recovery на основе последнего известного Idle; Established→Unknown→Established не создаёт ложный recovery; Unknown current не создаёт event. История ограничена существующими8 прочитанными collector runs, неизвестный период не становится новым фактом. Legacy peer keys serverName:peerName сохранены; миграция неоднозначных одинаковых имён этим блоком не заявляется.

Live-maps parser/profile прошёл; alert-engine groups/evaluate прошли, SQL confirm-stability тест пропущен из-за отсутствующего локального PG подключения/EACCES, не записан как pass. Outbox/alerts HTTP/JWT profile прошёл на controlled sender interfaces, реальные сообщения не отправлялись. На скомпилированном коде replay92 сохранённых настоящих RouterOS rows из160:19 Established/73 Unknown, selected/catalog states совпали;73 unknown problem и73 unknown previous recovery проверки не создали event. Это воспроизведение native payloads, не новый live mutation/SQL/outbox-delivery тест.

Backend build прошёл, окончательный Docker кандидат ux-bgp161b совпал с локальными988 emitted non-test файлами (новый module добавил4 outputs). Первоначальный ux-bgp161/984 был развёрнут до обнаружения last-known gap; финальный161b пересобран и развёрнут после исправления baseline, обе версии/rollback env сохранены. Backend/PG healthy, frontend ux-bfd158 сохранён;3 readonly real GET catalog/selected и2 browser1440/320 passed/no errors/overflow после cleanup. Positive missing-FSM rows доказаны replay, пустой live catalog не выдан за native inactive proof. Общая регрессия157 относится к прежнему source; эта delta проверена профильными сценариями.

Протоколы: compiled988, native payload replay, deployed API/UI. RouterOS конфигурация/пароли этим блоком не менялись, новые native fixtures не создавались, ReUI/Frame/base-nova UI primitives сохранены.

Следующий162 — native private4-byte ASN в IPv6 BGP и отображение длинных AS на1440/320; прежний BFD fault повторять без новой delta не требуется.12.5 открыт.

12.5.162 — четырёхбайтовые ASN в IPv6 BGP и интерфейсе (2026-10-12)

Два CHR7.24.5, own IPv4 outer GRE/IPv6 ULA fd00:162:1::1↔2/64 и loopbacks fd00:162:ff::1↔2/128. Private AS4200000162↔4200000163 взяты из диапазона IANA4200000000–4294967294, reserved4294967295 не использован. Input/output filters принимают только exact own/remote /128, afi=ipv6, default-originate=never и network-blackhole=no. Native Established и negotiated as4, local/remote AS сохранили исходные10-значные числа вместо AS_TRANS; catalog совпал, capabilities содержит4-byte-AS. Каждый узел получил ровно один own remote IPv6 NLRI, initial Ping3/3×2.

Readonly production UI1440/320 показал обе IPv6 сессии/Established и точные remote ASN в DOM, no errors/document overflow. Mobile проверен визуально; AS columns могут требовать горизонтального table scroll, одновременная viewport visibility всех columns не заявляется. Administrative disable одной own BGP connection снял own remote IPv6 route на другом узле, первое наблюдение135ms после PATCH, не hold timer/BFD/SLA/continuous loss. Enable вернул Established/NLRI и Ping3/3×2. BFD fault160 без source delta не повторялся.

Own connections/instances/routing filters/address-list/IPv6/bridge/GRE удалены,11 static collections×2 совпали по выбранным конфигурационным полям, filter order сохранён. Helper exit0; container удалён после exact-ID/state check. Main DB только читалась helper, background polling продолжался; пароли/public/default paths не менялись, оба CHR доступны при cleanup. Source/dependencies/build после161 не менялись, runtime ux-bgp161b/ux-bfd158 сохранён.

Протоколы: native/as4/withdrawal/recovery/cleanup, 2 live UI, ПК, телефон. Live UI162 использует отдельный файл bgp-ipv6-162-live-ui, протокол160 сохранён отдельно.

Границы: private four-byte ASN между двумя RouterOS, single-path IPv6 внутри IPv4 GRE, не interop со сторонними peers, IPv6 public outer/WAN, scale/physical redundancy. Следующий163 — проверка duplicate legacy alert keys serverName:peerName: два разных устройства с одинаковыми именами не должны создавать ложные state transitions внутри одного snapshot.12.5 открыт.

12.5.163 — неоднозначные ключи BGP-оповещений (2026-10-12)

Два CHR в native162 имели одинаковые legacy alert keys CHR:peerName. Раньше второй peer внутри того же snapshot мог стать previous state первого. Collector теперь сначала группирует строки одного run: повторный key становится current Unknown, а ambiguous history не используется для поиска previous known state через разные identities. Даже одинаковые states не доказывают уникальное соответствие configured target конкретному peer. Distinct keys и last-known переходы161 сохранены; stable server/peer ID target migration не выполнена. Для legacy ambiguous targets события подавляются консервативно.

Unit assertions проверили duplicate same/different/unknown states и исторический barrier. Compiled replay46 real native160 snapshot pairs подтвердил одинаковые ключи,46 Unknown/46 suppressed problem/46 suppressed recovery. Это сохранённые RouterOS payloads, не новая native mutation. Alert groups/evaluate и controlled outbox/HTTP/JWT profiles прошли; SQL stability снова skipped из-за отсутствующего PG подключения и не считается pass. Backend build/988 emitted parity passed, ux-bgp163 развёрнут с rollback env; backend/PG healthy, frontend ux-bfd158 сохранён.3 readonly catalog/selected GET и2 live UI1440/320 passed/no errors/overflow после fixture cleanup. Образы/сборка отражают эту delta, полная1481 UI/context regression157 повторно не запускалась.

Протоколы: replay46, compiled988, deployed API/UI. ReUI/Frame/base-nova UI primitives сохранены; RouterOS/пароли/объекты не менялись, сообщения не отправлялись.

Следующий164 — strict nullable selected BGP counters/AS/timers: legacy selected API ещё подменяет отсутствующие значения default numbers и UPDATE messages количеством prefixes.12.5 открыт.

12.5.164 — достоверные числа BGP во всех маршрутах чтения (2026-10-12)

Selected/all BGP parser и тип BgpSessionRead теперь используют nullable remote/local AS, timers, RX/TX prefixes и message counters. Отсутствующее/invalid/unsafe значение не становится0/90/30 или типом eBGP. Prefix RX читается только из prefix-count; UPDATE messages не являются количеством префиксов, TX prefixes остаётся null без доказательства. Наблюдаемый0 сохраняется0, известные ASN до32-bit сохраняются точно. Catalog переиспользует общий parser, добавляя AFI; миллисекунды в timers переведены в дробные секунды, overflow duration остаётся unknown.

Это намеренное изменение старого selected/all API numeric contract: clients должны обрабатывать null, историческое legacy-preserved утверждение ранних блоков больше не описывает эту версию. Все repository type consumers прошли backend build; основной BGP UI уже использовал nullable catalog. Collector keys/state и правила163 сохранены, новые numeric defaults не добавлялись.

Live-maps profile и controlled alert/outbox HTTP/JWT прошли,15 BGP data/freshness/link E2E passed. Compiled replay96 реальных rows из160/162:146 missing counters сохранены null,104 observed zero сохранены0,4 four-byte ASN rows точны; selected/catalog fields совпали с native values. Это replay, не новый live native lifecycle. Backend production build/988 emitted parity passed; ux-bgp164 развёрнут с rollback env, backend/PG healthy, frontend ux-bfd158 сохранён.3 readonly GET и2 real UI1440/320 passed/no errors/overflow после cleanup. Positive nullable rows доказаны replay и unit/HTTP profiles, empty live catalog не считается positive missing-field доказательством. Broad regression157 не повторялась без необходимости.

Протоколы: native replay96, compiled988, deployed API/UI. ReUI/Frame/base-nova primitives/RouterOS конфигурация/пароли сохранены, новые fixtures/сообщения не создавались.

Следующий165 — общий GRE/BGP collector: await внутри Promise.allSettled сериализует независимые reads и не сохраняет успешный BGP при раннем GRE throw; текущие BGP signals также не должны восстанавливать отсутствующий в newest snapshot peer из старого run.12.5 открыт.

12.5.165 — независимый сбор GRE/BGP и актуальные сигналы оповещений (2026-10-12)

Убраны await внутри Promise.allSettled: независимые GRE/BGP reads действительно запускаются параллельно. Promise boundary сохраняет sync и async ошибки отдельно; успешная группа не теряется при отказе другой. Dependency seam проверяет production collector без SQL/RouterOS. Busy guard не запускает повторных запросов, после отказа collecting сбрасывается. Permanent collector/history tests включены в test:alert-engine.

GRE/BGP reader берёт8 newest completed runs со status ok/error, включая null result_json: более новый отказ не скрывается фильтром успешных прогонов. Invalid/version-mismatched/null/malformed payload становится barrier с пустыми current collections и явным fatalError. Valid partial snapshot сохраняет успешную группу. Current peer/tunnel keys берутся только из newest run; прошлые строки используются только как previous state существующего текущего объекта. Удалённые/непрочитанные объекты не воскресают как current. GRE duplicate labels/history barrier также исключают cross-peer transitions; BGP163 guards сохранены. Остальные collector families, age disabled jobs и stable-ID legacy target migration этим блоком не закрыты.

Unit cases проверили concurrent start до GRE completion, busy/no second fetch, scoped sync/async failures, recovery/empty, failed/null/malformed history, successful partial BGP, deleted peers и GRE alias ambiguity. Alert/outbox HTTP/JWT profiles passed; SQL confirm-stability skipped без PG подключения и не записан как pass. Backend build/996 emitted parity passed. Actual production PG SELECT выполнен compiled candidate через default_transaction_read_only=on:8 history rows, newest BGP0/current BGP0/GRE0, old owned peers0; bootstrap/writes/RouterOS/messages отсутствовали. В этих real latest rows не доказан positive error/partial fixture — отдельный seeded SQL сценарий запланирован166.

ux-collector165 развёрнут с rollback env, backend/PG healthy, frontend ux-bfd158 сохранён;3 readonly GET и2 live UI1440/320 passed/no errors/overflow. Source frontend/primitives ReUI/Frame/base-nova не менялись; широкая UI regression157 не повторялась. Пароли/RouterOS config сохранены, fixtures не создавались этим блоком.

Протоколы: compiled996, real readonly PG, deployed API/UI. Следующий166 — own isolated PG с positive error/partial fixtures и полная backend regression при доступном PG, затем проверка удаления собственной DB/containers.12.5 открыт.

12.5.166 — полная backend-регрессия с доступным PostgreSQL (2026-10-12)

Общий npm --prefix backend test теперь запускает прежние24 профиля последовательно через cross-platform Node runner, устанавливая NODE_ENV=test без shell environment assignment. Pool использует штатный allowExitOnIdle только в test: завершённый SQL файл не ждёт30s idle socket. Production/development сохраняют обычный lifecycle; active queries не подменяются early exit. Permanent pool test проверяет оба режима без SQL подключения. Исходный список сохранён в test:all; прямой test:all — legacy chain без test-mode wrapper.

В отдельном Docker test image Node22/dev dependencies/PG18 tools создана собственная mm_accept_166_1791779292730. До bootstrap проверены уникальность, current_database и пустая public schema. Все SQL-тесты получили URL этой базы; основные server credentials не клонировались в тестовую DB, URL/env/полный лог остаются в private0600 вне Git. Все24 профиля завершились exit0 за286958ms (4m47s), PostgreSQL-unavailable skip отсутствовал. SQL confirm-stability тест, ранее skipped локально, выполнился и passed. Это измерение одного прогона, не процент ускорения без сопоставимого baseline.

Permanent owned SQL test перед DDL проверяет explicit MMAPP_OWN_SQL_DB/166 name/current_database.6 реальных scheduler_runs rows: old success, newest error с успешным BGP/failed GRE, SQL NULL result, malformed JSON string, successful empty и duplicate labels/keys. Actual reader/builder сохранили valid partial BGP, не восстановили старые/удалённые peers, не выдали malformed/null за success и подавили ambiguity. Собственные test rows удалены. Optional network-disabled SQL fixture152/156 без специального MMAPP_OWN_TEST_DB остался skipped;33 disabled/bigint guards156 не считаются повторно принятыми здесь.

Database owner проверен, только собственная DB удалена WITH FORCE после завершения child tests; main server id/host/name/username/password/type/enabled/country/site до/после совпали (в публичном отчёте только boolean, без значений). Own full-test container удалён после exact cidfile/state exited0 check. Main background polling продолжался, RouterOS сценарии не повторялись, реальные сообщения не отправлялись. Другие multi-instance/physical disconnect/real integrations границы прежние.

Backend production build и996 emitted parity passed; отдельный NODE_ENV=production readonly actual PG probe подтвердил allowExitOnIdle=false. ux-pg166 развёрнут с rollback env, backend/PG healthy, frontend ux-bfd158 сохранён;3 readonly GET/2 live UI1440/320 passed/no errors/overflow. Frontend source/ReUI/Frame/base-nova не менялись, UI/context regression157 не повторяли после backend-only delta.

Протоколы: full24/own SQL/cleanup, compiled996, production pool/read-only PG, deployed API/UI. Следующий167 — freshness/disabled collector-job audit; newest completed snapshot сам по себе не доказывает свежесть после остановки collector.12.5 открыт.

12.5.167 — устаревшие GRE/BGP снимки не подтверждают новые оповещения (2026-10-12)

Audit scheduler показал, что GRE/BGP сейчас всегда enabled, отдельного UI switch для него нет; interval30s фиксирован. Выдуманный disabled-job guard не добавлен. После остановки процесса/сборщика latest completed row может оставаться старым: reader теперь проверяет newest finished_at и producer sampledAt. Окно freshness —3 периода (90s), future clock tolerance —1 период (30s), привязанные к одной константе с scheduler timing/metadata. Старый, слишком будущий, invalid/nonstring sampledAt даёт unavailable/stale barrier и не порождает GRE/BGP current events. Прежние rows остаются last-known history при наличии свежего current; ambiguity guards163/165 сохранены. Это явно выбранная прикладная граница для30s collector, не RouterOS SLA или физическое обнаружение отказа.

Unit clock injection проверяет stale/future completion и sample, malformed/nonstring date,90s boundary; local alert/scheduler profiles/build passed. Local PG branches skipped, затем отдельный Node22/PG18.6 owned профиль test:alert-engine выполнился exit0 за31154ms:8 SQL rows (6 error/partial/NULL/malformed/empty/duplicate +stale/future sample) и actual confirm-stability passed, PostgreSQL-unavailable skip0. Полные24 profiles166 без необходимости не повторялись. Guarded integration test по-прежнему использует166 namespace; создана новая собственная mm_accept_166_1791781079670, прежняя166 база не переиспользована. Own rows/DB/container удалены; main server static fields до/после совпали. Приватный лог/env не попали в Git.

Backend production build/1000 emitted parity passed, ux-fresh167 развёрнут с rollback env, backend/PG healthy, frontend ux-bfd158 сохранён.3 readonly catalog/selected GET и2 live UI1440/320 passed/no errors/overflow. Source frontend/ReUI/Frame/base-nova и RouterOS правила/пароли не менялись, native tunnels не создавались, сообщения не отправлялись. Running containers после cleanup только3 основных сервиса. Свежесть других collector families/отключаемых jobs и stable-ID target migration этим блоком не закрыты.

Протоколы: owned SQL8/cleanup, compiled1000, deployed API/UI. Следующий168 — audit остальных alert source families: stale/disabled config не должны создавать current facts.12.5 остаётся открытым в матрице внешних ограничений.

12.5.168 — карта оставшихся источников оповещений (2026-10-12)

Выполнен source audit и чтение метаданных production PG с default_transaction_read_only=on. Source/database settings не менялись, default-seeding getters не вызывались, bootstrap/RouterOS/messages отсутствовали. Реальные текущие настройки: resources enabled/15s, traffic enabled/30s, REST disabled/120s, active Ping probes0. Builder в момент audit выдавал1 server signal (max age3.197s), traffic1 (max age18.24s), probes0. Это возраст наблюдаемого снимка, не controlled stale fixture. Одновременно обнаружена1 группа одинаковых имён у enabled servers: оба CHR называются одинаково,2 devices сворачиваются в1 name-based signal. Audit не исправляет это поведение.

Source findings: non-GRE/BGP reader выбирает только status=ok; resource/REST/traffic/probe reducers восстанавливают ключи из старых runs; evaluation не проверяет sampledAt age; builder не применяет текущие enabled flags источников. Resource reducer превращает всякое не-online значение в offline; одинаковые имена могут смешать current и previous разных устройств. Это подтверждённые свойства кода, но runtime disabled/stale/malformed fixture пока не выполнен. Не считать найденные проблемы устранёнными только по этому документу.

Источник Интервал / особенность Требование к следующему блоку
Resources Настраиваемый intervalSec, на стенде15s; default300s Effective resourcesEnabled; уникальная identity/current known state; возраст по своему периоду
REST availability Отдельные enabled/intervalSec; сейчас выключен Выключенные/старые REST данные не переопределяют свежий resource result и не подтверждают recovery
Ping probeIntervalSec и individual uptime_probes.intervalSec; snapshot содержит только due probes Фильтр enabled probes/source servers; latest observed row каждого probe и его собственный TTL, не latest-run-only
Traffic Настраиваемый enabled/intervalSec; сейчас30s Отсутствие/старое/disabled не превращается в zero/low traffic; identity не смешивает одинаковые имена

Период GRE/BGP30s/границу90s167 нельзя механически распространить на resources default5min или Ping с индивидуальным расписанием. Для169 сначала определить effective config каждого family и per-probe timing, затем coherent current states/previous known history без cross-device aliases. Проверить own PG: disabled source с retained history, stale/future times, newer error/null, empty/deleted object, duplicate labels, частичный due-probe batch и controlled recovery. Локальные unit/profile tests + scoped SQL; production build только backend после окончательной delta. Полную UI/context regression повторять лишь при frontend foundation change, остальные native протоколы не переснимать без новой причины.

Схема доработки:

flowchart LR
  A["Текущий источник и устройство"] --> B["Enabled и уникальная identity"]
  B --> C["Последнее наблюдение и свой интервал"]
  C --> D{"Свежий известный факт?"}
  D -->|да| E["Условие правила и last-known history"]
  D -->|нет| F["Нет подтверждения события"]
  E --> G["Outbox после подтверждения"]

Протокол: readonly audit168. Source/build/runtime не менялись после167, новые тесты и исправления не заявляются. Следующий169 — выполнить этот единый блок, сохранить profile/owned SQL результаты и локальный коммит без push. Реальные Telegram/Portal/внешние accounts, client OS/physical WAN/multi-instance остаются отдельными условиями12.5.

12.5.169 — идентификация устройств в сигналах оповещений (2026-10-12)

По поручению пользователя выполнить небольшой объём при оставшихся7% лимита. Исходный единый объём169 ограничен самостоятельной локальной частью; полная приёмка источников не заявляется. Добавлен server-signal-identity.ts, builder читает только id/name/host/enabled из текущего servers. До name-based timeline и traffic reducer каждая строка resource/REST/traffic сопоставляется с текущим активным устройством по ID, имени и адресу. Сигналы отключённых/удалённых устройств, старого имени/адреса и повторяющегося ID внутри одного run исключаются. Если несколько enabled устройств имеют одинаковое имя после trim/lowercase, их сигналы не выдаются: существующие правила адресуют цель по имени и не позволяют безопасно выбрать конкретное устройство. Имена/настройки самих CHR не менялись. На текущем стенде оба CHR имеют одинаковое имя; после будущего развёртывания такие цели будут подавлены до явного устранения неоднозначности или миграции правил на ID. Это консервативное отсутствие подтверждённого события, не offline и не нулевой traffic.

Новый постоянный тест добавлен в test:alert-engine: уникальная цель; отключённая/удалённая; два одноимённых устройства и перестановка каталога; отключение дубликата; изменение имени/адреса; другой ID; повторные строки; строковый безопасный PG ID и небезопасный ID; неизменность входа. Прошли доступные проверки alert-engine (identity/groups/evaluate-rule/collector/history), backend production build и ESLint трёх изменённых TS файлов. GRE/BGP SQL пропущен без явно выделенной own DB; confirm-stability SQL пропущен из-за PostgreSQL connect EACCES127.0.0.1:5432. Это не положительная SQL-приёмка. Полная UI/context regression не запускалась: frontend не менялся.

Ограничения сохранены явно: only-ok history всё ещё может поднимать старый факт, disabled flags самих jobs и sampledAt age не применяются; resource unknown и traffic отсутствующее значение требуют отдельного исправления; probe identity/enabled/individual interval остаются в170. Duplicate row guard не заменяет latest-current/error barrier. SQL/live fixtures и source/runtime parity для169 отсутствуют; удалённый backend/frontend не развёртывались, RouterOS writes/messages0, новые сетевые объекты не создавались. Доступность серверов в этом локальном блоке не перепроверялась. Runtime остаётся ux-fresh167/ux-bfd158; изменений169 в браузере пока нет.

Протокол: локальная проверка169. Следующий170 — source enabled/freshness/current known guards, per-probe timing и identity с owned SQL positive/negative fixtures, затем coherent backend build/deploy/live и локальный коммит без push. Этап12.5 остаётся открытым.

12.5.170 — достоверность серверных, пробных и трафиковых сигналов (2026-10-12)

Завершён оставшийся объём169 в одном coherent backend блоке. Новый collector-source-signals отделяет чтение от чистого построения фактов. Builder читает текущие настройки и identity без seeding getters и без credentials: resourcesEnabled/pingEnabled имеют тот же fallback на legacy enabled, что scheduler; REST/traffic используют собственные enabled. Выбираются последние завершённые ok/error runs, включая NULL/error JSON, вместо only-ok history. Текущие server/traffic keys берутся только из newest run: empty/error/malformed/unknown не восстанавливают старую цель. Частичная ошибочная коллекция сохраняет известные строки других устройств. ServerID/name/host/enabled/duplicate guards169 сохранены; пустое имя может использовать host, как collector. producer sample и completion проверяются по3 effective periods, future tolerance1 period; минимумы5s resources/traffic и10s REST повторяют scheduler. Resource неизвестное значение не становится offline; Traffic требует ok=true и конечные неотрицательные RX/TX, отсутствующее/ошибка не становится0. Подтверждённый нулевой трафик остаётся0.

Ping сопоставляется с текущим probeId/name/target/sourceServerId/interface/source label, enabled probe и enabled source. Повторные цели/строки исключаются; более новое unknown/null/fatal/error observation не подменяется старым. Valid due-only batch может не содержать медленную пробу: её latest observed row сохраняется в пределах своего TTL. Effective probe period учитывает individual interval и глобальный tick, default минимум5s; future tolerance привязана к глобальному tick. Чтение охватывает3 максимальных настроенных probe periods, с защитным пределом4096 rows (при очень большом масштабе возможен консервативный пропуск, масштаб этим блоком не принят). Сэмплы до server/probe updatedAt не подтверждают новую конфигурацию. Server timelines прекращают recovery history на unknown/invalid/ambiguous barrier; свежие resource/REST подтверждения объединяются без выдуманного cross-source recovery. Выбирается реальное собственное history успешного источника.

Постоянные чистые тесты проверяют config/identity/time/empty/error/partial/unknown/numeric boundaries, медленные due probes, изменения конфигурации, recovery и настоящий evaluateRule путь с положительным и отрицательным control (server offline, loss и RX low). Локальные alert-engine и scheduler profiles прошли, backend build и ESLint прошли. Локальный PostgreSQL недоступен, SQL branches там skipped; положительная SQL-приёмка выполнена отдельно на Node22/PostgreSQL18.6: test:alert-engine за18622ms,16 новых SQL cases (включая31 Ping batches, больше прежнего лимита24),8 GRE/BGP SQL rows и actual confirm-stability passed без PG skips.

Автоматическая проверка отклонила копирование всех production env в persistent файл; этот способ не использован. Для SQL созданы собственная база mm_accept_166_1791791913287 и отдельная LOGIN роль без SUPERUSER/CREATEDB/CREATEROLE/BYPASSRLS, пароль сгенерирован временно и не публиковался. URL/роль ограничены own DB; main credentials/JWT не копировались. Тестовые строки/контейнер, база и роль удалены и отсутствие проверено. Main SQL fixtures/RouterOS/messages отсутствуют; обычные фоновые сборщики main не останавливались. Полная24-profile/UI1260/context221 regression157/166 без новой причины не повторялась.

Production backend собран инкрементально на прежней базе ux-fresh167 с прежними зависимостями: backend dependency hash совпал.433 source inputs и1008 emitted files совпали поSHA256 с LF normalization, запущенный imageId совпал с проверенным образом. Развёрнут ux-sources170/version1.0.0-test.sources170, backend/PG healthy; frontend ux-bfd158 прежний. В.env изменён только BACKEND_IMAGE_TAG, для rollback сохранён прежний tag ux-fresh167, копия всего secret env не создавалась. После cleanup только3 основных running containers.

Readonly production PG builder подтвердил1 группу одинаковых enabled labels и0 server/traffic/probe signals. Ноль проб соответствует отсутствию configured probes, server/traffic подавлены из-за неоднозначности двух CHR с одним именем; это не отказ устройств и не доказательство положительных измерений (они проверены в owned SQL). Имена/пароли не менялись.4 read-only API checks включают оба selected CHR BGP endpoints и catalog без failures;6 UI cases /alerts,/servers,/uptime при1440/320 passed, pageerrors/API writes/overflow0. Первые локальные network calls получили sandbox EACCES, повтор с разрешённым network доступом passed; UI helper сначала ожидал отсутствующий в существующей странице h1, исправлен на фактический main без изменения frontend. Это scoped smoke, не новая полная accessibility сертификация.

Протоколы: SQL16/cleanup, source433, compiled1008, readonly production, runtime, API/UI.

Следующий171 — понятная диагностика неоднозначных/отключённых целей оповещений: silent suppression безопасен для engine, но пользователь должен понимать причину отсутствия события. Миграция name-based rules на stable ID, scale/multi-instance/physical WAN/внешние Telegram/Portal/client OS остаются отдельными условиями12.5. Локальный коммит без push.

12.5.171 — понятные причины недоступности целей оповещений (2026-10-12)

При conservative suppression170 пользователь должен понимать, почему событие не подтверждается. Добавлен чистый collectAlertTargetIssues и optional public meta.targetIssues: kind server/traffic/probe, подпись и причина ambiguous/disabled-object/disabled-source. Диагностика строится из текущих настроек внутри того же repeatable read/read only transaction, что основной overview; getters defaults не создают. Учитываются dedicated source switches, enabled REST как разрешённый availability source по конфигурации, enabled устройства/пробы, duplicate labels и fallback имени на host. Это диагностика конфигурации; она не заявляет свежесть измерений, online устройств или фактическую доставку Telegram. Поля credentials не выбираются и не публикуются. Engine правила, target representation и права не изменены.

На /alerts добавлен существующий ReUI/shadcn Alert warning в base-nova/Frame композиции без изменения vendor files/theme. Строки доступности и трафика одной цели объединены; причина и дальнейшее действие читаются вместе. Длинный список раскрывается native details/summary клавиатурой, большой список изначально свёрнут; длинные подписи переносятся на телефоне. Ссылки ведут к серверам, пробам и сбору данных. При устранении причины warning исчезает после подтверждённого обновления; legacy API без optional поля не подменяется догадкой. Имена двух CHR и targets действующих правил автоматически не переписывались.

Эталон Доработка Проверка
Существующие Alert и Frame проекта Подпись → причина → понятный переход → обновление ПК1440, телефон320

Локально прошли12 скриптов test:alerts-telegram (unit/transaction/config/queue/HTTP/JWT), application-source TypeScript, backend build и ESLint. Полный root tsc сначала захватил ignored tmp с давними test/build artifacts и выдал их ошибки; source check с исключением tmp/backend/packages прошёл, contracts/backend проверены собственной сборкой. Root tsconfig не менялся.42 unique E2E:22 readers/targets/pickers/rules/new diagnostics за44.7s;19 history/outbox/Telegram за30.6s;1 новый keyboard/long-label mobile за6.2s. Реальная отправка Telegram отсутствовала: HTTP пути подменены тестовыми receipts. Последняя проверка хронологии старым check-progress168 ожидала прежний header168; сам сохранённый historical slice имел12 dated blocks/35 существующих evidence links. Это устаревшее ожидание helper, не удаление журнала; актуальная сверка обновлена отдельно.

Owned Node22/PostgreSQL18.6 profile passed19540ms:16 source SQL cases плюс проверки actual getAlertsMeta (known empty, disabled-source reasons, ambiguous server/traffic kinds),8 GRE/BGP SQL rows и actual stability;PG unavailable skips0. Временная own DB/ограниченная роль mm_accept_166_1791794042576 и test container удалены. Main fixtures/RouterOS writes/messages0. Обе production сборки прошли; source434 backend+518 frontend inputs и1012 emitted backend/contracts files совпали SHA256 (text CRLF→LF, binary unchanged). Полную UI1260/context221/backend24 regression без новой причины не повторяли.

Развёртывание staged: frontend ux-targets171/version1.0.0-test.targets171 сначала принял реальный прежний API ux-sources170 без targetIssues; затем обновлён backend ux-targets171. На старом cached frontend строгий прежний DTO не знает additive поле: после обновления backend следует перезагрузить страницу для получения совместимого frontend. Менялись только image tags в existing.env; rollback tags сохранены отдельно без копирования secret env. Backend/PG healthy; frontend running/HTTP/browser подтверждён, отдельного healthcheck нет. Запущенные imageIds совпадают с проверенными образами; после cleanup3 основных running containers.

2 real UI1440/320 показали настоящий CHR warning:1 сгруппированная подпись,2 affected kinds, ссылка /servers, overflow/pageerrors/API writes0. Scoped axe нового блока WCAG2A/AA violations0, full WCAG certification не заявляется. Снимки просмотрены; исходные пользовательские GRE/VXLAN images сохранены без staging/revert. Настройки/имена/пароли CHR и исходные правила не менялись.

Протоколы: SQL/cleanup, source, compiled, interop, runtime, live UI.

Следующий172 — отдельная обнаруженная ветка: синтезированный monitoring history в alerts-service читает raw latest samples, пока не применяет enabled/freshness/current-error guards170 и требует проверки реального PG timestamp→public string на positive sample. Source finding не является уже выполненным исправлением или доказанной runtime ошибкой. Stable-ID target migration, отсутствующие цели удалённых правил, physical WAN/scale/multi-instance и реальные Telegram/Portal/client OS остаются отдельными условиями12.5. Локальный коммит без push.

12.5.172 — подтверждённые текущие проблемы в журнале мониторинга (2026-10-12)

Внешнее воспроизведение выполнено на compiled ux-targets171 с own PostgreSQL/ограниченной ролью. Прежний overview принимал положительный raw sample и корректно выдавал timestamp string: гипотеза Date/schema failure НЕ подтвердилась. Первая baseline попытка ожидала ошибку и завершилась assertion failure; её результат сохранён, own fixture/DB/role очищены. Уточнённый baseline прошёл: один и тот же live offline оставался после disabled server, disabled resources source и замены sampledAt на часовой давности. Это положительное независимое подтверждение реального disabled/freshness дефекта прежней ветки, не вывод только из кода.

Raw uptime_resource_samples/uptime_probe_samples больше не используются как самостоятельное доказательство текущей проблемы в alerts history. Выделен readCollectorSourceSnapshot с injectable reader: engine и history используют одинаковые current/config/identity/unknown/freshness/per-probe guards170. History читает source facts через параметризованный Drizzle adapter в том же repeatable read/read only transaction overview, без глобального pool обхода snapshot. Значения запроса остаются bound params, raw fragments — только внутренние постоянные SELECTs. Network GRE/BGP не перечитывается для этой ветки. Конфигурация, источники и lookup metadata остаются readonly; defaults/credentials не загружаются.

monitoringHistory строит live problems только по подтверждённым offline/degraded серверам и down/warn пробам. Заголовок сервера «Доступность сервера» соответствует объединению resource/REST, а не выдуманному outage CPU. Live sent=false/source=live сохраняются: это мониторинг, не факт отправки Telegram. ISO timestamps нормализованы, IDs используют stable hash вместо удаления символов, чтобы разные подписи не схлопывались. Persisted source=db receipts и sent flags сохранены независимо от доступности устройства/источника. Сортировка merged history сравнивает реальное время, чтобы новый ISO live timestamp и PostgreSQL datetime string не нарушали порядок. Это совместимость форматов; старый overview уже корректно проходил schema, driver Date bug не заявляется.

Source/build/unit/ESLint прошли. Локальные alert-engine и12 скриптов alerts-telegram прошли в доступных ветках; локальный PG skipped.4 профильных reader/history E2E прошли11.0s; frontend исходники не менялись, полную UI/context regression не повторяли. Owned Node22/PG18.6 сначала выполнил25 source/history cases; после дополнительного chronology control финальный профиль26 cases прошёл19421ms, плюс GRE/BGP8 и actual stability, PG skips0.9 history scenarios поверх прежних16 и1 chronology: positive live+synthetic stored receipt, disabled device/source, stale JSON при свежих raw tables, newer NULL/error, empty/current absence, same-name server ambiguity с независимой пробой, changed probe identity, raw-only samples без подтверждения; более новая DB receipt стоит первой при смешанном формате дат. Синтетический receipt в own DB не доказывает реальную Telegram доставку.

Все известные baseline/fix DB names и роли удалены, test containers отсутствуют. Один SCP connection закрылся после задержки authentication; финальный bundle повторно передан и verified перед deploy. Промежуточные25-case результаты не выданы за финальные26. Source437 и1020 emitted files совпали SHA256/LF normalization. Production build прошёл; backend ux-history172/version1.0.0-test.history172 развёрнут, imageId совпал с проверенным, backend/PG healthy, frontend ux-targets171 прежний. Existing.env изменён только backend tag, rollback ux-targets171 сохранён без копии secret env. Running containers3.

Первый live GET совпал с закрытием старого контейнера и получил socket closed; после healthy повтор прошёл.3 API reads (/api/alerts и оба selected CHR BGP)200,2 /alerts UI1440/320 accepted/overflow/pageerrors0, configuration warning171 сохранён. Source engine facts и UI journal теперь согласованы в проверенных границах. Raw-only/manual measurements без подтверждённого scheduler snapshot не синтезируются как текущие alerts; их provenance требует отдельного профиля. Native configs/пароли не менялись, RouterOS writes/messages0. Реальная packet loss/current state для scope устройств в этом блоке не создавалась: собственные SQL fixtures, не новый data-plane тест.

Протоколы: first baseline hypothesis, real baseline, SQL26/cleanup, source437, compiled1020, runtime, API/UI.

Следующий173 — source finding: collectPingProbesOnce/pingProbesNow catch превращает ошибку REST-команды в lossPct100/down; decoder пока разрешает ok=false/down/null/100. Это не независимое доказательство потери пакетов. Проверить и исправить подтверждение измерений/empty payload; не объявлять legacy raw UI stats и manual provenance уже исправленными. Также остаются unconfirmed/missing target diagnostics, stable-ID migration, scale/multi-instance/physical WAN и внешние Telegram/Portal/client OS.12.5 открыт. Локальный коммит без push.

12.5.173 — ошибка Ping не подменяет измеренные потери (2026-10-12)

Завершён целый раздел producer→SQL→API→UI. parsePing теперь возвращает measured: empty/unsupported replies, zero sent и противоречивые/malformed counts не подтверждают процент потерь. Подтверждённые received0/sent4 остаются100%/down с RTTnull; успешный настоящий RTT0/loss0 сохранён. Scheduled и manual collectors различают успешное измерение и ошибку REST/недостаточный ответ; after-bandwidth Ping при неизвестном результате возвращает null metrics/error, а не выдуманный outage. Alert decoder принимает только ok=true и известное состояние; retained legacy ok=false/down/100 не срабатывает как измеренная потеря. Malformed due-probe rows без ID — barrier, не разрешение восстановить старое измерение.

Миграция0010 добавляет uptime_probe_samples.measurement_known boolean defaulttrue и observation_error text; CHECK/legacy storage status и integer loss не ломаются. Raw100/down в failed rows — прежние storage sentinel с явным measurement_known=false, не публичное измерение. Snapshot/public observations/API loss становятсяnull/statusunknown, есть причина ошибки. Новые flags пишутся при scheduled и manual error/empty response. Старые scheduled failure samples переклассифицируются readonly по точному probeId+sampledAt retained v1 JSON provenance; genuine100% без failure flag не меняется. Старые manual/retention-lost failures без provenance надёжно восстановить нельзя: они остаются legacy ambiguity, полного historical cleanup не заявляем. Migration additive, прошлые данные не удаляет; source JSON internal v1 теперь допускает nullable loss/unknown. Для rollback старый код не интерпретирует measurement_known, поэтому совместимость хранения не означает корректное чтение новых unknown attempts старой версией.

Overview выдаёт unknown/null без fallback100/down и без padded historical0. Observations timestamps канонизированы; parser проверяет согласованность unknown/null. /uptime использует тот же observed decoder, что dashboard: «Нет данных», — для RTT/loss, причина execution error, отдельный filter/URLstatus=unknown. Новая draft probe тоже не объявляется заранее up/0. Мини-Sparkline сохраняет gaps; expanded RTT chart больше не превращаетnull в0 и не дублирует одиночную точку для выдуманной линии. Dashboard status tooltip получает причину. Source/speed-interface read endpoints теперь409 до RouterOS при disabled server; ошибочная подпись «для ping всё равно можно выбрать выключенный» исправлена. Это соответствует прямому правилу пользователя не опрашивать выключенные устройства любых типов. UI/ReUI primitives/theme не заменены.

Состояние Эталон Результат
Ошибка REST/нет измерения Существующие probe rows/StatusDot/Sparkline ПК1440, телефон320 — API-fixture, не production positive sample
Подтверждённые100% Тот же public observed path Down и100% сохранены отдельным positive control

Unit parser/observations/frontend dashboard-probes/URL guards прошли; backend build, application-source TypeScript и ESLint прошли (в uptime-collector два прежних unused settings warnings, functional scope не расширен). Первый npm --prefix exec взял неверный cwd, повтор direct tsx корректен; новый тест сначала использовал неверное имя Zod package, исправлен на установленный @fastify/type-provider-zod. Local cancellation test получил sandbox EACCES, разрешённый сетевой профиль прошёл; local own SQL skipped без выделенной базы.85 unique E2E Uptime/Ping/Speed: initial83passed/2failed были новые ambiguous test selectors (имя есть в sidebar и строке); selector исправлен на конкретную причину ошибки, delta3passed9.5s. Existing83 scenarios повторно не запускались;2 screenshot captures passed8.5s отдельно. Это не85 clean single-run и не87 новых сценариев. Два перезаписанных тестами прежних speed images восстановлены SHA256;8 user dirty GRE/VXLAN images не тронуты. Новые снимки просмотрены, nullable состояние читаемо при320px.

Owned Node22/PG18.6 профили alert-engine+probes прошли42380ms:26 source/history SQL cases, GRE/BGP8/actual stability и8 новых Ping cases. Последние проходят через реальный MikrotikClient HTTP к loopback simulator, persisted flags, GET overview Fastify path:401,empty,manual,real loss/zero,API,legacy exact provenance и disabled no-outbound requests. Simulator не является физическим RouterOS/network failure. Финальные unit guards zero/inconsistent counts/malformed probe проверены перед scoped rerun; temporary DB/role/container удалены. Production credentials/JWT не копировались. Type/producer tests подключены к стандартному test:probes; default profile count не увеличен.

Source440 backend+518 frontend inputs/1020 emitted parity совпали SHA256. Both production builds passed, backend image включает новый drizzle0010. Staged deploy: frontend ux-ping173 сначала принял старый API ux-history172, затем backend ux-ping173/version1.0.0-test.ping173. Migration0010 и2 новых columns подтверждены readonly в main PG. Backend/PG healthy, frontend running/HTTP/UI, imageIds verified, running containers3. В.env менялись толькоimage tags; rollback tags сохранились отдельно без secret env копии. Cached прежний frontend следует перезагрузить: новые nullable/unknown DTO требуют совместимого reader.

Независимо выполнен настоящий native Ping4 packets194.226.121.150→104.165.244.7 иобратно через running compiled173: обе команды приняты, обе4/4,0%loss, parsed RTT53ms. Это короткое наблюдение, не WAN SLA/max throughput. Main DB read-only, native конфигурация/пароли не менялись;2 operational Ping commands, routerConfigWrites0/messages0. На production configured probes0:2live UI1440/320 подтверждают actual empty catalog/new filter/reader/overflow/pageerrors0; nonempty/error UI доказан fixtures, не выдан за main positive measurement. Collector row/error flags проверены ownSQL, real parser отдельно native payloads.

Протоколы: SQL/HTTP8+cleanup, native4/4, source, compiled, interop, runtime, live UI.

Следующий174 — audit first-wave/invalid traffic rate confidence: ok request и numeric sum не всегда доказывают измеренный rate без previous wave. Не заявлять эту гипотезу как уже выполненное исправление. Source unconfirmed/missing target diagnostics, manual history provenance, unsupported/compound time formats, legacy ambiguous samples, scale/multi-instance/physical WAN/external integrations остаются отдельными условиями12.5. Полная acceptance открыта. Локальный коммит без push.

12.5.174 — достоверность суммы трафика: аудит и локальное исправление (2026-10-12)

На исходном8fb46b1 гипотеза подтверждена исполнением настоящих private sampleRate/toNum, извлечённых TypeScript AST, затем существующих collectSourceSignals/evaluateRule. Семь source fixtures: first-wave/reset/equal timestamps/missing/malformed counters дают0 и ложный RX<1; genuine zero даёт правильное срабатывание, positive1Mbps не срабатывает. Протокол baseline audit намеренно fixed=false и относится к исходной версии, а не к финальному исправлению. Это локальное source воспроизведение; отправки Telegram, реальной SQL persistence и физического сброса RouterOS не было.

Добавлен pure traffic-observation: строгие safe nonnegative integer counters, без parseFloat prefix/negative clamp/missing→0; observed rate подтверждается только двумя валидными дельтами. Traffic collector оставляет numeric stored-rate shape, но публикует sumRxMbps/sumTxMbps только при наличии учитываемых интерфейсов и measured=true у всех. First wave, reset, равное/invalid время, частично неизвестный интерфейс и отсутствие учитываемых интерфейсов не становятся измеренным нулём; genuine zero сохраняется. Некорректный interface counter завершает текущий server snapshot с ok=false до insert. WG peers остаются optional: ошибка их чтения/декодирования не превращает корректный interface snapshot в failure; частичные валидные peer rows могут остаться. Это не новая гарантия полноты peer history.

Existing snapshot types уже имеют optional суммы; source decoder174 не менялся и исключает отсутствующие суммы. Таблица snapshots уже показывает — при отсутствии значения; ReUI/theme не менялись. Historical traffic builder уже различает первый sample и measured zero при includeObservations=true. Старые загрязнённые counters/rates не переписаны: ошибку прежнего missing-counter→0 нельзя надёжно реконструировать без provenance. Consumer raw numeric-rate compatibility, freshness/failed attempts history, безопасный baseline после смены объекта, unsafe integer counters и масштаб требуют отдельной SQL/HTTP-приёмки.

npm --prefix backend run test:traffic-rate прошёл: существующие формулы/observations, новый counter/rate/source guard и actual collectTrafficOnce body через AST с in-memory DB/HTTP boundaries (first wave, zero, reset, malformed/no insert, excluded interfaces). Извлечение исполняет исходный collector, не копию алгоритма; это не реальный PostgreSQL или RouterOS. npm --prefix backend run build прошёл. Local check фиксирует хеши изменённых source и границы доказательства. Full regression/remote deployment не выполнялись, поскольку изменён только локальный producer guard.

Следующий175: real MikrotikClient loopback HTTP→owned PostgreSQL→scheduler resultJson→source decoder с first-wave/next-zero/reset/malformed/mixed-interface controls; проверить очистку своих объектов и исключение stale historical samples. После profile acceptance собрать backend и развернуть guard на тестовом стенде; frontend ux-ping173 совместим с absent optional totals. Сейчас оба сервиса удалённого стенда всё ещё ux-ping173, native Ping4/4 подтверждён в173; новое исправление там ещё не доступно. Пароли, конфигурация CHR и тестовый runtime этим блоком не менялись. Локальный коммит без push.

12.5.175 — SQL/HTTP-приёмка достоверности трафика и развёртывание (2026-10-12)

Producer guard174 проверен через настоящий MikrotikClient к loopback HTTP simulator, actual collectTrafficOnce, PostgreSQL18.6 и buildSignalSnapshotFromCollectors. Девять SQL controls: first wave без суммы/со stored valid counters; следующая genuine zero; reset без суммы; malformed123bad и missing counter дают ok=false/no insert; новый второй интерфейс не даёт частичную сумму; следующая полная zero wave; положительная скорость; disabled server без outbound HTTP. Каждая актуальная wave сохраняется в scheduler_runs и проходит реальный source reader. Fixture clock не задерживает тест: в своей базе сохраняется только последняя baseline wave и сдвигается её время на30s. Это не проверка длинной historical continuity/retention и не физический RouterOS counter reset.

Профиль test:traffic-rate дополнен тестом traffic-observation-sql.test.ts. Локально SQL явно skipped без own database; удалённый Node22/PG18.6 профиль прошёл9358ms без SQL skip. База mm_accept_166_1791803283546 принадлежала временному LOGIN без SUPERUSER/CREATEDB/CREATEROLE/BYPASSRLS. Актуальные production DB/JWT secrets не копировались. Тестовые rows убраны finally, база/роль/container удалены trap и отсутствие DB/role проверено каталогами; остались только3 основные контейнера. SQL.

Production backend build прошёл локально и на Debian; 1024 compiled artifacts совпали SHA256 с локальными, different/missing0. Backend ux-traffic175/version1.0.0-test.traffic175 развёрнут; frontend ux-ping173 сохранён и совместим с optional sums. До сборки исправлена строка Docker base, которую ошибочно заменила blanket tag substitution; неисправный Dockerfile не собирался и не выпускался. В.env менялся только BACKEND_IMAGE_TAG, rollback tag ux-ping173 сохранён без копии секретного env. Runtime: verified imageIds, backend healthy/frontend running.

Read-only live smoke: /traffic1440/320, traffic servers200/no pageerrors/no overflow; /servers,/traffic/servers,/scheduler/runs?jobKey=traffic200. Это проверка доступности/совместимости UI, не доказательство доставки Telegram или возникновения всех edge cases в main DB. Нет manual scheduler run/config/password/message writes; автоматический scheduler остаётся штатным. Пароли CHR не менялись; native Ping4/4 в обе стороны подтверждён ранее в173, здесь повторно не заявлен.

Следующий176 — inspect native compound durations53ms561us и parseFloat prefix fallback в Ping parser; положительные source payloads уже сохранены в173, не требуются новые сетевые сущности для первоначального доказательства. Legacy invalid traffic counters/raw-rate consumers, history freshness/failed attempt barriers, interface identity/config changes, scale/multiple backend и внешние интеграции остаются условиями12.5. Не считать guard174–175 полной приёмкой трафика. Локальный коммит без push.

12.5.176 — точность составных длительностей Ping RTT (2026-10-12)

В native payloads173 обоих CHR есть53ms561us и другие ms/us. Прежний parseFloat fallback терял microsecond component; например53ms900us превращалось в53ms вместо rounded54ms,1s53ms561us — в1ms вместо1054ms. parsePingTimeMs теперь разбирает ordered s/ms/us, простые decimal units, comma decimal, clock c minute/second<60 и полную bare millisecond numeric string; duplicate/reverse units, negative, exponent, unknown suffix и numeric-prefix garbage возвращаютnull. Значения хранят дробную точность до прежнего integer rounding общего RTT. Success-reply fallback теперь требует валидную duration; garbage time без explicit counts/loss не изображает успешное измерение. Summary с подтверждённым packet loss может иметь RTTnull — loss от этого не подменяется.

Добавлены unit positive/negative controls, genuine0,53ms900us→54 и1s53ms561us→1054. Offline replay двух сохранённых настоящих CHR responses173 подтвердил дробные значения53.xms и прежний правильный rounded mean53ms/0%loss. Это повторная интерпретация записанного ответа, не новый физический Ping. Local/native replay protocol. Файл evidence optional в test runner: если отсутствует в image, replay явно skipped, форматные guards продолжают исполняться.

Backend production build и полный профиль test:probes прошли (8.0s): HTTP/allowlist/cancellation/actual local fake RouterOS POST, parser/observations. SQL test явно skipped локально без own database; предыдущая SQL173 не выдана за приёмку изменённого176. Это не подтверждает полную RouterOS duration grammar или malformed summary loss/count consistency; остальные источники unknown/provenance и legacy rows остаются открыты. Новые Docker build/deploy/remote SQL на этом остатке квоты не запускались.

Следующий177 — owned SQL/HTTP regression Ping8 на изменённом parser, при необходимости добавить compound/raw-garbage producer cases; затем incremental backend build, compiled parity, deploy и read-only browser smoke. Backend удалённого стенда остаётся ux-traffic175 healthy, frontend ux-ping173. Отдельный реальный success replay не заменяет SQL error persistence. Конфигурация/пароли CHR, production DB, отправки сообщений этим блоком не менялись. Все изменения176 сохранены локальным коммитом без push;12.5 не закрыта.

12.5.177 — SQL-регрессия составного RTT и обновление стенда (2026-10-12)

Ping ownSQL173 расширен двумя controls: summary53ms900us сохраняется как RTT54ms/loss0; raw53bad без подтверждённых counts/loss сохраняется как unknown/null/error. Остальные8 controls сохранены:401/empty/manual/actual100%/zero/API/legacy exact provenance/disabled no outbound. Node22/PG18.6 полный test:probes прошёл24383ms,10 SQL cases без skip. Тесты используют настоящий MikrotikClient к локальному HTTP simulator и действующий collector/PG observations; физический RouterOS malformed response не создавался. Native replay2 выполнен локально176; в удалённом test image evidence file отсутствует и replay явно skipped, не выдан за повторную physical проверку. SQL.

Временная ownDB mm_accept_166_1791803917983 и ограниченная роль удалены trap; отсутствие проверено PG-каталогами, отсутствие test container — docker inventory. Рабочие DB/JWT secrets не копировались. Новая backend image ux-rtt177/version1.0.0-test.rtt177 собрана поверх ux-traffic175; 1024 compiled files совпали с локальными SHA256/missing0/different0. В.env изменён только BACKEND_IMAGE_TAG; rollback tag ux-traffic175. Runtime: backend healthy, frontend ux-ping173 running, imageIds совпали.

Live UI1440/320 прошёл: uptime overview200, unknown filter, no overflow/pageerrors. Actual production probes catalog пустой — эта smoke проверка не изображает main compound/error sample; они подтверждены отдельной ownSQL. Новых native Ping/config/password/Telegram операций не выполнялось. Пароли CHR не менялись. Исправления Ping173/176 и traffic174–175 теперь совместно доступны на тестовом backend; UI layout не менялся.

Следующий178 — read-only audit traffic history freshness при failed collection и legacy invalid-counter provenance; не объявлять старые неоднозначные строки исправленными по новому producer guard. Source unconfirmed/missing diagnostics, summary loss/count consistency, scale/multi-backend, физические WAN и внешние интеграции остаются условиями12.5. Журнал/план синхронизированы; локальный коммит без push. Новых блоков до следующего окна не начинать.

12.5.178 — достоверная история трафика, ручной сбор и свежесть UI (2026-10-12)

Подтверждены source gaps: исторические deltas могли выдавать старую скорость как текущую после failed collection; manual collect-now игнорировал snapshot failures и публиковал success. Добавлена migration0011/traffic_collection_state (одна актуальная запись на server): pending до HTTP, ok/error после записи, lastAttemptAt/lastSucceededAt и конфигурационный updatedAt fingerprint. Pending/error не стирают successful history. Completion обновляет только свою lastAttemptAt; pending не переписывает более новую попытку. Это ограничивает гонки записей, но не является распределённым lock/полной приёмкой нескольких backend.

Freshness reader read-only: enabled device/source, совпадение config fingerprint, state.ok и exact latest sample/success/attempt, TTL3periods (min5s), future tolerance1period. Error/pending/stale/disabled/config change/unknown маскируют current RX/TX; historical observed masks сохраняются. API серверов, клиентов и привязок получает observations/provenance; interface inventory больше не использует stored-rate fallback и не смешивает WG peer rows с interface counters. Source facts дополнительно учитывают новую attempt barrier, поэтому manual error/pending не оставляет старое traffic alarm активным. Для устройств без новой state пока читается прежняя scheduler provenance; первая новая попытка создаёт authoritative barrier. Не считать этот переход доказательством точности каждого старого snapshot.

В flags зарезервирован bit4 countersKnown, выставляется только новым strict collector. Старые/imported rows не переписаны и не объявлены достоверными; previous wave отбирает known counters. Исторический builder не строит deltas между legacy/unknown counters. Учтённые bytes суммируются по подтверждённым соседним дельтам; reset не добавляет произвольный новый counter как объём. Это lower-bound accounted volume, не утверждение полного покрытия периода. В UI подпись «Учтено RX/TX по замерам»; неизвестные скорости/пики/объёмы — —, chart gaps — null. Genuine measured0 сохраняется. Сортировка держит unknown после measured values. Dashboard existing decoder продолжает использовать masks.

Manual collect-now теперь через runSchedulerJobNow/общую запись результата и execution lock. Busy409; fatal/partial failures502 c failures/succeeded и сохранённым scheduler error; confirmed success200. Scheduler traffic ok=false теперь execution limitation, а genuine0 — success; valid offline/down других collectors не изменены. Ошибка setup больше не оставляет collecting=true навсегда: getSettingsRow находится внутри try/finally. Existing event/journal-unknown semantics сохранены.

Frontend projectTrafficObservations валидирует metadata/метрики, маскирует legacy numeric-only DTO, допускает RX/TX histories разной длины при корректных собственных masks. local10s clock переводит expired DTO в stale без новых сетевых запросов. Видны причина failed collection, последняя попытка и successful collection (не выдаётся за подтверждение measured rate). Offline object не скрывает сохранившуюся историю. ReUI Frame/installed Alert/KpiStatGrid/chart-23 adaptation и theme/base-nova сохранены; новые blocks/vendor components не устанавливались.

Сценарий Эталон и схема Артефакт
Ошибка опроса Существующая ReUI Alert → current — → сохранённая RX/TX история ПК1440, телефон320, API-fixture
Genuine0 → TTL Подтверждённая0 → expiry → —, история остаётся E2E clock/control; без clock-based refetch
Legacy counters Нет происхождения → unknown → новая baseline → measured delta Owned SQL/HTTP collector path

Backend test:traffic-rate прошёл: existing formulas, producer body/in-memory boundaries, strict counter/rate guards, freshness/merge. Frontend projection/dashboard unit tests, traffic flags, scheduler11, application-source TypeScript/backend production build/ESLint passed (unused obsolete ifaceNow helper удалён). Первоначальная freshness unit ошиблась default-param undefined, исправлена на прямой missing-state вызов; backend type adapter учитывает PG Date/string. Scheduler regression assertion разделена: traffic command failure является ошибкой исполнения, не device offline observation.

35 unique E2E eventually passed: initial31=27pass/4fail выявили лишнее требование равной RX/TX длины и положительные fixtures без explicit observations; malformed negative gap fixture заменена правильным null. Delta14=13pass/1fail выявил shorthand-json fixture без metadata; исправлено, delta1 passed. Остальные изменённые positive fixtures21 passed29.5s. Новые4 cases error1440/320/history retained even offline, true0/TTL/no refetch, numeric legacy unknown прошли. Screenshot-only scoped repeats2×2 для видимого warning/history внутри main scroller не считаются новыми сценариями; финальные изображения просмотрены. Existing8 user GRE/VXLAN dirty screenshots не тронуты. Full UI1260/backend24 не повторялись без необходимости.

Owned PG18.6/Node22: test:traffic-rate15709ms,9 counter/source +14 history controls (legacy/first/current/error/old-alarm barrier/users/interfaces/manual failure/success/stale/pending/config/disabled). Real MikrotikClient к loopback HTTP simulator, real SQL + Fastify GET/POST; не physical CHR fault. Common test:alert-engine20075ms:26 source/history SQL/GRE8/actual stability. Второй runner имел старую command label в report; corrected по actual command/harness и asserts before public recording, профиль не подменён повторным traffic run. Own DBs mm_accept_166_1791809970201 иmm_accept_166_1791810266923/ограниченные roles/test containers удалены; отсутствие проверено каталогами/docker. Production secrets не копировались. SQL.

Source448 backend+521 frontend/1032 compiled совпали SHA256. Обе production builds прошли (frontend185s Next phase); frontend ux-history178 staged with old backend ux-rtt177 interop, затем backend ux-history178/version1.0.0-test.history178. Runtime healthy/running/verified imageIds; в.env менялись только tags, rollback ux-rtt177/ux-ping173 без копии секретного env. Migration0011 подтверждена main PG. Новый frontend следует перезагрузить: прежняя вкладка не получает новый truth reader автоматически. Additive storage не гарантирует truthful interpretation старым UI.

Native read-only: оба CHR194.226.121.150/104.165.244.7, GET identity/interface200, по2 interfaces, counters valid;4 native GET, no routerConfigWrites/password changes/messages. Это не loss/speed/WAN proof. Live smoke1440/320+3 APIs подтверждает actual provenance/UI/overflow/pageerrors0; error/legacy branches — отдельно fixtures/ownSQL. Main DB read-only только для native checker; schema migration и штатный scheduler writes были частью deploy.

Следующий179 — inspect/fix live monitor-traffic empty/partial/malformed rates (текущий parseMonitorTraffic заменяет их нулями), per-interface fallback и disabled-after-stream-start polling. Не объявлять этот путь принятым по history guards. Peer collection completeness, long sparse intervals, interface recreation/identity, snapshot after restore, scale/multiple instances и external integrations остаются условиями12.5. Локальный коммит без push.

12.5.179 — достоверный live-трафик, остановка и переподключение (2026-10-12)

parseMonitorTraffic больше не превращает empty/missing/malformed/negative/prefix values в0. Требуются именованные уникальные интерфейсы и обе конечные неотрицательные скорости; для aggregate — полный expected set актуальных активных интерфейсов, loopback исключён. Duplicate/wrong/missing interface и неполный ответ дают error. Настоящий measured0 сохраняется. Дельты и Mbps больше не округляются до хранения/передачи: positive1byte/30s не исчезает; legacy bigint rxBps/txBps округляются только при insert, read consumers используют counters. sum snapshot сохраняет полную точность. UI positive меньше разрешения отображается «<1 Кбит/с», а не fake idle0. Это не подтверждение максимальной производительности интерфейса.

Новый readTrafficLiveSample revalidates enabled/current config перед каждым новым native request и перед публикацией. Device disabled/deleted/config change закрывает SSE с причиной; HTTP401/403 закрывают поток без повторного опроса. Inventory обновляется каждый aggregate tick. Только joined HTTP400 при нескольких интерфейсах допускает per-interface fallback; failures не заглушаются пустыми массивами, partial sum не публикуется. Fallback≤4 concurrent commands, complete-wave budget8s; parent abort/deadline отменяет POST/ожидаемые продолжения. Существующий GET транспорт не принимает AbortSignal, его already-started read ограничен4s; после abort не запускаются следующие commands. Нельзя отозвать уже отправленную native команду. Multiple instances/large inventory/long WAN/revocation of already-established JWT streams отдельно не приняты.

Hook сохраняет конкретную причину error при end-of-stream, закрывает transport после decoding/HTTP failure и cleanup, валидирует timestampKind. «Переподключить live» создаёт новый request key в том же object scope, сохраняет последнее подтверждённое значение как historical до нового sample. При смене scope значения не переносятся. Connecting/error состояния явные; disabled retry during connecting предотвращает повторный запуск. Короткая подпись «Последнее live» помещается на320px, причина видна отдельной Alert. TimestampKind backend-receipt подписан «ответ RouterOS получен приложением»: at не выдаётся за часы устройства. Existing ReUI primitives/layout/theme сохранены.

Состояние Схема Артефакт
Source выключен / SSE закрыт Причина → последнее значение → переподключить → новый sample ПК1440, телефон320, API-fixture
Partial native response Inventory → expected set → unknown/error вместо partial0 Real TCP/HTTP owned SQL

Unit tests parser/completeness/fallback/auth/source/abort/10-interface concurrency/positive-small-rate прошли; frontend formatter/projection, application-source TypeScript/backend build/ESLint прошли. Новая unit initially использовала undefined default argument вместо missing field; fixture исправлена.7 unique E2E (2new retry/cause/320/1440 +5 existing SSE), final pass13.3s. Screenshot scoped repeats2 не новые scenarios; visual review выявила clipped long hint, caption сокращена и final frontend пересобран. Hidden tooltip duplicates в production smoke selector исключены filter visible, functional UI не менялся ради теста.

Owned Node22/PG18.6 profile test:traffic-rate24570ms без skip:9 counters/source+14history+10 live transport cases. Последние — actual Fastify TCP SSE и MikrotikClient HTTP к loopback simulator:0,empty,malformed,partial,complete fallback,failed fallback,401 terminal,disable after first sample/no further native requests,initial disabled404/no native requests,config change/closed stream. Fake RouterOS response не объявлен физической неисправностью CHR. Budget/concurrency refinement вызвала оправданный scoped rerun; финальный DB mm_accept_166_1791814796307/ограниченная role/container удалены, отсутствие проверено. Предыдущий временный mm_accept_166_1791813403915 также удалён trap. Production env/credentials/JWT не копировались. SQL.

Source451 backend+522 frontend/1036 compiled совпали. Production builds прошли; первый frontend build с длинной caption superseded до deploy. Staged frontend ux-live179 с backend ux-history178 interop, затем both ux-live179/version1.0.0-test.live179 runtime healthy/running/imageIds. Только.env tags, rollback both ux-history178 без secret env copy; storage migration не добавлялась.

Настоящие CHR SSE получили первый полный sample на обоих sourceId1/2, затем streams отменены: native interface GET + monitor-traffic read-only POST. Пример краткого наблюдения194 RX0.031584/TX0.002016Mbps,104 RX/TX0.002112Mbps; это не SLA/capacity/WAN proof. Пароли/конфигурация не менялись, messages0. Production browser1440/320: actual live labels/receipt provenance,3APIs200,no overflow/pageerrors. Lab AUTH_REQUIRED=false; JWT/RBAC scopes не объявлены полностью принятыми по этой smoke.

Следующий180 — volume precision/binary units. Read-only baseline уже показал: measured1KiB/1MiB API round to0;100×1MiB также aggregate0;1GiB подписан1.0GB. Baseline сохранён в ignored tmp/volume180-baseline.json и пока не выдан за исправление. Sparse intervals/peer completeness/identity recreation/restore/multi-instance/scale и внешние integrations остаются12.5. Локальный коммит без push.

12.5.180 — точность учтённых объёмов и бинарные единицы (2026-10-12)

Read-only baseline подтверждён до правки: measured1KiB/1MiB превращались в API0 и0.0GB;100×1MiB также aggregate0;1GiB выдавался с decimal labelGB. Убрано toFixed(1) из buildTrafficFromSamples/mergeBuiltTraffic: округление отдельных слагаемых больше не теряет суммарный трафик. Учёт остаётся по known соседним counter deltas, reset/unknown не добавляют выдуманные bytes. Отсутствующий baseline и coverage gaps по-прежнему ограничивают полноту периода.

DTO серверов, пользователей и привязок объявляет volumeUnit=GiB. Frontend принимает эту единицу явно, absent unit оставляет volume — без потери known speed/history; unsupportedGB marker отклоняет DTO. fmtGiB отображает Б/КиБ/МиБ/ГиБ/ТиБ/ПиБ, positive ниже1B как<1B, true0 как0B. Число округляется только при форматировании. Existing rate formatter остаётся decimal Кбит/Мбит/Гбит, binary объёмы не смешиваются с decimal rates. TotalsRow получил semantic group label. ReUI layout/theme/components сохранены. Удалён N+1 server-status SELECT на каждую binding: используется уже прочитанный catalog snapshot.

Состояние Схема Пример
Small positive bytes bytes → exact GiB DTO → подходящая binary unit ПК, 320, API-fixture component capture
Old response without unit unknown unit → —, speeds/history retained E2E actual API path fixture

Backend formulas/volume assertion (known positive delta counts; reset does not), frontend unit boundary/unknown/zero/projection, TypeScript/backend build/ESLint passed.18 E2E passed36.3s (2new volume+10detail+6mobile), screenshot delta2 passed10.5s не новые cases; final widget captures просмотрены. Новые positive fixtures явно объявляют GiB. Existing user8 GRE/VXLAN screenshots не тронуты.

Owned Node22/PG18.6 test:traffic-rate31474ms:9 counters+14history+10actual TCP SSE+6new volume SQL cases, без SQL skip. Новые6 — storage/API GET для1B/1KiB/1MiB/1GiB на server/user/binding;100-part aggregate100MiB; reset lower-bound1MiB+512B. Seeded marker5 rows — собственные SQL fixtures, не физические device counts; отсутствие RouterOS calls в volume-only case не объявлено native acceptance. OwnDB mm_accept_166_1791816469068/ограниченная role/container удалены, absence verified. SQL.

Source452/522/compiled1036 SHA256 parity passed. Обе production builds прошли. Frontend ux-volume180 staged with backend ux-live179 interop: volumes без unit unknown до backend update. Затем both ux-volume180/version1.0.0-test.volume180 runtime healthy/running/imageIds. Только.env tags, rollback both ux-live179; no secret env copy/new migration. Старую вкладку следует перезагрузить для новых unit labels.

Actual volume API показывает GiB и неокруглённые quantities обоих CHR из штатных collector rows; этот checker не отправлял новых native commands. Browser1440/320:3APIs200, actual live/receipt labels/provenance, no errors/overflow. Рабочая конфигурация/пароли не менялись, messages0; auto collectors остаются штатными. Это не WAN byte billing/capacity/SLA proof и не exact arithmetic acceptance за пределами safe integer/scale bounds.

Следующий181 — freshness статуса привязанных интерфейсов: enabled device+old running flag не должен объявлять online после failed/stale poll; peer enabled не доказывает handshake. Проверить native flag provenance и scalar shape, не переписывать legacy rows по догадке. Coverage/peer completeness/recreated interfaces/restore/multi-instance/scale/external integrations остаются12.5. Локальный коммит без push.

12.5.181 — достоверность статусов привязанных интерфейсов (2026-10-12)

Статус привязки теперь требует свежего успешного опроса текущей конфигурации устройства и подтверждённых native флагов. Ошибка, pending, disabled source, истёкший TTL или legacy row без status-known marker дают «Нет данных». Первое корректное измерение интерфейса может подтвердить его running, даже когда ещё недостаточно соседних counters для скорости. История и объёмы сохраняются.

Producer строго принимает true/false и native строки true/false/yes/no; missing/invalid flags больше не подменяются false. Новый бит8 status-known добавляется только новым успешным измерениям; bit4 counter-known не меняется, legacy rows не переписываются. Interface inventory проверяет имена/дубликаты. Включённый WG peer означает конфигурацию, поэтому даёт unknown без handshake proof; disabled peer — «Неактивен». Это не проверка реального VPN-туннеля.

DTO привязок содержит statusObservedAt/statusExpiresAt. Frontend проверяет provenance и TTL, обновляет состояние по своему clock даже без повторной загрузки; прежний payload без дат не считается подтверждением. Общие ReUI layout/base-nova и компоненты сохранены.

Состояние Схема Проверка
Native running + свежий успешный poll native flag → known marker → TTL → Работает own SQL и UI1440/320
Ошибка / старый flag / истёкший TTL последнее измерение → Нет данных own SQL и UI1440/320
Enabled WireGuard peer configuration flag → Нет данных own SQL; handshake не заявлен

TypeScript/backend build/ESLint и профильные unit проверки прошли.8 E2E15.7s (2new+6mobile), после последней правки final delta2 passed10s. Один повтор первоначально не запустился из-за Windows sandbox/SWC access denied; корректный разрешённый запуск прошёл, это не UI failure.

Own PG SQL:48 cases9counter+14history+10TCP SSE+6volume+9status,36163ms, без unavailable skip. Новые9 проверяют настоящий collector→SQL→GET bindings на локальном HTTP RouterOS fixture: первое измерение, enabled/disabled peer, inactive interface, malformed flag,401,legacy bit,stale и disabled source. OwnDB mm_accept_166_1791818856762/ограниченная role/container удалены, отсутствие проверено. Первый запуск harness имел неверный путь распаковки; тесты не начались, его временная база/роль также удалены; пути исправлены до приведённого успешного результата.

Source454/524/compiled1036 SHA256 parity, обе production builds прошли. Frontend ux-status181 сначала проверен с backend ux-volume180 interop; затем both ux-status181 healthy/running/imageIds. Только .env tags, rollback ux-volume180, без копирования secret env и новой миграции.

Native GET: оба CHR доступны, interface counters и boolean flags валидны; DB read-only, RouterOS config writes0/password changes0/messages0. Browser1440/320: actual API/live/receipt labels без ошибок/overflow. Положительные binding branches доказаны собственными SQL/UI fixtures, не выданы за существующие пользовательские привязки стенда. Вкладку следует перезагрузить.

Следующий182 — полнота peer-среза при optional endpoint failure и пропуски истории. Interface running не доказывает end-to-end connectivity, enabled peer не доказывает handshake. Coverage/recreated identity/restore/multi-instance/scale/external integrations остаются открыты в12.5. Локальный коммит без push.

12.5.182 — атомарный приём измерений WireGuard peers (2026-10-12)

Разбор optional peers раньше добавлял каждую строку в общий массив сразу: ошибка следующей строки перехватывалась, а корректный префикс сохранялся как свежий срез. Отсутствующие ключи также молча пропускались. Теперь parseTrafficPeers сначала проверяет весь ответ: массив, объекты, непустые interface/public-key, уникальность пары interface+key, counter values и boolean disabled. Только полностью корректный массив передаётся collector. Ошибка не сохраняет ни одного peer из этого ответа; обычные интерфейсные измерения остаются доступны. Пустой массив — корректный пустой срез.

Ответ Схема результата Проверка
Все peers валидны полная проверка → запись полного среза existing SQL collector profile
Корректный peer → некорректный counter полный срез отклонён → interface сохранён → peer Нет данных новая own SQL проверка
Повторная пара / ответ не массив полный срез отклонён → interface сохранён ещё2 own SQL проверки

Owned PG:51 cases9counter+14history+10TCP SSE+6volume+12status,37534ms, без SQL skip.3 новые проверки используют настоящий HTTP fixture→collector→SQL→GET bindings; проверяют отсутствие partial peer rows, unknown peer status и online native iface. Временная база mm_accept_166_1791819465644, ограниченная роль и контейнер удалены, отсутствие проверено.

Backend TypeScript/build passed; source455/524, compiled1040 SHA256 parity. Frontend не менялся: используется уже собранный и проверенный ux-status181. Новая backend production build ux-peer182 развёрнута и healthy; frontend imageId также проверен. Только backend tag в .env, rollback ux-status181, без новой миграции и копирования секретов.

Native read-only проверил ответы identity/interface/peers обоих CHR; оба доступны. Фактическое число peers сохранено в отчёте: пустой native список не выдан за приёмку активного туннеля. Положительные/некорректные peer случаи доказаны собственными fixtures; новые VPN объекты не создавались, этот блок исправляет collector parser. DB read-only, RouterOS config writes0/password changes0/messages0. Production UI1440/320 проверен с actual API/live/receipt labels без ошибок/overflow.

Следующий183: optional peer endpoint failure пока не получает отдельной видимой причины — interface success остаётся успешным, stale peer становится unknown по предыдущему181. Нужно сохранить причину частичного сбоя, не превращая успешные interface measurements в ошибку. Покрытие пропусков истории, recreated identity, масштаб и внешние интеграции остаются12.5. Локальный коммит без push.